Improve performance of desugaring transformations

This commit is contained in:
Tom Hvitved
2021-06-03 21:03:12 +02:00
parent 57eee0368d
commit da9adfbab4
5 changed files with 338 additions and 256 deletions

View File

@@ -13,7 +13,7 @@ predicate isScopeResolutionMethodCall(Generated::ScopeResolution g, Generated::I
}
abstract class CallImpl extends Call {
abstract Expr getArgumentImpl(int n);
abstract AstNode getArgumentImpl(int n);
/**
* It is not possible to define this predicate as
@@ -28,7 +28,7 @@ abstract class CallImpl extends Call {
}
abstract class MethodCallImpl extends CallImpl, MethodCall {
abstract Expr getReceiverImpl();
abstract AstNode getReceiverImpl();
abstract string getMethodNameImpl();
}
@@ -42,9 +42,9 @@ class MethodCallSynth extends MethodCallImpl, TMethodCallSynth {
)
}
final override Expr getReceiverImpl() { synthChild(this, 0, result) }
final override AstNode getReceiverImpl() { synthChild(this, 0, result) }
final override Expr getArgumentImpl(int n) { synthChild(this, n + 1, result) and n >= 0 }
final override AstNode getArgumentImpl(int n) { synthChild(this, n + 1, result) and n >= 0 }
final override int getNumberOfArgumentsImpl() { this = TMethodCallSynth(_, _, _, _, result) }
}
@@ -56,7 +56,7 @@ class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall {
final override string getMethodNameImpl() { result = g.getValue() }
final override Self getReceiverImpl() { result = TSelfSynth(this, 0) }
final override AstNode getReceiverImpl() { result = TSelfSynth(this, 0) }
final override Expr getArgumentImpl(int n) { none() }

View File

@@ -3,9 +3,9 @@ private import AST
private import TreeSitter
class AssignmentImpl extends Operation, TAssignment {
abstract Pattern getLeftOperandImpl();
abstract AstNode getLeftOperandImpl();
abstract Expr getRightOperandImpl();
abstract AstNode getRightOperandImpl();
}
class AssignExprReal extends AssignmentImpl, AssignExpr, TAssignExprReal {
@@ -13,19 +13,19 @@ class AssignExprReal extends AssignmentImpl, AssignExpr, TAssignExprReal {
AssignExprReal() { this = TAssignExprReal(g) }
final override Pattern getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
final override AstNode getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
final override Expr getRightOperandImpl() { toGenerated(result) = g.getRight() }
final override AstNode getRightOperandImpl() { toGenerated(result) = g.getRight() }
}
class AssignExprSynth extends AssignmentImpl, AssignExpr, TAssignExprSynth {
final override Pattern getLeftOperandImpl() { synthChild(this, 0, result) }
final override AstNode getLeftOperandImpl() { synthChild(this, 0, result) }
final override Expr getRightOperandImpl() { synthChild(this, 1, result) }
final override AstNode getRightOperandImpl() { synthChild(this, 1, result) }
}
class AssignOperationImpl extends AssignmentImpl, AssignOperation {
final override LhsExpr getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
final override AstNode getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
final override Expr getRightOperandImpl() { toGenerated(result) = g.getRight() }
final override AstNode getRightOperandImpl() { toGenerated(result) = g.getRight() }
}

View File

@@ -3,8 +3,6 @@
private import AST
private import TreeSitter
private import codeql_ruby.ast.internal.Call
private import codeql_ruby.ast.internal.Operation
private import codeql_ruby.ast.internal.Parameter
private import codeql_ruby.ast.internal.Variable
private import codeql_ruby.AST
@@ -31,8 +29,8 @@ newtype SynthKind =
} or
ModuloExprKind() or
MulExprKind() or
StmtSequenceKind() or
RShiftExprKind() or
StmtSequenceKind() or
SelfKind() or
SubExprKind()
@@ -110,7 +108,7 @@ private predicate assign(
i = assignIndex and
child = SynthChild(AssignExprKind())
or
parent = getSynthChild(assignParent, assignIndex) and
parent = TAssignExprSynth(assignParent, assignIndex) and
(
i = 0 and
child = SynthChild(LocalVariableAccessSynthKind(v))
@@ -120,43 +118,128 @@ private predicate assign(
)
}
bindingset[arity, setter]
private SynthKind getCallKind(MethodCall mc, boolean setter, int arity) {
result = MethodCallKind(mc.getMethodName(), setter, arity)
}
private SomeLocation getSomeLocation(AstNode n) {
result = SomeLocation(toGenerated(n).getLocation())
}
private module ImplicitSelfSynthesis {
pragma[nomagic]
private predicate identifierMethodCallSelfSynthesis(
AstNode mc, int i, Child child, LocationOption l
) {
child = SynthChild(SelfKind()) and
mc = TIdentifierMethodCall(_) and
i = 0 and
l = NoneLocation()
}
private class IdentifierMethodCallSelfSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child, LocationOption l) {
child = SynthChild(SelfKind()) and
parent = TIdentifierMethodCall(_) and
i = 0 and
l = NoneLocation()
identifierMethodCallSelfSynthesis(parent, i, child, l)
}
}
pragma[nomagic]
private predicate regularMethodCallSelfSynthesis(
TRegularMethodCall mc, int i, Child child, LocationOption l
) {
exists(Generated::AstNode g |
mc = 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())
) and
child = SynthChild(SelfKind()) and
i = 0 and
l = NoneLocation()
}
private class RegularMethodCallSelfSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child, LocationOption l) {
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())
) and
l = NoneLocation()
regularMethodCallSelfSynthesis(parent, i, child, l)
}
}
}
private module SetterDesugar {
/** An assignment where the left-hand side is a method call. */
private class SetterAssignExpr extends AssignExpr {
private MethodCall mc;
pragma[nomagic]
SetterAssignExpr() { mc = this.getLeftOperand() }
MethodCall getMethodCall() { result = mc }
pragma[nomagic]
MethodCallKind getCallKind(boolean setter, int arity) {
result = MethodCallKind(mc.getMethodName(), setter, arity)
}
pragma[nomagic]
Expr getReceiver() { result = mc.getReceiver() }
pragma[nomagic]
Expr getArgument(int i) { result = mc.getArgument(i) }
pragma[nomagic]
int getNumberOfArguments() { result = mc.getNumberOfArguments() }
pragma[nomagic]
LocationOption getMethodCallLocation() { result = getSomeLocation(mc) }
}
pragma[nomagic]
private predicate setterMethodCallSynthesis(AstNode parent, int i, Child child, LocationOption l) {
exists(SetterAssignExpr sae |
parent = sae and
i = -1 and
child = SynthChild(StmtSequenceKind()) and
l = NoneLocation()
or
exists(AstNode seq | seq = TStmtSequenceSynth(sae, -1) |
parent = seq and
i = 0 and
child = SynthChild(sae.getCallKind(true, sae.getNumberOfArguments() + 1)) and
l = sae.getMethodCallLocation()
or
exists(AstNode call | call = TMethodCallSynth(seq, 0, _, _, _) |
parent = call and
i = 0 and
child = RealChild(sae.getReceiver()) and
l = NoneLocation()
or
parent = call and
child = RealChild(sae.getArgument(i - 1)) and
l = NoneLocation()
or
l = sae.getMethodCallLocation() and
exists(int valueIndex | valueIndex = sae.getNumberOfArguments() + 1 |
parent = call and
i = valueIndex and
child = SynthChild(AssignExprKind())
or
parent = TAssignExprSynth(call, valueIndex) and
(
i = 0 and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sae, 0)))
or
i = 1 and
child = RealChild(sae.getRightOperand())
)
)
)
or
parent = seq and
i = 1 and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sae, 0))) and
l = sae.getMethodCallLocation()
)
)
}
/**
* ```rb
* x.foo = y
@@ -171,68 +254,23 @@ private module SetterDesugar {
*/
private class SetterMethodCallSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child, LocationOption l) {
exists(AssignExpr ae, MethodCall mc | mc = ae.getLeftOperand() |
parent = ae and
i = -1 and
child = SynthChild(StmtSequenceKind()) and
l = NoneLocation()
or
exists(AstNode seq | seq = getSynthChild(ae, -1) |
parent = seq and
i = 0 and
child = SynthChild(getCallKind(mc, true, mc.getNumberOfArguments() + 1)) and
l = getSomeLocation(mc)
or
exists(AstNode call | call = getSynthChild(seq, 0) |
parent = call and
i = 0 and
child = RealChild(mc.getReceiver()) and
l = NoneLocation()
or
parent = call and
child = RealChild(mc.getArgument(i - 1)) and
l = NoneLocation()
or
l = getSomeLocation(mc) and
exists(int valueIndex | valueIndex = mc.getNumberOfArguments() + 1 |
parent = call and
i = valueIndex and
child = SynthChild(AssignExprKind())
or
parent = getSynthChild(call, valueIndex) and
(
i = 0 and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ae, 0)))
or
i = 1 and
child = RealChild(ae.getRightOperand())
)
)
)
or
parent = seq and
i = 1 and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ae, 0))) and
l = getSomeLocation(mc)
)
)
setterMethodCallSynthesis(parent, i, child, l)
}
final override predicate excludeFromControlFlowTree(AstNode n) {
n.(MethodCall) = any(AssignExpr ae).getLeftOperand()
n = any(SetterAssignExpr sae).getMethodCall()
}
final override predicate localVariable(AstNode n, int i) {
n.(AssignExpr).getLeftOperand() instanceof MethodCall and
n instanceof SetterAssignExpr and
i = 0
}
final override predicate methodCall(string name, boolean setter, int arity) {
exists(AssignExpr ae, MethodCall mc |
mc = ae.getLeftOperand() and
name = mc.getMethodName() and
exists(SetterAssignExpr sae |
name = sae.getMethodCall().getMethodName() and
setter = true and
arity = mc.getNumberOfArguments() + 1
arity = sae.getNumberOfArguments() + 1
)
}
}
@@ -279,6 +317,57 @@ private module AssignOperationDesugar {
)
}
/** An assignment operation where the left-hand side is a variable. */
private class VariableAssignOperation extends AssignOperation {
private Variable v;
pragma[nomagic]
VariableAssignOperation() { v = this.getLeftOperand().(VariableAccess).getVariable() }
pragma[nomagic]
SynthKind getVariableAccessKind() {
result in [
LocalVariableAccessRealKind(v).(SynthKind), InstanceVariableAccessKind(v),
ClassVariableAccessKind(v), GlobalVariableAccessKind(v)
]
}
}
pragma[nomagic]
private predicate variableAssignOperationSynthesis(
AstNode parent, int i, Child child, LocationOption l
) {
exists(VariableAssignOperation vao |
parent = vao and
i = -1 and
child = SynthChild(AssignExprKind()) and
l = NoneLocation()
or
exists(AstNode assign | assign = TAssignExprSynth(vao, -1) |
parent = assign and
i = 0 and
child = RealChild(vao.getLeftOperand()) and
l = NoneLocation()
or
parent = assign and
i = 1 and
child = SynthChild(getKind(vao)) and
l = SomeLocation(getAssignOperationLocation(vao))
or
parent = getSynthChild(assign, 1) and
(
i = 0 and
child = SynthChild(vao.getVariableAccessKind()) and
l = getSomeLocation(vao.getLeftOperand())
or
i = 1 and
child = RealChild(vao.getRightOperand()) and
l = NoneLocation()
)
)
)
}
/**
* ```rb
* x += y
@@ -294,46 +383,133 @@ private module AssignOperationDesugar {
*/
private class VariableAssignOperationSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child, LocationOption l) {
exists(AssignOperation ao, VariableReal v |
v = ao.getLeftOperand().(VariableAccess).getVariable()
|
parent = ao and
i = -1 and
child = SynthChild(AssignExprKind()) and
l = NoneLocation()
or
exists(AstNode assign | assign = getSynthChild(ao, -1) |
parent = assign and
i = 0 and
child = RealChild(ao.getLeftOperand()) and
l = NoneLocation()
or
parent = assign and
i = 1 and
child = SynthChild(getKind(ao)) and
l = SomeLocation(getAssignOperationLocation(ao))
or
parent = getSynthChild(assign, 1) and
(
i = 0 and
child =
SynthChild([
LocalVariableAccessRealKind(v).(SynthKind), InstanceVariableAccessKind(v),
ClassVariableAccessKind(v), GlobalVariableAccessKind(v)
]) and
l = getSomeLocation(ao.getLeftOperand())
or
i = 1 and
child = RealChild(ao.getRightOperand()) and
l = NoneLocation()
)
)
)
variableAssignOperationSynthesis(parent, i, child, l)
}
}
/** Gets an assignment operation where the LHS is method call `mc`. */
private AssignOperation assignOperationMethodCall(MethodCall mc) { result.getLeftOperand() = mc }
/** An assignment operation where the left-hand side is a method call. */
private class SetterAssignOperation extends AssignOperation {
private MethodCall mc;
pragma[nomagic]
SetterAssignOperation() { mc = this.getLeftOperand() }
MethodCall getMethodCall() { result = mc }
pragma[nomagic]
MethodCallKind getCallKind(boolean setter, int arity) {
result = MethodCallKind(mc.getMethodName(), setter, arity)
}
pragma[nomagic]
Expr getReceiver() { result = mc.getReceiver() }
pragma[nomagic]
Expr getArgument(int i) { result = mc.getArgument(i) }
pragma[nomagic]
int getNumberOfArguments() { result = mc.getNumberOfArguments() }
pragma[nomagic]
LocationOption getMethodCallLocation() { result = getSomeLocation(mc) }
}
pragma[nomagic]
private predicate methodCallAssignOperationSynthesis(
AstNode parent, int i, Child child, LocationOption l
) {
exists(SetterAssignOperation sao |
parent = sao and
i = -1 and
child = SynthChild(StmtSequenceKind()) and
l = NoneLocation()
or
exists(AstNode seq, AstNode receiver |
seq = TStmtSequenceSynth(sao, -1) and receiver = sao.getReceiver()
|
// `__synth__0 = foo`
assign(parent, i, child, TLocalVariableSynth(sao, 0), seq, 0, receiver) and
l = getSomeLocation(receiver)
or
// `__synth__1 = bar`
exists(Expr arg, int j | arg = sao.getArgument(j - 1) |
assign(parent, i, child, TLocalVariableSynth(sao, j), seq, j, arg) and
l = getSomeLocation(arg)
)
or
// `__synth__2 = __synth__0.[](__synth__1) + y`
exists(int opAssignIndex | opAssignIndex = sao.getNumberOfArguments() + 1 |
parent = seq and
i = opAssignIndex and
child = SynthChild(AssignExprKind()) and
l = SomeLocation(getAssignOperationLocation(sao))
or
exists(AstNode assign | assign = TAssignExprSynth(seq, opAssignIndex) |
parent = assign and
i = 0 and
child =
SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sao, opAssignIndex))) and
l = SomeLocation(getAssignOperationLocation(sao))
or
parent = assign and
i = 1 and
child = SynthChild(getKind(sao)) and
l = SomeLocation(getAssignOperationLocation(sao))
or
// `__synth__0.[](__synth__1) + y`
exists(AstNode op | op = getSynthChild(assign, 1) |
parent = op and
i = 0 and
child = SynthChild(sao.getCallKind(false, sao.getNumberOfArguments())) and
l = sao.getMethodCallLocation()
or
parent = TMethodCallSynth(op, 0, _, _, _) and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sao, i))) and
(
i = 0 and
l = getSomeLocation(receiver)
or
l = getSomeLocation(sao.getArgument(i - 1))
)
or
parent = op and
i = 1 and
child = RealChild(sao.getRightOperand()) and
l = NoneLocation()
)
)
or
// `__synth__0.[]=(__synth__1, __synth__2);`
parent = seq and
i = opAssignIndex + 1 and
child = SynthChild(sao.getCallKind(true, opAssignIndex)) and
l = sao.getMethodCallLocation()
or
exists(AstNode setter | setter = TMethodCallSynth(seq, opAssignIndex + 1, _, _, _) |
parent = setter and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sao, i))) and
(
i = 0 and
l = getSomeLocation(receiver)
or
l = getSomeLocation(sao.getArgument(i - 1))
)
or
parent = setter and
i = opAssignIndex + 1 and
child =
SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sao, opAssignIndex))) and
l = SomeLocation(getAssignOperationLocation(sao))
)
or
parent = seq and
i = opAssignIndex + 2 and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sao, opAssignIndex))) and
l = SomeLocation(getAssignOperationLocation(sao))
)
)
)
}
/**
* ```rb
@@ -352,119 +528,25 @@ private module AssignOperationDesugar {
*/
private class MethodCallAssignOperationSynthesis extends Synthesis {
final override predicate child(AstNode parent, int i, Child child, LocationOption l) {
exists(AssignOperation ao, MethodCall mc | ao = assignOperationMethodCall(mc) |
parent = ao and
i = -1 and
child = SynthChild(StmtSequenceKind()) and
l = NoneLocation()
or
exists(AstNode seq, AstNode receiver |
seq = getSynthChild(ao, -1) and receiver = mc.getReceiver()
|
// `__synth__0 = foo`
assign(parent, i, child, TLocalVariableSynth(ao, 0), seq, 0, receiver) and
l = getSomeLocation(receiver)
or
// `__synth__1 = bar`
exists(Expr arg, int j | arg = mc.getArgument(j - 1) |
assign(parent, i, child, TLocalVariableSynth(ao, j), seq, j, arg) and
l = getSomeLocation(arg)
)
or
// `__synth__2 = __synth__0.[](__synth__1) + y`
exists(int opAssignIndex | opAssignIndex = mc.getNumberOfArguments() + 1 |
parent = seq and
i = opAssignIndex and
child = SynthChild(AssignExprKind()) and
l = SomeLocation(getAssignOperationLocation(ao))
or
exists(AstNode assign | assign = getSynthChild(seq, opAssignIndex) |
parent = assign and
i = 0 and
child =
SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ao, opAssignIndex))) and
l = SomeLocation(getAssignOperationLocation(ao))
or
parent = assign and
i = 1 and
child = SynthChild(getKind(ao)) and
l = SomeLocation(getAssignOperationLocation(ao))
or
// `__synth__0.[](__synth__1) + y`
exists(AstNode op | op = getSynthChild(assign, 1) |
parent = op and
i = 0 and
child = SynthChild(getCallKind(mc, false, mc.getNumberOfArguments())) and
l = getSomeLocation(mc)
or
parent = getSynthChild(op, 0) and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ao, i))) and
(
i = 0 and
l = getSomeLocation(receiver)
or
l = getSomeLocation(mc.getArgument(i - 1))
)
or
parent = op and
i = 1 and
child = RealChild(ao.getRightOperand()) and
l = NoneLocation()
)
)
or
// `__synth__0.[]=(__synth__1, __synth__2);`
parent = seq and
i = opAssignIndex + 1 and
child = SynthChild(getCallKind(mc, true, opAssignIndex)) and
l = getSomeLocation(mc)
or
exists(AstNode setter | setter = getSynthChild(seq, opAssignIndex + 1) |
parent = setter and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ao, i))) and
(
i = 0 and
l = getSomeLocation(receiver)
or
l = getSomeLocation(mc.getArgument(i - 1))
)
or
parent = setter and
i = opAssignIndex + 1 and
child =
SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ao, opAssignIndex))) and
l = SomeLocation(getAssignOperationLocation(ao))
)
or
parent = seq and
i = opAssignIndex + 2 and
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(ao, opAssignIndex))) and
l = SomeLocation(getAssignOperationLocation(ao))
)
)
)
methodCallAssignOperationSynthesis(parent, i, child, l)
}
final override predicate localVariable(AstNode n, int i) {
exists(MethodCall mc | n = assignOperationMethodCall(mc) |
i in [0 .. mc.getNumberOfArguments() + 1]
)
n = any(SetterAssignOperation sao | i in [0 .. sao.getNumberOfArguments() + 1])
}
final override predicate methodCall(string name, boolean setter, int arity) {
exists(MethodCall mc | exists(assignOperationMethodCall(mc)) |
name = mc.getMethodName() and
exists(SetterAssignOperation sao | name = sao.getMethodCall().getMethodName() |
setter = false and
arity = mc.getNumberOfArguments()
arity = sao.getNumberOfArguments()
or
name = mc.getMethodName() and
setter = true and
arity = mc.getNumberOfArguments() + 1
arity = sao.getNumberOfArguments() + 1
)
}
final override predicate excludeFromControlFlowTree(AstNode n) {
exists(assignOperationMethodCall(n))
n = any(SetterAssignOperation sao).getMethodCall()
}
}
}

