diff --git a/ql/src/codeql_ruby/ast/internal/Call.qll b/ql/src/codeql_ruby/ast/internal/Call.qll index 1be6cbbff84..14b5cb9aba5 100644 --- a/ql/src/codeql_ruby/ast/internal/Call.qll +++ b/ql/src/codeql_ruby/ast/internal/Call.qll @@ -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() } diff --git a/ql/src/codeql_ruby/ast/internal/Operation.qll b/ql/src/codeql_ruby/ast/internal/Operation.qll index 8891b2a059c..1f0b466c1f9 100644 --- a/ql/src/codeql_ruby/ast/internal/Operation.qll +++ b/ql/src/codeql_ruby/ast/internal/Operation.qll @@ -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() } } diff --git a/ql/src/codeql_ruby/ast/internal/Synthesis.qll b/ql/src/codeql_ruby/ast/internal/Synthesis.qll index 940f30580b2..58d6d183168 100644 --- a/ql/src/codeql_ruby/ast/internal/Synthesis.qll +++ b/ql/src/codeql_ruby/ast/internal/Synthesis.qll @@ -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() } } } diff --git a/ql/test/library-tests/ast/AstDesugar.expected b/ql/test/library-tests/ast/AstDesugar.expected index 1e4f13ced59..9bba4ebe481 100644 --- a/ql/test/library-tests/ast/AstDesugar.expected +++ b/ql/test/library-tests/ast/AstDesugar.expected @@ -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] ... = ... diff --git a/ql/test/library-tests/controlflow/graph/Cfg.expected b/ql/test/library-tests/controlflow/graph/Cfg.expected index 0bc9ee491fb..9d545cd214c 100644 --- a/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -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 #-----| -> ... + ...