Skip to content

Commit c488392

Browse files
authored
Merge pull request github#11519 from erik-krogh/equiv
QL: Mock the `QlBuiltins` module in QL-for-QL
2 parents b330b62 + 38bd4d9 commit c488392

File tree

18 files changed

+590
-56
lines changed

18 files changed

+590
-56
lines changed

ql/ql/src/codeql_ql/ast/Ast.qll

Lines changed: 87 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ private import codeql_ql.ast.internal.Predicate
55
import codeql_ql.ast.internal.Type
66
private import codeql_ql.ast.internal.Variable
77
private import codeql_ql.ast.internal.Builtins
8+
private import internal.AstMocks as Mocks
89

910
bindingset[name]
1011
private string directMember(string name) { result = name + "()" }
@@ -501,11 +502,11 @@ class PredicateExpr extends TPredicateExpr, AstNode {
501502
* A classless predicate.
502503
*/
503504
class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclaration {
504-
QL::ClasslessPredicate pred;
505+
Mocks::ClasslessPredicateOrMock pred;
505506

506507
ClasslessPredicate() { this = TClasslessPredicate(pred) }
507508

508-
override Location getLocation() { result = pred.getName().getLocation() }
509+
override Location getLocation() { result = pred.asLeft().getName().getLocation() }
509510

510511
/**
511512
* Gets the aliased value if this predicate is an alias
@@ -514,25 +515,39 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati
514515
*/
515516
final AstNode getAlias() {
516517
exists(QL::PredicateAliasBody alias |
517-
alias.getParent() = pred and
518+
alias.getParent() = pred.asLeft() and
518519
toQL(result).getParent() = alias
519520
)
520521
or
521-
toQL(result) = pred.getChild(_).(QL::HigherOrderTerm)
522+
toQL(result) = pred.asLeft().getChild(_).(QL::HigherOrderTerm)
522523
}
523524

524525
override string getAPrimaryQlClass() { result = "ClasslessPredicate" }
525526

526-
override Formula getBody() { toQL(result) = pred.getChild(_).(QL::Body).getChild() }
527+
override Formula getBody() { toQL(result) = pred.asLeft().getChild(_).(QL::Body).getChild() }
527528

528-
override string getName() { result = pred.getName().getValue() }
529+
override string getName() {
530+
result = pred.asLeft().getName().getValue()
531+
or
532+
result = pred.asRight().getName()
533+
}
529534

530535
override VarDecl getParameter(int i) {
531536
toQL(result) =
532-
rank[i + 1](QL::VarDecl decl, int index | decl = pred.getChild(index) | decl order by index)
537+
rank[i + 1](QL::VarDecl decl, int index |
538+
decl = pred.asLeft().getChild(index)
539+
|
540+
decl order by index
541+
)
542+
or
543+
toMock(result) = pred.asRight().getParameter(i)
533544
}
534545

535-
override TypeExpr getReturnTypeExpr() { toQL(result) = pred.getReturnType() }
546+
override TypeExpr getReturnTypeExpr() {
547+
toQL(result) = pred.asLeft().getReturnType()
548+
or
549+
toMock(result) = pred.asRight().getReturnTypeExpr()
550+
}
536551

537552
override AstNode getAChild(string pred_name) {
538553
result = Predicate.super.getAChild(pred_name)
@@ -651,11 +666,15 @@ class VarDef extends TVarDef, AstNode {
651666
* A variable declaration, with a type and a name.
652667
*/
653668
class VarDecl extends TVarDecl, VarDef, Declaration {
654-
QL::VarDecl var;
669+
Mocks::VarDeclOrMock var;
655670

656671
VarDecl() { this = TVarDecl(var) }
657672

658-
override string getName() { result = var.getChild(1).(QL::VarName).getChild().getValue() }
673+
override string getName() {
674+
result = var.asLeft().getChild(1).(QL::VarName).getChild().getValue()
675+
or
676+
result = var.asRight().getName()
677+
}
659678

660679
override Type getType() { result = this.getTypeExpr().getResolvedType() }
661680

@@ -664,14 +683,18 @@ class VarDecl extends TVarDecl, VarDef, Declaration {
664683
/**
665684
* Gets the type part of this variable declaration.
666685
*/
667-
TypeExpr getTypeExpr() { toQL(result) = var.getChild(0) }
686+
TypeExpr getTypeExpr() {
687+
toQL(result) = var.asLeft().getChild(0)
688+
or
689+
toMock(result) = var.asRight().getType()
690+
}
668691

669692
/**
670693
* Holds if this variable declaration is a private field on a class.
671694
*/
672695
predicate isPrivate() {
673696
exists(QL::ClassMember member |
674-
var = member.getChild(_).(QL::Field).getChild() and
697+
var.asLeft() = member.getChild(_).(QL::Field).getChild() and
675698
member.getAFieldOrChild().(QL::Annotation).getName().getValue() = "private"
676699
)
677700
}
@@ -725,7 +748,7 @@ class FieldDecl extends TFieldDecl, AstNode {
725748
* A type reference, such as `DataFlow::Node`.
726749
*/
727750
class TypeExpr extends TType, TypeRef {
728-
QL::TypeExpr type;
751+
Mocks::TypeExprOrMock type;
729752

730753
TypeExpr() { this = TType(type) }
731754

@@ -738,28 +761,30 @@ class TypeExpr extends TType, TypeRef {
738761
* or db-types such as `@locateable`.
739762
*/
740763
string getClassName() {
741-
result = type.getName().getValue()
764+
result = type.asLeft().getName().getValue()
742765
or
743-
result = type.getChild().(QL::PrimitiveType).getValue()
766+
result = type.asLeft().getChild().(QL::PrimitiveType).getValue()
744767
or
745-
result = type.getChild().(QL::Dbtype).getValue()
768+
result = type.asLeft().getChild().(QL::Dbtype).getValue()
769+
or
770+
result = type.asRight().getClassName()
746771
}
747772

748773
/**
749774
* Holds if this type is a primitive such as `string` or `int`.
750775
*/
751-
predicate isPrimitive() { type.getChild() instanceof QL::PrimitiveType }
776+
predicate isPrimitive() { type.asLeft().getChild() instanceof QL::PrimitiveType }
752777

753778
/**
754779
* Holds if this type is a db-type.
755780
*/
756-
predicate isDBType() { type.getChild() instanceof QL::Dbtype }
781+
predicate isDBType() { type.asLeft().getChild() instanceof QL::Dbtype }
757782

758783
/**
759784
* Gets the module of the type, if it exists.
760785
* E.g. `DataFlow` in `DataFlow::Node`.
761786
*/
762-
ModuleExpr getModule() { toQL(result) = type.getQualifier() }
787+
ModuleExpr getModule() { toQL(result) = type.asLeft().getQualifier() }
763788

764789
/** Gets the type that this type reference refers to. */
765790
override Type getResolvedType() {
@@ -781,34 +806,44 @@ class TypeExpr extends TType, TypeRef {
781806
* A QL module.
782807
*/
783808
class Module extends TModule, ModuleDeclaration {
784-
QL::Module mod;
809+
Mocks::ModuleOrMock mod;
785810

786811
Module() { this = TModule(mod) }
787812

788-
override Location getLocation() { result = mod.getName().getLocation() }
813+
override Location getLocation() { result = mod.asLeft().getName().getLocation() }
789814

790815
override string getAPrimaryQlClass() { result = "Module" }
791816

792-
override string getName() { result = mod.getName().getChild().getValue() }
817+
override string getName() {
818+
result = mod.asLeft().getName().getChild().getValue()
819+
or
820+
result = mod.asRight().getName()
821+
}
793822

794823
/**
795824
* Gets a member of the module.
796825
*/
797-
AstNode getAMember() { toQL(result) = mod.getChild(_).(QL::ModuleMember).getChild(_) }
826+
AstNode getAMember() { result = this.getMember(_) }
798827

799-
AstNode getMember(int i) { toQL(result) = mod.getChild(i).(QL::ModuleMember).getChild(_) }
828+
AstNode getMember(int i) {
829+
toQL(result) = mod.asLeft().getChild(i).(QL::ModuleMember).getChild(_)
830+
or
831+
toMock(result) = mod.asRight().getMember(i)
832+
}
800833

801834
QLDoc getQLDocFor(AstNode m) {
802835
exists(int i | result = this.getMember(i) and m = this.getMember(i + 1))
803836
}
804837

805838
/** Gets a ref to the module that this module implements. */
806839
TypeRef getImplements(int i) {
807-
exists(SignatureExpr sig | sig.toQL() = mod.getImplements(i) | result = sig.asType())
840+
exists(SignatureExpr sig | sig.toQL() = mod.asLeft().getImplements(i) | result = sig.asType())
808841
}
809842

810843
/** Gets the module expression that this module is an alias for, if any. */
811-
ModuleExpr getAlias() { toQL(result) = mod.getAFieldOrChild().(QL::ModuleAliasBody).getChild() }
844+
ModuleExpr getAlias() {
845+
toQL(result) = mod.asLeft().getAFieldOrChild().(QL::ModuleAliasBody).getChild()
846+
}
812847

813848
override AstNode getAChild(string pred) {
814849
result = super.getAChild(pred)
@@ -825,10 +860,12 @@ class Module extends TModule, ModuleDeclaration {
825860
/** Holds if the `i`th parameter of this module has `name` and type `sig`. */
826861
predicate hasParameter(int i, string name, SignatureExpr sig) {
827862
exists(QL::ModuleParam param |
828-
param = mod.getParameter(i) and
863+
param = mod.asLeft().getParameter(i) and
829864
name = param.getParameter().getValue() and
830865
sig.toQL() = param.getSignature()
831866
)
867+
or
868+
mod.asRight().hasTypeParam(i, toMock(sig), name)
832869
}
833870
}
834871

@@ -866,22 +903,26 @@ class TypeDeclaration extends TTypeDeclaration, Declaration { }
866903
* A QL class.
867904
*/
868905
class Class extends TClass, TypeDeclaration, ModuleDeclaration {
869-
QL::Dataclass cls;
906+
Mocks::ClassOrMock cls;
870907

871908
Class() { this = TClass(cls) }
872909

873-
override Location getLocation() { result = cls.getName().getLocation() }
910+
override Location getLocation() { result = cls.asLeft().getName().getLocation() }
874911

875912
override string getAPrimaryQlClass() { result = "Class" }
876913

877-
override string getName() { result = cls.getName().getValue() }
914+
override string getName() {
915+
result = cls.asLeft().getName().getValue()
916+
or
917+
result = cls.asRight().getName()
918+
}
878919

879920
/**
880921
* Gets the characteristic predicate for this class.
881922
*/
882-
CharPred getCharPred() { toQL(result) = cls.getChild(_).(QL::ClassMember).getChild(_) }
923+
CharPred getCharPred() { toQL(result) = cls.asLeft().getChild(_).(QL::ClassMember).getChild(_) }
883924

884-
AstNode getMember(int i) { toQL(result) = cls.getChild(i).(QL::ClassMember).getChild(_) }
925+
AstNode getMember(int i) { toQL(result) = cls.asLeft().getChild(i).(QL::ClassMember).getChild(_) }
885926

886927
QLDoc getQLDocFor(AstNode m) {
887928
exists(int i | result = this.getMember(i) and m = this.getMember(i + 1))
@@ -891,7 +932,7 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
891932
* Gets a predicate in this class.
892933
*/
893934
ClassPredicate getAClassPredicate() {
894-
toQL(result) = cls.getChild(_).(QL::ClassMember).getChild(_)
935+
toQL(result) = cls.asLeft().getChild(_).(QL::ClassMember).getChild(_)
895936
}
896937

897938
/**
@@ -910,18 +951,20 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
910951
/**
911952
* Gets a super-type referenced in the `extends` part of the class declaration.
912953
*/
913-
TypeExpr getASuperType() { toQL(result) = cls.getExtends(_) }
954+
TypeExpr getASuperType() { toQL(result) = cls.asLeft().getExtends(_) }
914955

915956
/**
916957
* Gets a type referenced in the `instanceof` part of the class declaration.
917958
*/
918-
TypeExpr getAnInstanceofType() { toQL(result) = cls.getInstanceof(_) }
959+
TypeExpr getAnInstanceofType() { toQL(result) = cls.asLeft().getInstanceof(_) }
919960

920961
/** Gets the type that this class is defined to be an alias of. */
921-
TypeExpr getAliasType() { toQL(result) = cls.getChild(_).(QL::TypeAliasBody).getChild() }
962+
TypeExpr getAliasType() { toQL(result) = cls.asLeft().getChild(_).(QL::TypeAliasBody).getChild() }
922963

923964
/** Gets the type of one of the members that this class is defined to be a union of. */
924-
TypeExpr getUnionMember() { toQL(result) = cls.getChild(_).(QL::TypeUnionBody).getChild(_) }
965+
TypeExpr getUnionMember() {
966+
toQL(result) = cls.asLeft().getChild(_).(QL::TypeUnionBody).getChild(_)
967+
}
925968

926969
/** Gets the class type defined by this class declaration. */
927970
Type getType() { result.getDeclaration() = this }
@@ -2383,18 +2426,20 @@ class ModuleExpr extends TModuleExpr, TypeRef {
23832426

23842427
/** A signature expression, either a `PredicateExpr`, a `TypeExpr`, or a `ModuleExpr`. */
23852428
class SignatureExpr extends TSignatureExpr, AstNode {
2386-
QL::SignatureExpr sig;
2429+
Mocks::SignatureExprOrMock sig;
23872430

23882431
SignatureExpr() {
2389-
toQL(this) = sig.getPredicate()
2432+
toQL(this) = sig.asLeft().getPredicate()
2433+
or
2434+
toQL(this) = sig.asLeft().getTypeExpr()
23902435
or
2391-
toQL(this) = sig.getTypeExpr()
2436+
toMock(this) = sig.asRight()
23922437
or
2393-
toQL(this) = sig.getModExpr()
2438+
toQL(this) = sig.asLeft().getModExpr()
23942439
}
23952440

23962441
/** Gets the generated AST node that contains this signature expression. */
2397-
QL::SignatureExpr toQL() { result = sig }
2442+
QL::SignatureExpr toQL() { result = sig.asLeft() }
23982443

23992444
/** Gets this signature expression if it represents a predicate expression. */
24002445
PredicateExpr asPredicate() { result = this }

0 commit comments

Comments
 (0)