Запись toString () для типа данных algebrai c с параметрами в Semmle QL - PullRequest
0 голосов
/ 17 января 2020

Прочитав о поддержке algebrai c типов данных в QL, я пытаюсь определить тип List в консоли lgtm :

newtype TList =
  TNil()
  or
  TCons(int x,TList xs)

Кажется, это работает. Но затем я пытаюсь определить вспомогательные классы , чтобы иметь предикат 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, но, похоже, это не работает.

Как я могу ссылаться на параметры конструктора внутри предиката члена?

1 Ответ

1 голос
/ 17 января 2020

Поскольку 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, вы можете вместо этого объявить поля , чтобы захватить параметры конструктора один раз в предикате характеристики c, а затем использовать их в предикатах-членах:

class Cons extends List, TCons {
    int x;
    List xs;

    Cons() {
        this = TCons(x, xs)
    }

    override string toString() {
        result = x.toString() + ":" + xs.toString()
    }
}

Просто напоминание: как указывает страница справочника QL, на которую вы ссылаетесь, синтаксис типов алгебраических данных c в QL все еще является экспериментальным и может быть изменен.

...