在阅读了有关QL中对algebraic datatypes的支持后,我试图在List
中定义lgtm console类型:
newtype TList =
TNil()
or
TCons(int x,TList xs)
这似乎有效。但是然后我尝试定义auxiliary classes以便具有toString()
谓词:
class List extends TList {
abstract string toString();
}
class Nil extends List,TNil {
override string toString() {
result = "Nil"
}
}
class Cons extends List,TCons {
override string toString() {
// what to put here?
// I would like something like result = x.toString() + ':' + xs.toString()
}
}
而我很困惑。我不知道如何从x
中引用构造函数参数xs
和Cons
。我尝试了this.x
和this.xs
,但似乎不起作用。
如何在成员谓词中引用构造函数参数?
由于Cons
扩展了TCons
,因此您可以在this
的成员谓词中的任何位置将TCons
视为Cons
的实例。这意味着您可以将this
与TCons
的特定实例进行比较,并将变量绑定到构造函数参数。
override string toString() {
exists(int x, List xs |
this = TCons(x, xs) and
result = x.toString() + ":" + xs.toString()
)
}
由于您可能还希望在Cons
的其他成员谓词中使用构造函数参数,因此可以改为声明fields在特征谓词中捕获一次构造函数参数,然后在成员谓词中使用它们:
class Cons extends List, TCons {
int x;
List xs;
Cons() {
this = TCons(x, xs)
}
override string toString() {
result = x.toString() + ":" + xs.toString()
}
}
仅提醒您,正如您链接到的CodeQL手册页所指出的那样,CodeQL中代数数据类型的语法仍处于试验阶段,可能会发生变化。