在 Semmle QL 中为带参数的代数数据类型编写 toString()

Writing toString() for an algebraic data type with parameters in Semmle QL

阅读有关 algebraic datatypes in QL, I'm trying to define a List type in the 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()
    }
}

我被难住了。我不知道如何从 Cons 中引用构造函数参数 xxsthis.xthis.xs 都试过了,好像都不行。

如何在成员谓词中引用构造函数参数?

由于 Cons 扩展了 TCons,您可以将 this 视为 Cons 成员谓词中任何位置的 TCons 的实例。这意味着您可以将 thisTCons 的特定实例进行比较,并将变量绑定到构造函数参数。

    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()
    }
}

提醒一下:正如您 link 所指出的 QL 手册页面所示,QL 中代数数据类型的语法仍处于试验阶段,可能会发生变化。