Merge pull request #124 from github/aibaars/ast-stmt-expr

AST: make Expr extend Stmt and change ExprSequence to StmtSequence
This commit is contained in:
Nick Rolfe
2021-02-11 17:00:21 +00:00
committed by GitHub
19 changed files with 134 additions and 146 deletions

View File

@@ -57,11 +57,11 @@ class IfExpr extends ConditionalExpr {
final predicate isElsif() { this instanceof @elsif }
/** Gets the 'then' branch of this `if`/`elsif` expression. */
final ExprSequence getThen() { result = range.getThen() }
final StmtSequence getThen() { result = range.getThen() }
/**
* Gets the `elsif`/`else` branch of this `if`/`elsif` expression, if any. In
* the following example, the result is an `ExprSequence` containing `b`.
* the following example, the result is a `StmtSequence` containing `b`.
* ```rb
* if foo
* a
@@ -77,7 +77,7 @@ class IfExpr extends ConditionalExpr {
* ```
* There can be at most one result, since `elsif` branches nest. In the
* following example, `ifExpr.getElse()` returns an `ElsifExpr`, and the
* `else` branch is nested inside that. To get the `ExprSequence` for the
* `else` branch is nested inside that. To get the `StmtSequence` for the
* `else` branch, i.e. the one containing `c`, use
* `getElse().(ElsifExpr).getElse()`.
* ```rb
@@ -108,7 +108,7 @@ class UnlessExpr extends ConditionalExpr, @unless {
/**
* Gets the 'then' branch of this `unless` expression. In the following
* example, the result is the `ExprSequence` containing `foo`.
* example, the result is the `StmtSequence` containing `foo`.
* ```rb
* unless a == b then
* foo
@@ -117,11 +117,11 @@ class UnlessExpr extends ConditionalExpr, @unless {
* end
* ```
*/
final ExprSequence getThen() { result = range.getThen() }
final StmtSequence getThen() { result = range.getThen() }
/**
* Gets the 'else' branch of this `unless` expression. In the following
* example, the result is the `ExprSequence` containing `bar`.
* example, the result is the `StmtSequence` containing `bar`.
* ```rb
* unless a == b then
* foo
@@ -130,7 +130,7 @@ class UnlessExpr extends ConditionalExpr, @unless {
* end
* ```
*/
final ExprSequence getElse() { result = range.getElse() }
final StmtSequence getElse() { result = range.getElse() }
}
/**
@@ -220,8 +220,8 @@ class CaseExpr extends ControlExpr, @case__ {
final Expr getValue() { result = range.getValue() }
/**
* Gets the `n`th branch of this case expression, either a `WhenExpr` or an
* `ExprSequence`.
* Gets the `n`th branch of this case expression, either a `WhenExpr` or a
* `StmtSequence`.
*/
final Expr getBranch(int n) { result = range.getBranch(n) }
@@ -235,7 +235,7 @@ class CaseExpr extends ControlExpr, @case__ {
final WhenExpr getAWhenBranch() { result = getABranch() }
/** Gets the `else` branch of this case expression, if any. */
final ExprSequence getElseBranch() { result = getABranch() }
final StmtSequence getElseBranch() { result = getABranch() }
/**
* Gets the number of branches of this case expression.
@@ -257,7 +257,7 @@ class WhenExpr extends Expr, @when {
final override string getAPrimaryQlClass() { result = "WhenExpr" }
/** Gets the body of this case-when expression. */
final ExprSequence getBody() { result = range.getBody() }
final StmtSequence getBody() { result = range.getBody() }
/**
* Gets the `n`th pattern (or condition) in this case-when expression. In the
@@ -320,7 +320,7 @@ class WhileExpr extends ConditionalLoop, @while {
final override string getAPrimaryQlClass() { result = "WhileExpr" }
/** Gets the body of this `while` loop. */
final override ExprSequence getBody() { result = range.getBody() }
final override StmtSequence getBody() { result = range.getBody() }
}
/**
@@ -338,7 +338,7 @@ class UntilExpr extends ConditionalLoop, @until {
final override string getAPrimaryQlClass() { result = "UntilExpr" }
/** Gets the body of this `until` loop. */
final override ExprSequence getBody() { result = range.getBody() }
final override StmtSequence getBody() { result = range.getBody() }
}
/**

View File

@@ -1,30 +1,15 @@
private import codeql_ruby.AST
private import codeql_ruby.CFG
private import internal.Expr
private import internal.Variable
private import codeql_ruby.controlflow.internal.ControlFlowGraphImpl
/**
* An expression.
*
* This is the root QL class for all expressions.
*/
class Expr extends AstNode {
class Expr extends Stmt {
override Expr::Range range;
Expr() { this = range }
/** Gets a control-flow node for this expression, if any. */
CfgNodes::AstCfgNode getAControlFlowNode() { result.getNode() = this }
/** Gets the control-flow scope of this expression, if any. */
CfgScope getCfgScope() { result = getCfgScope(this) }
/** Gets the variable scope that this expression belongs to. */
VariableScope getVariableScope() { result = enclosingScope(this) }
/** Gets the enclosing callable, if any. */
Callable getEnclosingCallable() { result = this.getCfgScope() }
}
/**
@@ -117,40 +102,40 @@ class SymbolLiteral extends Literal {
}
/** A sequence of expressions. */
class ExprSequence extends Expr {
override ExprSequence::Range range;
class StmtSequence extends Expr {
override StmtSequence::Range range;
override string getAPrimaryQlClass() { result = "ExprSequence" }
override string getAPrimaryQlClass() { result = "StmtSequence" }
/** Gets the `n`th expression in this sequence. */
final Expr getExpr(int n) { result = range.getExpr(n) }
/** Gets the `n`th statement in this sequence. */
final Stmt getStmt(int n) { result = range.getStmt(n) }
/** Gets an expression in this sequence. */
final Expr getAnExpr() { result = this.getExpr(_) }
/** Gets a statement in this sequence. */
final Stmt getAStmt() { result = this.getStmt(_) }
/** Gets the last expression in this sequence, if any. */
final Expr getLastExpr() { result = this.getExpr(this.getNumberOfExpressions() - 1) }
final Expr getLastExpr() { result = this.getStmt(this.getNumberOfStatements() - 1) }
/** Gets the number of expressions in this sequence. */
final int getNumberOfExpressions() { result = count(this.getAnExpr()) }
/** Gets the number of statements in this sequence. */
final int getNumberOfStatements() { result = count(this.getAStmt()) }
/** Holds if this sequence has no expressions. */
final predicate isEmpty() { this.getNumberOfExpressions() = 0 }
/** Holds if this sequence has no statements. */
final predicate isEmpty() { this.getNumberOfStatements() = 0 }
}
/**
* A sequence of expressions representing the body of a method, class, module,
* A sequence of statements representing the body of a method, class, module,
* or do-block. That is, any body that may also include rescue/ensure/else
* statements.
*/
class BodyStatement extends ExprSequence {
class BodyStatement extends StmtSequence {
override BodyStatement::Range range;
/** Gets the `else` block in this block, if any. */
final ExprSequence getElse() { result = range.getElse() }
final StmtSequence getElse() { result = range.getElse() }
/** Gets the `ensure` block in this block, if any. */
final ExprSequence getEnsure() { result = range.getEnsure() }
final StmtSequence getEnsure() { result = range.getEnsure() }
final predicate hasEnsure() { exists(this.getEnsure()) }
}
@@ -170,7 +155,7 @@ class BodyStatement extends ExprSequence {
* ()
* ```
*/
class ParenthesizedExpr extends ExprSequence, @parenthesized_statements {
class ParenthesizedExpr extends StmtSequence, @parenthesized_statements {
final override ParenthesizedExpr::Range range;
final override string getAPrimaryQlClass() { result = "ParenthesizedExpr" }

View File

@@ -63,7 +63,7 @@ class Lambda extends Callable, BodyStatement, @lambda {
}
/** A block. */
class Block extends Callable, ExprSequence {
class Block extends Callable, StmtSequence {
override Block::Range range;
}

View File

@@ -9,19 +9,19 @@ class ModuleBase extends BodyStatement {
override ModuleBase::Range range;
/** Gets a method defined in this module/class. */
Method getAMethod() { result = this.getAnExpr() }
Method getAMethod() { result = this.getAStmt() }
/** Gets the method named `name` in this module/class, if any. */
Method getMethod(string name) { result = this.getAMethod() and result.getName() = name }
/** Gets a class defined in this module/class. */
Class getAClass() { result = this.getAnExpr() }
Class getAClass() { result = this.getAStmt() }
/** Gets the class named `name` in this module/class, if any. */
Class getClass(string name) { result = this.getAClass() and result.getName() = name }
/** Gets a module defined in this module/class. */
Module getAModule() { result = this.getAnExpr() }
Module getAModule() { result = this.getAStmt() }
/** Gets the module named `name` in this module/class, if any. */
Module getModule(string name) { result = this.getAModule() and result.getName() = name }

View File

@@ -1,6 +1,7 @@
private import codeql_ruby.AST
private import codeql_ruby.CFG
private import internal.Statement
private import internal.Variable
private import codeql_ruby.controlflow.internal.ControlFlowGraphImpl
/**
@@ -17,6 +18,9 @@ class Stmt extends AstNode {
/** Gets the control-flow scope of this statement, if any. */
CfgScope getCfgScope() { result = getCfgScope(this) }
/** Gets the variable scope that this statement belongs to. */
VariableScope getVariableScope() { result = enclosingScope(this) }
/** Gets the enclosing callable, if any. */
Callable getEnclosingCallable() { result = this.getCfgScope() }
}

View File

@@ -17,7 +17,7 @@ module ConditionalExpr {
module IfExpr {
abstract class Range extends ConditionalExpr::Range {
abstract ExprSequence getThen();
abstract StmtSequence getThen();
abstract Expr getElse();
@@ -31,7 +31,7 @@ module IfExpr {
final override Expr getCondition() { result = generated.getCondition() }
final override ExprSequence getThen() { result = generated.getConsequence() }
final override StmtSequence getThen() { result = generated.getConsequence() }
final override Expr getElse() { result = generated.getAlternative() }
@@ -47,7 +47,7 @@ module IfExpr {
final override Expr getCondition() { result = generated.getCondition() }
final override ExprSequence getThen() { result = generated.getConsequence() }
final override StmtSequence getThen() { result = generated.getConsequence() }
final override Expr getElse() { result = generated.getAlternative() }
@@ -65,9 +65,9 @@ module UnlessExpr {
final override Expr getCondition() { result = generated.getCondition() }
final ExprSequence getThen() { result = generated.getConsequence() }
final StmtSequence getThen() { result = generated.getConsequence() }
final ExprSequence getElse() { result = generated.getAlternative() }
final StmtSequence getElse() { result = generated.getAlternative() }
final override Expr getBranch(boolean cond) {
cond = false and result = getThen()
@@ -143,7 +143,7 @@ module WhenExpr {
class Range extends Expr::Range, @when {
final override Generated::When generated;
final ExprSequence getBody() { result = generated.getBody() }
final StmtSequence getBody() { result = generated.getBody() }
final Expr getPattern(int n) { result = generated.getPattern(n).getChild() }
@@ -167,7 +167,7 @@ module WhileExpr {
class Range extends ConditionalLoop::Range, @while {
final override Generated::While generated;
final override ExprSequence getBody() { result = generated.getBody() }
final override StmtSequence getBody() { result = generated.getBody() }
final override Expr getCondition() { result = generated.getCondition() }
@@ -179,7 +179,7 @@ module UntilExpr {
class Range extends ConditionalLoop::Range, @until {
final override Generated::Until generated;
final override ExprSequence getBody() { result = generated.getBody() }
final override StmtSequence getBody() { result = generated.getBody() }
final override Expr getCondition() { result = generated.getCondition() }
@@ -215,7 +215,7 @@ module ForExpr {
class Range extends Loop::Range, @for {
final override Generated::For generated;
final override ExprSequence getBody() { result = generated.getBody() }
final override StmtSequence getBody() { result = generated.getBody() }
final Pattern getPattern() { result = generated.getPattern() }

View File

@@ -1,11 +1,9 @@
private import codeql_ruby.AST
private import codeql_ruby.ast.internal.AST
private import codeql_ruby.ast.internal.Pattern
private import codeql_ruby.ast.internal.Statement
private import codeql_ruby.ast.internal.TreeSitter
private import codeql_ruby.ast.internal.Variable
module Expr {
abstract class Range extends AstNode::Range { }
abstract class Range extends Stmt::Range { }
}
module Literal {
@@ -166,17 +164,17 @@ module SymbolLiteral {
}
}
module ExprSequence {
module StmtSequence {
abstract class Range extends Expr::Range {
abstract Expr getExpr(int n);
abstract Stmt getStmt(int n);
int getNumberOfExpressions() { result = count(this.getExpr(_)) }
int getNumberOfStatements() { result = count(this.getStmt(_)) }
override string toString() {
exists(int c | c = this.getNumberOfExpressions() |
exists(int c | c = this.getNumberOfStatements() |
c = 0 and result = ";"
or
c = 1 and result = this.getExpr(0).toString()
c = 1 and result = this.getStmt(0).toString()
or
c > 1 and result = "...; ..."
)
@@ -185,8 +183,8 @@ module ExprSequence {
}
module BodyStatement {
abstract class Range extends ExprSequence::Range {
final override Expr getExpr(int n) {
abstract class Range extends StmtSequence::Range {
final override Stmt getStmt(int n) {
result =
rank[n + 1](Generated::AstNode node, int i |
node = getChild(i) and
@@ -198,59 +196,59 @@ module BodyStatement {
)
}
final ExprSequence getElse() { result = unique(Generated::Else s | s = getChild(_)) }
final StmtSequence getElse() { result = unique(Generated::Else s | s = getChild(_)) }
final ExprSequence getEnsure() { result = unique(Generated::Ensure s | s = getChild(_)) }
final StmtSequence getEnsure() { result = unique(Generated::Ensure s | s = getChild(_)) }
abstract Generated::AstNode getChild(int i);
}
}
module ParenthesizedExpr {
class Range extends ExprSequence::Range, @parenthesized_statements {
class Range extends StmtSequence::Range, @parenthesized_statements {
final override Generated::ParenthesizedStatements generated;
final override Expr getExpr(int n) { result = generated.getChild(n) }
final override Stmt getStmt(int n) { result = generated.getChild(n) }
final override string toString() {
exists(int c | c = this.getNumberOfExpressions() |
exists(int c | c = this.getNumberOfStatements() |
c = 0 and result = "()"
or
c > 0 and result = "(" + ExprSequence::Range.super.toString() + ")"
c > 0 and result = "(" + StmtSequence::Range.super.toString() + ")"
)
}
}
}
module ThenExpr {
class Range extends ExprSequence::Range, @then {
class Range extends StmtSequence::Range, @then {
final override Generated::Then generated;
final override Expr getExpr(int n) { result = generated.getChild(n) }
final override Stmt getStmt(int n) { result = generated.getChild(n) }
}
}
module ElseExpr {
class Range extends ExprSequence::Range, @else {
class Range extends StmtSequence::Range, @else {
final override Generated::Else generated;
final override Expr getExpr(int n) { result = generated.getChild(n) }
final override Stmt getStmt(int n) { result = generated.getChild(n) }
}
}
module DoExpr {
class Range extends ExprSequence::Range, @do {
class Range extends StmtSequence::Range, @do {
final override Generated::Do generated;
final override Expr getExpr(int n) { result = generated.getChild(n) }
final override Stmt getStmt(int n) { result = generated.getChild(n) }
}
}
module Ensure {
class Range extends ExprSequence::Range, @ensure {
class Range extends StmtSequence::Range, @ensure {
final override Generated::Ensure generated;
final override Expr getExpr(int n) { result = generated.getChild(n) }
final override Stmt getStmt(int n) { result = generated.getChild(n) }
final override string toString() { result = "ensure ... end" }
}

View File

@@ -65,7 +65,7 @@ module Lambda {
}
module Block {
abstract class Range extends Callable::Range, ExprSequence::Range {
abstract class Range extends Callable::Range, StmtSequence::Range {
Range() { not generated.getParent() instanceof Generated::Lambda }
}
}
@@ -92,7 +92,7 @@ module BraceBlock {
result = generated.getParameters().getChild(n)
}
final override Expr getExpr(int i) { result = generated.getChild(i) }
final override Stmt getStmt(int i) { result = generated.getChild(i) }
final override string toString() { result = "{ ... }" }
}

View File

@@ -292,21 +292,18 @@ module ExprNodes {
final ExprCfgNode getBranch(boolean cond) { e.hasCfgChild(e.getBranch(cond), this, result) }
}
private class ExprSequenceChildMapping extends ExprChildMapping, ExprSequence {
override predicate relevantChild(Expr e) { e = this.getAnExpr() }
private class StmtSequenceChildMapping extends ExprChildMapping, StmtSequence {
override predicate relevantChild(Expr e) { e = this.getLastExpr() }
}
/** A control-flow node that wraps an `ExprSequence` AST expression. */
class ExprSequenceCfgNode extends ExprCfgNode {
override ExprSequenceChildMapping e;
/** A control-flow node that wraps a `StmtSequence` AST expression. */
class StmtSequenceCfgNode extends ExprCfgNode {
override StmtSequenceChildMapping e;
final override ExprSequence getExpr() { result = ExprCfgNode.super.getExpr() }
final override StmtSequence getExpr() { result = ExprCfgNode.super.getExpr() }
/** Gets the last expression in this sequence, if any. */
final ExprCfgNode getLastExpr() { e.hasCfgChild(e.getLastExpr(), this, result) }
/** Gets the 'n'th expression of this expression sequence. */
final ExprCfgNode getExpr(int n) { e.hasCfgChild(e.getExpr(n), this, result) }
}
private class ForExprChildMapping extends ExprChildMapping, ForExpr {
@@ -324,7 +321,7 @@ module ExprNodes {
}
/** A control-flow node that wraps a `ParenthesizedExpr` AST expression. */
class ParenthesizedExprCfgNode extends ExprSequenceCfgNode {
class ParenthesizedExprCfgNode extends StmtSequenceCfgNode {
ParenthesizedExprCfgNode() { this.getExpr() instanceof ParenthesizedExpr }
}

View File

@@ -126,7 +126,7 @@ private module Cached {
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::AssignExprCfgNode).getRhs()
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::ExprSequenceCfgNode).getLastExpr()
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::StmtSequenceCfgNode).getLastExpr()
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::ConditionalExprCfgNode).getBranch(_)
or

View File

@@ -4,13 +4,13 @@ query predicate caseValues(CaseExpr c, Expr value) { value = c.getValue() }
query predicate caseNoValues(CaseExpr c) { not exists(c.getValue()) }
query predicate caseElseBranches(CaseExpr c, ExprSequence elseBranch) {
query predicate caseElseBranches(CaseExpr c, StmtSequence elseBranch) {
elseBranch = c.getElseBranch()
}
query predicate caseNoElseBranches(CaseExpr c) { not exists(c.getElseBranch()) }
query predicate caseWhenBranches(CaseExpr c, WhenExpr when, int pIndex, Expr p, ExprSequence body) {
query predicate caseWhenBranches(CaseExpr c, WhenExpr when, int pIndex, Expr p, StmtSequence body) {
when = c.getAWhenBranch() and
p = when.getPattern(pIndex) and
body = when.getBody()

View File

@@ -9,7 +9,7 @@ query predicate conditionalExprs(
}
query predicate ifExprs(
IfExpr e, string pClass, Expr cond, ExprSequence thenExpr, string elseStr, boolean isElsif
IfExpr e, string pClass, Expr cond, StmtSequence thenExpr, string elseStr, boolean isElsif
) {
pClass = e.getAPrimaryQlClass() and
cond = e.getCondition() and
@@ -19,7 +19,7 @@ query predicate ifExprs(
}
query predicate unlessExprs(
UnlessExpr e, string pClass, Expr cond, ExprSequence thenExpr, string elseStr
UnlessExpr e, string pClass, Expr cond, StmtSequence thenExpr, string elseStr
) {
pClass = e.getAPrimaryQlClass() and
cond = e.getCondition() and

View File

@@ -15,10 +15,10 @@
| loops.rb:9:1:12:3 | for ... in ... | ForExpr |
| loops.rb:16:1:19:3 | for ... in ... | ForExpr |
| loops.rb:22:1:25:3 | for ... in ... | ForExpr |
| loops.rb:28:1:31:3 | for ... in ... | ForExpr |
| loops.rb:34:1:37:3 | while ... | WhileExpr |
| loops.rb:40:1:43:3 | while ... | WhileExpr |
| loops.rb:46:1:46:19 | ... while ... | WhileModifierExpr |
| loops.rb:49:1:52:3 | until ... | UntilExpr |
| loops.rb:55:1:58:3 | until ... | UntilExpr |
| loops.rb:61:1:61:19 | ... until ... | UntilModifierExpr |
| loops.rb:28:1:32:3 | for ... in ... | ForExpr |
| loops.rb:35:1:39:3 | while ... | WhileExpr |
| loops.rb:42:1:45:3 | while ... | WhileExpr |
| loops.rb:48:1:48:19 | ... while ... | WhileModifierExpr |
| loops.rb:51:1:54:3 | until ... | UntilExpr |
| loops.rb:57:1:60:3 | until ... | UntilExpr |
| loops.rb:63:1:63:19 | ... until ... | UntilModifierExpr |

View File

@@ -1,21 +1,21 @@
loops
| loops.rb:9:1:12:3 | for ... in ... | ForExpr | loops.rb:9:15:12:3 | ...; ... | ExprSequence |
| loops.rb:16:1:19:3 | for ... in ... | ForExpr | loops.rb:16:15:19:3 | ...; ... | ExprSequence |
| loops.rb:22:1:25:3 | for ... in ... | ForExpr | loops.rb:22:35:25:3 | ...; ... | ExprSequence |
| loops.rb:28:1:31:3 | for ... in ... | ForExpr | loops.rb:28:37:31:3 | ...; ... | ExprSequence |
| loops.rb:34:1:37:3 | while ... | WhileExpr | loops.rb:34:12:37:3 | ...; ... | ExprSequence |
| loops.rb:40:1:43:3 | while ... | WhileExpr | loops.rb:40:13:43:3 | ...; ... | ExprSequence |
| loops.rb:46:1:46:19 | ... while ... | WhileModifierExpr | loops.rb:46:1:46:6 | ... += ... | AssignAddExpr |
| loops.rb:49:1:52:3 | until ... | UntilExpr | loops.rb:49:13:52:3 | ...; ... | ExprSequence |
| loops.rb:55:1:58:3 | until ... | UntilExpr | loops.rb:55:13:58:3 | ...; ... | ExprSequence |
| loops.rb:61:1:61:19 | ... until ... | UntilModifierExpr | loops.rb:61:1:61:6 | ... -= ... | AssignSubExpr |
| loops.rb:9:1:12:3 | for ... in ... | ForExpr | loops.rb:9:15:12:3 | ...; ... | StmtSequence |
| loops.rb:16:1:19:3 | for ... in ... | ForExpr | loops.rb:16:15:19:3 | ...; ... | StmtSequence |
| loops.rb:22:1:25:3 | for ... in ... | ForExpr | loops.rb:22:35:25:3 | ...; ... | StmtSequence |
| loops.rb:28:1:32:3 | for ... in ... | ForExpr | loops.rb:28:37:32:3 | ...; ... | StmtSequence |
| loops.rb:35:1:39:3 | while ... | WhileExpr | loops.rb:35:12:39:3 | ...; ... | StmtSequence |
| loops.rb:42:1:45:3 | while ... | WhileExpr | loops.rb:42:13:45:3 | ...; ... | StmtSequence |
| loops.rb:48:1:48:19 | ... while ... | WhileModifierExpr | loops.rb:48:1:48:6 | ... += ... | AssignAddExpr |
| loops.rb:51:1:54:3 | until ... | UntilExpr | loops.rb:51:13:54:3 | ...; ... | StmtSequence |
| loops.rb:57:1:60:3 | until ... | UntilExpr | loops.rb:57:13:60:3 | ...; ... | StmtSequence |
| loops.rb:63:1:63:19 | ... until ... | UntilModifierExpr | loops.rb:63:1:63:6 | ... -= ... | AssignSubExpr |
conditionalLoops
| loops.rb:34:1:37:3 | while ... | WhileExpr | loops.rb:34:7:34:11 | ... < ... | loops.rb:34:12:37:3 | ...; ... | ExprSequence |
| loops.rb:40:1:43:3 | while ... | WhileExpr | loops.rb:40:7:40:11 | ... < ... | loops.rb:40:13:43:3 | ...; ... | ExprSequence |
| loops.rb:46:1:46:19 | ... while ... | WhileModifierExpr | loops.rb:46:14:46:19 | ... >= ... | loops.rb:46:1:46:6 | ... += ... | AssignAddExpr |
| loops.rb:49:1:52:3 | until ... | UntilExpr | loops.rb:49:7:49:12 | ... == ... | loops.rb:49:13:52:3 | ...; ... | ExprSequence |
| loops.rb:55:1:58:3 | until ... | UntilExpr | loops.rb:55:7:55:11 | ... > ... | loops.rb:55:13:58:3 | ...; ... | ExprSequence |
| loops.rb:61:1:61:19 | ... until ... | UntilModifierExpr | loops.rb:61:14:61:19 | ... == ... | loops.rb:61:1:61:6 | ... -= ... | AssignSubExpr |
| loops.rb:35:1:39:3 | while ... | WhileExpr | loops.rb:35:7:35:11 | ... < ... | loops.rb:35:12:39:3 | ...; ... | StmtSequence |
| loops.rb:42:1:45:3 | while ... | WhileExpr | loops.rb:42:7:42:11 | ... < ... | loops.rb:42:13:45:3 | ...; ... | StmtSequence |
| loops.rb:48:1:48:19 | ... while ... | WhileModifierExpr | loops.rb:48:14:48:19 | ... >= ... | loops.rb:48:1:48:6 | ... += ... | AssignAddExpr |
| loops.rb:51:1:54:3 | until ... | UntilExpr | loops.rb:51:7:51:12 | ... == ... | loops.rb:51:13:54:3 | ...; ... | StmtSequence |
| loops.rb:57:1:60:3 | until ... | UntilExpr | loops.rb:57:7:57:11 | ... > ... | loops.rb:57:13:60:3 | ...; ... | StmtSequence |
| loops.rb:63:1:63:19 | ... until ... | UntilModifierExpr | loops.rb:63:14:63:19 | ... == ... | loops.rb:63:1:63:6 | ... -= ... | AssignSubExpr |
forExprs
| loops.rb:9:1:12:3 | for ... in ... | loops.rb:9:5:9:5 | n | loops.rb:9:15:12:3 | ...; ... | 0 | loops.rb:10:5:10:12 | ... += ... |
| loops.rb:9:1:12:3 | for ... in ... | loops.rb:9:5:9:5 | n | loops.rb:9:15:12:3 | ...; ... | 1 | loops.rb:11:5:11:11 | ... = ... |
@@ -23,23 +23,25 @@ forExprs
| loops.rb:16:1:19:3 | for ... in ... | loops.rb:16:5:16:5 | n | loops.rb:16:15:19:3 | ...; ... | 1 | loops.rb:18:5:18:12 | ... -= ... |
| loops.rb:22:1:25:3 | for ... in ... | loops.rb:22:5:22:14 | (..., ...) | loops.rb:22:35:25:3 | ...; ... | 0 | loops.rb:23:3:23:14 | ... += ... |
| loops.rb:22:1:25:3 | for ... in ... | loops.rb:22:5:22:14 | (..., ...) | loops.rb:22:35:25:3 | ...; ... | 1 | loops.rb:24:3:24:14 | ... *= ... |
| loops.rb:28:1:31:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | loops.rb:28:37:31:3 | ...; ... | 0 | loops.rb:29:3:29:14 | ... += ... |
| loops.rb:28:1:31:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | loops.rb:28:37:31:3 | ...; ... | 1 | loops.rb:30:3:30:14 | ... /= ... |
| loops.rb:28:1:32:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | loops.rb:28:37:32:3 | ...; ... | 0 | loops.rb:29:3:29:14 | ... += ... |
| loops.rb:28:1:32:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | loops.rb:28:37:32:3 | ...; ... | 1 | loops.rb:30:3:30:14 | ... /= ... |
| loops.rb:28:1:32:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | loops.rb:28:37:32:3 | ...; ... | 2 | loops.rb:31:3:31:7 | break |
forExprsTuplePatterns
| loops.rb:22:1:25:3 | for ... in ... | loops.rb:22:5:22:14 | (..., ...) | 0 | loops.rb:22:5:22:7 | key |
| loops.rb:22:1:25:3 | for ... in ... | loops.rb:22:5:22:14 | (..., ...) | 1 | loops.rb:22:10:22:14 | value |
| loops.rb:28:1:31:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | 0 | loops.rb:28:5:28:16 | (..., ...) |
| loops.rb:28:1:32:3 | for ... in ... | loops.rb:28:5:28:16 | (..., ...) | 0 | loops.rb:28:5:28:16 | (..., ...) |
whileExprs
| loops.rb:34:1:37:3 | while ... | loops.rb:34:7:34:11 | ... < ... | loops.rb:34:12:37:3 | ...; ... | 0 | loops.rb:35:3:35:8 | ... += ... |
| loops.rb:34:1:37:3 | while ... | loops.rb:34:7:34:11 | ... < ... | loops.rb:34:12:37:3 | ...; ... | 1 | loops.rb:36:3:36:8 | ... += ... |
| loops.rb:40:1:43:3 | while ... | loops.rb:40:7:40:11 | ... < ... | loops.rb:40:13:43:3 | ...; ... | 0 | loops.rb:41:3:41:8 | ... += ... |
| loops.rb:40:1:43:3 | while ... | loops.rb:40:7:40:11 | ... < ... | loops.rb:40:13:43:3 | ...; ... | 1 | loops.rb:42:3:42:8 | ... += ... |
| loops.rb:35:1:39:3 | while ... | loops.rb:35:7:35:11 | ... < ... | loops.rb:35:12:39:3 | ...; ... | 0 | loops.rb:36:3:36:8 | ... += ... |
| loops.rb:35:1:39:3 | while ... | loops.rb:35:7:35:11 | ... < ... | loops.rb:35:12:39:3 | ...; ... | 1 | loops.rb:37:3:37:8 | ... += ... |
| loops.rb:35:1:39:3 | while ... | loops.rb:35:7:35:11 | ... < ... | loops.rb:35:12:39:3 | ...; ... | 2 | loops.rb:38:3:38:6 | next |
| loops.rb:42:1:45:3 | while ... | loops.rb:42:7:42:11 | ... < ... | loops.rb:42:13:45:3 | ...; ... | 0 | loops.rb:43:3:43:8 | ... += ... |
| loops.rb:42:1:45:3 | while ... | loops.rb:42:7:42:11 | ... < ... | loops.rb:42:13:45:3 | ...; ... | 1 | loops.rb:44:3:44:8 | ... += ... |
whileModifierExprs
| loops.rb:46:1:46:19 | ... while ... | loops.rb:46:14:46:19 | ... >= ... | loops.rb:46:1:46:6 | ... += ... |
| loops.rb:48:1:48:19 | ... while ... | loops.rb:48:14:48:19 | ... >= ... | loops.rb:48:1:48:6 | ... += ... |
untilExprs
| loops.rb:49:1:52:3 | until ... | loops.rb:49:7:49:12 | ... == ... | loops.rb:49:13:52:3 | ...; ... | 0 | loops.rb:50:3:50:8 | ... += ... |
| loops.rb:49:1:52:3 | until ... | loops.rb:49:7:49:12 | ... == ... | loops.rb:49:13:52:3 | ...; ... | 1 | loops.rb:51:3:51:8 | ... -= ... |
| loops.rb:55:1:58:3 | until ... | loops.rb:55:7:55:11 | ... > ... | loops.rb:55:13:58:3 | ...; ... | 0 | loops.rb:56:3:56:8 | ... += ... |
| loops.rb:55:1:58:3 | until ... | loops.rb:55:7:55:11 | ... > ... | loops.rb:55:13:58:3 | ...; ... | 1 | loops.rb:57:3:57:8 | ... -= ... |
| loops.rb:51:1:54:3 | until ... | loops.rb:51:7:51:12 | ... == ... | loops.rb:51:13:54:3 | ...; ... | 0 | loops.rb:52:3:52:8 | ... += ... |
| loops.rb:51:1:54:3 | until ... | loops.rb:51:7:51:12 | ... == ... | loops.rb:51:13:54:3 | ...; ... | 1 | loops.rb:53:3:53:8 | ... -= ... |
| loops.rb:57:1:60:3 | until ... | loops.rb:57:7:57:11 | ... > ... | loops.rb:57:13:60:3 | ...; ... | 0 | loops.rb:58:3:58:8 | ... += ... |
| loops.rb:57:1:60:3 | until ... | loops.rb:57:7:57:11 | ... > ... | loops.rb:57:13:60:3 | ...; ... | 1 | loops.rb:59:3:59:8 | ... -= ... |
untilModifierExprs
| loops.rb:61:1:61:19 | ... until ... | loops.rb:61:14:61:19 | ... == ... | loops.rb:61:1:61:6 | ... -= ... |
| loops.rb:63:1:63:19 | ... until ... | loops.rb:63:14:63:19 | ... == ... | loops.rb:63:1:63:6 | ... -= ... |

View File

@@ -13,10 +13,10 @@ query predicate conditionalLoops(
cond = l.getCondition()
}
query predicate forExprs(ForExpr f, Pattern p, ExprSequence body, int i, Expr bodyChild) {
query predicate forExprs(ForExpr f, Pattern p, StmtSequence body, int i, Stmt bodyChild) {
p = f.getPattern() and
body = f.getBody() and
bodyChild = body.getExpr(i)
bodyChild = body.getStmt(i)
}
query predicate forExprsTuplePatterns(ForExpr f, TuplePattern tp, int i, Pattern cp) {
@@ -24,10 +24,10 @@ query predicate forExprsTuplePatterns(ForExpr f, TuplePattern tp, int i, Pattern
cp = tp.getElement(i)
}
query predicate whileExprs(WhileExpr e, Expr cond, ExprSequence body, int i, Expr bodyChild) {
query predicate whileExprs(WhileExpr e, Expr cond, StmtSequence body, int i, Stmt bodyChild) {
cond = e.getCondition() and
body = e.getBody() and
bodyChild = body.getExpr(i)
bodyChild = body.getStmt(i)
}
query predicate whileModifierExprs(WhileModifierExpr e, Expr cond, Expr body) {
@@ -35,10 +35,10 @@ query predicate whileModifierExprs(WhileModifierExpr e, Expr cond, Expr body) {
body = e.getBody()
}
query predicate untilExprs(UntilExpr e, Expr cond, ExprSequence body, int i, Expr bodyChild) {
query predicate untilExprs(UntilExpr e, Expr cond, StmtSequence body, int i, Stmt bodyChild) {
cond = e.getCondition() and
body = e.getBody() and
bodyChild = body.getExpr(i)
bodyChild = body.getStmt(i)
}
query predicate untilModifierExprs(UntilModifierExpr e, Expr cond, Expr body) {

View File

@@ -28,12 +28,14 @@ end
for (key, value) in {foo: 0, bar: 1}
sum += value
foo /= value
break
end
# While loop
while x < y
x += 1
z += 1
next
end
# While loop with `do` keyword

View File

@@ -9,7 +9,7 @@ query predicate classesWithNameScopeExprs(Class c, Expr se) { se = c.getScopeExp
query predicate classesWithGlobalNameScopeExprs(Class c) { c.hasGlobalScope() }
query predicate exprsInClasses(Class c, int i, Expr e, string eClass) {
e = c.getExpr(i) and eClass = e.getAPrimaryQlClass()
e = c.getStmt(i) and eClass = e.getAPrimaryQlClass()
}
query predicate methodsInClasses(Class c, Method m, string name) { m = c.getMethod(name) }

View File

@@ -9,7 +9,7 @@ query predicate modulesWithScopeExprs(Module m, Expr se) { se = m.getScopeExpr()
query predicate modulesWithGlobalNameScopeExprs(Module m) { m.hasGlobalScope() }
query predicate exprsInModules(Module m, int i, Expr e, string eClass) {
e = m.getExpr(i) and eClass = e.getAPrimaryQlClass()
e = m.getStmt(i) and eClass = e.getAPrimaryQlClass()
}
query predicate methodsInModules(Module mod, Method method, string name) {

View File

@@ -5,7 +5,7 @@ query predicate singletonClasses(SingletonClass sc, string pClass, Expr value) {
}
query predicate exprsInSingletonClasses(SingletonClass sc, int i, Expr e, string eClass) {
e = sc.getExpr(i) and eClass = e.getAPrimaryQlClass()
e = sc.getStmt(i) and eClass = e.getAPrimaryQlClass()
}
query predicate methodsInSingletonClasses(SingletonClass sc, Method m) { m = sc.getAMethod() }