Skip to content

Commit 5bafc0c

Browse files
authored
Merge pull request #183 from github/hvitved/assign-op-desugar
Desugar setter assignments
2 parents af6f050 + 3ffef63 commit 5bafc0c

24 files changed

Lines changed: 1149 additions & 534 deletions

ql/src/codeql_ruby/AST.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class AstNode extends TAstNode {
5151
string toString() { none() }
5252

5353
/** Gets the location of this node. */
54-
Location getLocation() { result = toGeneratedInclSynth(this).getLocation() }
54+
Location getLocation() { result = getLocation(this) }
5555

5656
/** Gets a child node of this `AstNode`. */
5757
final AstNode getAChild() { result = this.getAChild(_) }

ql/src/codeql_ruby/ast/Call.qll

Lines changed: 12 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
private import codeql_ruby.AST
22
private import internal.AST
3+
private import internal.Call
34
private import internal.TreeSitter
45

56
/**
@@ -20,7 +21,7 @@ class Call extends Expr, TCall {
2021
* yield 0, bar: 1
2122
* ```
2223
*/
23-
Expr getArgument(int n) { none() }
24+
final Expr getArgument(int n) { result = this.(CallImpl).getArgumentImpl(n) }
2425

2526
/**
2627
* Gets an argument of this method call.
@@ -46,24 +47,11 @@ class Call extends Expr, TCall {
4647
/**
4748
* Gets the number of arguments of this method call.
4849
*/
49-
final int getNumberOfArguments() { result = count(this.getAnArgument()) }
50+
final int getNumberOfArguments() { result = this.(CallImpl).getNumberOfArgumentsImpl() }
5051

5152
override AstNode getAChild(string pred) { pred = "getArgument" and result = this.getArgument(_) }
5253
}
5354

