classless predicate, used to model the edgeSig predicate

This commit is contained in:
erik-krogh 2022-12-01 13:40:14 +01:00
Родитель 4dc52379ad
Коммит 4feb48ce5f
Не найден ключ, соответствующий данной подписи
4 изменённых файлов: 65 добавлений и 17 удалений

Просмотреть файл

@ -500,11 +500,11 @@ class PredicateExpr extends TPredicateExpr, AstNode {
* A classless predicate.
*/
class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclaration {
QL::ClasslessPredicate pred;
Mocks::ClasslessPredicateOrMock pred;
ClasslessPredicate() { this = TClasslessPredicate(pred) }
override Location getLocation() { result = pred.getName().getLocation() }
override Location getLocation() { result = pred.asLeft().getName().getLocation() }
/**
* Gets the aliased value if this predicate is an alias
@ -513,25 +513,33 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati
*/
final AstNode getAlias() {
exists(QL::PredicateAliasBody alias |
alias.getParent() = pred and
alias.getParent() = pred.asLeft() and
toQL(result).getParent() = alias
)
or
toQL(result) = pred.getChild(_).(QL::HigherOrderTerm)
toQL(result) = pred.asLeft().getChild(_).(QL::HigherOrderTerm)
}
override string getAPrimaryQlClass() { result = "ClasslessPredicate" }
override Formula getBody() { toQL(result) = pred.getChild(_).(QL::Body).getChild() }
override Formula getBody() { toQL(result) = pred.asLeft().getChild(_).(QL::Body).getChild() }
override string getName() { result = pred.getName().getValue() }
override string getName() {
result = pred.asLeft().getName().getValue()
or
result = pred.asRight().getName()
}
override VarDecl getParameter(int i) {
toQL(result) =
rank[i + 1](QL::VarDecl decl, int index | decl = pred.getChild(index) | decl order by index)
rank[i + 1](QL::VarDecl decl, int index |
decl = pred.asLeft().getChild(index)
|
decl order by index
)
}
override TypeExpr getReturnTypeExpr() { toQL(result) = pred.getReturnType() }
override TypeExpr getReturnTypeExpr() { toQL(result) = pred.asLeft().getReturnType() }
override AstNode getAChild(string pred_name) {
result = Predicate.super.getAChild(pred_name)

Просмотреть файл

@ -17,7 +17,8 @@ private import codeql.util.Either
newtype TMockAst =
TMockModule(string id) { id instanceof MockModule::Range } or
TMockClass(string id) { id instanceof MockClass::Range } or
TMockTypeExpr(string id) { id instanceof MockTypeExpr::Range }
TMockTypeExpr(string id) { id instanceof MockTypeExpr::Range } or
TMockClasslessPredicate(string id) { id instanceof MockClasslessPredicate::Range }
/** Gets a mocked Ast node from the string ID that represents it. */
MockAst fromId(string id) {
@ -26,6 +27,8 @@ MockAst fromId(string id) {
result = TMockClass(id)
or
result = TMockTypeExpr(id)
or
result = TMockClasslessPredicate(id)
// TODO: Other nodes.
}
@ -51,7 +54,7 @@ class MockModule extends MockAst, TMockModule {
final MockAst getMember(int i) { result = fromId(range.getMember(i)) }
final predicate hasTypeParam(int i, MockAst type, string name) {
range.hasTypeParam(i, type.toString(), name)
range.hasTypeParam(i, type.getId(), name)
}
}
@ -139,3 +142,32 @@ module MockTypeExpr {
class TypeExprOrMock = Either<QL::TypeExpr, MockTypeExpr>::Either;
class SignatureExprOrMock = Either<QL::SignatureExpr, MockSignatureExpr>::Either;
/**
* A mocked `ClasslessPredicate`.
*/
class MockClasslessPredicate extends MockAst {
MockClasslessPredicate::Range range;
MockClasslessPredicate() { this = TMockClasslessPredicate(range) }
final string getName() { result = range.getName() }
// TODO: VarDecl.
final MockAst getParameter(int i) { result.getId() = range.getParameter(i) }
}
module MockClasslessPredicate {
abstract class Range extends string {
bindingset[this]
Range() { this = this }
/** Gets the name of the predicate. */
abstract string getName();
/** Gets the `i`th parameter of the predicate. */
abstract string getParameter(int i);
}
}
class ClasslessPredicateOrMock = Either<QL::ClasslessPredicate, MockClasslessPredicate>::Either;

Просмотреть файл

@ -9,7 +9,7 @@ newtype TAstNode =
TQLDoc(QL::Qldoc qldoc) or
TBlockComment(QL::BlockComment comment) or
TLineComment(QL::LineComment comment) or
TClasslessPredicate(QL::ClasslessPredicate pred) or
TClasslessPredicate(Mocks::ClasslessPredicateOrMock pred) or
TVarDecl(QL::VarDecl decl) or
TFieldDecl(QL::Field field) or
TClass(Mocks::ClassOrMock cls) or
@ -160,7 +160,7 @@ QL::AstNode toQL(AST::AstNode n) {
or
n = TLineComment(result)
or
n = TClasslessPredicate(result)
n = TClasslessPredicate(any(Mocks::ClasslessPredicateOrMock m | m.asLeft() = result))
or
n = TVarDecl(result)
or
@ -213,6 +213,8 @@ Mocks::MockAst toMock(AST::AstNode n) {
n = TClass(any(Mocks::ClassOrMock m | m.asRight() = result))
or
n = TType(any(Mocks::TypeExprOrMock m | m.asRight() = result))
or
n = TClasslessPredicate(any(Mocks::ClasslessPredicateOrMock m | m.asRight() = result))
}
class TPredicate =

Просмотреть файл

@ -150,11 +150,7 @@ module QlBuiltinsMocks {
i = 0 and name = "MyT" and type instanceof EdgeSigType
}
override string getMember(int i) {
// i = 0 and
// result instanceof EdgeSig::EdgeSigPredicate
none() // TODO:
}
override string getMember(int i) { i = 0 and result instanceof EdgeSigPred }
}
class EdgeSigType extends MockTypeExpr::Range {
@ -162,6 +158,16 @@ module QlBuiltinsMocks {
override string getClassName() { result = "MyT" }
}
class EdgeSigPred extends MockClasslessPredicate::Range {
EdgeSigPred() { this = "Mock: QlBuiltins::EdgeSig::edgeSig" }
override string getName() { result = "edgeSig" }
override string getParameter(int i) {
none() // TODO:
}
}
}
class EquivalenceRelationModule extends MockModule::Range {