mirror of
https://github.com/github/codeql.git
synced 2026-06-28 16:17:03 +02:00
Merge pull request #22067 from asgerf/unified/printast
Unified: Generate PrintAst helper and implement PrintAst query
This commit is contained in:
@@ -1312,6 +1312,244 @@ module QL {
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() { ql_variable_def(this, result) }
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(AddExpr).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(AddExpr).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(AddExpr).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Aggregate).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(AnnotArg).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Annotation).getArgs(i) and name = "getArgs"
|
||||
or
|
||||
result = node.(Annotation).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(AritylessPredicateExpr).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(AritylessPredicateExpr).getQualifier() and i = -1 and name = "getQualifier"
|
||||
or
|
||||
result = node.(AsExpr).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(AsExprs).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Body).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Bool).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(CallBody).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(CallOrUnqualAggExpr).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Charpred).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Charpred).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(ClassMember).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ClasslessPredicate).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ClasslessPredicate).getReturnType() and i = -1 and name = "getReturnType"
|
||||
or
|
||||
result = node.(ClasslessPredicate).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(CompTerm).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(CompTerm).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(CompTerm).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Conjunction).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(Conjunction).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(Dataclass).getExtends(i) and name = "getExtends"
|
||||
or
|
||||
result = node.(Dataclass).getInstanceof(i) and name = "getInstanceof"
|
||||
or
|
||||
result = node.(Dataclass).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Dataclass).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Datatype).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Datatype).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(DatatypeBranch).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(DatatypeBranch).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(DatatypeBranches).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Disjunction).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(Disjunction).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(ExprAggregateBody).getAsExprs() and i = -1 and name = "getAsExprs"
|
||||
or
|
||||
result = node.(ExprAggregateBody).getOrderBys() and i = -1 and name = "getOrderBys"
|
||||
or
|
||||
result = node.(ExprAnnotation).getAnnotArg() and i = -1 and name = "getAnnotArg"
|
||||
or
|
||||
result = node.(ExprAnnotation).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ExprAnnotation).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Field).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(FullAggregateBody).getAsExprs() and i = -1 and name = "getAsExprs"
|
||||
or
|
||||
result = node.(FullAggregateBody).getGuard() and i = -1 and name = "getGuard"
|
||||
or
|
||||
result = node.(FullAggregateBody).getOrderBys() and i = -1 and name = "getOrderBys"
|
||||
or
|
||||
result = node.(FullAggregateBody).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(HigherOrderTerm).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(HigherOrderTerm).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(IfTerm).getCond() and i = -1 and name = "getCond"
|
||||
or
|
||||
result = node.(IfTerm).getFirst() and i = -1 and name = "getFirst"
|
||||
or
|
||||
result = node.(IfTerm).getSecond() and i = -1 and name = "getSecond"
|
||||
or
|
||||
result = node.(Implication).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(Implication).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(ImportDirective).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ImportModuleExpr).getQualName(i) and name = "getQualName"
|
||||
or
|
||||
result = node.(ImportModuleExpr).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(InExpr).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(InExpr).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(InstanceOf).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Literal).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(MemberPredicate).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(MemberPredicate).getReturnType() and i = -1 and name = "getReturnType"
|
||||
or
|
||||
result = node.(MemberPredicate).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Module).getImplements(i) and name = "getImplements"
|
||||
or
|
||||
result = node.(Module).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Module).getParameter(i) and name = "getParameter"
|
||||
or
|
||||
result = node.(Module).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ModuleAliasBody).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(ModuleExpr).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ModuleExpr).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(ModuleInstantiation).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ModuleInstantiation).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ModuleMember).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ModuleName).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(ModuleParam).getParameter() and i = -1 and name = "getParameter"
|
||||
or
|
||||
result = node.(ModuleParam).getSignature() and i = -1 and name = "getSignature"
|
||||
or
|
||||
result = node.(MulExpr).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(MulExpr).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(MulExpr).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Negation).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(OrderBy).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(OrderBys).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ParExpr).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(PredicateAliasBody).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(PredicateExpr).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(PrefixCast).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Ql).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(QualifiedRhs).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(QualifiedRhs).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(QualifiedExpr).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Quantified).getExpr() and i = -1 and name = "getExpr"
|
||||
or
|
||||
result = node.(Quantified).getFormula() and i = -1 and name = "getFormula"
|
||||
or
|
||||
result = node.(Quantified).getRange() and i = -1 and name = "getRange"
|
||||
or
|
||||
result = node.(Quantified).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Range).getLower() and i = -1 and name = "getLower"
|
||||
or
|
||||
result = node.(Range).getUpper() and i = -1 and name = "getUpper"
|
||||
or
|
||||
result = node.(Select).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(SetLiteral).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(SignatureExpr).getModExpr() and i = -1 and name = "getModExpr"
|
||||
or
|
||||
result = node.(SignatureExpr).getPredicate() and i = -1 and name = "getPredicate"
|
||||
or
|
||||
result = node.(SignatureExpr).getTypeExpr() and i = -1 and name = "getTypeExpr"
|
||||
or
|
||||
result = node.(SpecialCall).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(SuperRef).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(TypeAliasBody).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(TypeExpr).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(TypeExpr).getQualifier() and i = -1 and name = "getQualifier"
|
||||
or
|
||||
result = node.(TypeExpr).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(TypeUnionBody).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(UnaryExpr).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(UnqualAggBody).getAsExprs(i) and name = "getAsExprs"
|
||||
or
|
||||
result = node.(UnqualAggBody).getGuard() and i = -1 and name = "getGuard"
|
||||
or
|
||||
result = node.(UnqualAggBody).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(VarDecl).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(VarName).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Variable).getChild() and i = -1 and name = "getChild"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
@@ -1669,6 +1907,60 @@ module Dbscheme {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
final override string getAPrimaryQlClass() { result = "Varchar" }
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(Annotation).getArgsAnnotation() and i = -1 and name = "getArgsAnnotation"
|
||||
or
|
||||
result = node.(Annotation).getSimpleAnnotation() and i = -1 and name = "getSimpleAnnotation"
|
||||
or
|
||||
result = node.(ArgsAnnotation).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ArgsAnnotation).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Branch).getQldoc() and i = -1 and name = "getQldoc"
|
||||
or
|
||||
result = node.(Branch).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(CaseDecl).getBase() and i = -1 and name = "getBase"
|
||||
or
|
||||
result = node.(CaseDecl).getDiscriminator() and i = -1 and name = "getDiscriminator"
|
||||
or
|
||||
result = node.(CaseDecl).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ColType).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Column).getColName() and i = -1 and name = "getColName"
|
||||
or
|
||||
result = node.(Column).getColType() and i = -1 and name = "getColType"
|
||||
or
|
||||
result = node.(Column).getIsRef() and i = -1 and name = "getIsRef"
|
||||
or
|
||||
result = node.(Column).getIsUnique() and i = -1 and name = "getIsUnique"
|
||||
or
|
||||
result = node.(Column).getQldoc() and i = -1 and name = "getQldoc"
|
||||
or
|
||||
result = node.(Column).getReprType() and i = -1 and name = "getReprType"
|
||||
or
|
||||
result = node.(Dbscheme).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Entry).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(ReprType).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Table).getTableName() and i = -1 and name = "getTableName"
|
||||
or
|
||||
result = node.(Table).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(TableName).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(UnionDecl).getBase() and i = -1 and name = "getBase"
|
||||
or
|
||||
result = node.(UnionDecl).getChild(i) and name = "getChild"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
@@ -1803,6 +2095,24 @@ module Blame {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
final override string getAPrimaryQlClass() { result = "Number" }
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(BlameEntry).getDate() and i = -1 and name = "getDate"
|
||||
or
|
||||
result = node.(BlameEntry).getLine(i) and name = "getLine"
|
||||
or
|
||||
result = node.(BlameInfo).getFileEntry(i) and name = "getFileEntry"
|
||||
or
|
||||
result = node.(BlameInfo).getToday() and i = -1 and name = "getToday"
|
||||
or
|
||||
result = node.(FileEntry).getBlameEntry(i) and name = "getBlameEntry"
|
||||
or
|
||||
result = node.(FileEntry).getFileName() and i = -1 and name = "getFileName"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
@@ -1977,4 +2287,22 @@ module JSON {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
final override string getAPrimaryQlClass() { result = "True" }
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(Array).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Document).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Object).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Pair).getKey() and i = -1 and name = "getKey"
|
||||
or
|
||||
result = node.(Pair).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(String).getChild(i) and name = "getChild"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1964,6 +1964,340 @@ module Ruby {
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() { ruby_yield_child(this, result) }
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(Alias).getAlias() and i = -1 and name = "getAlias"
|
||||
or
|
||||
result = node.(Alias).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(AlternativePattern).getAlternatives(i) and name = "getAlternatives"
|
||||
or
|
||||
result = node.(ArgumentList).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Array).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ArrayPattern).getClass() and i = -1 and name = "getClass"
|
||||
or
|
||||
result = node.(ArrayPattern).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(AsPattern).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(AsPattern).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Assignment).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(Assignment).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(BareString).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(BareSymbol).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Begin).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(BeginBlock).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Binary).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(Binary).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(Block).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Block).getParameters() and i = -1 and name = "getParameters"
|
||||
or
|
||||
result = node.(BlockArgument).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(BlockBody).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(BlockParameter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(BlockParameters).getLocals(i) and name = "getLocals"
|
||||
or
|
||||
result = node.(BlockParameters).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(BodyStatement).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Break).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Call).getArguments() and i = -1 and name = "getArguments"
|
||||
or
|
||||
result = node.(Call).getBlock() and i = -1 and name = "getBlock"
|
||||
or
|
||||
result = node.(Call).getMethod() and i = -1 and name = "getMethod"
|
||||
or
|
||||
result = node.(Call).getOperator() and i = -1 and name = "getOperator"
|
||||
or
|
||||
result = node.(Call).getReceiver() and i = -1 and name = "getReceiver"
|
||||
or
|
||||
result = node.(Case).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Case).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(CaseMatch).getClauses(i) and name = "getClauses"
|
||||
or
|
||||
result = node.(CaseMatch).getElse() and i = -1 and name = "getElse"
|
||||
or
|
||||
result = node.(CaseMatch).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(ChainedString).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Class).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Class).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Class).getSuperclass() and i = -1 and name = "getSuperclass"
|
||||
or
|
||||
result = node.(Complex).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Conditional).getAlternative() and i = -1 and name = "getAlternative"
|
||||
or
|
||||
result = node.(Conditional).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(Conditional).getConsequence() and i = -1 and name = "getConsequence"
|
||||
or
|
||||
result = node.(DelimitedSymbol).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(DestructuredLeftAssignment).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(DestructuredParameter).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Do).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(DoBlock).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(DoBlock).getParameters() and i = -1 and name = "getParameters"
|
||||
or
|
||||
result = node.(ElementReference).getBlock() and i = -1 and name = "getBlock"
|
||||
or
|
||||
result = node.(ElementReference).getObject() and i = -1 and name = "getObject"
|
||||
or
|
||||
result = node.(ElementReference).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Else).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Elsif).getAlternative() and i = -1 and name = "getAlternative"
|
||||
or
|
||||
result = node.(Elsif).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(Elsif).getConsequence() and i = -1 and name = "getConsequence"
|
||||
or
|
||||
result = node.(EndBlock).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Ensure).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ExceptionVariable).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Exceptions).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ExpressionReferencePattern).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(FindPattern).getClass() and i = -1 and name = "getClass"
|
||||
or
|
||||
result = node.(FindPattern).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(For).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(For).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(For).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Hash).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(HashPattern).getClass() and i = -1 and name = "getClass"
|
||||
or
|
||||
result = node.(HashPattern).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(HashSplatArgument).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(HashSplatParameter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(HeredocBody).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(If).getAlternative() and i = -1 and name = "getAlternative"
|
||||
or
|
||||
result = node.(If).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(If).getConsequence() and i = -1 and name = "getConsequence"
|
||||
or
|
||||
result = node.(IfGuard).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(IfModifier).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(IfModifier).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(In).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(InClause).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(InClause).getGuard() and i = -1 and name = "getGuard"
|
||||
or
|
||||
result = node.(InClause).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(Interpolation).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(KeywordParameter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(KeywordParameter).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(KeywordPattern).getKey() and i = -1 and name = "getKey"
|
||||
or
|
||||
result = node.(KeywordPattern).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Lambda).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Lambda).getParameters() and i = -1 and name = "getParameters"
|
||||
or
|
||||
result = node.(LambdaParameters).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(LeftAssignmentList).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(MatchPattern).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(MatchPattern).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Method).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Method).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Method).getParameters() and i = -1 and name = "getParameters"
|
||||
or
|
||||
result = node.(MethodParameters).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Module).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Module).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Next).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(OperatorAssignment).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(OperatorAssignment).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(OptionalParameter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(OptionalParameter).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Pair).getKey() and i = -1 and name = "getKey"
|
||||
or
|
||||
result = node.(Pair).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(ParenthesizedPattern).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(ParenthesizedStatements).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Pattern).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Program).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Range).getBegin() and i = -1 and name = "getBegin"
|
||||
or
|
||||
result = node.(Range).getEnd() and i = -1 and name = "getEnd"
|
||||
or
|
||||
result = node.(Rational).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Redo).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Regex).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Rescue).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Rescue).getExceptions() and i = -1 and name = "getExceptions"
|
||||
or
|
||||
result = node.(Rescue).getVariable() and i = -1 and name = "getVariable"
|
||||
or
|
||||
result = node.(RescueModifier).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(RescueModifier).getHandler() and i = -1 and name = "getHandler"
|
||||
or
|
||||
result = node.(RestAssignment).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Retry).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Return).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(RightAssignmentList).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(ScopeResolution).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ScopeResolution).getScope() and i = -1 and name = "getScope"
|
||||
or
|
||||
result = node.(Setter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(SingletonClass).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(SingletonClass).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(SingletonMethod).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(SingletonMethod).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(SingletonMethod).getObject() and i = -1 and name = "getObject"
|
||||
or
|
||||
result = node.(SingletonMethod).getParameters() and i = -1 and name = "getParameters"
|
||||
or
|
||||
result = node.(SplatArgument).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(SplatParameter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(String).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(StringArray).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Subshell).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Superclass).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(SymbolArray).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(TestPattern).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(TestPattern).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(Then).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Unary).getOperand() and i = -1 and name = "getOperand"
|
||||
or
|
||||
result = node.(Undef).getChild(i) and name = "getChild"
|
||||
or
|
||||
result = node.(Unless).getAlternative() and i = -1 and name = "getAlternative"
|
||||
or
|
||||
result = node.(Unless).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(Unless).getConsequence() and i = -1 and name = "getConsequence"
|
||||
or
|
||||
result = node.(UnlessGuard).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(UnlessModifier).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(UnlessModifier).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(Until).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(Until).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(UntilModifier).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(UntilModifier).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(VariableReferencePattern).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(When).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(When).getPattern(i) and name = "getPattern"
|
||||
or
|
||||
result = node.(While).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(While).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(WhileModifier).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(WhileModifier).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(Yield).getChild() and i = -1 and name = "getChild"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
@@ -2107,4 +2441,20 @@ module Erb {
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() { erb_template_child(this, _, result) }
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(CommentDirective).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Directive).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(GraphqlDirective).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(OutputDirective).getChild() and i = -1 and name = "getChild"
|
||||
or
|
||||
result = node.(Template).getChild(i) and name = "getChild"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ pub fn generate(
|
||||
));
|
||||
|
||||
body.append(&mut ql_gen::convert_nodes(&nodes));
|
||||
body.push(ql_gen::create_print_ast_module(&nodes));
|
||||
ql::write(
|
||||
&mut ql_writer,
|
||||
&[ql::TopLevel::Module(ql::Module {
|
||||
|
||||
@@ -150,12 +150,14 @@ impl fmt::Display for Type<'_> {
|
||||
pub enum Expression<'a> {
|
||||
Var(&'a str),
|
||||
String(&'a str),
|
||||
Integer(usize),
|
||||
Integer(i64),
|
||||
Pred(&'a str, Vec<Expression<'a>>),
|
||||
And(Vec<Expression<'a>>),
|
||||
Or(Vec<Expression<'a>>),
|
||||
Equals(Box<Expression<'a>>, Box<Expression<'a>>),
|
||||
Dot(Box<Expression<'a>>, &'a str, Vec<Expression<'a>>),
|
||||
/// A type cast, rendered as `x.(Type)`.
|
||||
Cast(Box<Expression<'a>>, &'a str),
|
||||
Aggregate {
|
||||
name: &'a str,
|
||||
vars: Vec<FormalParameter<'a>>,
|
||||
@@ -219,6 +221,7 @@ impl fmt::Display for Expression<'_> {
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
Expression::Cast(x, type_name) => write!(f, "{x}.({type_name})"),
|
||||
Expression::Aggregate {
|
||||
name,
|
||||
vars,
|
||||
|
||||
@@ -705,7 +705,7 @@ fn create_field_getters<'a>(
|
||||
),
|
||||
ql::Expression::Equals(
|
||||
Box::new(ql::Expression::Var("value")),
|
||||
Box::new(ql::Expression::Integer(*value)),
|
||||
Box::new(ql::Expression::Integer(*value as i64)),
|
||||
),
|
||||
])
|
||||
})
|
||||
@@ -874,3 +874,99 @@ pub fn convert_nodes(nodes: &node_types::NodeTypeMap) -> Vec<ql::TopLevel<'_>> {
|
||||
|
||||
classes
|
||||
}
|
||||
|
||||
/// Creates a `PrintAst` module containing a `getChild` predicate that maps each
|
||||
/// AST node to its children together with the name of the member predicate that
|
||||
/// produced them (and, for indexed fields, the index). This mirrors the
|
||||
/// information exposed by `getAFieldOrChild`, but keeps the member predicate
|
||||
/// name and index so that an AST printer can render labelled edges.
|
||||
pub fn create_print_ast_module(nodes: &node_types::NodeTypeMap) -> ql::TopLevel<'_> {
|
||||
let mut disjuncts: Vec<ql::Expression> = Vec::new();
|
||||
for node in nodes.values() {
|
||||
if let node_types::EntryKind::Table { name: _, fields } = &node.kind {
|
||||
for field in fields {
|
||||
// `ReservedWordInt` fields have string-valued getters, so they
|
||||
// are not children and are excluded (just as they are from
|
||||
// `getAFieldOrChild`).
|
||||
if matches!(
|
||||
field.type_info,
|
||||
node_types::FieldTypeInfo::ReservedWordInt(_)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
let has_index = matches!(
|
||||
field.storage,
|
||||
node_types::Storage::Table {
|
||||
has_index: true,
|
||||
..
|
||||
}
|
||||
);
|
||||
let getter_call = ql::Expression::Dot(
|
||||
Box::new(ql::Expression::Cast(
|
||||
Box::new(ql::Expression::Var("node")),
|
||||
&node.ql_class_name,
|
||||
)),
|
||||
&field.getter_name,
|
||||
if has_index {
|
||||
vec![ql::Expression::Var("i")]
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
);
|
||||
let mut conjuncts = vec![ql::Expression::Equals(
|
||||
Box::new(ql::Expression::Var("result")),
|
||||
Box::new(getter_call),
|
||||
)];
|
||||
if !has_index {
|
||||
conjuncts.push(ql::Expression::Equals(
|
||||
Box::new(ql::Expression::Var("i")),
|
||||
Box::new(ql::Expression::Integer(-1)),
|
||||
));
|
||||
}
|
||||
conjuncts.push(ql::Expression::Equals(
|
||||
Box::new(ql::Expression::Var("name")),
|
||||
Box::new(ql::Expression::String(&field.getter_name)),
|
||||
));
|
||||
disjuncts.push(ql::Expression::And(conjuncts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let get_child = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
"Gets a child of `node` returned by the member predicate with the given `name`. \
|
||||
If the predicate takes an index argument, `i` is bound to that index, otherwise \
|
||||
`i` is `-1` (which is never a valid index).",
|
||||
)),
|
||||
name: "getChild",
|
||||
overridden: false,
|
||||
is_private: false,
|
||||
is_final: false,
|
||||
return_type: Some(ql::Type::Normal("AstNode")),
|
||||
formal_parameters: vec![
|
||||
ql::FormalParameter {
|
||||
name: "node",
|
||||
param_type: ql::Type::Normal("AstNode"),
|
||||
},
|
||||
ql::FormalParameter {
|
||||
name: "name",
|
||||
param_type: ql::Type::String,
|
||||
},
|
||||
ql::FormalParameter {
|
||||
name: "i",
|
||||
param_type: ql::Type::Int,
|
||||
},
|
||||
],
|
||||
body: ql::Expression::Or(disjuncts),
|
||||
overlay: None,
|
||||
};
|
||||
|
||||
ql::TopLevel::Module(ql::Module {
|
||||
qldoc: Some(String::from(
|
||||
"Provides predicates for mapping AST nodes to their named children.",
|
||||
)),
|
||||
name: "PrintAst",
|
||||
body: vec![ql::TopLevel::Predicate(get_child)],
|
||||
overlay: None,
|
||||
})
|
||||
}
|
||||
|
||||
16
unified/ql/lib/codeql/IDEContextual.qll
Normal file
16
unified/ql/lib/codeql/IDEContextual.qll
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Provides shared predicates related to contextual queries in the code viewer.
|
||||
*/
|
||||
|
||||
private import codeql.files.FileSystem
|
||||
private import codeql.util.FileSystem
|
||||
|
||||
/**
|
||||
* Returns an appropriately encoded version of a filename `name`
|
||||
* passed by the VS Code extension in order to coincide with the
|
||||
* output of `.getFile()` on locatable entities.
|
||||
*/
|
||||
cached
|
||||
File getFileBySourceArchiveName(string name) {
|
||||
result = IdeContextual<File>::getFileBySourceArchiveName(name)
|
||||
}
|
||||
@@ -1439,4 +1439,328 @@ module Unified {
|
||||
unified_while_stmt_modifier(this, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides predicates for mapping AST nodes to their named children. */
|
||||
module PrintAst {
|
||||
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
|
||||
AstNode getChild(AstNode node, string name, int i) {
|
||||
result = node.(AccessorDeclaration).getAccessorKind() and i = -1 and name = "getAccessorKind"
|
||||
or
|
||||
result = node.(AccessorDeclaration).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(AccessorDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(AccessorDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(AccessorDeclaration).getParameter(i) and name = "getParameter"
|
||||
or
|
||||
result = node.(AccessorDeclaration).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(Argument).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(Argument).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(Argument).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(ArrayLiteral).getElement(i) and name = "getElement"
|
||||
or
|
||||
result = node.(AssignExpr).getTarget() and i = -1 and name = "getTarget"
|
||||
or
|
||||
result = node.(AssignExpr).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(AssociatedTypeDeclaration).getBound() and i = -1 and name = "getBound"
|
||||
or
|
||||
result = node.(AssociatedTypeDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(AssociatedTypeDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(BaseType).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(BaseType).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(BinaryExpr).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(BinaryExpr).getOperator() and i = -1 and name = "getOperator"
|
||||
or
|
||||
result = node.(BinaryExpr).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(Block).getStmt(i) and name = "getStmt"
|
||||
or
|
||||
result = node.(BoundTypeConstraint).getBound() and i = -1 and name = "getBound"
|
||||
or
|
||||
result = node.(BoundTypeConstraint).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(BreakExpr).getLabel() and i = -1 and name = "getLabel"
|
||||
or
|
||||
result = node.(BulkImportingPattern).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(CallExpr).getArgument(i) and name = "getArgument"
|
||||
or
|
||||
result = node.(CallExpr).getCallee() and i = -1 and name = "getCallee"
|
||||
or
|
||||
result = node.(CallExpr).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(CatchClause).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(CatchClause).getGuard() and i = -1 and name = "getGuard"
|
||||
or
|
||||
result = node.(CatchClause).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(CatchClause).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(ClassLikeDeclaration).getBaseType(i) and name = "getBaseType"
|
||||
or
|
||||
result = node.(ClassLikeDeclaration).getMember(i) and name = "getMember"
|
||||
or
|
||||
result = node.(ClassLikeDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(ClassLikeDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ClassLikeDeclaration).getTypeConstraint(i) and name = "getTypeConstraint"
|
||||
or
|
||||
result = node.(ClassLikeDeclaration).getTypeParameter(i) and name = "getTypeParameter"
|
||||
or
|
||||
result = node.(CompoundAssignExpr).getOperator() and i = -1 and name = "getOperator"
|
||||
or
|
||||
result = node.(CompoundAssignExpr).getTarget() and i = -1 and name = "getTarget"
|
||||
or
|
||||
result = node.(CompoundAssignExpr).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(ConstructorDeclaration).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(ConstructorDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(ConstructorDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(ConstructorDeclaration).getParameter(i) and name = "getParameter"
|
||||
or
|
||||
result = node.(ConstructorPattern).getConstructor() and i = -1 and name = "getConstructor"
|
||||
or
|
||||
result = node.(ConstructorPattern).getElement(i) and name = "getElement"
|
||||
or
|
||||
result = node.(ConstructorPattern).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(ContinueExpr).getLabel() and i = -1 and name = "getLabel"
|
||||
or
|
||||
result = node.(DestructorDeclaration).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(DestructorDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(DoWhileStmt).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(DoWhileStmt).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(DoWhileStmt).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(EqualityTypeConstraint).getLeft() and i = -1 and name = "getLeft"
|
||||
or
|
||||
result = node.(EqualityTypeConstraint).getRight() and i = -1 and name = "getRight"
|
||||
or
|
||||
result = node.(ExprEqualityPattern).getExpr() and i = -1 and name = "getExpr"
|
||||
or
|
||||
result = node.(ForEachStmt).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(ForEachStmt).getGuard() and i = -1 and name = "getGuard"
|
||||
or
|
||||
result = node.(ForEachStmt).getIterable() and i = -1 and name = "getIterable"
|
||||
or
|
||||
result = node.(ForEachStmt).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(ForEachStmt).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getParameter(i) and name = "getParameter"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getReturnType() and i = -1 and name = "getReturnType"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getTypeConstraint(i) and name = "getTypeConstraint"
|
||||
or
|
||||
result = node.(FunctionDeclaration).getTypeParameter(i) and name = "getTypeParameter"
|
||||
or
|
||||
result = node.(FunctionExpr).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(FunctionExpr).getCaptureDeclaration(i) and name = "getCaptureDeclaration"
|
||||
or
|
||||
result = node.(FunctionExpr).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(FunctionExpr).getParameter(i) and name = "getParameter"
|
||||
or
|
||||
result = node.(FunctionExpr).getReturnType() and i = -1 and name = "getReturnType"
|
||||
or
|
||||
result = node.(FunctionTypeExpr).getParameter(i) and name = "getParameter"
|
||||
or
|
||||
result = node.(FunctionTypeExpr).getReturnType() and i = -1 and name = "getReturnType"
|
||||
or
|
||||
result = node.(GenericTypeExpr).getBase() and i = -1 and name = "getBase"
|
||||
or
|
||||
result = node.(GenericTypeExpr).getTypeArgument(i) and name = "getTypeArgument"
|
||||
or
|
||||
result = node.(GuardIfStmt).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(GuardIfStmt).getElse() and i = -1 and name = "getElse"
|
||||
or
|
||||
result = node.(IfExpr).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(IfExpr).getElse() and i = -1 and name = "getElse"
|
||||
or
|
||||
result = node.(IfExpr).getThen() and i = -1 and name = "getThen"
|
||||
or
|
||||
result = node.(ImportDeclaration).getImportedExpr() and i = -1 and name = "getImportedExpr"
|
||||
or
|
||||
result = node.(ImportDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(ImportDeclaration).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(InitializerDeclaration).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(InitializerDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(KeyValuePair).getKey() and i = -1 and name = "getKey"
|
||||
or
|
||||
result = node.(KeyValuePair).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(LabeledStmt).getLabel() and i = -1 and name = "getLabel"
|
||||
or
|
||||
result = node.(LabeledStmt).getStmt() and i = -1 and name = "getStmt"
|
||||
or
|
||||
result = node.(MapLiteral).getElement(i) and name = "getElement"
|
||||
or
|
||||
result = node.(MemberAccessExpr).getBase() and i = -1 and name = "getBase"
|
||||
or
|
||||
result = node.(MemberAccessExpr).getMember() and i = -1 and name = "getMember"
|
||||
or
|
||||
result = node.(NameExpr).getIdentifier() and i = -1 and name = "getIdentifier"
|
||||
or
|
||||
result = node.(NamePattern).getIdentifier() and i = -1 and name = "getIdentifier"
|
||||
or
|
||||
result = node.(NamePattern).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(NamedTypeExpr).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(NamedTypeExpr).getQualifier() and i = -1 and name = "getQualifier"
|
||||
or
|
||||
result = node.(OperatorSyntaxDeclaration).getFixity() and i = -1 and name = "getFixity"
|
||||
or
|
||||
result = node.(OperatorSyntaxDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(OperatorSyntaxDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(OperatorSyntaxDeclaration).getPrecedence() and
|
||||
i = -1 and
|
||||
name = "getPrecedence"
|
||||
or
|
||||
result = node.(Parameter).getDefault() and i = -1 and name = "getDefault"
|
||||
or
|
||||
result = node.(Parameter).getExternalName() and i = -1 and name = "getExternalName"
|
||||
or
|
||||
result = node.(Parameter).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(Parameter).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(Parameter).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(PatternElement).getKey() and i = -1 and name = "getKey"
|
||||
or
|
||||
result = node.(PatternElement).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(PatternElement).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(PatternGuardExpr).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(PatternGuardExpr).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(ReturnExpr).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(SwitchCase).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(SwitchCase).getGuard() and i = -1 and name = "getGuard"
|
||||
or
|
||||
result = node.(SwitchCase).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(SwitchCase).getPattern(i) and name = "getPattern"
|
||||
or
|
||||
result = node.(SwitchExpr).getCase(i) and name = "getCase"
|
||||
or
|
||||
result = node.(SwitchExpr).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(SwitchExpr).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(ThrowExpr).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(TopLevel).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(TryExpr).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(TryExpr).getCatchClause(i) and name = "getCatchClause"
|
||||
or
|
||||
result = node.(TryExpr).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(TupleExpr).getElement(i) and name = "getElement"
|
||||
or
|
||||
result = node.(TuplePattern).getElement(i) and name = "getElement"
|
||||
or
|
||||
result = node.(TuplePattern).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(TupleTypeElement).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(TupleTypeElement).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(TupleTypeExpr).getElement(i) and name = "getElement"
|
||||
or
|
||||
result = node.(TypeAliasDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(TypeAliasDeclaration).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(TypeAliasDeclaration).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(TypeAliasDeclaration).getTypeConstraint(i) and name = "getTypeConstraint"
|
||||
or
|
||||
result = node.(TypeAliasDeclaration).getTypeParameter(i) and name = "getTypeParameter"
|
||||
or
|
||||
result = node.(TypeCastExpr).getExpr() and i = -1 and name = "getExpr"
|
||||
or
|
||||
result = node.(TypeCastExpr).getOperator() and i = -1 and name = "getOperator"
|
||||
or
|
||||
result = node.(TypeCastExpr).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(TypeParameter).getBound() and i = -1 and name = "getBound"
|
||||
or
|
||||
result = node.(TypeParameter).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(TypeParameter).getName() and i = -1 and name = "getName"
|
||||
or
|
||||
result = node.(TypeTestExpr).getExpr() and i = -1 and name = "getExpr"
|
||||
or
|
||||
result = node.(TypeTestExpr).getOperator() and i = -1 and name = "getOperator"
|
||||
or
|
||||
result = node.(TypeTestExpr).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(TypeTestPattern).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(TypeTestPattern).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(UnaryExpr).getOperand() and i = -1 and name = "getOperand"
|
||||
or
|
||||
result = node.(UnaryExpr).getOperator() and i = -1 and name = "getOperator"
|
||||
or
|
||||
result = node.(VariableDeclaration).getModifier(i) and name = "getModifier"
|
||||
or
|
||||
result = node.(VariableDeclaration).getPattern() and i = -1 and name = "getPattern"
|
||||
or
|
||||
result = node.(VariableDeclaration).getType() and i = -1 and name = "getType"
|
||||
or
|
||||
result = node.(VariableDeclaration).getValue() and i = -1 and name = "getValue"
|
||||
or
|
||||
result = node.(WhileStmt).getBody() and i = -1 and name = "getBody"
|
||||
or
|
||||
result = node.(WhileStmt).getCondition() and i = -1 and name = "getCondition"
|
||||
or
|
||||
result = node.(WhileStmt).getModifier(i) and name = "getModifier"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
96
unified/ql/lib/codeql/unified/printAst.qll
Normal file
96
unified/ql/lib/codeql/unified/printAst.qll
Normal file
@@ -0,0 +1,96 @@
|
||||
/** Provides a configurable query for printing AST nodes */
|
||||
|
||||
private import unified
|
||||
|
||||
/**
|
||||
* The query can extend this class to control which nodes are printed.
|
||||
*/
|
||||
class PrintAstConfiguration extends string {
|
||||
PrintAstConfiguration() { this = "PrintAstConfiguration" }
|
||||
|
||||
/**
|
||||
* Holds if the given node should be printed.
|
||||
*/
|
||||
predicate shouldPrintNode(AstNode n) { not n instanceof TriviaToken }
|
||||
|
||||
/**
|
||||
* Holds if the given edge should be printed.
|
||||
*/
|
||||
predicate shouldPrintAstEdge(AstNode parent, string edgeName, AstNode child) {
|
||||
exists(string name, int i |
|
||||
child = PrintAst::getChild(parent, name, i) and
|
||||
(if i = -1 then edgeName = name else edgeName = name + "(" + i + ")")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate shouldPrintNode(AstNode n) {
|
||||
any(PrintAstConfiguration config).shouldPrintNode(n)
|
||||
}
|
||||
|
||||
private predicate shouldPrintAstEdge(AstNode parent, string edgeName, AstNode child) {
|
||||
any(PrintAstConfiguration config).shouldPrintAstEdge(parent, edgeName, child) and
|
||||
shouldPrintNode(parent) and
|
||||
shouldPrintNode(child)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an alias for the predicate `name` to use for ordering purposes, to control where
|
||||
* in the list of children it should appear.
|
||||
*/
|
||||
private string reorderName1(string name) { name = "getModifier" and result = "00_getModifier" }
|
||||
|
||||
bindingset[name]
|
||||
private string reorderName(string name) {
|
||||
result = reorderName1(name)
|
||||
or
|
||||
not exists(reorderName1(name)) and
|
||||
result = name
|
||||
}
|
||||
|
||||
class PrintAstNode extends AstNode {
|
||||
final int getOrder() {
|
||||
this =
|
||||
rank[result](AstNode parent, AstNode child, string name, int i |
|
||||
child = PrintAst::getChild(parent, name, i)
|
||||
|
|
||||
child order by reorderName(name), i
|
||||
)
|
||||
}
|
||||
|
||||
final string getProperty(string key) {
|
||||
key = "semmle.label" and
|
||||
result = this.toString()
|
||||
or
|
||||
key = "semmle.order" and result = this.getOrder().toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` belongs to the output tree, and its property `key` has the
|
||||
* given `value`.
|
||||
*/
|
||||
query predicate nodes(PrintAstNode node, string key, string value) {
|
||||
shouldPrintNode(node) and
|
||||
value = node.getProperty(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `target` is a child of `source` in the AST, and property `key` of
|
||||
* the edge has the given `value`.
|
||||
*/
|
||||
query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) {
|
||||
key = "semmle.label" and
|
||||
shouldPrintAstEdge(source, value, target)
|
||||
or
|
||||
key = "semmle.order" and
|
||||
shouldPrintAstEdge(source, _, target) and
|
||||
value = target.getProperty("semmle.order")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if property `key` of the graph has the given `value`.
|
||||
*/
|
||||
query predicate graphProperties(string key, string value) {
|
||||
key = "semmle.graphKind" and value = "tree"
|
||||
}
|
||||
27
unified/ql/lib/ide-contextual-queries/printAst.ql
Normal file
27
unified/ql/lib/ide-contextual-queries/printAst.ql
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @name Print AST
|
||||
* @description Produces a representation of a file's Abstract Syntax Tree.
|
||||
* This query is used by the VS Code extension.
|
||||
* @id unified/print-ast
|
||||
* @kind graph
|
||||
* @tags ide-contextual-queries/print-ast
|
||||
*/
|
||||
|
||||
private import codeql.IDEContextual
|
||||
private import unified
|
||||
private import codeql.unified.printAst
|
||||
|
||||
/**
|
||||
* The source file to generate an AST from.
|
||||
*/
|
||||
external string selectedSourceFile();
|
||||
|
||||
/**
|
||||
* A configuration that only prints nodes in the selected source file.
|
||||
*/
|
||||
class Cfg extends PrintAstConfiguration {
|
||||
override predicate shouldPrintNode(AstNode n) {
|
||||
super.shouldPrintNode(n) and
|
||||
n.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user