54-
bindingset[s]
55-
private string getMethodName(MethodCall mc, string s) {
56-
(
57-
not mc instanceof LhsExpr
58-
or
59-
mc.getParent() instanceof AssignOperation
60-
) and
61-
result = s
62-
or
63-
mc instanceof LhsExpr and
64-
result = s + "="
65-
}
66-
6755
/**
6856
* A method call.
6957
*/
@@ -83,22 +71,7 @@ class MethodCall extends Call, TMethodCall {
8371
* the call to `qux` is the `Expr` for `Baz`; for the call to `corge` there
8472
* is no result.
8573
*/
86-
Expr getReceiver() { none() }
87-
88-
/**
89-
* Holds if the receiver is `self` or there is no receiver, which has the same
90-
* meaning as an explict `self`. For example:
91-
*
92-
* ```rb
93-
* self.foo
94-
* foo
95-
* ```
96-
*/
97-
predicate receiverIsSelf() {
98-
this.getReceiver() instanceof Self
99-
or
100-
not exists(this.getReceiver())
101-
}
74+
final Expr getReceiver() { result = this.(MethodCallImpl).getReceiverImpl() }
10275

10376
/**
10477
* Gets the name of the method being called. For example, in:
@@ -109,7 +82,7 @@ class MethodCall extends Call, TMethodCall {
10982
*
11083
* the result is `"bar"`.
11184
*/
112-
string getMethodName() { none() }
85+
final string getMethodName() { result = this.(MethodCallImpl).getMethodNameImpl() }
11386

11487
/**
11588
* Gets the block of this method call, if any.
@@ -119,79 +92,27 @@ class MethodCall extends Call, TMethodCall {
11992
*/
12093
Block getBlock() { none() }
12194

122-
override string toString() { result = "call to " + concat(this.getMethodName(), "/") }
95+
override string toString() { result = "call to " + this.getMethodName() }
12396

124-
final override AstNode getAChild(string pred) {
125-
result = Call.super.getAChild(pred)
97+
override AstNode getAChild(string pred) {
98+
result = super.getAChild(pred)
12699
or
127100
pred = "getReceiver" and result = this.getReceiver()
128101
or
129102
pred = "getBlock" and result = this.getBlock()
130103
}
131104
}
132105

133-
private class IdentifierMethodCall extends MethodCall, TIdentifierMethodCall {
134-
private Generated::Identifier g;
135-
136-
IdentifierMethodCall() { this = TIdentifierMethodCall(g) }
137-
138-
final override string getMethodName() { result = getMethodName(this, g.getValue()) }
139-
140-
final override Self getReceiver() { result = TSelfSynth(this, 0) }
141-
}
142-
143-
private class ScopeResolutionMethodCall extends MethodCall, TScopeResolutionMethodCall {
144-
private Generated::ScopeResolution g;
145-
private Generated::Identifier i;
146-
147-
ScopeResolutionMethodCall() { this = TScopeResolutionMethodCall(g, i) }
148-
149-
final override Expr getReceiver() { toGenerated(result) = g.getScope() }
150-
151-
final override string getMethodName() { result = getMethodName(this, i.getValue()) }
152-
}
153-
154-
private class RegularMethodCall extends MethodCall, TRegularMethodCall {
155-
private Generated::Call g;
156-
157-
RegularMethodCall() { this = TRegularMethodCall(g) }
158-
159-
final override Expr getReceiver() {
160-
toGenerated(result) = g.getReceiver()
161-
or
162-
not exists(g.getReceiver()) and
163-
toGenerated(result) = g.getMethod().(Generated::ScopeResolution).getScope()
164-
or
165-
result = TSelfSynth(this, 0)
166-
}
167-
168-
final override string getMethodName() {
169-
exists(string res | result = getMethodName(this, res) |
170-
res = "call" and g.getMethod() instanceof Generated::ArgumentList
171-
or
172-
res = g.getMethod().(Generated::Token).getValue()
173-
or
174-
res = g.getMethod().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
175-
)
176-
}
177-
178-
final override Expr getArgument(int n) {
179-
toGenerated(result) = g.getArguments().getChild(n)
180-
or
181-
toGenerated(result) = g.getMethod().(Generated::ArgumentList).getChild(n)
182-
}
183-
184-
final override Block getBlock() { toGenerated(result) = g.getBlock() }
185-
}
186-
187106
/**
188107
* A call to a setter method.
189108
* ```rb
190109
* self.foo = 10
191110
* a[0] = 10
192111
* ```
193112
*/
194-
class SetterMethodCall extends MethodCall, LhsExpr {
113+
class SetterMethodCall extends MethodCall {
114+
SetterMethodCall() { this = TMethodCallSynth(_, _, _, true, _) }
115+
195116
final override string getAPrimaryQlClass() { result = "SetterMethodCall" }
196117
}
197118

@@ -202,18 +123,8 @@ class SetterMethodCall extends MethodCall, LhsExpr {
202123
* ```
203124
*/
204125
class ElementReference extends MethodCall, TElementReference {
205-
private Generated::ElementReference g;
206-
207-
ElementReference() { this = TElementReference(g) }
208-
209126
final override string getAPrimaryQlClass() { result = "ElementReference" }
210127

211-
final override Expr getReceiver() { toGenerated(result) = g.getObject() }
212-
213-
final override string getMethodName() { result = getMethodName(this, "[]") }
214-
215-
final override Expr getArgument(int n) { toGenerated(result) = g.getChild(n) }
216-
217128
final override string toString() { result = "...[...]" }
218129
}
219130

@@ -224,14 +135,12 @@ class ElementReference extends MethodCall, TElementReference {
224135
* ```
225136
*/
226137
class YieldCall extends Call, TYieldCall {
227-
private Generated::Yield g;
138+
Generated::Yield g;
228139

229140
YieldCall() { this = TYieldCall(g) }
230141

231142
final override string getAPrimaryQlClass() { result = "YieldCall" }
232143

233-
final override Expr getArgument(int n) { toGenerated(result) = g.getChild().getChild(n) }
234-
235144
final override string toString() { result = "yield ..." }
236145
}
237146

@@ -249,28 +158,6 @@ class SuperCall extends MethodCall, TSuperCall {
249158
final override string getAPrimaryQlClass() { result = "SuperCall" }
250159
}
251160

252-
private class TokenSuperCall extends SuperCall, TTokenSuperCall {
253-
private Generated::Super g;
254-
255-
TokenSuperCall() { this = TTokenSuperCall(g) }
256-
257-
final override string getMethodName() { result = getMethodName(this, g.getValue()) }
258-
}
259-
260-
private class RegularSuperCall extends SuperCall, TRegularSuperCall {
261-
private Generated::Call g;
262-
263-
RegularSuperCall() { this = TRegularSuperCall(g) }
264-
265-
final override string getMethodName() {
266-
result = getMethodName(this, g.getMethod().(Generated::Super).getValue())
267-
}
268-
269-
final override Expr getArgument(int n) { toGenerated(result) = g.getArguments().getChild(n) }
270-
271-
final override Block getBlock() { toGenerated(result) = g.getBlock() }
272-
}
273-
274161
/**
275162
* A block argument in a method call.
276163
* ```rb

ql/src/codeql_ruby/ast/Literal.qll

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,22 @@ class NumericLiteral extends Literal, TNumericLiteral { }
4242
* ```
4343
*/
4444
class IntegerLiteral extends NumericLiteral, TIntegerLiteral {
45+
/** Gets the numerical value of this integer literal. */
46+
int getValue() { none() }
47+
48+
final override string toString() { result = this.getValueText() }
49+
50+
final override string getAPrimaryQlClass() { result = "IntegerLiteral" }
51+
}
52+
53+
private class IntegerLiteralReal extends IntegerLiteral, TIntegerLiteralReal {
4554
private Generated::Integer g;
4655

47-
IntegerLiteral() { this = TIntegerLiteral(g) }
56+
IntegerLiteralReal() { this = TIntegerLiteralReal(g) }
4857

4958
final override string getValueText() { result = g.getValue() }
5059

51-
/** Gets the numerical value of this integer literal. */
52-
final int getValue() {
60+
final override int getValue() {
5361
exists(string s, string values, string str |
5462
s = this.getValueText().toLowerCase() and
5563
(
@@ -83,10 +91,16 @@ class IntegerLiteral extends NumericLiteral, TIntegerLiteral {
8391
)
8492
)
8593
}
94+
}
8695

87-
final override string toString() { result = this.getValueText() }
96+
private class IntegerLiteralSynth extends IntegerLiteral, TIntegerLiteralSynth {
97+
private int value;
8898

89-
final override string getAPrimaryQlClass() { result = "IntegerLiteral" }
99+
IntegerLiteralSynth() { this = TIntegerLiteralSynth(_, _, value) }
100+
101+
final override string getValueText() { result = value.toString() }
102+
103+
final override int getValue() { result = value }
90104
}
91105

92106
/**

ql/src/codeql_ruby/ast/Operation.qll

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
private import codeql_ruby.AST
22
private import internal.AST
33
private import internal.TreeSitter
4+
private import internal.Operation
45

56
/**
67
* An operation.
@@ -492,10 +493,10 @@ class NoRegexMatchExpr extends BinaryOperation, TNoRegexMatchExpr {
492493
*/
493494
class Assignment extends Operation, TAssignment {
494495
/** Gets the left hand side of this assignment. */
495-
Pattern getLeftOperand() { none() }
496+
final Pattern getLeftOperand() { result = this.(AssignmentImpl).getLeftOperandImpl() }
496497

497498
/** Gets the right hand side of this assignment. */
498-
Expr getRightOperand() { none() }
499+
final Expr getRightOperand() { result = this.(AssignmentImpl).getRightOperandImpl() }
499500

500501
final override Expr getAnOperand() {
501502
result = this.getLeftOperand() or result = this.getRightOperand()
@@ -524,35 +525,15 @@ class AssignExpr extends Assignment, TAssignExpr {
524525
final override string getAPrimaryQlClass() { result = "AssignExpr" }
525526
}
526527

527-
private class AssignExprReal extends AssignExpr, TAssignExprReal {
528-
private Generated::Assignment g;
529-
530-
AssignExprReal() { this = TAssignExprReal(g) }
531-
532-
final override Pattern getLeftOperand() { toGenerated(result) = g.getLeft() }
533-
534-
final override Expr getRightOperand() { toGenerated(result) = g.getRight() }
535-
}
536-
537-
private class AssignExprSynth extends AssignExpr, TAssignExprSynth {
538-
final override Pattern getLeftOperand() { synthChild(this, 0, result) }
539-
540-
final override Expr getRightOperand() { synthChild(this, 1, result) }
541-
}
542-
543528
/**
544529
* A binary assignment operation other than `=`.
545530
*/
546531
class AssignOperation extends Assignment, TAssignOperation {
547-
private Generated::OperatorAssignment g;
532+
Generated::OperatorAssignment g;
548533

549534
AssignOperation() { g = toGenerated(this) }
550535

551536
final override string getOperator() { result = g.getOperator() }
552-
553-
final override LhsExpr getLeftOperand() { toGenerated(result) = g.getLeft() }
554-
555-
final override Expr getRightOperand() { toGenerated(result) = g.getRight() }
556537
}
557538

558539
/**

ql/src/codeql_ruby/ast/Variable.qll

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class ClassVariable extends VariableReal, TClassVariable {
7575
/** An access to a variable. */
7676
class VariableAccess extends Expr, TVariableAccess {
7777
/** Gets the variable this identifier refers to. */
78-
Variable getVariable() { none() }
78+
final Variable getVariable() { result = this.(VariableAccessImpl).getVariableImpl() }
7979

8080
/**
8181
* Holds if this access is a write access belonging to the explicit
@@ -126,8 +126,6 @@ class VariableReadAccess extends VariableAccess {
126126

127127
/** An access to a local variable. */
128128
class LocalVariableAccess extends VariableAccess, TLocalVariableAccess {
129-
override LocalVariable getVariable() { none() }
130-
131129
final override string getAPrimaryQlClass() { result = "LocalVariableAccess" }
132130

133131
/**
@@ -156,8 +154,6 @@ class LocalVariableReadAccess extends LocalVariableAccess, VariableReadAccess {
156154

157155
/** An access to a global variable. */
158156
class GlobalVariableAccess extends VariableAccess, TGlobalVariableAccess {
159-
override GlobalVariable getVariable() { none() }
160-
161157
final override string getAPrimaryQlClass() { result = "GlobalVariableAccess" }
162158
}
163159

@@ -169,14 +165,10 @@ class GlobalVariableReadAccess extends GlobalVariableAccess, VariableReadAccess
169165

170166
/** An access to an instance variable. */
171167
class InstanceVariableAccess extends VariableAccess, TInstanceVariableAccess {
172-
override InstanceVariable getVariable() { none() }
173-
174168
final override string getAPrimaryQlClass() { result = "InstanceVariableAccess" }
175169
}
176170

177171
/** An access to a class variable. */
178172
class ClassVariableAccess extends VariableAccess, TClassVariableAccess {
179-
override ClassVariable getVariable() { none() }
180-
181173
final override string getAPrimaryQlClass() { result = "ClassVariableAccess" }
182174
}

0 commit comments

Comments
 (0)