mirror of
https://github.com/github/codeql.git
synced 2026-02-19 08:23:45 +01:00
Merge pull request #179 from github/hvitved/synth-framework-take2
AST synthesis framework (take 2)
This commit is contained in:
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() }
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
)
|
||||
|
||||
173
ql/src/codeql_ruby/ast/internal/Synthesis.qll
Normal file
173
ql/src/codeql_ruby/ast/internal/Synthesis.qll
Normal 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())
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
32
ql/src/codeql_ruby/controlflow/internal/Cfg.qll
Normal file
32
ql/src/codeql_ruby/controlflow/internal/Cfg.qll
Normal 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()
|
||||
)
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/**
|
||||
* @kind graph
|
||||
* @id rb/test/print-ast
|
||||
*/
|
||||
|
||||
import codeql_ruby.printAst
|
||||
|
||||
180
ql/test/library-tests/ast/AstDesugar.expected
Normal file
180
ql/test/library-tests/ast/AstDesugar.expected
Normal 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
|
||||
9
ql/test/library-tests/ast/AstDesugar.ql
Normal file
9
ql/test/library-tests/ast/AstDesugar.ql
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import codeql_ruby.printAst
|
||||
|
||||
class DesugarPrintAstConfiguration extends PrintAstConfiguration {
|
||||
override predicate shouldPrintNode(AstNode n) { isDesugared(n) }
|
||||
}
|
||||
@@ -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 | ...[...] |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
9
ql/test/library-tests/controlflow/graph/Cfg.ql
Normal file
9
ql/test/library-tests/controlflow/graph/Cfg.ql
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import codeql_ruby.controlflow.internal.Cfg
|
||||
|
||||
class MyRelevantCfgNode extends RelevantCfgNode {
|
||||
MyRelevantCfgNode() { exists(this) }
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
codeql_ruby/controlflow/internal/Cfg.ql
|
||||
22
ql/test/library-tests/controlflow/graph/desugar.rb
Normal file
22
ql/test/library-tests/controlflow/graph/desugar.rb
Normal 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
|
||||
@@ -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 | ... = ... |
|
||||
|
||||
@@ -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> |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user