Merge pull request #179 from github/hvitved/synth-framework-take2

AST synthesis framework (take 2)
This commit is contained in:
Tom Hvitved
2021-05-17 15:36:56 +02:00
committed by GitHub
34 changed files with 1503 additions and 240 deletions

View File

@@ -15,6 +15,14 @@ query predicate missingParent(AstNode node, string cls) {
query predicate multipleParents(AstNode node, AstNode parent, string cls) {
parent = node.getParent() and
count(node.getParent()) > 1 and
cls = getAPrimaryQlClass(parent)
cls = getAPrimaryQlClass(parent) and
exists(AstNode one, AstNode two |
one = node.getParent() and
two = node.getParent() and
one != two
|
one.isSynthesized() and two.isSynthesized()
or
not one.isSynthesized() and not two.isSynthesized()
)
}

View File

@@ -14,6 +14,7 @@ import ast.Statement
import ast.Variable
private import ast.internal.AST
private import ast.internal.Scope
private import ast.internal.Synthesis
/**
* A node in the abstract syntax tree. This class is the base class for all Ruby
@@ -56,7 +57,11 @@ class AstNode extends TAstNode {
final AstNode getAChild() { result = this.getAChild(_) }
/** Gets the parent of this `AstNode`, if this node is not a root node. */
final AstNode getParent() { result.getAChild() = this }
final AstNode getParent() {
result.getAChild() = this
or
result.getAChild().getDesugared() = this
}
/**
* Gets a child of this node, which can also be retrieved using a predicate
@@ -75,5 +80,25 @@ class AstNode extends TAstNode {
* foo(123)
* ```
*/
predicate isSynthesized() { this instanceof TImplicitSelf }
final predicate isSynthesized() { this = getSynthChild(_, _) }
/**
* Gets the desugared version of this AST node, if any.
*
* For example, the desugared version of
*
* ```rb
* x += y
* ```
*
* is
*
* ```rb
* x = x + y
* ```
*
* when `x` is a variable. Whenever an AST node can be desugared,
* then the desugared version is used in the control-flow graph.
*/
final AstNode getDesugared() { result = getSynthChild(this, -1) }
}

View File

