Merge pull request #305 from github/hvitved/desugar/array-literals

Desugar array literals to `::Array.[]`
This commit is contained in:
Tom Hvitved
2021-09-23 17:30:34 +02:00
committed by GitHub
14 changed files with 378 additions and 69 deletions

View File

@@ -70,6 +70,20 @@ private class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolu
final override predicate hasGlobalScope() { not exists(g.getScope()) }
}
private class ConstantReadAccessSynth extends ConstantAccess, TConstantReadAccessSynth {
private string value;
ConstantReadAccessSynth() { this = TConstantReadAccessSynth(_, _, value) }
final override string getName() {
if this.hasGlobalScope() then result = value.suffix(2) else result = value
}
final override Expr getScopeExpr() { synthChild(this, 0, result) }
final override predicate hasGlobalScope() { value.matches("::%") }
}
/**
* A use (read) of a constant.
*
@@ -92,6 +106,8 @@ class ConstantReadAccess extends ConstantAccess {
or
// `X` in `X ||= 10` is considered both a read and a write
this = any(AssignOperation a).getLeftOperand()
or
this instanceof TConstantReadAccessSynth
}
/**

View File

@@ -678,13 +678,13 @@ class ArrayLiteral extends Literal, TArrayLiteral {
final override string getAPrimaryQlClass() { result = "ArrayLiteral" }
/** Gets the `n`th element in this array literal. */
Expr getElement(int n) { none() }
final Expr getElement(int n) { result = this.(ArrayLiteralImpl).getElementImpl(n) }
/** Gets an element in this array literal. */
final Expr getAnElement() { result = this.getElement(_) }
/** Gets the number of elements in this array literal. */
final int getNumberOfElements() { result = count(this.getAnElement()) }
final int getNumberOfElements() { result = this.(ArrayLiteralImpl).getNumberOfElementsImpl() }
final override AstNode getAChild(string pred) {
result = super.getAChild(pred)
@@ -693,32 +693,44 @@ class ArrayLiteral extends Literal, TArrayLiteral {
}
}
private class RegularArrayLiteral extends ArrayLiteral, TRegularArrayLiteral {
abstract private class ArrayLiteralImpl extends ArrayLiteral {
abstract Expr getElementImpl(int n);
abstract int getNumberOfElementsImpl();
}
private class RegularArrayLiteral extends ArrayLiteralImpl, TRegularArrayLiteral {
private Ruby::Array g;
RegularArrayLiteral() { this = TRegularArrayLiteral(g) }
final override Expr getElement(int i) { toGenerated(result) = g.getChild(i) }
final override Expr getElementImpl(int i) { toGenerated(result) = g.getChild(i) }
final override int getNumberOfElementsImpl() { result = count(g.getChild(_)) }
final override string toString() { result = "[...]" }
}
private class StringArrayLiteral extends ArrayLiteral, TStringArrayLiteral {
private class StringArrayLiteral extends ArrayLiteralImpl, TStringArrayLiteral {
private Ruby::StringArray g;
StringArrayLiteral() { this = TStringArrayLiteral(g) }
final override Expr getElement(int i) { toGenerated(result) = g.getChild(i) }
final override Expr getElementImpl(int i) { toGenerated(result) = g.getChild(i) }
final override int getNumberOfElementsImpl() { result = count(g.getChild(_)) }
final override string toString() { result = "%w(...)" }
}
private class SymbolArrayLiteral extends ArrayLiteral, TSymbolArrayLiteral {
private class SymbolArrayLiteral extends ArrayLiteralImpl, TSymbolArrayLiteral {
private Ruby::SymbolArray g;
SymbolArrayLiteral() { this = TSymbolArrayLiteral(g) }
final override Expr getElement(int i) { toGenerated(result) = g.getChild(i) }
final override Expr getElementImpl(int i) { toGenerated(result) = g.getChild(i) }
final override int getNumberOfElementsImpl() { result = count(g.getChild(_)) }
final override string toString() { result = "%i(...)" }
}

View File

@@ -107,6 +107,9 @@ private module Cached {
} or
TComplementExpr(Ruby::Unary g) { g instanceof @ruby_unary_tilde } or
TComplexLiteral(Ruby::Complex g) or
TConstantReadAccessSynth(AST::AstNode parent, int i, string value) {
mkSynthChild(ConstantReadAccessKind(value), parent, i)
} or
TDefinedExpr(Ruby::Unary g) { g instanceof @ruby_unary_definedquestion } or
TDelimitedSymbolLiteral(Ruby::DelimitedSymbol g) or
TDestructuredLeftAssignment(Ruby::DestructuredLeftAssignment g) {
@@ -439,6 +442,8 @@ private module Cached {
or
result = TClassVariableAccessSynth(parent, i, _)
or
result = TConstantReadAccessSynth(parent, i, _)
or
result = TDivExprSynth(parent, i)
or
result = TExponentExprSynth(parent, i)
@@ -526,7 +531,8 @@ class TMethodCall =
class TSuperCall = TTokenSuperCall or TRegularSuperCall;
class TConstantAccess = TTokenConstantAccess or TScopeResolutionConstantAccess or TNamespace;
class TConstantAccess =
TTokenConstantAccess or TScopeResolutionConstantAccess or TNamespace or TConstantReadAccessSynth;
class TControlExpr = TConditionalExpr or TCaseExpr or TLoop;

View File

@@ -35,7 +35,8 @@ newtype SynthKind =
SplatExprKind() or
StmtSequenceKind() or
SelfKind() or
SubExprKind()
SubExprKind() or
ConstantReadAccessKind(string value) { any(Synthesis s).constantReadAccess(value) }
/**
* An AST child.
@@ -77,6 +78,11 @@ class Synthesis extends TSynthesis {
*/
predicate methodCall(string name, boolean setter, int arity) { none() }
/**
* Holds if a constant read access of `name` is needed.
*/
predicate constantReadAccess(string name) { none() }
/**
* Holds if `n` should be excluded from `ControlFlowTree` in the CFG construction.
*/
@@ -373,7 +379,7 @@ private module AssignOperationDesugar {
* x += y
* ```
*
* desguars to
* desugars to
*
* ```rb
* x = x + y
@@ -503,7 +509,7 @@ private module AssignOperationDesugar {
* foo[bar] += y
* ```
*
* desguars to
* desugars to
*
* ```rb
* __synth__0 = foo;
@@ -702,7 +708,7 @@ private module CompoundAssignDesugar {
* ```rb
* x, *y, z = w
* ```
* desguars to
* desugars to
*
* ```rb
* __synth__0 = *w;
@@ -745,3 +751,47 @@ private module CompoundAssignDesugar {
}
}
}
private module ArrayLiteralDesugar {
pragma[nomagic]
private predicate arrayLiteralSynthesis(AstNode parent, int i, Child child) {
exists(ArrayLiteral al |
parent = al and
i = -1 and
child = SynthChild(MethodCallKind("[]", false, al.getNumberOfElements() + 1))
or
exists(AstNode mc | mc = TMethodCallSynth(al, -1, _, _, _) |
parent = mc and
i = 0 and
child = SynthChild(ConstantReadAccessKind("::Array"))
or
parent = mc and
child = RealChild(al.getElement(i - 1))
)
)
}
/**
* ```rb
* [1, 2, 3]
* ```
* desugars to
*
* ```rb
* ::Array.[](1, 2, 3)
* ```
*/
private class CompoundAssignSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child) {
arrayLiteralSynthesis(parent, i, child)
}
final override predicate methodCall(string name, boolean setter, int arity) {
name = "[]" and
setter = false and
arity = any(ArrayLiteral al).getNumberOfElements() + 1
}
final override predicate constantReadAccess(string name) { name = "::Array" }
}
}

View File

@@ -130,10 +130,6 @@ module Trees {
}
}
private class ArrayLiteralTree extends StandardPostOrderTree, ArrayLiteral {
final override ControlFlowTree getChildElement(int i) { result = this.getElement(i) }
}
private class AssignExprTree extends StandardPostOrderTree, AssignExpr {
AssignExprTree() {
exists(Expr left | left = this.getLeftOperand() |

View File

@@ -236,7 +236,14 @@ private DataFlow::LocalSourceNode trackInstance(Module tp, TypeTracker t) {
or
result.asExpr().getExpr() instanceof StringlikeLiteral and tp = TResolved("String")
or
result.asExpr().getExpr() instanceof ArrayLiteral and tp = TResolved("Array")
exists(ConstantReadAccess array, MethodCall mc |
result.asExpr().getExpr() = mc and
mc.getMethodName() = "[]" and
mc.getReceiver() = array and
array.getName() = "Array" and
array.hasGlobalScope() and
tp = TResolved("Array")
)
or
result.asExpr().getExpr() instanceof HashLiteral and tp = TResolved("Hash")
or

View File

@@ -1,4 +1,14 @@
calls/calls.rb:
# 58| [ArrayLiteral] [...]
# 58| getDesugared: [MethodCall] call to []
# 58| getReceiver: [ConstantReadAccess] Array
# 58| getArgument: [MethodCall] call to foo
# 58| getReceiver: [Self] self
# 59| [ArrayLiteral] [...]
# 59| getDesugared: [MethodCall] call to []
# 59| getReceiver: [ConstantReadAccess] Array
# 59| getArgument: [MethodCall] call to foo
# 59| getReceiver: [ConstantReadAccess] X
# 66| [AssignAddExpr] ... += ...
# 66| getDesugared: [AssignExpr] ... = ...
# 66| getAnOperand/getLeftOperand: [LocalVariableAccess] var1
@@ -73,10 +83,12 @@ calls/calls.rb:
# 316| getStmt: [AssignExpr] ... = ...
# 316| getAnOperand/getRightOperand: [SplatExpr] * ...
# 316| getAnOperand/getOperand: [ArrayLiteral] [...]
# 316| getElement: [IntegerLiteral] 1
# 316| getElement: [IntegerLiteral] 2
# 316| getElement: [IntegerLiteral] 3
# 316| getElement: [IntegerLiteral] 4
# 316| getDesugared: [MethodCall] call to []
# 316| getReceiver: [ConstantReadAccess] Array
# 316| getArgument: [IntegerLiteral] 1
# 316| getArgument: [IntegerLiteral] 2
# 316| getArgument: [IntegerLiteral] 3
# 316| getArgument: [IntegerLiteral] 4
# 316| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 317| [AssignExpr] ... = ...
# 317| getDesugared: [StmtSequence] ...
@@ -103,9 +115,11 @@ calls/calls.rb:
# 317| getStmt: [AssignExpr] ... = ...
# 317| getAnOperand/getRightOperand: [SplatExpr] * ...
# 317| getAnOperand/getOperand: [ArrayLiteral] [...]
# 317| getElement: [IntegerLiteral] 1
# 317| getElement: [IntegerLiteral] 2
# 317| getElement: [IntegerLiteral] 3
# 317| getDesugared: [MethodCall] call to []
# 317| getReceiver: [ConstantReadAccess] Array
# 317| getArgument: [IntegerLiteral] 1
# 317| getArgument: [IntegerLiteral] 2
# 317| getArgument: [IntegerLiteral] 3
# 317| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 318| [AssignAddExpr] ... += ...
# 318| getDesugared: [StmtSequence] ...
@@ -181,6 +195,137 @@ calls/calls.rb:
# 320| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 320| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__4
# 320| getStmt: [LocalVariableAccess] __synth__4
constants/constants.rb:
# 20| [ArrayLiteral] [...]
# 20| getDesugared: [MethodCall] call to []
# 20| getReceiver: [ConstantReadAccess] Array
# 20| getArgument: [StringLiteral] "Vera"
# 20| getComponent: [StringTextComponent] Vera
# 20| getArgument: [StringLiteral] "Chuck"
# 20| getComponent: [StringTextComponent] Chuck
# 20| getArgument: [StringLiteral] "Dave"
# 20| getComponent: [StringTextComponent] Dave
literals/literals.rb:
# 92| [ArrayLiteral] [...]
# 92| getDesugared: [MethodCall] call to []
# 92| getReceiver: [ConstantReadAccess] Array
# 93| [ArrayLiteral] [...]
# 93| getDesugared: [MethodCall] call to []
# 93| getReceiver: [ConstantReadAccess] Array
# 93| getArgument: [IntegerLiteral] 1
# 93| getArgument: [IntegerLiteral] 2
# 93| getArgument: [IntegerLiteral] 3
# 94| [ArrayLiteral] [...]
# 94| getDesugared: [MethodCall] call to []
# 94| getReceiver: [ConstantReadAccess] Array
# 94| getArgument: [IntegerLiteral] 4
# 94| getArgument: [IntegerLiteral] 5
# 94| getArgument: [DivExpr] ... / ...
# 94| getAnOperand/getLeftOperand: [IntegerLiteral] 12
# 94| getAnOperand/getRightOperand: [IntegerLiteral] 2
# 95| [ArrayLiteral] [...]
# 95| getDesugared: [MethodCall] call to []
# 95| getReceiver: [ConstantReadAccess] Array
# 95| getArgument: [IntegerLiteral] 7
# 95| getArgument: [ArrayLiteral] [...]
# 95| getDesugared: [MethodCall] call to []
# 95| getReceiver: [ConstantReadAccess] Array
# 95| getArgument: [IntegerLiteral] 8
# 95| getArgument: [IntegerLiteral] 9
# 98| [ArrayLiteral] %w(...)
# 98| getDesugared: [MethodCall] call to []
# 98| getReceiver: [ConstantReadAccess] Array
# 99| [ArrayLiteral] %w(...)
# 99| getDesugared: [MethodCall] call to []
# 99| getReceiver: [ConstantReadAccess] Array
# 99| getArgument: [StringLiteral] "foo"
# 99| getComponent: [StringTextComponent] foo
# 99| getArgument: [StringLiteral] "bar"
# 99| getComponent: [StringTextComponent] bar
# 99| getArgument: [StringLiteral] "baz"
# 99| getComponent: [StringTextComponent] baz
# 100| [ArrayLiteral] %w(...)
# 100| getDesugared: [MethodCall] call to []
# 100| getReceiver: [ConstantReadAccess] Array
# 100| getArgument: [StringLiteral] "foo"
# 100| getComponent: [StringTextComponent] foo
# 100| getArgument: [StringLiteral] "bar"
# 100| getComponent: [StringTextComponent] bar
# 100| getArgument: [StringLiteral] "baz"
# 100| getComponent: [StringTextComponent] baz
# 101| [ArrayLiteral] %w(...)
# 101| getDesugared: [MethodCall] call to []
# 101| getReceiver: [ConstantReadAccess] Array
# 101| getArgument: [StringLiteral] "foo"
# 101| getComponent: [StringTextComponent] foo
# 101| getArgument: [StringLiteral] "bar#{...}"
# 101| getComponent: [StringTextComponent] bar
# 101| getComponent: [StringInterpolationComponent] #{...}
# 101| getStmt: [AddExpr] ... + ...
# 101| getAnOperand/getLeftOperand: [IntegerLiteral] 1
# 101| getAnOperand/getRightOperand: [IntegerLiteral] 1
# 101| getArgument: [StringLiteral] "baz"
# 101| getComponent: [StringTextComponent] baz
# 102| [ArrayLiteral] %w(...)
# 102| getDesugared: [MethodCall] call to []
# 102| getReceiver: [ConstantReadAccess] Array
# 102| getArgument: [StringLiteral] "foo"
# 102| getComponent: [StringTextComponent] foo
# 102| getArgument: [StringLiteral] "bar#{1+1}"
# 102| getComponent: [StringTextComponent] bar#{1+1}
# 102| getArgument: [StringLiteral] "baz"
# 102| getComponent: [StringTextComponent] baz
# 105| [ArrayLiteral] %i(...)
# 105| getDesugared: [MethodCall] call to []
# 105| getReceiver: [ConstantReadAccess] Array
# 106| [ArrayLiteral] %i(...)
# 106| getDesugared: [MethodCall] call to []
# 106| getReceiver: [ConstantReadAccess] Array
# 106| getArgument: [SymbolLiteral] :"foo"
# 106| getComponent: [StringTextComponent] foo
# 106| getArgument: [SymbolLiteral] :"bar"
# 106| getComponent: [StringTextComponent] bar
# 106| getArgument: [SymbolLiteral] :"baz"
# 106| getComponent: [StringTextComponent] baz
# 107| [ArrayLiteral] %i(...)
# 107| getDesugared: [MethodCall] call to []
# 107| getReceiver: [ConstantReadAccess] Array
# 107| getArgument: [SymbolLiteral] :"foo"
# 107| getComponent: [StringTextComponent] foo
# 107| getArgument: [SymbolLiteral] :"bar"
# 107| getComponent: [StringTextComponent] bar
# 107| getArgument: [SymbolLiteral] :"baz"
# 107| getComponent: [StringTextComponent] baz
# 108| [ArrayLiteral] %i(...)
# 108| getDesugared: [MethodCall] call to []
# 108| getReceiver: [ConstantReadAccess] Array
# 108| getArgument: [SymbolLiteral] :"foo"
# 108| getComponent: [StringTextComponent] foo
# 108| getArgument: [SymbolLiteral] :"bar#{...}"
# 108| getComponent: [StringTextComponent] bar
# 108| getComponent: [StringInterpolationComponent] #{...}
# 108| getStmt: [AddExpr] ... + ...
# 108| getAnOperand/getLeftOperand: [IntegerLiteral] 2
# 108| getAnOperand/getRightOperand: [IntegerLiteral] 4
# 108| getArgument: [SymbolLiteral] :"baz"
# 108| getComponent: [StringTextComponent] baz
# 109| [ArrayLiteral] %i(...)
# 109| getDesugared: [MethodCall] call to []
# 109| getReceiver: [ConstantReadAccess] Array
# 109| getArgument: [SymbolLiteral] :"foo"
# 109| getComponent: [StringTextComponent] foo
# 109| getArgument: [SymbolLiteral] :"bar#{"
# 109| getComponent: [StringTextComponent] bar#{
# 109| getArgument: [SymbolLiteral] :"2"
# 109| getComponent: [StringTextComponent] 2
# 109| getArgument: [SymbolLiteral] :"+"
# 109| getComponent: [StringTextComponent] +
# 109| getArgument: [SymbolLiteral] :"4"
# 109| getComponent: [StringTextComponent] 4
# 109| getArgument: [SymbolLiteral] :"}"
# 109| getComponent: [StringTextComponent] }
# 109| getArgument: [SymbolLiteral] :"baz"
# 109| getComponent: [StringTextComponent] baz
control/loops.rb:
# 10| [AssignAddExpr] ... += ...
# 10| getDesugared: [AssignExpr] ... = ...
@@ -285,6 +430,10 @@ control/loops.rb:
# 63| getAnOperand/getLeftOperand: [LocalVariableAccess] x
# 63| getAnOperand/getRightOperand: [IntegerLiteral] 1
operations/operations.rb:
# 29| [ArrayLiteral] [...]
# 29| getDesugared: [MethodCall] call to []
# 29| getReceiver: [ConstantReadAccess] Array
# 29| getArgument: [IntegerLiteral] 2
# 69| [AssignAddExpr] ... += ...
# 69| getDesugared: [AssignExpr] ... = ...
# 69| getAnOperand/getLeftOperand: [LocalVariableAccess] x
@@ -381,7 +530,20 @@ operations/operations.rb:
# 96| getAnOperand/getRightOperand: [MulExpr] ... * ...
# 96| getAnOperand/getLeftOperand: [GlobalVariableAccess] $global_var
# 96| getAnOperand/getRightOperand: [IntegerLiteral] 6
params/params.rb:
# 21| [ArrayLiteral] [...]
# 21| getDesugared: [MethodCall] call to []
# 21| getReceiver: [ConstantReadAccess] Array
erb/template.html.erb:
# 27| [ArrayLiteral] [...]
# 27| getDesugared: [MethodCall] call to []
# 27| getReceiver: [ConstantReadAccess] Array
# 27| getArgument: [StringLiteral] "foo"
# 27| getComponent: [StringTextComponent] foo
# 27| getArgument: [StringLiteral] "bar"
# 27| getComponent: [StringTextComponent] bar
# 27| getArgument: [StringLiteral] "baz"
# 27| getComponent: [StringTextComponent] baz
# 28| [AssignAddExpr] ... += ...
# 28| getDesugared: [AssignExpr] ... = ...
# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs
@@ -432,8 +594,10 @@ gems/test.gemspec:
# 6| getArgument: [AssignExpr] ... = ...
# 6| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 6| getAnOperand/getRightOperand: [ArrayLiteral] [...]
# 6| getElement: [StringLiteral] "Mona Lisa"
# 6| getComponent: [StringTextComponent] Mona Lisa
# 6| getDesugared: [MethodCall] call to []
# 6| getReceiver: [ConstantReadAccess] Array
# 6| getArgument: [StringLiteral] "Mona Lisa"
# 6| getComponent: [StringTextComponent] Mona Lisa
# 6| getStmt: [LocalVariableAccess] __synth__0
# 7| [AssignExpr] ... = ...
# 7| getDesugared: [StmtSequence] ...
@@ -451,8 +615,10 @@ gems/test.gemspec:
# 8| getArgument: [AssignExpr] ... = ...
# 8| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 8| getAnOperand/getRightOperand: [ArrayLiteral] [...]
# 8| getElement: [StringLiteral] "lib/test.rb"
# 8| getComponent: [StringTextComponent] lib/test.rb
# 8| getDesugared: [MethodCall] call to []
# 8| getReceiver: [ConstantReadAccess] Array
# 8| getArgument: [StringLiteral] "lib/test.rb"
# 8| getComponent: [StringTextComponent] lib/test.rb
# 8| getStmt: [LocalVariableAccess] __synth__0
# 9| [AssignExpr] ... = ...
# 9| getDesugared: [StmtSequence] ...

View File

@@ -12,6 +12,8 @@ callsWithArguments
| calls.rb:36:3:36:16 | yield ... | (none) | 1 | calls.rb:36:14:36:16 | 200 |
| calls.rb:54:1:54:14 | call to some_func | some_func | 0 | calls.rb:54:11:54:13 | call to foo |
| calls.rb:55:1:55:17 | call to some_func | some_func | 0 | calls.rb:55:11:55:16 | call to foo |
| calls.rb:58:1:58:5 | call to [] | [] | 0 | calls.rb:58:2:58:4 | call to foo |
| calls.rb:59:1:59:8 | call to [] | [] | 0 | calls.rb:59:2:59:7 | call to foo |
| calls.rb:234:1:234:8 | ...[...] | [] | 0 | calls.rb:234:5:234:7 | call to bar |
| calls.rb:235:1:235:14 | ...[...] | [] | 0 | calls.rb:235:8:235:13 | call to bar |
| calls.rb:266:1:266:9 | call to foo | foo | 0 | calls.rb:266:5:266:8 | &... |
@@ -43,11 +45,18 @@ callsWithArguments
| calls.rb:316:22:316:27 | call to [] | [] | 0 | calls.rb:316:22:316:27 | -1 |
| calls.rb:316:22:316:27 | call to []= | []= | 0 | calls.rb:316:26:316:26 | 4 |
| calls.rb:316:22:316:27 | call to []= | []= | 1 | calls.rb:316:22:316:27 | ... = ... |
| calls.rb:316:31:316:42 | call to [] | [] | 0 | calls.rb:316:32:316:32 | 1 |
| calls.rb:316:31:316:42 | call to [] | [] | 1 | calls.rb:316:35:316:35 | 2 |
| calls.rb:316:31:316:42 | call to [] | [] | 2 | calls.rb:316:38:316:38 | 3 |
| calls.rb:316:31:316:42 | call to [] | [] | 3 | calls.rb:316:41:316:41 | 4 |
| calls.rb:317:1:317:1 | call to [] | [] | 0 | calls.rb:317:1:317:1 | 0 |
| calls.rb:317:5:317:10 | ...[...] | [] | 0 | calls.rb:317:9:317:9 | 5 |
| calls.rb:317:5:317:10 | call to [] | [] | 0 | calls.rb:317:5:317:10 | _ .. _ |
| calls.rb:317:5:317:10 | call to []= | []= | 0 | calls.rb:317:9:317:9 | 5 |
| calls.rb:317:5:317:10 | call to []= | []= | 1 | calls.rb:317:5:317:10 | ... = ... |
| calls.rb:317:14:317:22 | call to [] | [] | 0 | calls.rb:317:15:317:15 | 1 |
| calls.rb:317:14:317:22 | call to [] | [] | 1 | calls.rb:317:18:317:18 | 2 |
| calls.rb:317:14:317:22 | call to [] | [] | 2 | calls.rb:317:21:317:21 | 3 |
| calls.rb:318:1:318:10 | call to count= | count= | 1 | calls.rb:318:12:318:13 | __synth__1 |
| calls.rb:319:1:319:6 | ...[...] | [] | 0 | calls.rb:319:5:319:5 | 0 |
| calls.rb:319:1:319:6 | call to [] | [] | 0 | calls.rb:319:5:319:5 | __synth__1 |
@@ -80,7 +89,9 @@ callsWithReceiver
| calls.rb:54:11:54:13 | call to foo | calls.rb:54:11:54:13 | self |
| calls.rb:55:1:55:17 | call to some_func | calls.rb:55:1:55:17 | self |
| calls.rb:55:11:55:16 | call to foo | calls.rb:55:11:55:11 | X |
| calls.rb:58:1:58:5 | call to [] | calls.rb:58:1:58:5 | Array |
| calls.rb:58:2:58:4 | call to foo | calls.rb:58:2:58:4 | self |
| calls.rb:59:1:59:8 | call to [] | calls.rb:59:1:59:8 | Array |
| calls.rb:59:2:59:7 | call to foo | calls.rb:59:2:59:2 | X |
| calls.rb:62:8:62:10 | call to foo | calls.rb:62:8:62:10 | self |
| calls.rb:63:8:63:13 | call to foo | calls.rb:63:8:63:8 | X |
@@ -246,11 +257,13 @@ callsWithReceiver
| calls.rb:316:22:316:27 | ...[...] | calls.rb:316:22:316:24 | call to foo |
| calls.rb:316:22:316:27 | call to [] | calls.rb:316:22:316:27 | __synth__0 |
| calls.rb:316:22:316:27 | call to []= | calls.rb:316:22:316:24 | call to foo |
| calls.rb:316:31:316:42 | call to [] | calls.rb:316:31:316:42 | Array |
| calls.rb:317:1:317:1 | call to [] | calls.rb:317:1:317:1 | __synth__0 |
| calls.rb:317:5:317:7 | call to foo | calls.rb:317:5:317:7 | self |
| calls.rb:317:5:317:10 | ...[...] | calls.rb:317:5:317:7 | call to foo |
| calls.rb:317:5:317:10 | call to [] | calls.rb:317:5:317:10 | __synth__0 |
| calls.rb:317:5:317:10 | call to []= | calls.rb:317:5:317:7 | call to foo |
| calls.rb:317:14:317:22 | call to [] | calls.rb:317:14:317:22 | Array |
| calls.rb:318:1:318:10 | call to count | calls.rb:318:1:318:4 | __synth__0 |
| calls.rb:318:1:318:10 | call to count | calls.rb:318:1:318:4 | self |
| calls.rb:318:1:318:10 | call to count= | calls.rb:318:1:318:4 | __synth__0 |

View File

@@ -17,6 +17,7 @@ constantAccess
| constants.rb:17:49:17:55 | ModuleA | read | ModuleA | ConstantReadAccess |
| constants.rb:17:49:17:64 | CONST_B | read | CONST_B | ConstantReadAccess |
| constants.rb:20:5:20:9 | Names | write | Names | ConstantAssignment |
| constants.rb:20:13:20:37 | Array | read | Array | ConstantReadAccess |
| constants.rb:22:5:22:9 | Names | read | Names | ConstantReadAccess |
| constants.rb:23:18:23:25 | GREETING | read | GREETING | ConstantReadAccess |
| constants.rb:31:1:32:3 | ClassD | write | ClassD | ClassDeclaration |

View File

@@ -15,9 +15,11 @@
| test.gemspec:5:3:5:15 | call to description= |
| test.gemspec:6:3:6:11 | call to authors |
| test.gemspec:6:3:6:11 | call to authors= |
| test.gemspec:6:19:6:31 | call to [] |
| test.gemspec:7:3:7:9 | call to email |
| test.gemspec:7:3:7:9 | call to email= |
| test.gemspec:8:3:8:9 | call to files |
| test.gemspec:8:3:8:9 | call to files= |
| test.gemspec:8:19:8:33 | call to [] |
| test.gemspec:9:3:9:12 | call to homepage |
| test.gemspec:9:3:9:12 | call to homepage= |

View File

@@ -691,7 +691,7 @@ cfg.rb:
#-----| -> b
# 5| ... = ...
#-----| -> b
#-----| -> Array
# 5| b
#-----| -> 42
@@ -699,7 +699,10 @@ cfg.rb:
# 5| 42
#-----| -> ... = ...
# 7| %i(...)
# 7| call to []
#-----| -> Array
# 7| Array
#-----| -> b
# 7| :"one#{...}"
@@ -712,11 +715,14 @@ cfg.rb:
#-----| -> #{...}
# 7| :"another"
#-----| -> %i(...)
#-----| -> call to []
# 9| %w(...)
# 9| call to []
#-----| -> self
# 9| Array
#-----| -> b
# 9| "one#{...}"
#-----| -> "another"
@@ -727,7 +733,7 @@ cfg.rb:
#-----| -> #{...}
# 9| "another"
#-----| -> %w(...)
#-----| -> call to []
# 12| call to puts
#-----| -> END { ... }
@@ -1151,29 +1157,35 @@ cfg.rb:
# 62| __synth__0__1
#-----| -> 1
# 62| [...]
# 62| call to []
#-----| -> * ...
# 62| ... = ...
#-----| -> x
# 62| Array
#-----| -> 1
# 62| * ...
#-----| -> ... = ...
# 62| __synth__0
#-----| -> 1
#-----| -> Array
# 62| 1
#-----| -> 2
#-----| -> Array
# 62| [...]
#-----| -> [...]
# 62| call to []
#-----| -> call to []
# 62| Array
#-----| -> 2
# 62| 2
#-----| -> 3
# 62| 3
#-----| -> [...]
#-----| -> call to []
# 63| enter pattern
#-----| -> a
@@ -1217,11 +1229,14 @@ cfg.rb:
#-----| -> self
# 67| items
#-----| -> 1
#-----| -> Array
# 67| [...]
# 67| call to []
#-----| -> ... = ...
# 67| Array
#-----| -> 1
# 67| 1
#-----| -> 2
@@ -1229,7 +1244,7 @@ cfg.rb:
#-----| -> 3
# 67| 3
#-----| -> [...]
#-----| -> call to []
# 68| call to puts
#-----| -> print
@@ -1347,7 +1362,7 @@ cfg.rb:
#-----| -> call to puts
# 88| ... = ...
#-----| -> 1.4
#-----| -> Array
# 88| escape
#-----| -> x
@@ -1371,9 +1386,12 @@ cfg.rb:
#-----| empty -> for ... in ...
#-----| non-empty -> x
# 90| [...]
# 90| call to []
#-----| -> In
# 90| Array
#-----| -> 1.4
# 90| 1.4
#-----| -> 2.5
@@ -1381,7 +1399,7 @@ cfg.rb:
#-----| -> 3.4e5
# 90| 3.4e5
#-----| -> [...]
#-----| -> call to []
# 90| do ...
#-----| -> In
@@ -1634,7 +1652,7 @@ cfg.rb:
#-----| -> exit -> { ... }
# 120| (..., ...)
#-----| -> y
#-----| -> Array
# 120| x
#-----| -> y
@@ -1642,14 +1660,17 @@ cfg.rb:
# 120| y
#-----| -> (..., ...)
# 120| [...]
# 120| call to []
#-----| -> exit -> { ... } (normal)
# 120| Array
#-----| -> y
# 120| y
#-----| -> x
# 120| x
#-----| -> [...]
#-----| -> call to []
# 122| M
#-----| -> EmptyClass
@@ -1974,19 +1995,22 @@ cfg.rb:
#-----| -> scriptfile
# 158| self
#-----| -> 1
#-----| -> Array
# 158| * ...
#-----| -> call to two_parameters
# 158| [...]
# 158| call to []
#-----| -> * ...
# 158| Array
#-----| -> 1
# 158| 1
#-----| -> 2
# 158| 2
#-----| -> [...]
#-----| -> call to []
# 160| ... = ...
#-----| -> symbol
@@ -2749,17 +2773,20 @@ desugar.rb:
# 22| __synth__0__1
#-----| -> __synth__0
# 22| [...]
# 22| call to []
#-----| -> * ...
# 22| ... = ...
#-----| -> x
# 22| Array
#-----| -> 1
# 22| * ...
#-----| -> ... = ...
# 22| __synth__0
#-----| -> 1
#-----| -> Array
# 22| 1
#-----| -> 2
@@ -2771,7 +2798,7 @@ desugar.rb:
#-----| -> 4
# 22| 4
#-----| -> [...]
#-----| -> call to []
# 25| enter m7
#-----| -> __synth__0
@@ -2853,29 +2880,35 @@ desugar.rb:
# 26| __synth__0__1
#-----| -> 1
# 26| [...]
# 26| call to []
#-----| -> * ...
# 26| ... = ...
#-----| -> x
# 26| Array
#-----| -> 1
# 26| * ...
#-----| -> ... = ...
# 26| __synth__0
#-----| -> 1
#-----| -> Array
# 26| 1
#-----| -> 2
#-----| -> Array
# 26| [...]
#-----| -> [...]
# 26| call to []
#-----| -> call to []
# 26| Array
#-----| -> 2
# 26| 2
#-----| -> 3
# 26| 3
#-----| -> [...]
#-----| -> call to []
# 29| X
#-----| -> $global_var
@@ -3764,7 +3797,7 @@ loops.rb:
#-----| -> call to puts
# 24| enter m3
#-----| -> 1
#-----| -> Array
# 24| m3
#-----| -> m4
@@ -3774,12 +3807,15 @@ loops.rb:
# 24| exit m3 (normal)
#-----| -> exit m3
# 25| [...]
#-----| -> do ... end
# 25| call to each
#-----| -> exit m3 (normal)
# 25| call to []
#-----| -> do ... end
# 25| Array
#-----| -> 1
# 25| 1
#-----| -> 2
@@ -3787,7 +3823,7 @@ loops.rb:
#-----| -> 3
# 25| 3
#-----| -> [...]
#-----| -> call to []
# 25| enter do ... end
#-----| -> x

View File

@@ -12,7 +12,7 @@ end
Unknown.new.run #$ use=getMember("Unknown").instance.getReturn("run")
Foo::Bar::Baz #$ use=getMember("Foo").getMember("Bar").getMember("Baz")
Const = [1, 2, 3]
Const = [1, 2, 3] #$ use=getMember("Array").getReturn("[]")
Const.each do |c| #$ use=getMember("Const").getReturn("each")
puts c
end

View File

@@ -21,8 +21,8 @@
| local_dataflow.rb:6:8:6:13 | ... = ... | local_dataflow.rb:6:7:6:14 | ( ... ) |
| local_dataflow.rb:6:10:6:11 | ... + ... | local_dataflow.rb:6:8:6:13 | ... = ... |
| 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 | ... = ... |
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... |
| local_dataflow.rb:10:5:13:3 | for ... in ... | local_dataflow.rb:10:1:13:3 | ... = ... |
| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x |
| local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:10:5:13:3 | for ... in ... |

View File

@@ -97,8 +97,12 @@ unresolvedCall
| calls.rb:42:9:42:24 | call to singleton_m |
| calls.rb:48:1:48:13 | call to singleton_m |
| calls.rb:59:1:59:13 | call to singleton_m |
| calls.rb:129:1:129:13 | call to [] |
| calls.rb:129:48:129:59 | call to capitalize |
| calls.rb:131:1:131:7 | call to [] |
| calls.rb:133:1:133:7 | call to [] |
| calls.rb:133:28:133:39 | call to capitalize |
| calls.rb:135:1:135:8 | call to [] |
| calls.rb:135:32:135:36 | call to abs |
| private.rb:24:1:24:14 | call to private1 |
| private.rb:25:1:25:14 | call to private2 |