View File

@@ -33,12 +33,12 @@ calls/calls.rb:
# 315| getStmt: [LocalVariableAccess] __synth__0
# 318| [AssignAddExpr] ... += ...
# 318| getDesugared: [StmtSequence] ...
# 318| getStmt: [SetterMethodCall] call to count=
# 318| getReceiver: [LocalVariableAccess] __synth__0
# 318| getArgument: [LocalVariableAccess] __synth__1
# 318| getStmt: [AssignExpr] ... = ...
# 318| getAnOperand/getRightOperand: [Self] self
# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 318| getStmt: [SetterMethodCall] call to count=
# 318| getReceiver: [LocalVariableAccess] __synth__0
# 318| getArgument: [LocalVariableAccess] __synth__1
# 318| getStmt: [AssignExpr] ... = ...
# 318| getAnOperand/getRightOperand: [AddExpr] ... + ...
# 318| getAnOperand/getLeftOperand: [MethodCall] call to count
@@ -48,14 +48,14 @@ calls/calls.rb:
# 318| getStmt: [LocalVariableAccess] __synth__1
# 319| [AssignAddExpr] ... += ...
# 319| getDesugared: [StmtSequence] ...
# 319| getStmt: [SetterMethodCall] call to []=
# 319| getReceiver: [LocalVariableAccess] __synth__0
# 319| getArgument: [LocalVariableAccess] __synth__1
# 319| getArgument: [LocalVariableAccess] __synth__2
# 319| getStmt: [AssignExpr] ... = ...
# 319| getAnOperand/getRightOperand: [MethodCall] call to foo
# 319| getReceiver: [Self] self
# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 319| getStmt: [SetterMethodCall] call to []=
# 319| getReceiver: [LocalVariableAccess] __synth__0
# 319| getArgument: [LocalVariableAccess] __synth__1
# 319| getArgument: [LocalVariableAccess] __synth__2
# 319| getStmt: [AssignExpr] ... = ...
# 319| getAnOperand/getRightOperand: [IntegerLiteral] 0
# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1
@@ -69,6 +69,11 @@ calls/calls.rb:
# 319| getStmt: [LocalVariableAccess] __synth__2
# 320| [AssignMulExpr] ... *= ...
# 320| getDesugared: [StmtSequence] ...
# 320| getStmt: [AssignExpr] ... = ...
# 320| getAnOperand/getRightOperand: [MethodCall] call to bar
# 320| getReceiver: [MethodCall] call to foo
# 320| getReceiver: [Self] self
# 320| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 320| getStmt: [SetterMethodCall] call to []=
# 320| getReceiver: [LocalVariableAccess] __synth__0
# 320| getArgument: [LocalVariableAccess] __synth__1
@@ -76,11 +81,6 @@ calls/calls.rb:
# 320| getArgument: [LocalVariableAccess] __synth__3
# 320| getArgument: [LocalVariableAccess] __synth__4
# 320| getStmt: [AssignExpr] ... = ...
# 320| getAnOperand/getRightOperand: [MethodCall] call to bar
# 320| getReceiver: [MethodCall] call to foo
# 320| getReceiver: [Self] self
# 320| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0
# 320| getStmt: [AssignExpr] ... = ...
# 320| getAnOperand/getRightOperand: [IntegerLiteral] 0
# 320| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1
# 320| getStmt: [AssignExpr] ... = ...