@@ -137,7 +137,7 @@ private class IdentifierMethodCall extends MethodCall, TIdentifierMethodCall {
final override string getMethodName() { result = getMethodName(this, g.getValue()) }
final override Self getReceiver() { result = TImplicitSelf(g) }
final override Self getReceiver() { result = TSelfSynth(this, 0) }
}
private class ScopeResolutionMethodCall extends MethodCall, TScopeResolutionMethodCall {
@@ -162,12 +162,7 @@ private class RegularMethodCall extends MethodCall, TRegularMethodCall {
not exists(g.getReceiver()) and
toGenerated(result) = g.getMethod().(Generated::ScopeResolution).getScope()
or
// If there's no explicit receiver (or scope resolution that acts like a
// receiver), then the receiver is implicitly `self`. N.B. `::Foo()` is
// not valid Ruby.
not exists(g.getReceiver()) and
not exists(g.getMethod().(Generated::ScopeResolution).getScope()) and
result = TImplicitSelf(g)
result = TSelfSynth(this, 0)
}
final override string getMethodName() {

View File

@@ -79,6 +79,12 @@ class StmtSequence extends Expr, TStmtSequence {
override AstNode getAChild(string pred) { pred = "getStmt" and result = this.getStmt(_) }
}
private class StmtSequenceSynth extends StmtSequence, TStmtSequenceSynth {
final override Stmt getStmt(int n) { synthChild(this, n, result) }
final override string toString() { result = "..." }
}
private class Then extends StmtSequence, TThen {
private Generated::Then g;
@@ -210,11 +216,11 @@ class ParenthesizedExpr extends StmtSequence, TParenthesizedExpr {
ParenthesizedExpr() { this = TParenthesizedExpr(g) }
final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
final override string getAPrimaryQlClass() { result = "ParenthesizedExpr" }
final override string toString() { result = "( ... )" }
final override Stmt getStmt(int n) { toGenerated(result) = g.getChild(n) }
}
/**

View File

@@ -101,12 +101,6 @@ class DefinedExpr extends UnaryOperation, TDefinedExpr {
/** A binary operation. */
class BinaryOperation extends Operation, TBinaryOperation {
private Generated::Binary g;
BinaryOperation() { g = toGenerated(this) }
final override string getOperator() { result = g.getOperator() }
final override Expr getAnOperand() {
result = this.getLeftOperand() or result = this.getRightOperand()
}
@@ -122,10 +116,28 @@ class BinaryOperation extends Operation, TBinaryOperation {
}
/** Gets the left operand of this binary operation. */
final Stmt getLeftOperand() { toGenerated(result) = g.getLeft() }
Stmt getLeftOperand() { none() }
/** Gets the right operand of this binary operation. */
final Stmt getRightOperand() { toGenerated(result) = g.getRight() }
Stmt getRightOperand() { none() }
}
private class BinaryOperationReal extends BinaryOperation {
private Generated::Binary g;
BinaryOperationReal() { g = toGenerated(this) }
final override string getOperator() { result = g.getOperator() }
final override Stmt getLeftOperand() { toGenerated(result) = g.getLeft() }
final override Stmt getRightOperand() { toGenerated(result) = g.getRight() }
}
abstract private class BinaryOperationSynth extends BinaryOperation {
final override Stmt getLeftOperand() { synthChild(this, 0, result) }
final override Stmt getRightOperand() { synthChild(this, 1, result) }
}
/**
@@ -143,6 +155,10 @@ class AddExpr extends BinaryArithmeticOperation, TAddExpr {
final override string getAPrimaryQlClass() { result = "AddExpr" }
}
private class AddExprSynth extends AddExpr, BinaryOperationSynth, TAddExprSynth {
final override string getOperator() { result = "+" }
}
/**
* A subtract expression.
* ```rb
@@ -153,6 +169,10 @@ class SubExpr extends BinaryArithmeticOperation, TSubExpr {
final override string getAPrimaryQlClass() { result = "SubExpr" }
}
private class SubExprSynth extends SubExpr, BinaryOperationSynth, TSubExprSynth {
final override string getOperator() { result = "-" }
}
/**
* A multiply expression.
* ```rb
@@ -163,6 +183,10 @@ class MulExpr extends BinaryArithmeticOperation, TMulExpr {
final override string getAPrimaryQlClass() { result = "MulExpr" }
}
private class MulExprSynth extends MulExpr, BinaryOperationSynth, TMulExprSynth {
final override string getOperator() { result = "*" }
}
/**
* A divide expression.
* ```rb
@@ -173,6 +197,10 @@ class DivExpr extends BinaryArithmeticOperation, TDivExpr {
final override string getAPrimaryQlClass() { result = "DivExpr" }
}
private class DivExprSynth extends DivExpr, BinaryOperationSynth, TDivExprSynth {
final override string getOperator() { result = "/" }
}
/**
* A modulo expression.
* ```rb
@@ -183,6 +211,10 @@ class ModuloExpr extends BinaryArithmeticOperation, TModuloExpr {
final override string getAPrimaryQlClass() { result = "ModuloExpr" }
}
private class ModuloExprSynth extends ModuloExpr, BinaryOperationSynth, TModuloExprSynth {
final override string getOperator() { result = "%" }
}
/**
* An exponent expression.
* ```rb
@@ -193,6 +225,10 @@ class ExponentExpr extends BinaryArithmeticOperation, TExponentExpr {
final override string getAPrimaryQlClass() { result = "ExponentExpr" }
}
private class ExponentExprSynth extends ExponentExpr, BinaryOperationSynth, TExponentExprSynth {
final override string getOperator() { result = "**" }
}
/**
* A binary logical operation.
*/
@@ -209,6 +245,10 @@ class LogicalAndExpr extends BinaryLogicalOperation, TLogicalAndExpr {
final override string getAPrimaryQlClass() { result = "LogicalAndExpr" }
}
private class LogicalAndExprSynth extends LogicalAndExpr, BinaryOperationSynth, TLogicalAndExprSynth {
final override string getOperator() { result = "&&" }
}
/**
* A logical OR operation, using either `or` or `||`.
* ```rb
@@ -220,6 +260,10 @@ class LogicalOrExpr extends BinaryLogicalOperation, TLogicalOrExpr {
final override string getAPrimaryQlClass() { result = "LogicalOrExpr" }
}
private class LogicalOrExprSynth extends LogicalOrExpr, BinaryOperationSynth, TLogicalOrExprSynth {
final override string getOperator() { result = "||" }
}
/**
* A binary bitwise operation.
*/
@@ -235,6 +279,10 @@ class LShiftExpr extends BinaryBitwiseOperation, TLShiftExpr {
final override string getAPrimaryQlClass() { result = "LShiftExpr" }
}
private class LShiftExprSynth extends LShiftExpr, BinaryOperationSynth, TLShiftExprSynth {
final override string getOperator() { result = "<<" }
}
/**
* A right-shift operation.
* ```rb
@@ -245,6 +293,10 @@ class RShiftExpr extends BinaryBitwiseOperation, TRShiftExpr {
final override string getAPrimaryQlClass() { result = "RShiftExpr" }
}
private class RShiftExprSynth extends RShiftExpr, BinaryOperationSynth, TRShiftExprSynth {
final override string getOperator() { result = ">>" }
}
/**
* A bitwise AND operation.
* ```rb
@@ -255,6 +307,10 @@ class BitwiseAndExpr extends BinaryBitwiseOperation, TBitwiseAndExpr {
final override string getAPrimaryQlClass() { result = "BitwiseAndExpr" }
}
private class BitwiseAndSynthExpr extends BitwiseAndExpr, BinaryOperationSynth, TBitwiseAndExprSynth {
final override string getOperator() { result = "&" }
}
/**
* A bitwise OR operation.
* ```rb
@@ -265,6 +321,10 @@ class BitwiseOrExpr extends BinaryBitwiseOperation, TBitwiseOrExpr {
final override string getAPrimaryQlClass() { result = "BitwiseOrExpr" }
}
private class BitwiseOrSynthExpr extends BitwiseOrExpr, BinaryOperationSynth, TBitwiseOrExprSynth {
final override string getOperator() { result = "|" }
}
/**
* An XOR (exclusive OR) operation.
* ```rb
@@ -275,6 +335,10 @@ class BitwiseXorExpr extends BinaryBitwiseOperation, TBitwiseXorExpr {
final override string getAPrimaryQlClass() { result = "BitwiseXorExpr" }
}
private class BitwiseXorSynthExpr extends BitwiseXorExpr, BinaryOperationSynth, TBitwiseXorExprSynth {
final override string getOperator() { result = "^" }
}
/**
* A comparison operation. That is, either an equality operation or a
* relational operation.
@@ -455,17 +519,25 @@ class Assignment extends Operation, TAssignment {
* ```
*/
class AssignExpr extends Assignment, TAssignExpr {
final override string getOperator() { result = "=" }
final override string getAPrimaryQlClass() { result = "AssignExpr" }
}
private class AssignExprReal extends AssignExpr, TAssignExprReal {
private Generated::Assignment g;
AssignExpr() { this = TAssignExpr(g) }
AssignExprReal() { this = TAssignExprReal(g) }
final override Pattern getLeftOperand() { toGenerated(result) = g.getLeft() }
final override Expr getRightOperand() { toGenerated(result) = g.getRight() }
}
final override string getOperator() { result = "=" }
private class AssignExprSynth extends AssignExpr, TAssignExprSynth {
final override Pattern getLeftOperand() { synthChild(this, 0, result) }
override string getAPrimaryQlClass() { result = "AssignExpr" }
final override Expr getRightOperand() { synthChild(this, 1, result) }
}
/**

View File

@@ -37,10 +37,7 @@ class TuplePatternParameter extends PatternParameter, TuplePattern, TTuplePatter
final override string getAPrimaryQlClass() { result = "TuplePatternParameter" }
override AstNode getAChild(string pred) {
result = PatternParameter.super.getAChild(pred) or
result = TuplePattern.super.getAChild(pred)
}
override AstNode getAChild(string pred) { result = TuplePattern.super.getAChild(pred) }
}
/** A named parameter. */
@@ -60,8 +57,6 @@ class NamedParameter extends Parameter, TNamedParameter {
final VariableAccess getDefiningAccess() { result = this.getVariable().getDefiningAccess() }
override AstNode getAChild(string pred) {
result = Parameter.super.getAChild(pred)
or
pred = "getDefiningAccess" and
result = this.getDefiningAccess()
}
@@ -75,7 +70,7 @@ class SimpleParameter extends NamedParameter, PatternParameter, VariablePattern,
final override string getName() { result = g.getValue() }
final override LocalVariable getVariable() { result = TLocalVariable(_, _, g) }
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g) }
final override LocalVariable getAVariable() { result = this.getVariable() }
@@ -99,7 +94,7 @@ class BlockParameter extends NamedParameter, TBlockParameter {
final override string getName() { result = g.getName().getValue() }
final override LocalVariable getVariable() { result = TLocalVariable(_, _, g.getName()) }
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
final override string toString() { result = "&" + this.getName() }
@@ -122,7 +117,7 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter {
final override string getAPrimaryQlClass() { result = "HashSplatParameter" }
final override LocalVariable getVariable() { result = TLocalVariable(_, _, g.getName()) }
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
final override string toString() { result = "**" + this.getName() }
@@ -147,7 +142,7 @@ class KeywordParameter extends NamedParameter, TKeywordParameter {
final override string getAPrimaryQlClass() { result = "KeywordParameter" }
final override LocalVariable getVariable() { result = TLocalVariable(_, _, g.getName()) }
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
/**
* Gets the default value, i.e. the value assigned to the parameter when one
@@ -197,7 +192,7 @@ class OptionalParameter extends NamedParameter, TOptionalParameter {
*/
final Expr getDefaultValue() { toGenerated(result) = g.getValue() }
final override LocalVariable getVariable() { result = TLocalVariable(_, _, g.getName()) }
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
final override string toString() { result = this.getName() }
@@ -227,7 +222,7 @@ class SplatParameter extends NamedParameter, TSplatParameter {
final override string getAPrimaryQlClass() { result = "SplatParameter" }
final override LocalVariable getVariable() { result = TLocalVariable(_, _, g.getName()) }
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
final override string toString() { result = "*" + this.getName() }

View File

@@ -7,9 +7,13 @@ private import internal.Variable
/** A pattern. */
class Pattern extends AstNode {
Pattern() {
explicitAssignmentNode(toGenerated(this), _) or
implicitAssignmentNode(toGenerated(this)) or
explicitAssignmentNode(toGenerated(this), _)
or
implicitAssignmentNode(toGenerated(this))
or
implicitParameterAssignmentNode(toGenerated(this), _)
or
this = getSynthChild(any(AssignExpr ae), 0)
}
/** Gets a variable used in (or introduced by) this pattern. */

View File

@@ -8,21 +8,17 @@ private import internal.Variable
/** A variable declared in a scope. */
class Variable extends TVariable {
Variable::Range range;
Variable() { range = this }
/** Gets the name of this variable. */
final string getName() { result = range.getName() }
string getName() { none() }
/** Gets a textual representation of this variable. */
final string toString() { result = this.getName() }
/** Gets the location of this variable. */
final Location getLocation() { result = range.getLocation() }
Location getLocation() { none() }
/** Gets the scope this variable is declared in. */
final Scope getDeclaringScope() { toGenerated(result) = range.getDeclaringScope() }
Scope getDeclaringScope() { none() }
/** Gets an access to this variable. */
VariableAccess getAnAccess() { result.getVariable() = this }
@@ -30,12 +26,10 @@ class Variable extends TVariable {
/** A local variable. */
class LocalVariable extends Variable, TLocalVariable {
override LocalVariable::Range range;
final override LocalVariableAccess getAnAccess() { result.getVariable() = this }
override LocalVariableAccess getAnAccess() { none() }
/** Gets the access where this local variable is first introduced. */
VariableAccess getDefiningAccess() { result = range.getDefiningAccess() }
VariableAccess getDefiningAccess() { none() }
/**
* Holds if this variable is captured. For example in
@@ -55,14 +49,14 @@ class LocalVariable extends Variable, TLocalVariable {
}
/** A global variable. */
class GlobalVariable extends Variable, TGlobalVariable {
class GlobalVariable extends VariableReal, TGlobalVariable {
override GlobalVariable::Range range;
final override GlobalVariableAccess getAnAccess() { result.getVariable() = this }
}
/** An instance variable. */
class InstanceVariable extends Variable, TInstanceVariable {
class InstanceVariable extends VariableReal, TInstanceVariable {
override InstanceVariable::Range range;
/** Holds is this variable is a class instance variable. */
@@ -72,7 +66,7 @@ class InstanceVariable extends Variable, TInstanceVariable {
}
/** A class variable. */
class ClassVariable extends Variable, TClassVariable {
class ClassVariable extends VariableReal, TClassVariable {
override ClassVariable::Range range;
final override ClassVariableAccess getAnAccess() { result.getVariable() = this }
@@ -95,6 +89,8 @@ class VariableAccess extends Expr, TVariableAccess {
*/
predicate isExplicitWrite(AstNode assignment) {
explicitWriteAccess(toGenerated(this), toGenerated(assignment))
or
this = assignment.(AssignExpr).getLeftOperand()
}
/**
@@ -125,22 +121,12 @@ class VariableWriteAccess extends VariableAccess {
/** An access to a variable where the value is read. */
class VariableReadAccess extends VariableAccess {
VariableReadAccess() {
not this instanceof VariableWriteAccess
or
// `x` in `x += y` is considered both a read and a write
this = any(AssignOperation a).getLeftOperand()
}
VariableReadAccess() { not this instanceof VariableWriteAccess }
}
/** An access to a local variable. */
class LocalVariableAccess extends VariableAccess, TLocalVariableAccess {
private Generated::Identifier g;
private LocalVariable v;
LocalVariableAccess() { this = TLocalVariableAccess(g, v) }
final override LocalVariable getVariable() { result = v }
override LocalVariable getVariable() { none() }
final override string getAPrimaryQlClass() { result = "LocalVariableAccess" }
@@ -160,8 +146,6 @@ class LocalVariableAccess extends VariableAccess, TLocalVariableAccess {
* the access to `x` in the second `puts x` is not.
*/
final predicate isCapturedAccess() { isCapturedAccess(this) }
final override string toString() { result = g.getValue() }
}
/** An access to a local variable where the value is updated. */
@@ -172,16 +156,9 @@ class LocalVariableReadAccess extends LocalVariableAccess, VariableReadAccess {
/** An access to a global variable. */
class GlobalVariableAccess extends VariableAccess, TGlobalVariableAccess {
private Generated::GlobalVariable g;
private GlobalVariable v;
GlobalVariableAccess() { this = TGlobalVariableAccess(g, v) }
final override GlobalVariable getVariable() { result = v }
override GlobalVariable getVariable() { none() }
final override string getAPrimaryQlClass() { result = "GlobalVariableAccess" }
final override string toString() { result = g.getValue() }
}
/** An access to a global variable where the value is updated. */
@@ -192,28 +169,14 @@ class GlobalVariableReadAccess extends GlobalVariableAccess, VariableReadAccess
/** An access to an instance variable. */
class InstanceVariableAccess extends VariableAccess, TInstanceVariableAccess {
private Generated::InstanceVariable g;
private InstanceVariable v;
InstanceVariableAccess() { this = TInstanceVariableAccess(g, v) }
final override InstanceVariable getVariable() { result = v }
override InstanceVariable getVariable() { none() }
final override string getAPrimaryQlClass() { result = "InstanceVariableAccess" }
final override string toString() { result = g.getValue() }
}
/** An access to a class variable. */
class ClassVariableAccess extends VariableAccess, TClassVariableAccess {
private Generated::ClassVariable g;
private ClassVariable v;
ClassVariableAccess() { this = TClassVariableAccess(g, v) }
final override ClassVariable getVariable() { result = v }
override ClassVariable getVariable() { none() }
final override string getAPrimaryQlClass() { result = "ClassVariableAccess" }
final override string toString() { result = g.getValue() }
}

View File

@@ -3,6 +3,7 @@ private import TreeSitter
private import codeql_ruby.ast.internal.Parameter
private import codeql_ruby.ast.internal.Variable
private import codeql_ruby.AST as AST
private import Synthesis
module MethodName {
predicate range(Generated::UnderscoreMethodName g) {
@@ -16,11 +17,16 @@ module MethodName {
@token_identifier or @token_instance_variable or @token_operator;
}
private predicate mkSynthChild(SynthKind kind, AST::AstNode parent, int i) {
any(Synthesis s).child(parent, i, SynthChild(kind))
}
cached
private module Cached {
cached
newtype TAstNode =
TAddExpr(Generated::Binary g) { g instanceof @binary_plus } or
TAddExprReal(Generated::Binary g) { g instanceof @binary_plus } or
TAddExprSynth(AST::AstNode parent, int i) { mkSynthChild(AddExprKind(), parent, i) } or
TAliasStmt(Generated::Alias g) or
TArgumentList(Generated::AstNode g) {
(
@@ -50,7 +56,8 @@ private module Cached {
TAssignExponentExpr(Generated::OperatorAssignment g) {
g instanceof @operator_assignment_starstarequal
} or
TAssignExpr(Generated::Assignment g) or
TAssignExprReal(Generated::Assignment g) or
TAssignExprSynth(AST::AstNode parent, int i) { mkSynthChild(AssignExprKind(), parent, i) } or
TAssignLShiftExpr(Generated::OperatorAssignment g) {
g instanceof @operator_assignment_langlelangleequal
} or
@@ -72,9 +79,16 @@ private module Cached {
TBareSymbolLiteral(Generated::BareSymbol g) or
TBeginBlock(Generated::BeginBlock g) or
TBeginExpr(Generated::Begin g) or
TBitwiseAndExpr(Generated::Binary g) { g instanceof @binary_ampersand } or
TBitwiseOrExpr(Generated::Binary g) { g instanceof @binary_pipe } or
TBitwiseXorExpr(Generated::Binary g) { g instanceof @binary_caret } or
TBitwiseAndExprReal(Generated::Binary g) { g instanceof @binary_ampersand } or
TBitwiseAndExprSynth(AST::AstNode parent, int i) {
mkSynthChild(BitwiseAndExprKind(), parent, i)
} or
TBitwiseOrExprReal(Generated::Binary g) { g instanceof @binary_pipe } or
TBitwiseOrExprSynth(AST::AstNode parent, int i) { mkSynthChild(BitwiseOrExprKind(), parent, i) } or
TBitwiseXorExprReal(Generated::Binary g) { g instanceof @binary_caret } or
TBitwiseXorExprSynth(AST::AstNode parent, int i) {
mkSynthChild(BitwiseXorExprKind(), parent, i)
} or
TBlockArgument(Generated::BlockArgument g) or
TBlockParameter(Generated::BlockParameter g) or
TBraceBlock(Generated::Block g) { not g.getParent() instanceof Generated::Lambda } or
@@ -83,9 +97,12 @@ private module Cached {
TCaseExpr(Generated::Case g) or
TCharacterLiteral(Generated::Character g) or
TClassDeclaration(Generated::Class g) or
TClassVariableAccess(Generated::ClassVariable g, AST::ClassVariable v) {
TClassVariableAccessReal(Generated::ClassVariable g, AST::ClassVariable v) {
ClassVariableAccess::range(g, v)
} or
TClassVariableAccessSynth(AST::AstNode parent, int i, AST::ClassVariable v) {
mkSynthChild(ClassVariableAccessKind(v), parent, i)
} or
TComplementExpr(Generated::Unary g) { g instanceof @unary_tilde } or
TComplexLiteral(Generated::Complex g) or
TDefinedExpr(Generated::Unary g) { g instanceof @unary_definedquestion } or
@@ -93,7 +110,8 @@ private module Cached {
TDestructuredLeftAssignment(Generated::DestructuredLeftAssignment g) {
not strictcount(int i | exists(g.getParent().(Generated::LeftAssignmentList).getChild(i))) = 1
} or
TDivExpr(Generated::Binary g) { g instanceof @binary_slash } or
TDivExprReal(Generated::Binary g) { g instanceof @binary_slash } or
TDivExprSynth(AST::AstNode parent, int i) { mkSynthChild(DivExprKind(), parent, i) } or
TDo(Generated::Do g) or
TDoBlock(Generated::DoBlock g) { not g.getParent() instanceof Generated::Lambda } or
TElementReference(Generated::ElementReference g) or
@@ -103,17 +121,20 @@ private module Cached {
TEndBlock(Generated::EndBlock g) or
TEnsure(Generated::Ensure g) or
TEqExpr(Generated::Binary g) { g instanceof @binary_equalequal } or
TExplicitSelf(Generated::Self g) or
TExponentExpr(Generated::Binary g) { g instanceof @binary_starstar } or
TExponentExprReal(Generated::Binary g) { g instanceof @binary_starstar } or
TExponentExprSynth(AST::AstNode parent, int i) { mkSynthChild(ExponentExprKind(), parent, i) } or
TFalseLiteral(Generated::False g) or
TFloatLiteral(Generated::Float g) { not any(Generated::Rational r).getChild() = g } or
TForExpr(Generated::For g) or
TForIn(Generated::In g) or // TODO REMOVE
TGEExpr(Generated::Binary g) { g instanceof @binary_rangleequal } or
TGTExpr(Generated::Binary g) { g instanceof @binary_rangle } or
TGlobalVariableAccess(Generated::GlobalVariable g, AST::GlobalVariable v) {
TGlobalVariableAccessReal(Generated::GlobalVariable g, AST::GlobalVariable v) {
GlobalVariableAccess::range(g, v)
} or
TGlobalVariableAccessSynth(AST::AstNode parent, int i, AST::GlobalVariable v) {
mkSynthChild(GlobalVariableAccessKind(v), parent, i)
} or
THashKeySymbolLiteral(Generated::HashKeySymbol g) or
THashLiteral(Generated::Hash g) or
THashSplatArgument(Generated::HashSplatArgument g) or
@@ -122,34 +143,44 @@ private module Cached {
TIdentifierMethodCall(Generated::Identifier g) { isIdentifierMethodCall(g) } or
TIf(Generated::If g) or
TIfModifierExpr(Generated::IfModifier g) or
TImplicitSelf(Generated::AstNode g) {
isIdentifierMethodCall(g)
or
isRegularMethodCall(g) and
not exists(g.(Generated::Call).getReceiver()) and
not exists(g.(Generated::Call).getMethod().(Generated::ScopeResolution).getScope())
} or
TInstanceVariableAccess(Generated::InstanceVariable g, AST::InstanceVariable v) {
TInstanceVariableAccessReal(Generated::InstanceVariable g, AST::InstanceVariable v) {
InstanceVariableAccess::range(g, v)
} or
TInstanceVariableAccessSynth(AST::AstNode parent, int i, AST::InstanceVariable v) {
mkSynthChild(InstanceVariableAccessKind(v), parent, i)
} or
TIntegerLiteral(Generated::Integer g) { not any(Generated::Rational r).getChild() = g } or
TKeywordParameter(Generated::KeywordParameter g) or
TLEExpr(Generated::Binary g) { g instanceof @binary_langleequal } or
TLShiftExpr(Generated::Binary g) { g instanceof @binary_langlelangle } or
TLShiftExprReal(Generated::Binary g) { g instanceof @binary_langlelangle } or
TLShiftExprSynth(AST::AstNode parent, int i) { mkSynthChild(LShiftExprKind(), parent, i) } or
TLTExpr(Generated::Binary g) { g instanceof @binary_langle } or
TLambda(Generated::Lambda g) or
TLeftAssignmentList(Generated::LeftAssignmentList g) or
TLocalVariableAccess(Generated::Identifier g, AST::LocalVariable v) {
TLocalVariableAccessReal(Generated::Identifier g, AST::LocalVariable v) {
LocalVariableAccess::range(g, v)
} or
TLogicalAndExpr(Generated::Binary g) {
TLocalVariableAccessSynth(AST::AstNode parent, int i, AST::LocalVariable v) {
mkSynthChild(LocalVariableAccessRealKind(v), parent, i)
or
mkSynthChild(LocalVariableAccessSynthKind(v), parent, i)
} or
TLogicalAndExprReal(Generated::Binary g) {
g instanceof @binary_and or g instanceof @binary_ampersandampersand
} or
TLogicalOrExpr(Generated::Binary g) { g instanceof @binary_or or g instanceof @binary_pipepipe } or
TLogicalAndExprSynth(AST::AstNode parent, int i) {
mkSynthChild(LogicalAndExprKind(), parent, i)
} or
TLogicalOrExprReal(Generated::Binary g) {
g instanceof @binary_or or g instanceof @binary_pipepipe
} or
TLogicalOrExprSynth(AST::AstNode parent, int i) { mkSynthChild(LogicalOrExprKind(), parent, i) } or
TMethod(Generated::Method g) or
TModuleDeclaration(Generated::Module g) or
TModuloExpr(Generated::Binary g) { g instanceof @binary_percent } or
TMulExpr(Generated::Binary g) { g instanceof @binary_star } or
TModuloExprReal(Generated::Binary g) { g instanceof @binary_percent } or
TModuloExprSynth(AST::AstNode parent, int i) { mkSynthChild(ModuloExprKind(), parent, i) } or
TMulExprReal(Generated::Binary g) { g instanceof @binary_star } or
TMulExprSynth(AST::AstNode parent, int i) { mkSynthChild(MulExprKind(), parent, i) } or
TNEExpr(Generated::Binary g) { g instanceof @binary_bangequal } or
TNextStmt(Generated::Next g) or
TNilLiteral(Generated::Nil g) or
@@ -158,7 +189,8 @@ private module Cached {
TOptionalParameter(Generated::OptionalParameter g) or
TPair(Generated::Pair g) or
TParenthesizedExpr(Generated::ParenthesizedStatements g) or
TRShiftExpr(Generated::Binary g) { g instanceof @binary_ranglerangle } or
TRShiftExprReal(Generated::Binary g) { g instanceof @binary_ranglerangle } or
TRShiftExprSynth(AST::AstNode parent, int i) { mkSynthChild(RShiftExprKind(), parent, i) } or
TRangeLiteral(Generated::Range g) or
TRationalLiteral(Generated::Rational g) or
TRedoStmt(Generated::Redo g) or
@@ -187,6 +219,8 @@ private module Cached {
i = g.getName() and
not exists(Generated::Call c | c.getMethod() = g)
} or
TSelfReal(Generated::Self g) or
TSelfSynth(AST::AstNode parent, int i) { mkSynthChild(SelfKind(), parent, i) } or
TSimpleParameter(Generated::Identifier g) { g instanceof Parameter::Range } or
TSimpleSymbolLiteral(Generated::SimpleSymbol g) or
TSingletonClass(Generated::SingletonClass g) or
@@ -194,6 +228,7 @@ private module Cached {
TSpaceshipExpr(Generated::Binary g) { g instanceof @binary_langleequalrangle } or
TSplatArgument(Generated::SplatArgument g) or
TSplatParameter(Generated::SplatParameter g) or
TStmtSequenceSynth(AST::AstNode parent, int i) { mkSynthChild(StmtSequenceKind(), parent, i) } or
TStringArrayLiteral(Generated::StringArray g) or
TStringConcatenation(Generated::ChainedString g) or
TStringEscapeSequenceComponent(Generated::EscapeSequence g) or
@@ -201,7 +236,8 @@ private module Cached {
TStringTextComponent(Generated::Token g) {
g instanceof Generated::StringContent or g instanceof Generated::HeredocContent
} or
TSubExpr(Generated::Binary g) { g instanceof @binary_minus } or
TSubExprReal(Generated::Binary g) { g instanceof @binary_minus } or
TSubExprSynth(AST::AstNode parent, int i) { mkSynthChild(SubExprKind(), parent, i) } or
TSubshellLiteral(Generated::Subshell g) or
TSymbolArrayLiteral(Generated::SymbolArray g) or
TTernaryIfExpr(Generated::Conditional g) or
@@ -245,7 +281,7 @@ private module Cached {
*/
cached
Generated::AstNode toGenerated(AST::AstNode n) {
n = TAddExpr(result) or
n = TAddExprReal(result) or
n = TAliasStmt(result) or
n = TArgumentList(result) or
n = TAssignAddExpr(result) or
@@ -254,7 +290,7 @@ private module Cached {
n = TAssignBitwiseXorExpr(result) or
n = TAssignDivExpr(result) or
n = TAssignExponentExpr(result) or
n = TAssignExpr(result) or
n = TAssignExprReal(result) or
n = TAssignLShiftExpr(result) or
n = TAssignLogicalAndExpr(result) or
n = TAssignLogicalOrExpr(result) or
@@ -266,9 +302,9 @@ private module Cached {
n = TBareSymbolLiteral(result) or
n = TBeginBlock(result) or
n = TBeginExpr(result) or
n = TBitwiseAndExpr(result) or
n = TBitwiseOrExpr(result) or
n = TBitwiseXorExpr(result) or
n = TBitwiseAndExprReal(result) or
n = TBitwiseOrExprReal(result) or
n = TBitwiseXorExprReal(result) or
n = TBlockArgument(result) or
n = TBlockParameter(result) or
n = TBraceBlock(result) or
@@ -277,13 +313,13 @@ private module Cached {
n = TCaseExpr(result) or
n = TCharacterLiteral(result) or
n = TClassDeclaration(result) or
n = TClassVariableAccess(result, _) or
n = TClassVariableAccessReal(result, _) or
n = TComplementExpr(result) or
n = TComplexLiteral(result) or
n = TDefinedExpr(result) or
n = TDelimitedSymbolLiteral(result) or
n = TDestructuredLeftAssignment(result) or
n = TDivExpr(result) or
n = TDivExprReal(result) or
n = TDo(result) or
n = TDoBlock(result) or
n = TElementReference(result) or
@@ -293,15 +329,14 @@ private module Cached {
n = TEndBlock(result) or
n = TEnsure(result) or
n = TEqExpr(result) or
n = TExplicitSelf(result) or
n = TExponentExpr(result) or
n = TExponentExprReal(result) or
n = TFalseLiteral(result) or
n = TFloatLiteral(result) or
n = TForExpr(result) or
n = TForIn(result) or // TODO REMOVE
n = TGEExpr(result) or
n = TGTExpr(result) or
n = TGlobalVariableAccess(result, _) or
n = TGlobalVariableAccessReal(result, _) or
n = THashKeySymbolLiteral(result) or
n = THashLiteral(result) or
n = THashSplatArgument(result) or
@@ -310,21 +345,21 @@ private module Cached {
n = TIdentifierMethodCall(result) or
n = TIf(result) or
n = TIfModifierExpr(result) or
n = TInstanceVariableAccess(result, _) or
n = TInstanceVariableAccessReal(result, _) or
n = TIntegerLiteral(result) or
n = TKeywordParameter(result) or
n = TLEExpr(result) or
n = TLShiftExpr(result) or
n = TLShiftExprReal(result) or
n = TLTExpr(result) or
n = TLambda(result) or
n = TLeftAssignmentList(result) or
n = TLocalVariableAccess(result, _) or
n = TLogicalAndExpr(result) or
n = TLogicalOrExpr(result) or
n = TLocalVariableAccessReal(result, _) or
n = TLogicalAndExprReal(result) or
n = TLogicalOrExprReal(result) or
n = TMethod(result) or
n = TModuleDeclaration(result) or
n = TModuloExpr(result) or
n = TMulExpr(result) or
n = TModuloExprReal(result) or
n = TMulExprReal(result) or
n = TNEExpr(result) or
n = TNextStmt(result) or
n = TNilLiteral(result) or
@@ -333,7 +368,7 @@ private module Cached {
n = TOptionalParameter(result) or
n = TPair(result) or
n = TParenthesizedExpr(result) or
n = TRShiftExpr(result) or
n = TRShiftExprReal(result) or
n = TRangeLiteral(result) or
n = TRationalLiteral(result) or
n = TRedoStmt(result) or
@@ -349,6 +384,7 @@ private module Cached {
n = TReturnStmt(result) or
n = TScopeResolutionConstantAccess(result, _) or
n = TScopeResolutionMethodCall(result, _) or
n = TSelfReal(result) or
n = TSimpleParameter(result) or
n = TSimpleSymbolLiteral(result) or
n = TSingletonClass(result) or
@@ -361,7 +397,7 @@ private module Cached {
n = TStringEscapeSequenceComponent(result) or
n = TStringInterpolationComponent(result) or
n = TStringTextComponent(result) or
n = TSubExpr(result) or
n = TSubExprReal(result) or
n = TSubshellLiteral(result) or
n = TSymbolArrayLiteral(result) or
n = TTernaryIfExpr(result) or
@@ -385,14 +421,105 @@ private module Cached {
n = TYieldCall(result)
}
/** Gets the `i`th synthesized child of `parent`. */
cached
AST::AstNode getSynthChild(AST::AstNode parent, int i) {
exists(SynthKind kind | mkSynthChild(kind, parent, i) |
kind = AddExprKind() and
result = TAddExprSynth(parent, i)
or
kind = AssignExprKind() and
result = TAssignExprSynth(parent, i)
or
kind = BitwiseAndExprKind() and
result = TBitwiseAndExprSynth(parent, i)
or
kind = BitwiseOrExprKind() and
result = TBitwiseOrExprSynth(parent, i)
or
kind = BitwiseXorExprKind() and
result = TBitwiseXorExprSynth(parent, i)
or
exists(AST::ClassVariable v |
kind = ClassVariableAccessKind(v) and
result = TClassVariableAccessSynth(parent, i, v)
)
or
kind = DivExprKind() and
result = TDivExprSynth(parent, i)
or
kind = ExponentExprKind() and
result = TExponentExprSynth(parent, i)
or
exists(AST::GlobalVariable v |
kind = GlobalVariableAccessKind(v) and
result = TGlobalVariableAccessSynth(parent, i, v)
)
or
exists(AST::InstanceVariable v |
kind = InstanceVariableAccessKind(v) and
result = TInstanceVariableAccessSynth(parent, i, v)
)
or
kind = LShiftExprKind() and
result = TLShiftExprSynth(parent, i)
or
exists(AST::LocalVariable v | result = TLocalVariableAccessSynth(parent, i, v) |
kind = LocalVariableAccessRealKind(v)
or
kind = LocalVariableAccessSynthKind(v)
)
or
kind = LogicalAndExprKind() and
result = TLogicalAndExprSynth(parent, i)
or
kind = LogicalOrExprKind() and
result = TLogicalOrExprSynth(parent, i)
or
kind = ModuloExprKind() and
result = TModuloExprSynth(parent, i)
or
kind = MulExprKind() and
result = TMulExprSynth(parent, i)
or
kind = RShiftExprKind() and
result = TRShiftExprSynth(parent, i)
or
kind = SelfKind() and
result = TSelfSynth(parent, i)
or
kind = StmtSequenceKind() and
result = TStmtSequenceSynth(parent, i)
or
kind = SubExprKind() and
result = TSubExprSynth(parent, i)
)
}
/**
* Holds if the `i`th child of `parent` is `child`. Either `parent` or
* `child` (or both) is a synthesized node.
*/
cached
predicate synthChild(AST::AstNode parent, int i, AST::AstNode child) {
child = getSynthChild(parent, i)
or
any(Synthesis s).child(parent, i, RealChild(child))
}
/**
* Like `toGenerated`, but also returns generated nodes for synthesized AST
* nodes.
*/
cached
Generated::AstNode toGeneratedInclSynth(AST::AstNode n) {
result = toGenerated(n) or
n = TImplicitSelf(result)
result = toGenerated(n)
or
not exists(toGenerated(n)) and
exists(AST::AstNode parent |
synthChild(parent, _, n) and
result = toGeneratedInclSynth(parent)
)
}
}
@@ -421,7 +548,7 @@ class TConditionalLoop = TWhileExpr or TUntilExpr or TWhileModifierExpr or TUnti
class TLoop = TConditionalLoop or TForExpr;
class TSelf = TExplicitSelf or TImplicitSelf;
class TSelf = TSelfReal or TSelfSynth;
class TExpr =
TSelf or TArgumentList or TRescueClause or TRescueModifierExpr or TPair or TStringConcatenation or
@@ -431,7 +558,7 @@ class TExpr =
class TStmtSequence =
TBeginBlock or TEndBlock or TThen or TElse or TDo or TEnsure or TStringInterpolationComponent or
TBlock or TBodyStmt or TParenthesizedExpr;
TBlock or TBodyStmt or TParenthesizedExpr or TStmtSequenceSynth;
class TBodyStmt = TBeginExpr or TModuleBase or TMethod or TLambda or TDoBlock or TSingletonMethod;
@@ -485,17 +612,45 @@ class TBinaryOperation =
class TBinaryArithmeticOperation =
TAddExpr or TSubExpr or TMulExpr or TDivExpr or TModuloExpr or TExponentExpr;
class TAddExpr = TAddExprReal or TAddExprSynth;
class TSubExpr = TSubExprReal or TSubExprSynth;
class TMulExpr = TMulExprReal or TMulExprSynth;
class TDivExpr = TDivExprReal or TDivExprSynth;
class TModuloExpr = TModuloExprReal or TModuloExprSynth;
class TExponentExpr = TExponentExprReal or TExponentExprSynth;
class TBinaryLogicalOperation = TLogicalAndExpr or TLogicalOrExpr;
class TLogicalAndExpr = TLogicalAndExprReal or TLogicalAndExprSynth;
class TLogicalOrExpr = TLogicalOrExprReal or TLogicalOrExprSynth;
class TBinaryBitwiseOperation =
TLShiftExpr or TRShiftExpr or TBitwiseAndExpr or TBitwiseOrExpr or TBitwiseXorExpr;
class TLShiftExpr = TLShiftExprReal or TLShiftExprSynth;
class TRShiftExpr = TRShiftExprReal or TRShiftExprSynth;
class TBitwiseAndExpr = TBitwiseAndExprReal or TBitwiseAndExprSynth;
class TBitwiseOrExpr = TBitwiseOrExprReal or TBitwiseOrExprSynth;
class TBitwiseXorExpr = TBitwiseXorExprReal or TBitwiseXorExprSynth;
class TComparisonOperation = TEqualityOperation or TRelationalOperation;
class TEqualityOperation = TEqExpr or TNEExpr or TCaseEqExpr;
class TRelationalOperation = TGTExpr or TGEExpr or TLTExpr or TLEExpr;
class TAssignExpr = TAssignExprReal or TAssignExprSynth;
class TAssignment = TAssignExpr or TAssignOperation;
class TAssignOperation =
@@ -531,3 +686,11 @@ class TTuplePattern = TTuplePatternParameter or TDestructuredLeftAssignment or T
class TVariableAccess =
TLocalVariableAccess or TGlobalVariableAccess or TInstanceVariableAccess or TClassVariableAccess;
class TLocalVariableAccess = TLocalVariableAccessReal or TLocalVariableAccessSynth;
class TGlobalVariableAccess = TGlobalVariableAccessReal or TGlobalVariableAccessSynth;
class TInstanceVariableAccess = TInstanceVariableAccessReal or TInstanceVariableAccessSynth;
class TClassVariableAccess = TClassVariableAccessReal or TClassVariableAccessSynth;

View File

@@ -67,7 +67,7 @@ private module Cached {
m = resolveScopeExpr(c.getReceiver())
or
m = enclosingModule(c).getModule() and
c.receiverIsSelf()
c.getReceiver() instanceof Self
) and
result = resolveScopeExpr(c.getAnArgument())
)
@@ -81,7 +81,7 @@ private module Cached {
m = resolveScopeExpr(c.getReceiver())
or
m = enclosingModule(c).getModule() and
c.receiverIsSelf()
c.getReceiver() instanceof Self
) and
result = resolveScopeExpr(c.getAnArgument())
)

View File

@@ -0,0 +1,173 @@
/** Provides predicates for synthesizing AST nodes. */
private import AST
private import TreeSitter
private import codeql_ruby.ast.internal.Parameter
private import codeql_ruby.ast.internal.Variable
private import codeql_ruby.AST
/** A synthesized AST node kind. */
newtype SynthKind =
AddExprKind() or
AssignExprKind() or
BitwiseAndExprKind() or
BitwiseOrExprKind() or
BitwiseXorExprKind() or
ClassVariableAccessKind(ClassVariable v) or
DivExprKind() or
ExponentExprKind() or
GlobalVariableAccessKind(GlobalVariable v) or
InstanceVariableAccessKind(InstanceVariable v) or
LShiftExprKind() or
LocalVariableAccessRealKind(LocalVariableReal v) or
LocalVariableAccessSynthKind(TLocalVariableSynth v) or
LogicalAndExprKind() or
LogicalOrExprKind() or
ModuloExprKind() or
MulExprKind() or
StmtSequenceKind() or
RShiftExprKind() or
SelfKind() or
SubExprKind()
/**
* An AST child.
*
* Either a new synthesized node or a reference to an existing node.
*/
newtype Child =
SynthChild(SynthKind k) or
RealChild(AstNode n)
private newtype TSynthesis = MkSynthesis()
/** A class used for synthesizing AST nodes. */
class Synthesis extends TSynthesis {
/**
* Holds if a node should be synthesized as the `i`th child of `parent`, or if
* a non-synthesized node should be the `i`th child of synthesized node `parent`.
*
* `i = -1` is used to represent that the synthesized node is a desugared version
* of its parent.
*/
predicate child(AstNode parent, int i, Child child) { none() }
/**
* Holds if a local variable, identified by `i`, should be synthesized for AST
* node `n`.
*/
predicate localVariable(AstNode n, int i) { none() }
/**
* Holds if `n` should be excluded from `ControlFlowTree` in the CFG construction.
*/
predicate excludeFromControlFlowTree(AstNode n) { none() }
final string toString() { none() }
}
private module ImplicitSelfSynthesis {
private class IdentifierMethodCallSelfSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
child = SynthChild(SelfKind()) and
parent = TIdentifierMethodCall(_) and
i = 0
}
}
private class RegularMethodCallSelfSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
child = SynthChild(SelfKind()) and
i = 0 and
exists(Generated::AstNode g |
parent = TRegularMethodCall(g) and
// If there's no explicit receiver (or scope resolution that acts like a
// receiver), then the receiver is implicitly `self`. N.B. `::Foo()` is
// not valid Ruby.
not exists(g.(Generated::Call).getReceiver()) and
not exists(g.(Generated::Call).getMethod().(Generated::ScopeResolution).getScope())
)
}
}
}
private module AssignOperationDesugar {
/**
* Gets the operator kind to synthesize for operator assignment `ao`.
*/
private SynthKind getKind(AssignOperation ao) {
ao instanceof AssignAddExpr and result = AddExprKind()
or
ao instanceof AssignSubExpr and result = SubExprKind()
or
ao instanceof AssignMulExpr and result = MulExprKind()
or
ao instanceof AssignDivExpr and result = DivExprKind()
or
ao instanceof AssignModuloExpr and result = ModuloExprKind()
or
ao instanceof AssignExponentExpr and result = ExponentExprKind()
or
ao instanceof AssignLogicalAndExpr and result = LogicalAndExprKind()
or
ao instanceof AssignLogicalOrExpr and result = LogicalOrExprKind()
or
ao instanceof AssignLShiftExpr and result = LShiftExprKind()
or
ao instanceof AssignRShiftExpr and result = RShiftExprKind()
or
ao instanceof AssignBitwiseAndExpr and result = BitwiseAndExprKind()
or
ao instanceof AssignBitwiseOrExpr and result = BitwiseOrExprKind()
or
ao instanceof AssignBitwiseXorExpr and result = BitwiseXorExprKind()
}
/**
* ```rb
* x += y
* ```
*
* desguars to
*
* ```rb
* x = x + y
* ```
*
* when `x` is a variable.
*/
private class VariableAssignOperationSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
exists(AssignOperation ao, VariableReal v |
v = ao.getLeftOperand().(VariableAccessReal).getVariableReal()
|
parent = ao and
i = -1 and
child = SynthChild(AssignExprKind())
or
exists(AstNode assign | assign = getSynthChild(ao, -1) |
parent = assign and
i = 0 and
child = RealChild(ao.getLeftOperand())
or
parent = assign and
i = 1 and
child = SynthChild(getKind(ao))
or
parent = getSynthChild(assign, 1) and
(
i = 0 and
child =
SynthChild([
LocalVariableAccessRealKind(v).(SynthKind), InstanceVariableAccessKind(v),
ClassVariableAccessKind(v), GlobalVariableAccessKind(v)
])
or
i = 1 and
child = RealChild(ao.getRightOperand())
)
)
)
}
}
}

View File

@@ -4,6 +4,7 @@ private import codeql_ruby.AST
private import codeql_ruby.ast.internal.AST
private import codeql_ruby.ast.internal.Parameter
private import codeql_ruby.ast.internal.Scope
private import codeql_ruby.ast.internal.Synthesis
/**
* Holds if `n` is in the left-hand-side of an explicit assignment `assignment`.
@@ -128,7 +129,7 @@ private module Cached {
other order by other.getLocation().getStartLine(), other.getLocation().getStartColumn()
)
} or
TLocalVariable(Scope::Range scope, string name, Generated::Identifier i) {
TLocalVariableReal(Scope::Range scope, string name, Generated::Identifier i) {
scopeDefinesParameterVariable(scope, name, i)
or
i =
@@ -139,7 +140,8 @@ private module Cached {
) and
not scopeDefinesParameterVariable(scope, name, _) and
not inherits(scope, name, _)
}
} or
TLocalVariableSynth(AstNode n, int i) { any(Synthesis s).localVariable(n, i) }
// Db types that can be vcalls
private class VcallToken =
@@ -288,7 +290,7 @@ private module Cached {
}
cached
predicate access(Generated::Identifier access, Variable::Range variable) {
predicate access(Generated::Identifier access, VariableReal::Range variable) {
exists(string name |
variable.getName() = name and
name = access.getValue()
@@ -372,8 +374,10 @@ private predicate inherits(Scope::Range scope, string name, Scope::Range outer)
)
}
module Variable {
class Range extends TVariable {
class TVariableReal = TGlobalVariable or TClassVariable or TInstanceVariable or TLocalVariableReal;
module VariableReal {
class Range extends TVariableReal {
abstract string getName();
string toString() { result = this.getName() }
@@ -384,13 +388,15 @@ module Variable {
}
}
class TLocalVariable = TLocalVariableReal or TLocalVariableSynth;
module LocalVariable {
class Range extends Variable::Range, TLocalVariable {
class Range extends VariableReal::Range, TLocalVariableReal {
private Scope::Range scope;
private string name;
private Generated::Identifier i;
Range() { this = TLocalVariable(scope, name, i) }
Range() { this = TLocalVariableReal(scope, name, i) }
final override string getName() { result = name }
@@ -402,8 +408,41 @@ module LocalVariable {
}
}
class VariableReal extends Variable, TVariableReal {
VariableReal::Range range;
VariableReal() { range = this }
final override string getName() { result = range.getName() }
final override Location getLocation() { result = range.getLocation() }
final override Scope getDeclaringScope() { toGenerated(result) = range.getDeclaringScope() }
}
class LocalVariableReal extends VariableReal, LocalVariable, TLocalVariableReal {
override LocalVariable::Range range;
final override LocalVariableAccessReal getAnAccess() { result.getVariable() = this }
final override VariableAccess getDefiningAccess() { result = range.getDefiningAccess() }
}
class LocalVariableSynth extends LocalVariable, TLocalVariableSynth {
private AstNode n;
private int i;
LocalVariableSynth() { this = TLocalVariableSynth(n, i) }
final override string getName() { result = "__synth__" + i }
final override Location getLocation() { result = n.getLocation() }
final override Scope getDeclaringScope() { none() } // not relevant for synthesized variables
}
module GlobalVariable {
class Range extends Variable::Range, TGlobalVariable {
class Range extends VariableReal::Range, TGlobalVariable {
private string name;
Range() { this = TGlobalVariable(name) }
@@ -417,7 +456,7 @@ module GlobalVariable {
}
module InstanceVariable {
class Range extends Variable::Range, TInstanceVariable {
class Range extends VariableReal::Range, TInstanceVariable {
private ModuleBase::Range scope;
private boolean instance;
private string name;
@@ -436,7 +475,7 @@ module InstanceVariable {
}
module ClassVariable {
class Range extends Variable::Range, TClassVariable {
class Range extends VariableReal::Range, TClassVariable {
private ModuleBase::Range scope;
private string name;
private Generated::AstNode decl;
@@ -464,16 +503,126 @@ module LocalVariableAccess {
}
}
class TVariableAccessReal =
TLocalVariableAccessReal or TGlobalVariableAccess or TInstanceVariableAccess or
TClassVariableAccess;
abstract class VariableAccessReal extends VariableAccess, TVariableAccessReal {
/**
* Same as `getVariable()`, but restricted to non-synthesized variable accesses.
*
* The sole purpose of this predicate is to make AST synthesis monotonic.
*/
abstract VariableReal getVariableReal();
}
private class LocalVariableAccessReal extends VariableAccessReal, LocalVariableAccess,
TLocalVariableAccessReal {
private Generated::Identifier g;
private LocalVariable v;
LocalVariableAccessReal() { this = TLocalVariableAccessReal(g, v) }
final override LocalVariable getVariable() { result = v }
final override LocalVariableReal getVariableReal() { result = v }
final override string toString() { result = g.getValue() }
}
private class LocalVariableAccessSynth extends LocalVariableAccess, TLocalVariableAccessSynth {
private LocalVariable v;
LocalVariableAccessSynth() { this = TLocalVariableAccessSynth(_, _, v) }
final override LocalVariable getVariable() { result = v }
final override string toString() { result = v.getName() }
}
module GlobalVariableAccess {
predicate range(Generated::GlobalVariable n, GlobalVariable v) { n.getValue() = v.getName() }
}
private class GlobalVariableAccessReal extends VariableAccessReal, GlobalVariableAccess,
TGlobalVariableAccessReal {
private Generated::GlobalVariable g;
private GlobalVariable v;
GlobalVariableAccessReal() { this = TGlobalVariableAccessReal(g, v) }
final override GlobalVariable getVariable() { result = v }
final override GlobalVariable getVariableReal() { result = v }
final override string toString() { result = g.getValue() }
}
private class GlobalVariableAccessSynth extends GlobalVariableAccess, TGlobalVariableAccessSynth {
private GlobalVariable v;
GlobalVariableAccessSynth() { this = TGlobalVariableAccessSynth(_, _, v) }
final override GlobalVariable getVariable() { result = v }
final override string toString() { result = v.getName() }
}
module InstanceVariableAccess {
predicate range(Generated::InstanceVariable n, InstanceVariable v) {
instanceVariableAccess(n, v)
}
}
private class InstanceVariableAccessReal extends VariableAccessReal, InstanceVariableAccess,
TInstanceVariableAccessReal {
private Generated::InstanceVariable g;
private InstanceVariable v;
InstanceVariableAccessReal() { this = TInstanceVariableAccessReal(g, v) }
final override InstanceVariable getVariable() { result = v }
final override InstanceVariable getVariableReal() { result = v }
final override string toString() { result = g.getValue() }
}
private class InstanceVariableAccessSynth extends InstanceVariableAccess,
TInstanceVariableAccessSynth {
private InstanceVariable v;
InstanceVariableAccessSynth() { this = TInstanceVariableAccessSynth(_, _, v) }
final override InstanceVariable getVariable() { result = v }
final override string toString() { result = v.getName() }
}
module ClassVariableAccess {
predicate range(Generated::ClassVariable n, ClassVariable v) { classVariableAccess(n, v) }
}
private class ClassVariableAccessReal extends VariableAccessReal, ClassVariableAccess,
TClassVariableAccessReal {
private Generated::ClassVariable g;
private ClassVariable v;
ClassVariableAccessReal() { this = TClassVariableAccessReal(g, v) }
final override ClassVariable getVariable() { result = v }
final override ClassVariable getVariableReal() { result = v }
final override string toString() { result = g.getValue() }
}
private class ClassVariableAccessSynth extends ClassVariableAccess, TClassVariableAccessSynth {
private ClassVariable v;
ClassVariableAccessSynth() { this = TClassVariableAccessSynth(_, _, v) }
final override ClassVariable getVariable() { result = v }
final override string toString() { result = v.getName() }
}

View File

@@ -159,6 +159,13 @@ abstract private class ExprChildMapping extends Expr {
)
}
private Expr desugar(Expr n) {
result = n.getDesugared()
or
not exists(n.getDesugared()) and
result = n
}
/**
* Holds if there is a control-flow path from `cfn` to `cfnChild`, where `cfn`
* is a control-flow node for this expression, and `cfnChild` is a control-flow
@@ -171,13 +178,13 @@ abstract private class ExprChildMapping extends Expr {
exists(BasicBlock bb |
this.reachesBasicBlockBase(child, cfn, bb) and
cfnChild = bb.getANode() and
cfnChild = child.getAControlFlowNode()
cfnChild = desugar(child).getAControlFlowNode()
)
or
exists(BasicBlock bb |
this.reachesBasicBlockRec(child, cfn, bb) and
cfnChild = bb.getANode() and
cfnChild = child.getAControlFlowNode()
cfnChild = desugar(child).getAControlFlowNode()
)
}
}

View File

@@ -1,28 +0,0 @@
/**
* @kind graph
* @id rb/test/cfg
*/
import codeql_ruby.CFG
query predicate nodes(CfgNode n, string attr, string val) {
attr = "semmle.order" and
val =
any(int i |
n =
rank[i](CfgNode p |
|
p
order by
p.getLocation().getFile().getBaseName(), p.getLocation().getFile().getAbsolutePath(),
p.getLocation().getStartLine(), p.getLocation().getStartColumn()
)
).toString()
}
query predicate edges(CfgNode pred, CfgNode succ, string attr, string val) {
exists(SuccessorType t | succ = pred.getASuccessor(t) |
attr = "semmle.label" and
if t instanceof SuccessorTypes::NormalSuccessor then val = "" else val = t.toString()
)
}

View File

@@ -0,0 +1,32 @@
/**
* Import this module into a `.ql` file of `@kind graph` to render a CFG. The
* graph is restricted to nodes from `RelevantCfgNode`.
*/
private import codeql.Locations
import codeql_ruby.CFG
abstract class RelevantCfgNode extends CfgNode { }
query predicate nodes(RelevantCfgNode n, string attr, string val) {
attr = "semmle.order" and
val =
any(int i |
n =
rank[i](RelevantCfgNode p, Location l |
l = p.getLocation()
|
p
order by
l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(),
l.getStartColumn()
)
).toString()
}
query predicate edges(RelevantCfgNode pred, RelevantCfgNode succ, string attr, string val) {
exists(SuccessorType t | succ = pred.getASuccessor(t) |
attr = "semmle.label" and
if t instanceof SuccessorTypes::NormalSuccessor then val = "" else val = t.toString()
)
}

View File

@@ -35,6 +35,7 @@ private import codeql_ruby.AST
private import codeql_ruby.ast.internal.AST as ASTInternal
private import codeql_ruby.ast.internal.Scope
private import codeql_ruby.ast.Scope
private import codeql_ruby.ast.internal.Synthesis
private import codeql_ruby.ast.internal.TreeSitter
private import codeql_ruby.ast.internal.Variable
private import codeql_ruby.controlflow.ControlFlowGraph
@@ -85,6 +86,8 @@ module CfgScope {
}
abstract private class ControlFlowTree extends AstNode {
ControlFlowTree() { not any(Synthesis s).excludeFromControlFlowTree(this) }
/**
* Holds if `first` is the first element executed within this AST node.
*/
@@ -284,6 +287,8 @@ module Trees {
}
private class AssignOperationTree extends StandardPostOrderTree, AssignOperation {
AssignOperationTree() { not this.getLeftOperand() instanceof VariableAccess }
final override ControlFlowTree getChildNode(int i) {
result = this.getLeftOperand() and i = 0
or
@@ -728,6 +733,22 @@ module Trees {
}
}
private class DesugaredTree extends ControlFlowTree {
ControlFlowTree desugared;
DesugaredTree() { desugared = this.getDesugared() }
final override predicate propagatesAbnormal(AstNode child) {
desugared.propagatesAbnormal(child)
}
final override predicate first(AstNode first) { desugared.first(first) }
final override predicate last(AstNode last, Completion c) { desugared.last(last, c) }
final override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
}
private class DoBlockTree extends BodyStmtPostOrderTree, DoBlock {
/** Gets the `i`th child in the body of this block. */
final override AstNode getBodyChild(int i, boolean rescuable) {

View File

@@ -8,6 +8,13 @@
import AST
/** Holds if `n` appears in the desugaring of some other node. */
predicate isDesugared(AstNode n) {
n = any(AstNode sugar).getDesugared()
or
isDesugared(n.getParent())
}
/**
* The query can extend this class to control which nodes are printed.
*/
@@ -17,7 +24,19 @@ class PrintAstConfiguration extends string {
/**
* Holds if the given node should be printed.
*/
predicate shouldPrintNode(AstNode n) { any() }
predicate shouldPrintNode(AstNode n) {
not isDesugared(n)
or
not n.isSynthesized()
or
n.isSynthesized() and
not n = any(AstNode sugar).getDesugared() and
exists(AstNode parent |
parent = n.getParent() and
not parent.isSynthesized() and
not n = parent.getDesugared()
)
}
}
/**
@@ -32,12 +51,11 @@ class PrintAstNode extends AstNode {
result =
any(int i |
this =
rank[i](AstNode p |
|
p
order by
p.getLocation().getFile().getBaseName(), p.getLocation().getFile().getAbsolutePath(),
p.getLocation().getStartLine(), p.getLocation().getStartColumn()
rank[i](AstNode p, Location l, File f |
l = p.getLocation() and
f = l.getFile()
|
p order by f.getBaseName(), f.getAbsolutePath(), l.getStartLine(), l.getStartColumn()
)
).toString()
}
@@ -75,10 +93,10 @@ query predicate nodes(PrintAstNode node, string key, string value) {
query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) {
source.shouldPrint() and
target.shouldPrint() and
target = source.getAChild() and
target = source.getChild(_) and
(
key = "semmle.label" and
value = concat(string name | source.getChild(name) = target | name, "/")
value = strictconcat(string name | source.getChild(name) = target | name, "/")
or
key = "semmle.order" and
value = target.getProperty("semmle.order")

View File

@@ -567,6 +567,21 @@ calls/calls.rb:
# 319| getReceiver: [Self] self
# 319| getArgument: [IntegerLiteral] 0
# 319| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 320| getStmt: [AssignMulExpr] ... *= ...
# 320| getAnOperand/getLeftOperand: [ElementReference, SetterMethodCall] ...[...]
# 320| getReceiver: [MethodCall] call to bar
# 320| getReceiver: [MethodCall] call to foo
# 320| getReceiver: [Self] self
# 320| getArgument: [IntegerLiteral] 0
# 320| getArgument: [MethodCall] call to baz
# 320| getReceiver: [MethodCall] call to foo
# 320| getReceiver: [Self] self
# 320| getArgument: [AddExpr] ... + ...
# 320| getAnOperand/getLeftOperand: [MethodCall] call to boo
# 320| getReceiver: [MethodCall] call to foo
# 320| getReceiver: [Self] self
# 320| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 320| getAnOperand/getRightOperand: [IntegerLiteral] 2
control/cases.rb:
# 1| [Toplevel] cases.rb
# 2| getStmt: [AssignExpr] ... = ...
@@ -1718,6 +1733,25 @@ operations/operations.rb:
# 84| getStmt: [AssignBitwiseXorExpr] ... ^= ...
# 84| getAnOperand/getLeftOperand: [LocalVariableAccess] baz
# 84| getAnOperand/getRightOperand: [LocalVariableAccess] qux
# 86| getStmt: [ClassDeclaration] X
# 87| getStmt: [AssignExpr] ... = ...
# 87| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 87| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 88| getStmt: [AssignAddExpr] ... += ...
# 88| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 88| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 90| getStmt: [AssignExpr] ... = ...
# 90| getAnOperand/getLeftOperand: [ClassVariableAccess] @@y
# 90| getAnOperand/getRightOperand: [IntegerLiteral] 3
# 91| getStmt: [AssignDivExpr] ... /= ...
# 91| getAnOperand/getLeftOperand: [ClassVariableAccess] @@y
# 91| getAnOperand/getRightOperand: [IntegerLiteral] 4
# 94| getStmt: [AssignExpr] ... = ...
# 94| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 94| getAnOperand/getRightOperand: [IntegerLiteral] 5
# 95| getStmt: [AssignMulExpr] ... *= ...
# 95| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 95| getAnOperand/getRightOperand: [IntegerLiteral] 6
params/params.rb:
# 1| [Toplevel] params.rb
# 4| getStmt: [Method] identifier_method_params

View File

@@ -1,6 +1,5 @@
/**
* @kind graph
* @id rb/test/print-ast
*/
import codeql_ruby.printAst

View File

@@ -0,0 +1,180 @@
calls/calls.rb:
# 66| [AssignExpr] ... = ...
# 66| getAnOperand/getLeftOperand: [LocalVariableAccess] var1
# 66| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 66| getAnOperand/getLeftOperand: [LocalVariableAccess] var1
# 66| getAnOperand/getRightOperand: [MethodCall] call to bar
# 66| getReceiver: [Self] self
# 67| [AssignExpr] ... = ...
# 67| getAnOperand/getLeftOperand: [LocalVariableAccess] var1
# 67| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 67| getAnOperand/getLeftOperand: [LocalVariableAccess] var1
# 67| getAnOperand/getRightOperand: [MethodCall] call to bar
# 67| getReceiver: [ConstantReadAccess] X
control/loops.rb:
# 10| [AssignExpr] ... = ...
# 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 10| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 10| getAnOperand/getRightOperand: [LocalVariableAccess] n
# 17| [AssignExpr] ... = ...
# 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 17| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 17| getAnOperand/getRightOperand: [LocalVariableAccess] n
# 18| [AssignExpr] ... = ...
# 18| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 18| getAnOperand/getRightOperand: [SubExpr] ... - ...
# 18| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 18| getAnOperand/getRightOperand: [LocalVariableAccess] n
# 23| [AssignExpr] ... = ...
# 23| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 23| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 23| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 23| getAnOperand/getRightOperand: [LocalVariableAccess] value
# 24| [AssignExpr] ... = ...
# 24| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 24| getAnOperand/getRightOperand: [MulExpr] ... * ...
# 24| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 24| getAnOperand/getRightOperand: [LocalVariableAccess] value
# 29| [AssignExpr] ... = ...
# 29| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 29| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 29| getAnOperand/getLeftOperand: [LocalVariableAccess] sum
# 29| getAnOperand/getRightOperand: [LocalVariableAccess] value
# 30| [AssignExpr] ... = ...
# 30| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 30| getAnOperand/getRightOperand: [DivExpr] ... / ...
# 30| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 30| getAnOperand/getRightOperand: [LocalVariableAccess] value
# 36| [AssignExpr] ... = ...
# 36| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 36| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 36| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 36| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 37| [AssignExpr] ... = ...
# 37| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 37| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 37| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 37| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 43| [AssignExpr] ... = ...
# 43| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 43| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 43| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 43| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 44| [AssignExpr] ... = ...
# 44| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 44| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 44| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 44| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 48| [AssignExpr] ... = ...
# 48| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 48| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 48| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 48| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 52| [AssignExpr] ... = ...
# 52| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 52| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 52| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 52| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 53| [AssignExpr] ... = ...
# 53| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 53| getAnOperand/getRightOperand: [SubExpr] ... - ...
# 53| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 53| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 58| [AssignExpr] ... = ...
# 58| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 58| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 58| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 58| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 59| [AssignExpr] ... = ...
# 59| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 59| getAnOperand/getRightOperand: [SubExpr] ... - ...
# 59| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 59| getAnOperand/getRightOperand: [IntegerLiteral] 4
# 63| [AssignExpr] ... = ...
# 63| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 63| getAnOperand/getRightOperand: [SubExpr] ... - ...
# 63| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 63| getAnOperand/getRightOperand: [IntegerLiteral] 1
operations/operations.rb:
# 68| [AssignExpr] ... = ...
# 68| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 68| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 68| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 68| getAnOperand/getRightOperand: [IntegerLiteral] 128
# 69| [AssignExpr] ... = ...
# 69| getAnOperand/getLeftOperand: [LocalVariableAccess] y
# 69| getAnOperand/getRightOperand: [SubExpr] ... - ...
# 69| getAnOperand/getLeftOperand: [LocalVariableAccess] y
# 69| getAnOperand/getRightOperand: [IntegerLiteral] 32
# 70| [AssignExpr] ... = ...
# 70| getAnOperand/getLeftOperand: [LocalVariableAccess] a
# 70| getAnOperand/getRightOperand: [MulExpr] ... * ...
# 70| getAnOperand/getLeftOperand: [LocalVariableAccess] a
# 70| getAnOperand/getRightOperand: [IntegerLiteral] 12
# 71| [AssignExpr] ... = ...
# 71| getAnOperand/getLeftOperand: [LocalVariableAccess] b
# 71| getAnOperand/getRightOperand: [DivExpr] ... / ...
# 71| getAnOperand/getLeftOperand: [LocalVariableAccess] b
# 71| getAnOperand/getRightOperand: [IntegerLiteral] 4
# 72| [AssignExpr] ... = ...
# 72| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 72| getAnOperand/getRightOperand: [ModuloExpr] ... % ...
# 72| getAnOperand/getLeftOperand: [LocalVariableAccess] z
# 72| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 73| [AssignExpr] ... = ...
# 73| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 73| getAnOperand/getRightOperand: [ExponentExpr] ... ** ...
# 73| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 73| getAnOperand/getRightOperand: [LocalVariableAccess] bar
# 76| [AssignExpr] ... = ...
# 76| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 76| getAnOperand/getRightOperand: [LogicalAndExpr] ... && ...
# 76| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 76| getAnOperand/getRightOperand: [LocalVariableAccess] y
# 77| [AssignExpr] ... = ...
# 77| getAnOperand/getLeftOperand: [LocalVariableAccess] a
# 77| getAnOperand/getRightOperand: [LogicalOrExpr] ... || ...
# 77| getAnOperand/getLeftOperand: [LocalVariableAccess] a
# 77| getAnOperand/getRightOperand: [LocalVariableAccess] b
# 80| [AssignExpr] ... = ...
# 80| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 80| getAnOperand/getRightOperand: [LShiftExpr] ... << ...
# 80| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 80| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 81| [AssignExpr] ... = ...
# 81| getAnOperand/getLeftOperand: [LocalVariableAccess] y
# 81| getAnOperand/getRightOperand: [RShiftExpr] ... >> ...
# 81| getAnOperand/getLeftOperand: [LocalVariableAccess] y
# 81| getAnOperand/getRightOperand: [IntegerLiteral] 3
# 82| [AssignExpr] ... = ...
# 82| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 82| getAnOperand/getRightOperand: [BitwiseAndExpr] ... & ...
# 82| getAnOperand/getLeftOperand: [LocalVariableAccess] foo
# 82| getAnOperand/getRightOperand: [LocalVariableAccess] mask
# 83| [AssignExpr] ... = ...
# 83| getAnOperand/getLeftOperand: [LocalVariableAccess] bar
# 83| getAnOperand/getRightOperand: [BitwiseOrExpr] ... | ...
# 83| getAnOperand/getLeftOperand: [LocalVariableAccess] bar
# 83| getAnOperand/getRightOperand: [IntegerLiteral] 0x01
# 84| [AssignExpr] ... = ...
# 84| getAnOperand/getLeftOperand: [LocalVariableAccess] baz
# 84| getAnOperand/getRightOperand: [BitwiseXorExpr] ... ^ ...
# 84| getAnOperand/getLeftOperand: [LocalVariableAccess] baz
# 84| getAnOperand/getRightOperand: [LocalVariableAccess] qux
# 88| [AssignExpr] ... = ...
# 88| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 88| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 88| getAnOperand/getLeftOperand: [InstanceVariableAccess] @x
# 88| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 91| [AssignExpr] ... = ...
# 91| getAnOperand/getLeftOperand: [ClassVariableAccess] @@y
# 91| getAnOperand/getRightOperand: [DivExpr] ... / ...
# 91| getAnOperand/getLeftOperand: [ClassVariableAccess] @@y
# 91| getAnOperand/getRightOperand: [IntegerLiteral] 4
# 95| [AssignExpr] ... = ...
# 95| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 95| getAnOperand/getRightOperand: [MulExpr] ... * ...
# 95| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 95| getAnOperand/getRightOperand: [IntegerLiteral] 6

View File

@@ -0,0 +1,9 @@
/**
* @kind graph
*/
import codeql_ruby.printAst
class DesugarPrintAstConfiguration extends PrintAstConfiguration {
override predicate shouldPrintNode(AstNode n) { isDesugared(n) }
}

View File

@@ -36,6 +36,12 @@ callsWithArguments
| calls.rb:317:5:317:10 | ...[...] | []= | 0 | calls.rb:317:9:317:9 | 5 |
| calls.rb:319:1:319:6 | ...[...] | [] | 0 | calls.rb:319:5:319:5 | 0 |
| calls.rb:319:1:319:6 | ...[...] | []= | 0 | calls.rb:319:5:319:5 | 0 |
| calls.rb:320:1:320:32 | ...[...] | [] | 0 | calls.rb:320:9:320:9 | 0 |
| calls.rb:320:1:320:32 | ...[...] | [] | 1 | calls.rb:320:12:320:18 | call to baz |
| calls.rb:320:1:320:32 | ...[...] | [] | 2 | calls.rb:320:21:320:31 | ... + ... |
| calls.rb:320:1:320:32 | ...[...] | []= | 0 | calls.rb:320:9:320:9 | 0 |
| calls.rb:320:1:320:32 | ...[...] | []= | 1 | calls.rb:320:12:320:18 | call to baz |
| calls.rb:320:1:320:32 | ...[...] | []= | 2 | calls.rb:320:21:320:31 | ... + ... |
callsWithReceiver
| calls.rb:2:1:2:5 | call to foo | calls.rb:2:1:2:5 | self |
| calls.rb:5:1:5:10 | call to bar | calls.rb:5:1:5:3 | Foo |
@@ -216,6 +222,13 @@ callsWithReceiver
| calls.rb:318:1:318:10 | call to count/count= | calls.rb:318:1:318:4 | self |
| calls.rb:319:1:319:3 | call to foo | calls.rb:319:1:319:3 | self |
| calls.rb:319:1:319:6 | ...[...] | calls.rb:319:1:319:3 | call to foo |
| calls.rb:320:1:320:3 | call to foo | calls.rb:320:1:320:3 | self |
| calls.rb:320:1:320:7 | call to bar | calls.rb:320:1:320:3 | call to foo |
| calls.rb:320:1:320:32 | ...[...] | calls.rb:320:1:320:7 | call to bar |
| calls.rb:320:12:320:14 | call to foo | calls.rb:320:12:320:14 | self |
| calls.rb:320:12:320:18 | call to baz | calls.rb:320:12:320:14 | call to foo |
| calls.rb:320:21:320:23 | call to foo | calls.rb:320:21:320:23 | self |
| calls.rb:320:21:320:27 | call to boo | calls.rb:320:21:320:23 | call to foo |
callsWithBlock
| calls.rb:17:1:17:17 | call to foo | calls.rb:17:5:17:17 | { ... } |
| calls.rb:20:1:22:3 | call to foo | calls.rb:20:5:22:3 | do ... end |
@@ -262,3 +275,4 @@ setterCalls
| calls.rb:317:5:317:10 | ...[...] |
| calls.rb:318:1:318:10 | call to count/count= |
| calls.rb:319:1:319:6 | ...[...] |
| calls.rb:320:1:320:32 | ...[...] |

View File

@@ -317,3 +317,4 @@ self.foo, *self.bar, foo[4] = [1, 2, 3, 4]
a, *foo[5] = [1, 2, 3]
self.count += 1
foo[0] += 1
foo.bar[0, foo.baz, foo.boo + 1] *= 2

View File

@@ -18,18 +18,40 @@ assignments
| operations.rb:19:1:19:5 | ... = ... | = | operations.rb:19:1:19:1 | y | operations.rb:19:5:19:5 | 0 | AssignExpr |
| operations.rb:20:1:20:5 | ... = ... | = | operations.rb:20:1:20:1 | z | operations.rb:20:5:20:5 | 0 | AssignExpr |
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:1:68:1 | x | operations.rb:68:6:68:8 | 128 | AssignAddExpr |
| operations.rb:68:1:68:8 | ... = ... | = | operations.rb:68:1:68:1 | x | operations.rb:68:1:68:8 | ... + ... | AssignExpr |
| operations.rb:69:1:69:7 | ... -= ... | -= | operations.rb:69:1:69:1 | y | operations.rb:69:6:69:7 | 32 | AssignSubExpr |
| operations.rb:69:1:69:7 | ... = ... | = | operations.rb:69:1:69:1 | y | operations.rb:69:1:69:7 | ... - ... | AssignExpr |
| operations.rb:70:1:70:7 | ... *= ... | *= | operations.rb:70:1:70:1 | a | operations.rb:70:6:70:7 | 12 | AssignMulExpr |
| operations.rb:70:1:70:7 | ... = ... | = | operations.rb:70:1:70:1 | a | operations.rb:70:1:70:7 | ... * ... | AssignExpr |
| operations.rb:71:1:71:6 | ... /= ... | /= | operations.rb:71:1:71:1 | b | operations.rb:71:6:71:6 | 4 | AssignDivExpr |
| operations.rb:71:1:71:6 | ... = ... | = | operations.rb:71:1:71:1 | b | operations.rb:71:1:71:6 | ... / ... | AssignExpr |
| operations.rb:72:1:72:6 | ... %= ... | %= | operations.rb:72:1:72:1 | z | operations.rb:72:6:72:6 | 2 | AssignModuloExpr |
| operations.rb:72:1:72:6 | ... = ... | = | operations.rb:72:1:72:1 | z | operations.rb:72:1:72:6 | ... % ... | AssignExpr |
| operations.rb:73:1:73:11 | ... **= ... | **= | operations.rb:73:1:73:3 | foo | operations.rb:73:9:73:11 | bar | AssignExponentExpr |
| operations.rb:73:1:73:11 | ... = ... | = | operations.rb:73:1:73:3 | foo | operations.rb:73:1:73:11 | ... ** ... | AssignExpr |
| operations.rb:76:2:76:8 | ... &&= ... | &&= | operations.rb:76:2:76:2 | x | operations.rb:76:8:76:8 | y | AssignLogicalAndExpr |
| operations.rb:76:2:76:8 | ... = ... | = | operations.rb:76:2:76:2 | x | operations.rb:76:2:76:8 | ... && ... | AssignExpr |
| operations.rb:77:2:77:8 | ... = ... | = | operations.rb:77:2:77:2 | a | operations.rb:77:2:77:8 | ... \|\| ... | AssignExpr |
| operations.rb:77:2:77:8 | ... \|\|= ... | \|\|= | operations.rb:77:2:77:2 | a | operations.rb:77:8:77:8 | b | AssignLogicalOrExpr |
| operations.rb:80:2:80:8 | ... <<= ... | <<= | operations.rb:80:2:80:2 | x | operations.rb:80:8:80:8 | 2 | AssignLShiftExpr |
| operations.rb:80:2:80:8 | ... = ... | = | operations.rb:80:2:80:2 | x | operations.rb:80:2:80:8 | ... << ... | AssignExpr |
| operations.rb:81:2:81:8 | ... = ... | = | operations.rb:81:2:81:2 | y | operations.rb:81:2:81:8 | ... >> ... | AssignExpr |
| operations.rb:81:2:81:8 | ... >>= ... | >>= | operations.rb:81:2:81:2 | y | operations.rb:81:8:81:8 | 3 | AssignRShiftExpr |
| operations.rb:82:2:82:12 | ... &= ... | &= | operations.rb:82:2:82:4 | foo | operations.rb:82:9:82:12 | mask | AssignBitwiseAndExpr |
| operations.rb:82:2:82:12 | ... = ... | = | operations.rb:82:2:82:4 | foo | operations.rb:82:2:82:12 | ... & ... | AssignExpr |
| operations.rb:83:2:83:12 | ... = ... | = | operations.rb:83:2:83:4 | bar | operations.rb:83:2:83:12 | ... \| ... | AssignExpr |
| operations.rb:83:2:83:12 | ... \|= ... | \|= | operations.rb:83:2:83:4 | bar | operations.rb:83:9:83:12 | 0x01 | AssignBitwiseOrExpr |
| operations.rb:84:2:84:11 | ... = ... | = | operations.rb:84:2:84:4 | baz | operations.rb:84:2:84:11 | ... ^ ... | AssignExpr |
| operations.rb:84:2:84:11 | ... ^= ... | ^= | operations.rb:84:2:84:4 | baz | operations.rb:84:9:84:11 | qux | AssignBitwiseXorExpr |
| operations.rb:87:3:87:8 | ... = ... | = | operations.rb:87:3:87:4 | @x | operations.rb:87:8:87:8 | 1 | AssignExpr |
| operations.rb:88:3:88:9 | ... += ... | += | operations.rb:88:3:88:4 | @x | operations.rb:88:9:88:9 | 2 | AssignAddExpr |
| operations.rb:88:3:88:9 | ... = ... | = | operations.rb:88:3:88:4 | @x | operations.rb:88:3:88:9 | ... + ... | AssignExpr |
| operations.rb:90:3:90:9 | ... = ... | = | operations.rb:90:3:90:5 | @@y | operations.rb:90:9:90:9 | 3 | AssignExpr |
| operations.rb:91:3:91:10 | ... /= ... | /= | operations.rb:91:3:91:5 | @@y | operations.rb:91:10:91:10 | 4 | AssignDivExpr |
| operations.rb:91:3:91:10 | ... = ... | = | operations.rb:91:3:91:5 | @@y | operations.rb:91:3:91:10 | ... / ... | AssignExpr |
| operations.rb:94:1:94:15 | ... = ... | = | operations.rb:94:1:94:11 | $global_var | operations.rb:94:15:94:15 | 5 | AssignExpr |
| operations.rb:95:1:95:16 | ... *= ... | *= | operations.rb:95:1:95:11 | $global_var | operations.rb:95:16:95:16 | 6 | AssignMulExpr |
| operations.rb:95:1:95:16 | ... = ... | = | operations.rb:95:1:95:11 | $global_var | operations.rb:95:1:95:16 | ... * ... | AssignExpr |
assignOperations
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:1:68:1 | x | operations.rb:68:6:68:8 | 128 | AssignAddExpr |
| operations.rb:69:1:69:7 | ... -= ... | -= | operations.rb:69:1:69:1 | y | operations.rb:69:6:69:7 | 32 | AssignSubExpr |
@@ -44,6 +66,9 @@ assignOperations
| operations.rb:82:2:82:12 | ... &= ... | &= | operations.rb:82:2:82:4 | foo | operations.rb:82:9:82:12 | mask | AssignBitwiseAndExpr |
| operations.rb:83:2:83:12 | ... \|= ... | \|= | operations.rb:83:2:83:4 | bar | operations.rb:83:9:83:12 | 0x01 | AssignBitwiseOrExpr |
| operations.rb:84:2:84:11 | ... ^= ... | ^= | operations.rb:84:2:84:4 | baz | operations.rb:84:9:84:11 | qux | AssignBitwiseXorExpr |
| operations.rb:88:3:88:9 | ... += ... | += | operations.rb:88:3:88:4 | @x | operations.rb:88:9:88:9 | 2 | AssignAddExpr |
| operations.rb:91:3:91:10 | ... /= ... | /= | operations.rb:91:3:91:5 | @@y | operations.rb:91:10:91:10 | 4 | AssignDivExpr |
| operations.rb:95:1:95:16 | ... *= ... | *= | operations.rb:95:1:95:11 | $global_var | operations.rb:95:16:95:16 | 6 | AssignMulExpr |
assignArithmeticOperations
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:1:68:1 | x | operations.rb:68:6:68:8 | 128 | AssignAddExpr |
| operations.rb:69:1:69:7 | ... -= ... | -= | operations.rb:69:1:69:1 | y | operations.rb:69:6:69:7 | 32 | AssignSubExpr |
@@ -51,6 +76,9 @@ assignArithmeticOperations
| operations.rb:71:1:71:6 | ... /= ... | /= | operations.rb:71:1:71:1 | b | operations.rb:71:6:71:6 | 4 | AssignDivExpr |
| operations.rb:72:1:72:6 | ... %= ... | %= | operations.rb:72:1:72:1 | z | operations.rb:72:6:72:6 | 2 | AssignModuloExpr |
| operations.rb:73:1:73:11 | ... **= ... | **= | operations.rb:73:1:73:3 | foo | operations.rb:73:9:73:11 | bar | AssignExponentExpr |
| operations.rb:88:3:88:9 | ... += ... | += | operations.rb:88:3:88:4 | @x | operations.rb:88:9:88:9 | 2 | AssignAddExpr |
| operations.rb:91:3:91:10 | ... /= ... | /= | operations.rb:91:3:91:5 | @@y | operations.rb:91:10:91:10 | 4 | AssignDivExpr |
| operations.rb:95:1:95:16 | ... *= ... | *= | operations.rb:95:1:95:11 | $global_var | operations.rb:95:16:95:16 | 6 | AssignMulExpr |
assignLogicalOperations
| operations.rb:76:2:76:8 | ... &&= ... | &&= | operations.rb:76:2:76:2 | x | operations.rb:76:8:76:8 | y | AssignLogicalAndExpr |
| operations.rb:77:2:77:8 | ... \|\|= ... | \|\|= | operations.rb:77:2:77:2 | a | operations.rb:77:8:77:8 | b | AssignLogicalOrExpr |

View File

@@ -24,6 +24,22 @@ binaryOperations
| operations.rb:63:1:63:7 | ... <=> ... | <=> | operations.rb:63:1:63:1 | a | operations.rb:63:7:63:7 | b | SpaceshipExpr |
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:1:64:4 | name | operations.rb:64:9:64:15 | /foo.*/ | RegexMatchExpr |
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | operations.rb:65:11:65:17 | /.*bar/ | NoRegexMatchExpr |
| operations.rb:68:1:68:8 | ... + ... | + | operations.rb:68:1:68:8 | x | operations.rb:68:6:68:8 | 128 | AddExpr |
| operations.rb:69:1:69:7 | ... - ... | - | operations.rb:69:1:69:7 | y | operations.rb:69:6:69:7 | 32 | SubExpr |
| operations.rb:70:1:70:7 | ... * ... | * | operations.rb:70:1:70:7 | a | operations.rb:70:6:70:7 | 12 | MulExpr |
| operations.rb:71:1:71:6 | ... / ... | / | operations.rb:71:1:71:6 | b | operations.rb:71:6:71:6 | 4 | DivExpr |
| operations.rb:72:1:72:6 | ... % ... | % | operations.rb:72:1:72:6 | z | operations.rb:72:6:72:6 | 2 | ModuloExpr |
| operations.rb:73:1:73:11 | ... ** ... | ** | operations.rb:73:1:73:11 | foo | operations.rb:73:9:73:11 | bar | ExponentExpr |
| operations.rb:76:2:76:8 | ... && ... | && | operations.rb:76:2:76:8 | x | operations.rb:76:8:76:8 | y | LogicalAndExpr |
| operations.rb:77:2:77:8 | ... \|\| ... | \|\| | operations.rb:77:2:77:8 | a | operations.rb:77:8:77:8 | b | LogicalOrExpr |
| operations.rb:80:2:80:8 | ... << ... | << | operations.rb:80:2:80:8 | x | operations.rb:80:8:80:8 | 2 | LShiftExpr |
| operations.rb:81:2:81:8 | ... >> ... | >> | operations.rb:81:2:81:8 | y | operations.rb:81:8:81:8 | 3 | RShiftExpr |
| operations.rb:82:2:82:12 | ... & ... | & | operations.rb:82:2:82:12 | foo | operations.rb:82:9:82:12 | mask | BitwiseAndExpr |
| operations.rb:83:2:83:12 | ... \| ... | \| | operations.rb:83:2:83:12 | bar | operations.rb:83:9:83:12 | 0x01 | BitwiseOrExpr |
| operations.rb:84:2:84:11 | ... ^ ... | ^ | operations.rb:84:2:84:11 | baz | operations.rb:84:9:84:11 | qux | BitwiseXorExpr |
| operations.rb:88:3:88:9 | ... + ... | + | operations.rb:88:3:88:9 | @x | operations.rb:88:9:88:9 | 2 | AddExpr |
| operations.rb:91:3:91:10 | ... / ... | / | operations.rb:91:3:91:10 | @@y | operations.rb:91:10:91:10 | 4 | DivExpr |
| operations.rb:95:1:95:16 | ... * ... | * | operations.rb:95:1:95:16 | $global_var | operations.rb:95:16:95:16 | 6 | MulExpr |
binaryArithmeticOperations
| operations.rb:31:1:31:7 | ... + ... | + | operations.rb:31:1:31:1 | w | operations.rb:31:5:31:7 | 234 | AddExpr |
| operations.rb:32:1:32:6 | ... - ... | - | operations.rb:32:1:32:1 | x | operations.rb:32:5:32:6 | 17 | SubExpr |
@@ -31,17 +47,33 @@ binaryArithmeticOperations
| operations.rb:34:1:34:5 | ... / ... | / | operations.rb:34:1:34:1 | z | operations.rb:34:5:34:5 | 2 | DivExpr |
| operations.rb:35:1:35:7 | ... % ... | % | operations.rb:35:1:35:3 | num | operations.rb:35:7:35:7 | 2 | ModuloExpr |
| operations.rb:36:1:36:13 | ... ** ... | ** | operations.rb:36:1:36:4 | base | operations.rb:36:9:36:13 | power | ExponentExpr |
| operations.rb:68:1:68:8 | ... + ... | + | operations.rb:68:1:68:8 | x | operations.rb:68:6:68:8 | 128 | AddExpr |
| operations.rb:69:1:69:7 | ... - ... | - | operations.rb:69:1:69:7 | y | operations.rb:69:6:69:7 | 32 | SubExpr |
| operations.rb:70:1:70:7 | ... * ... | * | operations.rb:70:1:70:7 | a | operations.rb:70:6:70:7 | 12 | MulExpr |
| operations.rb:71:1:71:6 | ... / ... | / | operations.rb:71:1:71:6 | b | operations.rb:71:6:71:6 | 4 | DivExpr |
| operations.rb:72:1:72:6 | ... % ... | % | operations.rb:72:1:72:6 | z | operations.rb:72:6:72:6 | 2 | ModuloExpr |
| operations.rb:73:1:73:11 | ... ** ... | ** | operations.rb:73:1:73:11 | foo | operations.rb:73:9:73:11 | bar | ExponentExpr |
| operations.rb:88:3:88:9 | ... + ... | + | operations.rb:88:3:88:9 | @x | operations.rb:88:9:88:9 | 2 | AddExpr |
| operations.rb:91:3:91:10 | ... / ... | / | operations.rb:91:3:91:10 | @@y | operations.rb:91:10:91:10 | 4 | DivExpr |
| operations.rb:95:1:95:16 | ... * ... | * | operations.rb:95:1:95:16 | $global_var | operations.rb:95:16:95:16 | 6 | MulExpr |
binaryLogicalOperations
| operations.rb:39:1:39:10 | ... && ... | && | operations.rb:39:1:39:3 | foo | operations.rb:39:8:39:10 | bar | LogicalAndExpr |
| operations.rb:40:1:40:11 | ... and ... | and | operations.rb:40:1:40:3 | baz | operations.rb:40:9:40:11 | qux | LogicalAndExpr |
| operations.rb:41:1:41:6 | ... or ... | or | operations.rb:41:1:41:1 | a | operations.rb:41:6:41:6 | b | LogicalOrExpr |
| operations.rb:42:1:42:6 | ... \|\| ... | \|\| | operations.rb:42:1:42:1 | x | operations.rb:42:6:42:6 | y | LogicalOrExpr |
| operations.rb:76:2:76:8 | ... && ... | && | operations.rb:76:2:76:8 | x | operations.rb:76:8:76:8 | y | LogicalAndExpr |
| operations.rb:77:2:77:8 | ... \|\| ... | \|\| | operations.rb:77:2:77:8 | a | operations.rb:77:8:77:8 | b | LogicalOrExpr |
binaryBitwiseOperations
| operations.rb:45:1:45:6 | ... << ... | << | operations.rb:45:1:45:1 | x | operations.rb:45:6:45:6 | 3 | LShiftExpr |
| operations.rb:46:1:46:7 | ... >> ... | >> | operations.rb:46:1:46:1 | y | operations.rb:46:6:46:7 | 16 | RShiftExpr |
| operations.rb:47:1:47:10 | ... & ... | & | operations.rb:47:1:47:3 | foo | operations.rb:47:7:47:10 | 0xff | BitwiseAndExpr |
| operations.rb:48:1:48:10 | ... \| ... | \| | operations.rb:48:1:48:3 | bar | operations.rb:48:7:48:10 | 0x02 | BitwiseOrExpr |
| operations.rb:49:1:49:9 | ... ^ ... | ^ | operations.rb:49:1:49:3 | baz | operations.rb:49:7:49:9 | qux | BitwiseXorExpr |
| operations.rb:80:2:80:8 | ... << ... | << | operations.rb:80:2:80:8 | x | operations.rb:80:8:80:8 | 2 | LShiftExpr |
| operations.rb:81:2:81:8 | ... >> ... | >> | operations.rb:81:2:81:8 | y | operations.rb:81:8:81:8 | 3 | RShiftExpr |
| operations.rb:82:2:82:12 | ... & ... | & | operations.rb:82:2:82:12 | foo | operations.rb:82:9:82:12 | mask | BitwiseAndExpr |
| operations.rb:83:2:83:12 | ... \| ... | \| | operations.rb:83:2:83:12 | bar | operations.rb:83:9:83:12 | 0x01 | BitwiseOrExpr |
| operations.rb:84:2:84:11 | ... ^ ... | ^ | operations.rb:84:2:84:11 | baz | operations.rb:84:9:84:11 | qux | BitwiseXorExpr |
comparisonOperations
| operations.rb:52:1:52:6 | ... == ... | == | operations.rb:52:1:52:1 | x | operations.rb:52:6:52:6 | y | EqExpr |
| operations.rb:53:1:53:8 | ... != ... | != | operations.rb:53:1:53:1 | a | operations.rb:53:6:53:8 | 123 | NEExpr |

View File

@@ -90,29 +90,105 @@
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:9:64:15 | /foo.*/ | RegexMatchExpr |
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | NoRegexMatchExpr |
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:11:65:17 | /.*bar/ | NoRegexMatchExpr |
| operations.rb:68:1:68:8 | ... + ... | + | operations.rb:68:1:68:8 | x | AddExpr |
| operations.rb:68:1:68:8 | ... + ... | + | operations.rb:68:6:68:8 | 128 | AddExpr |
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:1:68:1 | x | AssignAddExpr |
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:6:68:8 | 128 | AssignAddExpr |
| operations.rb:68:1:68:8 | ... = ... | = | operations.rb:68:1:68:1 | x | AssignExpr |
| operations.rb:68:1:68:8 | ... = ... | = | operations.rb:68:1:68:8 | ... + ... | AssignExpr |
| operations.rb:69:1:69:7 | ... - ... | - | operations.rb:69:1:69:7 | y | SubExpr |
| operations.rb:69:1:69:7 | ... - ... | - | operations.rb:69:6:69:7 | 32 | SubExpr |
| operations.rb:69:1:69:7 | ... -= ... | -= | operations.rb:69:1:69:1 | y | AssignSubExpr |
| operations.rb:69:1:69:7 | ... -= ... | -= | operations.rb:69:6:69:7 | 32 | AssignSubExpr |
| operations.rb:69:1:69:7 | ... = ... | = | operations.rb:69:1:69:1 | y | AssignExpr |
| operations.rb:69:1:69:7 | ... = ... | = | operations.rb:69:1:69:7 | ... - ... | AssignExpr |
| operations.rb:70:1:70:7 | ... * ... | * | operations.rb:70:1:70:7 | a | MulExpr |
| operations.rb:70:1:70:7 | ... * ... | * | operations.rb:70:6:70:7 | 12 | MulExpr |
| operations.rb:70:1:70:7 | ... *= ... | *= | operations.rb:70:1:70:1 | a | AssignMulExpr |
| operations.rb:70:1:70:7 | ... *= ... | *= | operations.rb:70:6:70:7 | 12 | AssignMulExpr |
| operations.rb:70:1:70:7 | ... = ... | = | operations.rb:70:1:70:1 | a | AssignExpr |
| operations.rb:70:1:70:7 | ... = ... | = | operations.rb:70:1:70:7 | ... * ... | AssignExpr |
| operations.rb:71:1:71:6 | ... / ... | / | operations.rb:71:1:71:6 | b | DivExpr |
| operations.rb:71:1:71:6 | ... / ... | / | operations.rb:71:6:71:6 | 4 | DivExpr |
| operations.rb:71:1:71:6 | ... /= ... | /= | operations.rb:71:1:71:1 | b | AssignDivExpr |
| operations.rb:71:1:71:6 | ... /= ... | /= | operations.rb:71:6:71:6 | 4 | AssignDivExpr |
| operations.rb:71:1:71:6 | ... = ... | = | operations.rb:71:1:71:1 | b | AssignExpr |
| operations.rb:71:1:71:6 | ... = ... | = | operations.rb:71:1:71:6 | ... / ... | AssignExpr |
| operations.rb:72:1:72:6 | ... % ... | % | operations.rb:72:1:72:6 | z | ModuloExpr |
| operations.rb:72:1:72:6 | ... % ... | % | operations.rb:72:6:72:6 | 2 | ModuloExpr |
| operations.rb:72:1:72:6 | ... %= ... | %= | operations.rb:72:1:72:1 | z | AssignModuloExpr |
| operations.rb:72:1:72:6 | ... %= ... | %= | operations.rb:72:6:72:6 | 2 | AssignModuloExpr |
| operations.rb:72:1:72:6 | ... = ... | = | operations.rb:72:1:72:1 | z | AssignExpr |
| operations.rb:72:1:72:6 | ... = ... | = | operations.rb:72:1:72:6 | ... % ... | AssignExpr |
| operations.rb:73:1:73:11 | ... ** ... | ** | operations.rb:73:1:73:11 | foo | ExponentExpr |
| operations.rb:73:1:73:11 | ... ** ... | ** | operations.rb:73:9:73:11 | bar | ExponentExpr |
| operations.rb:73:1:73:11 | ... **= ... | **= | operations.rb:73:1:73:3 | foo | AssignExponentExpr |
| operations.rb:73:1:73:11 | ... **= ... | **= | operations.rb:73:9:73:11 | bar | AssignExponentExpr |
| operations.rb:73:1:73:11 | ... = ... | = | operations.rb:73:1:73:3 | foo | AssignExpr |
| operations.rb:73:1:73:11 | ... = ... | = | operations.rb:73:1:73:11 | ... ** ... | AssignExpr |
| operations.rb:76:2:76:8 | ... && ... | && | operations.rb:76:2:76:8 | x | LogicalAndExpr |
| operations.rb:76:2:76:8 | ... && ... | && | operations.rb:76:8:76:8 | y | LogicalAndExpr |
| operations.rb:76:2:76:8 | ... &&= ... | &&= | operations.rb:76:2:76:2 | x | AssignLogicalAndExpr |
| operations.rb:76:2:76:8 | ... &&= ... | &&= | operations.rb:76:8:76:8 | y | AssignLogicalAndExpr |
| operations.rb:76:2:76:8 | ... = ... | = | operations.rb:76:2:76:2 | x | AssignExpr |
| operations.rb:76:2:76:8 | ... = ... | = | operations.rb:76:2:76:8 | ... && ... | AssignExpr |
| operations.rb:77:2:77:8 | ... = ... | = | operations.rb:77:2:77:2 | a | AssignExpr |
| operations.rb:77:2:77:8 | ... = ... | = | operations.rb:77:2:77:8 | ... \|\| ... | AssignExpr |
| operations.rb:77:2:77:8 | ... \|\| ... | \|\| | operations.rb:77:2:77:8 | a | LogicalOrExpr |
| operations.rb:77:2:77:8 | ... \|\| ... | \|\| | operations.rb:77:8:77:8 | b | LogicalOrExpr |
| operations.rb:77:2:77:8 | ... \|\|= ... | \|\|= | operations.rb:77:2:77:2 | a | AssignLogicalOrExpr |
| operations.rb:77:2:77:8 | ... \|\|= ... | \|\|= | operations.rb:77:8:77:8 | b | AssignLogicalOrExpr |
| operations.rb:80:2:80:8 | ... << ... | << | operations.rb:80:2:80:8 | x | LShiftExpr |
| operations.rb:80:2:80:8 | ... << ... | << | operations.rb:80:8:80:8 | 2 | LShiftExpr |
| operations.rb:80:2:80:8 | ... <<= ... | <<= | operations.rb:80:2:80:2 | x | AssignLShiftExpr |
| operations.rb:80:2:80:8 | ... <<= ... | <<= | operations.rb:80:8:80:8 | 2 | AssignLShiftExpr |
| operations.rb:80:2:80:8 | ... = ... | = | operations.rb:80:2:80:2 | x | AssignExpr |
| operations.rb:80:2:80:8 | ... = ... | = | operations.rb:80:2:80:8 | ... << ... | AssignExpr |
| operations.rb:81:2:81:8 | ... = ... | = | operations.rb:81:2:81:2 | y | AssignExpr |
| operations.rb:81:2:81:8 | ... = ... | = | operations.rb:81:2:81:8 | ... >> ... | AssignExpr |
| operations.rb:81:2:81:8 | ... >> ... | >> | operations.rb:81:2:81:8 | y | RShiftExpr |
| operations.rb:81:2:81:8 | ... >> ... | >> | operations.rb:81:8:81:8 | 3 | RShiftExpr |
| operations.rb:81:2:81:8 | ... >>= ... | >>= | operations.rb:81:2:81:2 | y | AssignRShiftExpr |
| operations.rb:81:2:81:8 | ... >>= ... | >>= | operations.rb:81:8:81:8 | 3 | AssignRShiftExpr |
| operations.rb:82:2:82:12 | ... & ... | & | operations.rb:82:2:82:12 | foo | BitwiseAndExpr |
| operations.rb:82:2:82:12 | ... & ... | & | operations.rb:82:9:82:12 | mask | BitwiseAndExpr |
| operations.rb:82:2:82:12 | ... &= ... | &= | operations.rb:82:2:82:4 | foo | AssignBitwiseAndExpr |
| operations.rb:82:2:82:12 | ... &= ... | &= | operations.rb:82:9:82:12 | mask | AssignBitwiseAndExpr |
| operations.rb:82:2:82:12 | ... = ... | = | operations.rb:82:2:82:4 | foo | AssignExpr |
| operations.rb:82:2:82:12 | ... = ... | = | operations.rb:82:2:82:12 | ... & ... | AssignExpr |
| operations.rb:83:2:83:12 | ... = ... | = | operations.rb:83:2:83:4 | bar | AssignExpr |
| operations.rb:83:2:83:12 | ... = ... | = | operations.rb:83:2:83:12 | ... \| ... | AssignExpr |
| operations.rb:83:2:83:12 | ... \| ... | \| | operations.rb:83:2:83:12 | bar | BitwiseOrExpr |
| operations.rb:83:2:83:12 | ... \| ... | \| | operations.rb:83:9:83:12 | 0x01 | BitwiseOrExpr |
| operations.rb:83:2:83:12 | ... \|= ... | \|= | operations.rb:83:2:83:4 | bar | AssignBitwiseOrExpr |
| operations.rb:83:2:83:12 | ... \|= ... | \|= | operations.rb:83:9:83:12 | 0x01 | AssignBitwiseOrExpr |
| operations.rb:84:2:84:11 | ... = ... | = | operations.rb:84:2:84:4 | baz | AssignExpr |
| operations.rb:84:2:84:11 | ... = ... | = | operations.rb:84:2:84:11 | ... ^ ... | AssignExpr |
| operations.rb:84:2:84:11 | ... ^ ... | ^ | operations.rb:84:2:84:11 | baz | BitwiseXorExpr |
| operations.rb:84:2:84:11 | ... ^ ... | ^ | operations.rb:84:9:84:11 | qux | BitwiseXorExpr |
| operations.rb:84:2:84:11 | ... ^= ... | ^= | operations.rb:84:2:84:4 | baz | AssignBitwiseXorExpr |
| operations.rb:84:2:84:11 | ... ^= ... | ^= | operations.rb:84:9:84:11 | qux | AssignBitwiseXorExpr |
| operations.rb:87:3:87:8 | ... = ... | = | operations.rb:87:3:87:4 | @x | AssignExpr |
| operations.rb:87:3:87:8 | ... = ... | = | operations.rb:87:8:87:8 | 1 | AssignExpr |
| operations.rb:88:3:88:9 | ... + ... | + | operations.rb:88:3:88:9 | @x | AddExpr |
| operations.rb:88:3:88:9 | ... + ... | + | operations.rb:88:9:88:9 | 2 | AddExpr |
| operations.rb:88:3:88:9 | ... += ... | += | operations.rb:88:3:88:4 | @x | AssignAddExpr |
| operations.rb:88:3:88:9 | ... += ... | += | operations.rb:88:9:88:9 | 2 | AssignAddExpr |
| operations.rb:88:3:88:9 | ... = ... | = | operations.rb:88:3:88:4 | @x | AssignExpr |
| operations.rb:88:3:88:9 | ... = ... | = | operations.rb:88:3:88:9 | ... + ... | AssignExpr |
| operations.rb:90:3:90:9 | ... = ... | = | operations.rb:90:3:90:5 | @@y | AssignExpr |
| operations.rb:90:3:90:9 | ... = ... | = | operations.rb:90:9:90:9 | 3 | AssignExpr |
| operations.rb:91:3:91:10 | ... / ... | / | operations.rb:91:3:91:10 | @@y | DivExpr |
| operations.rb:91:3:91:10 | ... / ... | / | operations.rb:91:10:91:10 | 4 | DivExpr |
| operations.rb:91:3:91:10 | ... /= ... | /= | operations.rb:91:3:91:5 | @@y | AssignDivExpr |
| operations.rb:91:3:91:10 | ... /= ... | /= | operations.rb:91:10:91:10 | 4 | AssignDivExpr |
| operations.rb:91:3:91:10 | ... = ... | = | operations.rb:91:3:91:5 | @@y | AssignExpr |
| operations.rb:91:3:91:10 | ... = ... | = | operations.rb:91:3:91:10 | ... / ... | AssignExpr |
| operations.rb:94:1:94:15 | ... = ... | = | operations.rb:94:1:94:11 | $global_var | AssignExpr |
| operations.rb:94:1:94:15 | ... = ... | = | operations.rb:94:15:94:15 | 5 | AssignExpr |
| operations.rb:95:1:95:16 | ... * ... | * | operations.rb:95:1:95:16 | $global_var | MulExpr |
| operations.rb:95:1:95:16 | ... * ... | * | operations.rb:95:16:95:16 | 6 | MulExpr |
| operations.rb:95:1:95:16 | ... *= ... | *= | operations.rb:95:1:95:11 | $global_var | AssignMulExpr |
| operations.rb:95:1:95:16 | ... *= ... | *= | operations.rb:95:16:95:16 | 6 | AssignMulExpr |
| operations.rb:95:1:95:16 | ... = ... | = | operations.rb:95:1:95:11 | $global_var | AssignExpr |
| operations.rb:95:1:95:16 | ... = ... | = | operations.rb:95:1:95:16 | ... * ... | AssignExpr |

View File

@@ -81,4 +81,15 @@ foo **= bar
y >>= 3
foo &= mask
bar |= 0x01
baz ^= qux
baz ^= qux
class X
@x = 1
@x += 2
@@y = 3
@@y /= 4
end
$global_var = 5
$global_var *= 6

View File

@@ -687,12 +687,12 @@ cfg.rb:
# 35| false
#-----| false -> if ...
# 39| self
#-----| -> 42
# 39| call to puts
#-----| -> case ...
# 39| self
#-----| -> 42
# 39| 42
#-----| -> call to puts
@@ -1444,14 +1444,20 @@ cfg.rb:
# 124| 2
#-----| -> ... = ...
# 125| ... += ...
# 125| some
#-----| -> some
# 125| ... = ...
#-----| -> last
# 125| ... + ...
#-----| -> ... = ...
# 125| some
#-----| -> 10
# 125| 10
#-----| -> ... += ...
#-----| -> ... + ...
# 126| ... = ...
#-----| -> range
@@ -1544,8 +1550,8 @@ cfg.rb:
#-----| -> ... rescue ...
# 136| ... / ...
#-----| raise -> self
#-----| -> init
#-----| raise -> self
# 136| 1
#-----| -> 0
@@ -1880,14 +1886,20 @@ cfg.rb:
# 176| do ...
#-----| -> x
# 176| ... += ...
# 176| x
#-----| -> x
# 176| ... = ...
#-----| -> self
# 176| ... + ...
#-----| -> ... = ...
# 176| x
#-----| -> 10
# 176| 10
#-----| -> ... += ...
#-----| -> ... + ...
# 176| call to puts
#-----| -> x
@@ -1922,14 +1934,20 @@ cfg.rb:
# 179| "hello"
#-----| -> call to puts
# 179| ... += ...
# 179| i
#-----| -> i
# 179| ... = ...
#-----| -> ( ... )
# 179| ... + ...
#-----| -> ... = ...
# 179| i
#-----| -> 1
# 179| 1
#-----| -> ... += ...
#-----| -> ... + ...
# 179| ... == ...
#-----| true -> ... until ...
@@ -1966,14 +1984,20 @@ cfg.rb:
# 182| do ...
#-----| -> x
# 183| ... += ...
# 183| x
#-----| -> x
# 183| ... = ...
#-----| -> x
# 183| ... + ...
#-----| -> ... = ...
# 183| x
#-----| -> 1
# 183| 1
#-----| -> ... += ...
#-----| -> ... + ...
# 184| if ...
#-----| -> self
@@ -2018,14 +2042,20 @@ cfg.rb:
# 188| "hello"
#-----| -> call to puts
# 188| ... -= ...
# 188| i
#-----| -> i
# 188| ... = ...
#-----| -> ( ... )
# 188| ... - ...
#-----| -> ... = ...
# 188| i
#-----| -> 1
# 188| 1
#-----| -> ... -= ...
#-----| -> ... - ...
# 188| ... != ...
#-----| false -> ... while ...
@@ -2083,6 +2113,201 @@ cfg.rb:
# 194| x
#-----| -> call to puts
desugar.rb:
# 1| enter m1
#-----| -> x
# 1| enter desugar.rb
#-----| -> m1
# 1| m1
#-----| -> m2
# 1| exit m1
# 1| exit desugar.rb
# 1| exit m1 (normal)
#-----| -> exit m1
# 1| exit desugar.rb (normal)
#-----| -> exit desugar.rb
# 1| x
#-----| -> x
# 2| x
#-----| -> x
# 2| ... = ...
#-----| -> exit m1 (normal)
# 2| ... + ...
#-----| -> ... = ...
# 2| x
#-----| -> 1
# 2| 1
#-----| -> ... + ...
# 5| enter m2
#-----| -> x
# 5| m2
#-----| -> m3
# 5| exit m2
# 5| exit m2 (normal)
#-----| -> exit m2
# 5| x
#-----| -> x
# 6| ... += ...
#-----| -> exit m2 (normal)
# 6| call to count/count=
#-----| -> 1
# 6| call to foo
#-----| -> call to count/count=
# 6| x
#-----| -> call to foo
# 6| 1
#-----| -> ... += ...
# 9| enter m3
#-----| -> x
# 9| m3
#-----| -> X
# 9| exit m3
# 9| exit m3 (normal)
#-----| -> exit m3
# 9| x
#-----| -> y
# 9| y
#-----| -> x
# 10| ... += ...
#-----| -> exit m3 (normal)
# 10| ...[...]
#-----| -> 1
# 10| call to foo
#-----| -> 0
# 10| x
#-----| -> call to foo
# 10| 0
#-----| -> y
# 10| call to bar
#-----| -> x
# 10| y
#-----| -> call to bar
# 10| ... + ...
#-----| -> ...[...]
# 10| call to baz
#-----| -> 3
# 10| x
#-----| -> call to baz
# 10| 3
#-----| -> ... + ...
# 10| 1
#-----| -> ... += ...
# 13| X
#-----| -> @x
# 14| ... = ...
#-----| -> @x
# 14| @x
#-----| -> 1
# 14| 1
#-----| -> ... = ...
# 15| @x
#-----| -> @x
# 15| ... = ...
#-----| -> @@y
# 15| ... + ...
#-----| -> ... = ...
# 15| @x
#-----| -> 2
# 15| 2
#-----| -> ... + ...
# 17| ... = ...
#-----| -> @@y
# 17| @@y
#-----| -> 3
# 17| 3
#-----| -> ... = ...
# 18| @@y
#-----| -> @@y
# 18| ... = ...
#-----| -> $global_var
# 18| ... / ...
#-----| -> ... = ...
# 18| @@y
#-----| -> 4
# 18| 4
#-----| -> ... / ...
# 21| ... = ...
#-----| -> $global_var
# 21| $global_var
#-----| -> 5
# 21| 5
#-----| -> ... = ...
# 22| $global_var
#-----| -> $global_var
# 22| ... = ...
#-----| -> exit desugar.rb (normal)
# 22| ... * ...
#-----| -> ... = ...
# 22| $global_var
#-----| -> 6
# 22| 6
#-----| -> ... * ...
exit.rb:
# 1| enter m1
#-----| -> x
@@ -2763,14 +2988,20 @@ loops.rb:
# 3| x
#-----| -> call to puts
# 4| ... -= ...
# 4| x
#-----| -> x
# 4| ... = ...
#-----| -> x
# 4| ... - ...
#-----| -> ... = ...
# 4| x
#-----| -> 1
# 4| 1
#-----| -> ... -= ...
#-----| -> ... - ...
# 8| enter m2
#-----| -> x
@@ -2811,14 +3042,20 @@ loops.rb:
# 10| x
#-----| -> call to puts
# 11| ... -= ...
# 11| x
#-----| -> x
# 11| ... = ...
#-----| -> x
# 11| ... - ...
#-----| -> ... = ...
# 11| x
#-----| -> 1
# 11| 1
#-----| -> ... -= ...
#-----| -> ... - ...
# 12| if ...
#-----| -> self

View File

@@ -0,0 +1,9 @@
/**
* @kind graph
*/
import codeql_ruby.controlflow.internal.Cfg
class MyRelevantCfgNode extends RelevantCfgNode {
MyRelevantCfgNode() { exists(this) }
}

View File

@@ -1 +0,0 @@
codeql_ruby/controlflow/internal/Cfg.ql

View File

@@ -0,0 +1,22 @@
def m1 x
x += 1
end
def m2 x
x.foo.count += 1
end
def m3 x, y
x.foo[0, y.bar, x.baz + 3] += 1
end
class X
@x = 1
@x += 2
@@y = 3
@@y /= 4
end
$global_var = 5
$global_var *= 6

View File

@@ -14,9 +14,10 @@
| local_dataflow.rb:5:7:5:13 | ( ... ) | local_dataflow.rb:5:3:5:13 | ... = ... |
| local_dataflow.rb:5:8:5:12 | ... = ... | local_dataflow.rb:5:7:5:13 | ( ... ) |
| local_dataflow.rb:5:12:5:12 | a | local_dataflow.rb:5:8:5:12 | ... = ... |
| local_dataflow.rb:5:12:5:12 | a | local_dataflow.rb:6:8:6:8 | a |
| local_dataflow.rb:5:12:5:12 | a | local_dataflow.rb:6:8:6:13 | a |
| local_dataflow.rb:6:7:6:14 | ( ... ) | local_dataflow.rb:6:3:6:14 | ... = ... |
| local_dataflow.rb:6:8:6:13 | ... += ... | local_dataflow.rb:6:7:6:14 | ( ... ) |
| local_dataflow.rb:6:8:6:13 | ... + ... | local_dataflow.rb:6:8:6:13 | ... = ... |
| local_dataflow.rb:6:8:6:13 | ... = ... | local_dataflow.rb:6:7:6:14 | ( ... ) |
| local_dataflow.rb:9:1:9:15 | ... = ... | local_dataflow.rb:10:14:10:18 | array |
| local_dataflow.rb:9:9:9:15 | [...] | local_dataflow.rb:9:1:9:15 | ... = ... |
| local_dataflow.rb:9:9:9:15 | [...] | local_dataflow.rb:9:1:9:15 | ... = ... |

View File

@@ -42,7 +42,7 @@ definition
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a |
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a |
| scopes.rb:11:4:11:9 | ... += ... | scopes.rb:7:1:7:1 | a |
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:7:1:7:1 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:7:13:7 | b |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:11:13:11 | c |
@@ -55,7 +55,7 @@ definition
| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i |
| ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x |
| ssa.rb:21:5:21:10 | ... -= ... | ssa.rb:18:8:18:8 | x |
| ssa.rb:21:5:21:10 | ... = ... | ssa.rb:18:8:18:8 | x |
| ssa.rb:25:1:30:3 | <uninitialized> | ssa.rb:26:7:26:10 | elem |
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements |
| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem |
@@ -72,13 +72,13 @@ definition
| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo |
| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x |
| ssa.rb:60:3:60:9 | ... += ... | ssa.rb:59:3:59:3 | x |
| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x |
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a |
| ssa.rb:65:3:65:15 | ... = ... | ssa.rb:65:3:65:10 | captured |
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured |
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a |
| ssa.rb:69:5:69:17 | ... += ... | ssa.rb:65:3:65:10 | captured |
| ssa.rb:69:5:69:17 | ... = ... | ssa.rb:65:3:65:10 | captured |
| ssa.rb:75:3:75:14 | ... = ... | ssa.rb:75:3:75:10 | captured |
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured |
| ssa.rb:82:3:82:14 | ... = ... | ssa.rb:82:3:82:10 | captured |
@@ -124,8 +124,8 @@ read
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a |
| scopes.rb:11:4:11:9 | ... += ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:9 | a |
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c |
@@ -145,7 +145,7 @@ read
| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:12:10:12:10 | i |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:10 | x |
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
| ssa.rb:26:12:26:22 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
@@ -156,12 +156,12 @@ read
| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:50:8:50:8 | y |
| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:54:7:54:9 | foo |
| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x |
| ssa.rb:60:3:60:9 | ... += ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:9 | x |
| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x |
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:12 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:17 | captured |
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
@@ -204,7 +204,7 @@ firstRead
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a |
| scopes.rb:11:4:11:9 | ... += ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c |
@@ -226,8 +226,8 @@ firstRead
| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:50:8:50:8 | y |
| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:54:7:54:9 | foo |
| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x |
| ssa.rb:60:3:60:9 | ... += ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:9 | x |
| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x |
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured |
@@ -272,8 +272,8 @@ lastRead
| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:55:9:55:9 | x |
| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a |
| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a |
| scopes.rb:11:4:11:9 | ... += ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:9 | a |
| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b |
| scopes.rb:13:4:13:32 | ... = ... | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c |
@@ -285,7 +285,7 @@ lastRead
| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:8:10:8:10 | i |
| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:12:10:12:10 | i |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:10 | x |
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements |
| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem |
| ssa.rb:26:12:26:22 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem |
@@ -296,11 +296,11 @@ lastRead
| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:50:8:50:8 | y |
| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:54:7:54:9 | foo |
| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x |
| ssa.rb:60:3:60:9 | ... += ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x |
| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:9 | x |
| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x |
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a |
| ssa.rb:66:3:70:5 | call to times | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:12 | captured |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:69:5:69:17 | captured |
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | ssa.rb:67:10:67:10 | a |
| ssa.rb:76:7:78:5 | <captured> | ssa.rb:75:3:75:10 | captured | ssa.rb:77:15:77:22 | captured |
| ssa.rb:84:10:86:8 | <captured> | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
@@ -308,7 +308,7 @@ adjacentReads
| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:15:11:15:11 | a |
| parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | parameters.rb:8:6:8:11 | pizzas | parameters.rb:11:14:11:19 | pizzas |
| parameters.rb:25:15:25:18 | name | parameters.rb:25:15:25:18 | name | parameters.rb:25:40:25:43 | name | parameters.rb:26:8:26:11 | name |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | scopes.rb:11:4:11:4 | a |
| scopes.rb:9:9:18:3 | <captured> | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | scopes.rb:11:4:11:9 | a |
| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | scopes.rb:31:10:31:10 | x |
| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | scopes.rb:34:7:34:7 | x |
| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | scopes.rb:34:14:34:14 | x |
@@ -317,8 +317,8 @@ adjacentReads
| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | ssa.rb:8:10:8:10 | i |
| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | ssa.rb:12:10:12:10 | i |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | ssa.rb:20:10:20:10 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | ssa.rb:21:5:21:5 | x |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured | ssa.rb:69:5:69:12 | captured |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | ssa.rb:21:5:21:10 | x |
| ssa.rb:66:11:70:5 | <captured> | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured | ssa.rb:69:5:69:17 | captured |
phi
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | <uninitialized> |
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:20 | ... = ... |
@@ -329,7 +329,7 @@ phi
| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:6:5:6:9 | ... = ... |
| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:9 | ... = ... |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:10 | ... -= ... |
| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:10 | ... = ... |
| ssa.rb:26:12:26:22 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | <uninitialized> |
| ssa.rb:26:12:26:22 | phi | ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem |
| ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | <uninitialized> |

View File

@@ -103,6 +103,7 @@ variableAccess
| scopes.rb:9:14:9:14 | x | scopes.rb:9:14:9:14 | x | scopes.rb:9:9:18:3 | do ... end |
| scopes.rb:10:9:10:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb |
| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb |
| scopes.rb:11:4:11:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb |
| scopes.rb:12:9:12:9 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb |
| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:1:1:40:1 | scopes.rb |
| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:9:9:18:3 | do ... end |
@@ -139,6 +140,7 @@ variableAccess
| ssa.rb:19:9:19:9 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 |
| ssa.rb:20:10:20:10 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 |
| ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 |
| ssa.rb:21:5:21:10 | x | ssa.rb:18:8:18:8 | x | ssa.rb:18:1:23:3 | m1 |
| ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 |
| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:25:1:30:3 | m2 |
| ssa.rb:26:15:26:22 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:25:1:30:3 | m2 |
@@ -161,6 +163,7 @@ variableAccess
| ssa.rb:55:8:55:8 | x | ssa.rb:54:3:54:3 | x | ssa.rb:53:1:56:3 | m7 |
| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 |
| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 |
| ssa.rb:60:3:60:9 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 |
| ssa.rb:61:8:61:8 | x | ssa.rb:59:3:59:3 | x | ssa.rb:58:1:62:3 | m8 |
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:64:1:72:3 | m9 |
| ssa.rb:65:3:65:10 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 |
@@ -169,6 +172,7 @@ variableAccess
| ssa.rb:67:10:67:10 | a | ssa.rb:66:15:66:15 | a | ssa.rb:66:11:70:5 | do ... end |
| ssa.rb:68:10:68:17 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 |
| ssa.rb:69:5:69:12 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 |
| ssa.rb:69:5:69:17 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 |
| ssa.rb:71:8:71:15 | captured | ssa.rb:65:3:65:10 | captured | ssa.rb:64:1:72:3 | m9 |
| ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:10 | captured | ssa.rb:74:1:79:3 | m10 |
| ssa.rb:77:15:77:22 | captured | ssa.rb:75:3:75:10 | captured | ssa.rb:74:1:79:3 | m10 |
@@ -205,6 +209,7 @@ explicitWrite
| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:8 | ... = ... |
| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:5 | ... = ... |
| scopes.rb:11:4:11:4 | a | scopes.rb:11:4:11:9 | ... += ... |
| scopes.rb:11:4:11:4 | a | scopes.rb:11:4:11:9 | ... = ... |
| scopes.rb:13:4:13:4 | a | scopes.rb:13:4:13:32 | ... = ... |
| scopes.rb:13:7:13:7 | b | scopes.rb:13:4:13:32 | ... = ... |
| scopes.rb:13:11:13:11 | c | scopes.rb:13:4:13:32 | ... = ... |
@@ -220,14 +225,17 @@ explicitWrite
| ssa.rb:6:5:6:5 | i | ssa.rb:6:5:6:9 | ... = ... |
| ssa.rb:10:5:10:5 | i | ssa.rb:10:5:10:9 | ... = ... |
| ssa.rb:21:5:21:5 | x | ssa.rb:21:5:21:10 | ... -= ... |
| ssa.rb:21:5:21:5 | x | ssa.rb:21:5:21:10 | ... = ... |
| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:9 | ... = ... |
| ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:7 | ... = ... |
| ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:19 | ... = ... |
| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:11 | ... = ... |
| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:8 | ... = ... |
| ssa.rb:60:3:60:3 | x | ssa.rb:60:3:60:9 | ... += ... |
| ssa.rb:60:3:60:3 | x | ssa.rb:60:3:60:9 | ... = ... |
| ssa.rb:65:3:65:10 | captured | ssa.rb:65:3:65:15 | ... = ... |
| ssa.rb:69:5:69:12 | captured | ssa.rb:69:5:69:17 | ... += ... |
| ssa.rb:69:5:69:12 | captured | ssa.rb:69:5:69:17 | ... = ... |
| ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:14 | ... = ... |
| ssa.rb:82:3:82:10 | captured | ssa.rb:82:3:82:14 | ... = ... |
implicitWrite
@@ -316,7 +324,7 @@ readAccess
| scopes.rb:5:9:5:9 | a |
| scopes.rb:8:6:8:6 | a |
| scopes.rb:10:9:10:9 | a |
| scopes.rb:11:4:11:4 | a |
| scopes.rb:11:4:11:9 | a |
| scopes.rb:12:9:12:9 | a |
| scopes.rb:14:9:14:9 | a |
| scopes.rb:15:9:15:9 | b |
@@ -338,7 +346,7 @@ readAccess
| ssa.rb:15:8:15:8 | i |
| ssa.rb:19:9:19:9 | x |
| ssa.rb:20:10:20:10 | x |
| ssa.rb:21:5:21:5 | x |
| ssa.rb:21:5:21:10 | x |
| ssa.rb:26:15:26:22 | elements |
| ssa.rb:27:10:27:13 | elem |
| ssa.rb:29:8:29:11 | elem |
@@ -349,12 +357,12 @@ readAccess
| ssa.rb:50:8:50:8 | y |
| ssa.rb:54:7:54:9 | foo |
| ssa.rb:55:8:55:8 | x |
| ssa.rb:60:3:60:3 | x |
| ssa.rb:60:3:60:9 | x |
| ssa.rb:61:8:61:8 | x |
| ssa.rb:66:3:66:3 | a |
| ssa.rb:67:10:67:10 | a |
| ssa.rb:68:10:68:17 | captured |
| ssa.rb:69:5:69:12 | captured |
| ssa.rb:69:5:69:17 | captured |
| ssa.rb:71:8:71:15 | captured |
| ssa.rb:77:15:77:22 | captured |
| ssa.rb:85:15:85:22 | captured |