From 5659388ec087b2f297a38203be2dff6cc2d46609 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Thu, 18 Feb 2021 13:33:08 +0100 Subject: [PATCH] AST: implement AstNode::child --- ql/src/codeql_ruby/ast/internal/Call.qll | 21 ++++++ ql/src/codeql_ruby/ast/internal/Constant.qll | 5 ++ ql/src/codeql_ruby/ast/internal/Control.qll | 73 +++++++++++++++++++ ql/src/codeql_ruby/ast/internal/Expr.qll | 39 ++++++++++ ql/src/codeql_ruby/ast/internal/Literal.qll | 22 ++++++ ql/src/codeql_ruby/ast/internal/Method.qll | 35 +++++++++ ql/src/codeql_ruby/ast/internal/Module.qll | 27 +++++++ ql/src/codeql_ruby/ast/internal/Operation.qll | 37 +++++++++- ql/src/codeql_ruby/ast/internal/Parameter.qll | 6 ++ ql/src/codeql_ruby/ast/internal/Pattern.qll | 4 + ql/src/codeql_ruby/ast/internal/Statement.qll | 16 ++++ ql/src/codeql_ruby/ast/internal/Variable.qll | 2 + 12 files changed, 286 insertions(+), 1 deletion(-) diff --git a/ql/src/codeql_ruby/ast/internal/Call.qll b/ql/src/codeql_ruby/ast/internal/Call.qll index b8eb59965d6..ca35a21e07c 100644 --- a/ql/src/codeql_ruby/ast/internal/Call.qll +++ b/ql/src/codeql_ruby/ast/internal/Call.qll @@ -1,4 +1,5 @@ private import codeql_ruby.AST +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.TreeSitter private import codeql_ruby.ast.internal.Variable @@ -14,6 +15,14 @@ module Call { abstract Block getBlock(); override string toString() { result = "call to " + this.getMethodName() } + + final override predicate child(string label, AstNode::Range child) { + label = "getReceiver" and child = getReceiver() + or + label = "getArgument" and child = getArgument(_) + or + label = "getBlock" and child = getBlock() + } } private class IdentifierCallRange extends Call::Range, @token_identifier { @@ -144,6 +153,10 @@ module BlockArgument { final Expr getExpr() { result = generated.getChild() } final override string toString() { result = "&..." } + + final override predicate child(string label, AstNode::Range child) { + label = "getExpr" and child = getExpr() + } } } @@ -154,6 +167,10 @@ module SplatArgument { final Expr getExpr() { result = generated.getChild() } final override string toString() { result = "*..." } + + final override predicate child(string label, AstNode::Range child) { + label = "getExpr" and child = getExpr() + } } } @@ -164,5 +181,9 @@ module HashSplatArgument { final Expr getExpr() { result = generated.getChild() } final override string toString() { result = "**..." } + + final override predicate child(string label, AstNode::Range child) { + label = "getExpr" and child = getExpr() + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Constant.qll b/ql/src/codeql_ruby/ast/internal/Constant.qll index f40feda50b3..87082ae35c7 100644 --- a/ql/src/codeql_ruby/ast/internal/Constant.qll +++ b/ql/src/codeql_ruby/ast/internal/Constant.qll @@ -1,3 +1,4 @@ +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.Pattern private import codeql_ruby.ast.internal.TreeSitter @@ -12,6 +13,10 @@ module ConstantAccess { abstract Expr::Range getScopeExpr(); abstract predicate hasGlobalScope(); + + override predicate child(string label, AstNode::Range child) { + label = "getScopeExpr" and child = getScopeExpr() + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Control.qll b/ql/src/codeql_ruby/ast/internal/Control.qll index 518cb8e7505..c8a1e9d300c 100644 --- a/ql/src/codeql_ruby/ast/internal/Control.qll +++ b/ql/src/codeql_ruby/ast/internal/Control.qll @@ -1,4 +1,5 @@ private import codeql_ruby.AST +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.Pattern private import codeql_ruby.ast.internal.TreeSitter @@ -12,6 +13,12 @@ module ConditionalExpr { abstract Expr getCondition(); abstract Expr getBranch(boolean cond); + + override predicate child(string label, AstNode::Range child) { + label = "getCondition" and child = getCondition() + or + label = "getBranch" and child = getBranch(_) + } } } @@ -24,6 +31,14 @@ module IfExpr { final override string toString() { if this instanceof @elsif then result = "elsif ..." else result = "if ..." } + + override predicate child(string label, AstNode::Range child) { + super.child(label, child) + or + label = "getThen" and child = getThen() + or + label = "getElse" and child = getElse() + } } private class IfRange extends IfExpr::Range, @if { @@ -76,6 +91,14 @@ module UnlessExpr { } final override string toString() { result = "unless ..." } + + override predicate child(string label, AstNode::Range child) { + ConditionalExpr::Range.super.child(label, child) + or + label = "getThen" and child = getThen() + or + label = "getElse" and child = getElse() + } } } @@ -90,6 +113,12 @@ module IfModifierExpr { final override Expr getBranch(boolean cond) { cond = true and result = getExpr() } final override string toString() { result = "... if ..." } + + override predicate child(string label, AstNode::Range child) { + ConditionalExpr::Range.super.child(label, child) + or + label = "getExpr" and child = getExpr() + } } } @@ -104,6 +133,12 @@ module UnlessModifierExpr { final override Expr getBranch(boolean cond) { cond = false and result = getExpr() } final override string toString() { result = "... unless ..." } + + override predicate child(string label, AstNode::Range child) { + ConditionalExpr::Range.super.child(label, child) + or + label = "getExpr" and child = getExpr() + } } } @@ -124,6 +159,14 @@ module TernaryIfExpr { } final override string toString() { result = "... ? ... : ..." } + + override predicate child(string label, AstNode::Range child) { + ConditionalExpr::Range.super.child(label, child) + or + label = "getThen" and child = getThen() + or + label = "getElse" and child = getElse() + } } } @@ -136,6 +179,12 @@ module CaseExpr { final Expr getBranch(int n) { result = generated.getChild(n) } final override string toString() { result = "case ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getValue" and child = getValue() + or + label = "getBranch" and child = getBranch(_) + } } } @@ -148,18 +197,34 @@ module WhenExpr { final Expr getPattern(int n) { result = generated.getPattern(n).getChild() } final override string toString() { result = "when ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getBody" and child = getBody() + or + label = "getPattern" and child = getPattern(_) + } } } module Loop { abstract class Range extends ControlExpr::Range { abstract Expr getBody(); + + override predicate child(string label, AstNode::Range child) { + label = "getBody" and child = getBody() + } } } module ConditionalLoop { abstract class Range extends Loop::Range { abstract Expr getCondition(); + + override predicate child(string label, AstNode::Range child) { + super.child(label, child) + or + label = "getCondition" and child = getCondition() + } } } @@ -222,5 +287,13 @@ module ForExpr { final Expr getValue() { result = generated.getValue().getChild() } final override string toString() { result = "for ... in ..." } + + override predicate child(string label, AstNode::Range child) { + Loop::Range.super.child(label, child) + or + label = "getPattern" and child = getPattern() + or + label = "getValue" and child = getValue() + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Expr.qll b/ql/src/codeql_ruby/ast/internal/Expr.qll index f258501e309..1d10bf85680 100644 --- a/ql/src/codeql_ruby/ast/internal/Expr.qll +++ b/ql/src/codeql_ruby/ast/internal/Expr.qll @@ -1,4 +1,5 @@ private import codeql_ruby.AST +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Literal private import codeql_ruby.ast.internal.Statement private import codeql_ruby.ast.internal.TreeSitter @@ -30,6 +31,10 @@ module StmtSequence { c > 1 and result = "...; ..." ) } + + override predicate child(string label, AstNode::Range child) { + label = "getStmt" and child = getStmt(_) + } } } @@ -56,6 +61,16 @@ module BodyStatement { final StmtSequence getEnsure() { result = unique(Generated::Ensure s | s = getChild(_)) } abstract Generated::AstNode getChild(int i); + + override predicate child(string label, AstNode::Range child) { + StmtSequence::Range.super.child(label, child) + or + label = "getRescue" and child = getRescue(_) + or + label = "getElse" and child = getElse() + or + label = "getEnsure" and child = getEnsure() + } } } @@ -130,6 +145,14 @@ module RescueClause { final StmtSequence getBody() { result = generated.getBody() } final override string toString() { result = "rescue ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getException" and child = getException(_) + or + label = "getVariableExpr" and child = getVariableExpr() + or + label = "getBody" and child = getBody() + } } } @@ -142,6 +165,12 @@ module RescueModifierExpr { final Stmt getHandler() { result = generated.getHandler() } final override string toString() { result = "... rescue ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getBody" and child = getBody() + or + label = "getHandler" and child = getHandler() + } } } @@ -154,6 +183,12 @@ module Pair { final Expr getValue() { result = generated.getValue() } final override string toString() { result = "Pair" } + + override predicate child(string label, AstNode::Range child) { + label = "getKey" and child = getKey() + or + label = "getValue" and child = getValue() + } } } @@ -164,5 +199,9 @@ module StringConcatenation { final StringLiteral::Range getString(int i) { result = generated.getChild(i) } final override string toString() { result = "\"...\" \"...\"" } + + override predicate child(string label, AstNode::Range child) { + label = "getString" and child = getString(_) + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Literal.qll b/ql/src/codeql_ruby/ast/internal/Literal.qll index bd2243b93c5..2aab1ede55e 100644 --- a/ql/src/codeql_ruby/ast/internal/Literal.qll +++ b/ql/src/codeql_ruby/ast/internal/Literal.qll @@ -128,6 +128,10 @@ module StringInterpolationComponent { } final override string getValueText() { none() } + + override predicate child(string label, AstNode::Range child) { + StmtSequence::Range.super.child(label, child) + } } } @@ -176,6 +180,10 @@ module StringlikeLiteral { result = this.getStartDelimiter() + summary + this.getEndDelimiter() ) } + + override predicate child(string label, AstNode::Range child) { + label = "getComponent" and child = getComponent(_) + } } } @@ -340,6 +348,10 @@ module ArrayLiteral { final override string getValueText() { none() } abstract Expr getElement(int i); + + override predicate child(string label, AstNode::Range child) { + label = "getElement" and child = getElement(_) + } } private class RegularArrayRange extends ArrayLiteral::Range, @array { @@ -376,6 +388,10 @@ module HashLiteral { final Expr getElement(int i) { result = generated.getChild(i) } final override string toString() { result = "{...}" } + + override predicate child(string label, AstNode::Range child) { + label = "getElement" and child = getElement(_) + } } } @@ -394,6 +410,12 @@ module RangeLiteral { final predicate isInclusive() { this instanceof @range_dotdot } final predicate isExclusive() { this instanceof @range_dotdotdot } + + override predicate child(string label, AstNode::Range child) { + label = "getBegin" and child = getBegin() + or + label = "getEnd" and child = getEnd() + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Method.qll b/ql/src/codeql_ruby/ast/internal/Method.qll index f4d3779e639..49540f9b788 100644 --- a/ql/src/codeql_ruby/ast/internal/Method.qll +++ b/ql/src/codeql_ruby/ast/internal/Method.qll @@ -1,4 +1,5 @@ private import codeql_ruby.AST +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.Parameter private import TreeSitter @@ -6,6 +7,10 @@ private import TreeSitter module Callable { abstract class Range extends Expr::Range { abstract Parameter::Range getParameter(int n); + + override predicate child(string label, AstNode::Range child) { + label = "getParameter" and child = getParameter(_) + } } } @@ -25,6 +30,10 @@ module Method { final override Generated::AstNode getChild(int i) { result = generated.getChild(i) } final override string toString() { result = this.getName() } + + override predicate child(string label, AstNode::Range child) { + Callable::Range.super.child(label, child) or BodyStatement::Range.super.child(label, child) + } } } @@ -45,6 +54,14 @@ module SingletonMethod { final override Generated::AstNode getChild(int i) { result = generated.getChild(i) } final override string toString() { result = this.getName() } + + override predicate child(string label, AstNode::Range child) { + Callable::Range.super.child(label, child) + or + BodyStatement::Range.super.child(label, child) + or + label = "getObject" and child = getObject() + } } } @@ -62,12 +79,24 @@ module Lambda { } final override string toString() { result = "-> { ... }" } + + override predicate child(string label, AstNode::Range child) { + Callable::Range.super.child(label, child) + or + BodyStatement::Range.super.child(label, child) + } } } module Block { abstract class Range extends Callable::Range, StmtSequence::Range { Range() { not generated.getParent() instanceof Generated::Lambda } + + override predicate child(string label, AstNode::Range child) { + Callable::Range.super.child(label, child) + or + StmtSequence::Range.super.child(label, child) + } } } @@ -82,6 +111,12 @@ module DoBlock { } final override string toString() { result = "do ... end" } + + override predicate child(string label, AstNode::Range child) { + Block::Range.super.child(label, child) + or + BodyStatement::Range.super.child(label, child) + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Module.qll b/ql/src/codeql_ruby/ast/internal/Module.qll index 3897435bf4b..79bb29429cd 100644 --- a/ql/src/codeql_ruby/ast/internal/Module.qll +++ b/ql/src/codeql_ruby/ast/internal/Module.qll @@ -1,4 +1,5 @@ private import codeql_ruby.AST +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.Constant private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.TreeSitter @@ -23,6 +24,12 @@ module Toplevel { } final override string toString() { result = generated.getLocation().getFile().getBaseName() } + + override predicate child(string label, AstNode::Range child) { + ModuleBase::Range.super.child(label, child) + or + label = "getBeginBlock" and child = getBeginBlock(_) + } } } @@ -52,6 +59,14 @@ module Class { final Expr getSuperclassExpr() { result = generated.getSuperclass().getChild() } final override string toString() { result = this.getName() } + + override predicate child(string label, AstNode::Range child) { + ModuleBase::Range.super.child(label, child) + or + ConstantWriteAccess::Range.super.child(label, child) + or + label = "getSuperclassExpr" and child = getSuperclassExpr() + } } } @@ -64,6 +79,12 @@ module SingletonClass { final Expr getValue() { result = generated.getValue() } final override string toString() { result = "class << ..." } + + override predicate child(string label, AstNode::Range child) { + ModuleBase::Range.super.child(label, child) + or + label = "getValue" and child = getValue() + } } } @@ -91,5 +112,11 @@ module Module { } final override string toString() { result = this.getName() } + + override predicate child(string label, AstNode::Range child) { + ModuleBase::Range.super.child(label, child) + or + ConstantWriteAccess::Range.super.child(label, child) + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Operation.qll b/ql/src/codeql_ruby/ast/internal/Operation.qll index c55af802ef8..f6ad5e158d0 100644 --- a/ql/src/codeql_ruby/ast/internal/Operation.qll +++ b/ql/src/codeql_ruby/ast/internal/Operation.qll @@ -1,4 +1,5 @@ -import codeql_ruby.AST +private import codeql_ruby.AST +private import codeql_ruby.ast.internal.AST private import codeql_ruby.ast.internal.TreeSitter private import codeql_ruby.ast.internal.Expr @@ -7,6 +8,10 @@ module Operation { abstract string getOperator(); abstract Expr getAnOperand(); + + override predicate child(string label, AstNode::Range child) { + label = "getAnOperand" and child = getAnOperand() + } } } @@ -21,6 +26,12 @@ module UnaryOperation { final override Expr getAnOperand() { result = this.getOperand() } override string toString() { result = this.getOperator() + " ..." } + + override predicate child(string label, AstNode::Range child) { + Operation::Range.super.child(label, child) + or + label = "getOperand" and child = getOperand() + } } } @@ -73,6 +84,14 @@ module BinaryOperation { } override string toString() { result = "... " + this.getOperator() + " ..." } + + override predicate child(string label, AstNode::Range child) { + Operation::Range.super.child(label, child) + or + label = "getLeftOperand" and child = getLeftOperand() + or + label = "getRightOperand" and child = getRightOperand() + } } } @@ -169,6 +188,14 @@ module RelationalOperation { abstract Expr getGreaterOperand(); abstract Expr getLesserOperand(); + + override predicate child(string label, AstNode::Range child) { + ComparisonOperation::Range.super.child(label, child) + or + label = "getGreaterOperand" and child = getGreaterOperand() + or + label = "getLesserOperand" and child = getLesserOperand() + } } } @@ -227,6 +254,14 @@ module Assignment { } override string toString() { result = "... " + this.getOperator() + " ..." } + + override predicate child(string label, AstNode::Range child) { + Operation::Range.super.child(label, child) + or + label = "getLeftOperand" and child = getLeftOperand() + or + label = "getRightOperand" and child = getRightOperand() + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Parameter.qll b/ql/src/codeql_ruby/ast/internal/Parameter.qll index 5d4026eda5c..d73339e4da4 100644 --- a/ql/src/codeql_ruby/ast/internal/Parameter.qll +++ b/ql/src/codeql_ruby/ast/internal/Parameter.qll @@ -1,6 +1,7 @@ private import codeql_ruby.AST private import TreeSitter private import codeql_ruby.ast.internal.AST +private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.Variable private import codeql_ruby.ast.internal.Method private import codeql_ruby.ast.internal.Pattern @@ -61,6 +62,11 @@ module TuplePatternParameter { override LocalVariable getAVariable() { result = TuplePattern::Range.super.getAVariable() } override string toString() { result = TuplePattern::Range.super.toString() } + + override predicate child(string label, AstNode::Range child) { + PatternParameter::Range.super.child(label, child) or + TuplePattern::Range.super.child(label, child) + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Pattern.qll b/ql/src/codeql_ruby/ast/internal/Pattern.qll index 205439881d2..44ea94e2704 100644 --- a/ql/src/codeql_ruby/ast/internal/Pattern.qll +++ b/ql/src/codeql_ruby/ast/internal/Pattern.qll @@ -101,5 +101,9 @@ module TuplePattern { override Variable getAVariable() { result = this.getElement(_).getAVariable() } override string toString() { result = "(..., ...)" } + + override predicate child(string label, AstNode::Range child) { + label = "getElement" and child = getElement(_) + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Statement.qll b/ql/src/codeql_ruby/ast/internal/Statement.qll index 7c0aee758bd..8fd7291b503 100644 --- a/ql/src/codeql_ruby/ast/internal/Statement.qll +++ b/ql/src/codeql_ruby/ast/internal/Statement.qll @@ -12,6 +12,8 @@ module EmptyStmt { final override Generated::EmptyStatement generated; final override string toString() { result = ";" } + + override predicate child(string label, AstNode::Range child) { none() } } } @@ -32,6 +34,10 @@ module UndefStmt { final MethodName getMethodName(int n) { result = generated.getChild(n) } final override string toString() { result = "undef ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getMethodName" and child = getMethodName(_) + } } } @@ -44,6 +50,12 @@ module AliasStmt { final MethodName getOldName() { result = generated.getAlias() } final override string toString() { result = "alias ..." } + + override predicate child(string label, AstNode::Range child) { + label = "getNewName" and child = getNewName() + or + label = "getOldName" and child = getOldName() + } } } @@ -60,6 +72,10 @@ module ReturningStmt { result = a and c > 1 ) } + + override predicate child(string label, AstNode::Range child) { + label = "getValue" and child = getValue() + } } } diff --git a/ql/src/codeql_ruby/ast/internal/Variable.qll b/ql/src/codeql_ruby/ast/internal/Variable.qll index 24f1cb1e733..a0e2ea83056 100644 --- a/ql/src/codeql_ruby/ast/internal/Variable.qll +++ b/ql/src/codeql_ruby/ast/internal/Variable.qll @@ -578,6 +578,8 @@ module VariableAccess { abstract Variable getVariable(); final override string toString() { result = this.getVariable().getName() } + + override predicate child(string label, AstNode::Range child) { none() } } }