View File

@@ -2214,18 +2214,18 @@ desugar.rb:
# 14| ...
#-----| -> exit m4 (normal)
# 14| call to count=
#-----| -> __synth__1
# 14| ... = ...
#-----| -> __synth__1
# 14| __synth__0
# 14| call to count=
#-----| -> __synth__1
# 14| __synth__0
#-----| -> x
# 14| __synth__0
#-----| -> __synth__1
# 14| call to count
#-----| -> 1
@@ -2242,10 +2242,10 @@ desugar.rb:
#-----| -> ... = ...
# 14| __synth__1
#-----| -> call to count=
#-----| -> __synth__0
# 14| __synth__1
#-----| -> __synth__0
#-----| -> call to count=
# 14| 1
#-----| -> ... + ...
@@ -2276,18 +2276,18 @@ desugar.rb:
# 18| ...
#-----| -> exit m5 (normal)
# 18| call to []=
#-----| -> __synth__4
# 18| ... = ...
#-----| -> __synth__1
# 18| __synth__0
#-----| -> __synth__1
# 18| call to []=
#-----| -> __synth__4
# 18| __synth__0
#-----| -> x
# 18| __synth__0
#-----| -> __synth__1
# 18| call to []
#-----| -> 1
@@ -2301,10 +2301,10 @@ desugar.rb:
#-----| -> __synth__2
# 18| __synth__1
#-----| -> __synth__2
#-----| -> 0
# 18| __synth__1
#-----| -> 0
#-----| -> __synth__2
# 18| __synth__1
#-----| -> __synth__2
@@ -2319,10 +2319,10 @@ desugar.rb:
#-----| -> __synth__3
# 18| __synth__2
#-----| -> __synth__3
#-----| -> y
# 18| __synth__2
#-----| -> y
#-----| -> __synth__3
# 18| __synth__2
#-----| -> __synth__3
@@ -2340,10 +2340,10 @@ desugar.rb:
#-----| -> __synth__4
# 18| __synth__3
#-----| -> __synth__4
#-----| -> x
# 18| __synth__3
#-----| -> x
#-----| -> __synth__4
# 18| __synth__3
#-----| -> call to []
@@ -2361,10 +2361,10 @@ desugar.rb:
#-----| -> ... = ...
# 18| __synth__4
#-----| -> call to []=
#-----| -> __synth__0
# 18| __synth__4
#-----| -> __synth__0
#-----| -> call to []=
# 18| 1
#-----| -> ... + ...