Skip to content

Commit 3ffef63

Browse files
committed
More synthesis refactoring
- Join `TElementReferenceSynth` and `TMethodCallSynth`. - Move arity and setter information into `MethodCallKind`. - Add `Synthesis::methodCall` for specifying which method calls need synthesis.
1 parent e8841e6 commit 3ffef63

8 files changed

Lines changed: 142 additions & 202 deletions

File tree

ql/src/codeql_ruby/ast/Call.qll

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class MethodCall extends Call, TMethodCall {
8282
*
8383
* the result is `"bar"`.
8484
*/
85-
string getMethodName() { none() }
85+
final string getMethodName() { result = this.(MethodCallImpl).getMethodNameImpl() }
8686

8787
/**
8888
* Gets the block of this method call, if any.
@@ -111,13 +111,7 @@ class MethodCall extends Call, TMethodCall {
111111
* ```
112112
*/
113113
class SetterMethodCall extends MethodCall {
114-
SetterMethodCall() {
115-
this instanceof LhsExpr
116-
or
117-
this = any(Assignment a).getDesugared()
118-
or
119-
this = any(Assignment a).getDesugared().(StmtSequence).getAStmt()
120-
}
114+
SetterMethodCall() { this = TMethodCallSynth(_, _, _, true, _) }
121115

122116
final override string getAPrimaryQlClass() { result = "SetterMethodCall" }
123117
}
@@ -131,8 +125,6 @@ class SetterMethodCall extends MethodCall {
131125
class ElementReference extends MethodCall, TElementReference {
132126
final override string getAPrimaryQlClass() { result = "ElementReference" }
133127

134-
final override string getMethodName() { result = getMethodName(this, "[]") }
135-
136128
final override string toString() { result = "...[...]" }
137129
}
138130

ql/src/codeql_ruby/ast/internal/AST.qll

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,7 @@ private module Cached {
115115
TDivExprSynth(AST::AstNode parent, int i) { mkSynthChild(DivExprKind(), parent, i) } or
116116
TDo(Generated::Do g) or
117117
TDoBlock(Generated::DoBlock g) { not g.getParent() instanceof Generated::Lambda } or
118-
TElementReferenceReal(Generated::ElementReference g) or
119-
TElementReferenceSynth(AST::AstNode parent, int i) {
120-
mkSynthChild(ElementReferenceKind(), parent, i)
121-
} or
118+
TElementReference(Generated::ElementReference g) or
122119
TElse(Generated::Else g) or
123120
TElsif(Generated::Elsif g) or
124121
TEmptyStmt(Generated::EmptyStatement g) or
@@ -183,8 +180,8 @@ private module Cached {
183180
} or
184181
TLogicalOrExprSynth(AST::AstNode parent, int i) { mkSynthChild(LogicalOrExprKind(), parent, i) } or
185182
TMethod(Generated::Method g) or
186-
TMethodCallSynth(AST::AstNode parent, int i, string name) {
187-
mkSynthChild(MethodCallKind(name), parent, i)
183+
TMethodCallSynth(AST::AstNode parent, int i, string name, boolean setter, int arity) {
184+
mkSynthChild(MethodCallKind(name, setter, arity), parent, i)
188185
} or
189186
TModuleDeclaration(Generated::Module g) or
190187
TModuloExprReal(Generated::Binary g) { g instanceof @binary_percent } or
@@ -323,7 +320,7 @@ private module Cached {
323320
n = TDivExprReal(result) or
324321
n = TDo(result) or
325322
n = TDoBlock(result) or
326-
n = TElementReferenceReal(result) or
323+
n = TElementReference(result) or
327324
n = TElse(result) or
328325
n = TElsif(result) or
329326
n = TEmptyStmt(result) or
@@ -439,8 +436,6 @@ private module Cached {
439436
or
440437
result = TDivExprSynth(parent, i)
441438
or
442-
result = TElementReferenceSynth(parent, i)
443-
or
444439
result = TExponentExprSynth(parent, i)
445440
or
446441
result = TGlobalVariableAccessSynth(parent, i, _)
@@ -457,7 +452,7 @@ private module Cached {
457452
or
458453
result = TLogicalOrExprSynth(parent, i)
459454
or
460-
result = TMethodCallSynth(parent, i, _)
455+
result = TMethodCallSynth(parent, i, _, _, _)
461456
or
462457
result = TModuloExprSynth(parent, i)
463458
or
@@ -524,8 +519,6 @@ class TMethodCall =
524519
TMethodCallSynth or TIdentifierMethodCall or TScopeResolutionMethodCall or TRegularMethodCall or
525520
TElementReference or TSuperCall;
526521

527-
class TElementReference = TElementReferenceReal or TElementReferenceSynth;
528-
529522
class TSuperCall = TTokenSuperCall or TRegularSuperCall;
530523

531524
class TConstantAccess = TTokenConstantAccess or TScopeResolutionConstantAccess or TNamespace;

ql/src/codeql_ruby/ast/internal/Call.qll

Lines changed: 31 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,11 @@ predicate isIdentifierMethodCall(Generated::Identifier g) { vcall(g) and not acc
77

88
predicate isRegularMethodCall(Generated::Call g) { not g.getMethod() instanceof Generated::Super }
99

10-
string regularMethodCallName(Generated::Call g) {
11-
isRegularMethodCall(g) and
12-
(
13-
result = "call" and g.getMethod() instanceof Generated::ArgumentList
14-
or
15-
result = g.getMethod().(Generated::Token).getValue()
16-
or
17-
result = g.getMethod().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
18-
)
19-
}
20-
2110
predicate isScopeResolutionMethodCall(Generated::ScopeResolution g, Generated::Identifier i) {
2211
i = g.getName() and
2312
not exists(Generated::Call c | c.getMethod() = g)
2413
}
2514

26-
string methodCallName(MethodCall mc) {
27-
exists(Generated::AstNode g | g = toGenerated(mc) |
28-
isIdentifierMethodCall(g) and result = g.(Generated::Identifier).getValue()
29-
or
30-
result = regularMethodCallName(g)
31-
or
32-
isScopeResolutionMethodCall(g, any(Generated::Identifier i | result = i.getValue()))
33-
)
34-
}
35-
36-
bindingset[s]
37-
string getMethodName(MethodCall mc, string s) {
38-
if mc instanceof SetterMethodCall then result = s + "=" else result = s
39-
}
40-
4115
abstract class CallImpl extends Call {
4216
abstract Expr getArgumentImpl(int n);
4317

@@ -55,44 +29,32 @@ abstract class CallImpl extends Call {
5529

5630
abstract class MethodCallImpl extends CallImpl, MethodCall {
5731
abstract Expr getReceiverImpl();
58-
}
5932

60-
/**
61-
* Gets the special integer literal used to specify the number of arguments
62-
* in a synthesized call.
63-
*/
64-
private TIntegerLiteralSynth getNumberOfArgumentsSynth(MethodCall mc, int value) {
65-
result = TIntegerLiteralSynth(mc, -2, value)
33+
abstract string getMethodNameImpl();
6634
}
6735

6836
class MethodCallSynth extends MethodCallImpl, TMethodCallSynth {
69-
final override string getMethodName() {
70-
exists(string name |
71-
this = TMethodCallSynth(_, _, name) and
72-
result = getMethodName(this, name)
37+
final override string getMethodNameImpl() {
38+
exists(boolean setter, string name | this = TMethodCallSynth(_, _, name, setter, _) |
39+
setter = true and result = name + "="
40+
or
41+
setter = false and result = name
7342
)
7443
}
7544

7645
final override Expr getReceiverImpl() { synthChild(this, 0, result) }
7746

7847
final override Expr getArgumentImpl(int n) { synthChild(this, n + 1, result) and n >= 0 }
7948

80-
final override int getNumberOfArgumentsImpl() { exists(getNumberOfArgumentsSynth(this, result)) }
81-
82-
final override AstNode getAChild(string pred) {
83-
result = super.getAChild(pred)
84-
or
85-
pred = "getNumberOfArguments" and
86-
result = getNumberOfArgumentsSynth(this, _)
87-
}
49+
final override int getNumberOfArgumentsImpl() { this = TMethodCallSynth(_, _, _, _, result) }
8850
}
8951

9052
class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall {
9153
private Generated::Identifier g;
9254

9355
IdentifierMethodCall() { this = TIdentifierMethodCall(g) }
9456

95-
final override string getMethodName() { result = getMethodName(this, g.getValue()) }
57+
final override string getMethodNameImpl() { result = g.getValue() }
9658

9759
final override Self getReceiverImpl() { result = TSelfSynth(this, 0) }
9860

@@ -107,7 +69,7 @@ class ScopeResolutionMethodCall extends MethodCallImpl, TScopeResolutionMethodCa
10769

10870
ScopeResolutionMethodCall() { this = TScopeResolutionMethodCall(g, i) }
10971

110-
final override string getMethodName() { result = getMethodName(this, i.getValue()) }
72+
final override string getMethodNameImpl() { result = i.getValue() }
11173

11274
final override Expr getReceiverImpl() { toGenerated(result) = g.getScope() }
11375

@@ -130,7 +92,16 @@ class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
13092
result = TSelfSynth(this, 0)
13193
}
13294

133-
final override string getMethodName() { result = getMethodName(this, regularMethodCallName(g)) }
95+
final override string getMethodNameImpl() {
96+
isRegularMethodCall(g) and
97+
(
98+
result = "call" and g.getMethod() instanceof Generated::ArgumentList
99+
or
100+
result = g.getMethod().(Generated::Token).getValue()
101+
or
102+
result = g.getMethod().(Generated::ScopeResolution).getName().(Generated::Token).getValue()
103+
)
104+
}
134105

135106
final override Expr getArgumentImpl(int n) {
136107
toGenerated(result) = g.getArguments().getChild(n)
@@ -147,49 +118,40 @@ class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
147118
final override Block getBlock() { toGenerated(result) = g.getBlock() }
148119
}
149120

150-
class ElementReferenceReal extends MethodCallImpl, TElementReferenceReal {
121+
class ElementReferenceImpl extends MethodCallImpl, TElementReference {
151122
private Generated::ElementReference g;
152123

153-
ElementReferenceReal() { this = TElementReferenceReal(g) }
124+
ElementReferenceImpl() { this = TElementReference(g) }
154125

155126
final override Expr getReceiverImpl() { toGenerated(result) = g.getObject() }
156127

157128
final override Expr getArgumentImpl(int n) { toGenerated(result) = g.getChild(n) }
158129

159130
final override int getNumberOfArgumentsImpl() { result = count(g.getChild(_)) }
160-
}
161-
162-
class ElementReferenceSynth extends MethodCallImpl, TElementReferenceSynth {
163-
final override Expr getReceiverImpl() { synthChild(this, 0, result) }
164-
165-
final override Expr getArgumentImpl(int n) { synthChild(this, n + 1, result) and n >= 0 }
166-
167-
final override int getNumberOfArgumentsImpl() { exists(getNumberOfArgumentsSynth(this, result)) }
168131

169-
final override AstNode getAChild(string pred) {
170-
result = super.getAChild(pred)
171-
or
172-
pred = "getNumberOfArguments" and
173-
result = getNumberOfArgumentsSynth(this, _)
174-
}
132+
final override string getMethodNameImpl() { result = "[]" }
175133
}
176134

177-
class TokenSuperCall extends SuperCall, TTokenSuperCall {
135+
class TokenSuperCall extends SuperCall, MethodCallImpl, TTokenSuperCall {
178136
private Generated::Super g;
179137

180138
TokenSuperCall() { this = TTokenSuperCall(g) }
181139

182-
final override string getMethodName() { result = getMethodName(this, g.getValue()) }
140+
final override string getMethodNameImpl() { result = g.getValue() }
141+
142+
final override Expr getReceiverImpl() { none() }
143+
144+
final override Expr getArgumentImpl(int n) { none() }
145+
146+
final override int getNumberOfArgumentsImpl() { result = 0 }
183147
}
184148

185149
class RegularSuperCall extends SuperCall, MethodCallImpl, TRegularSuperCall {
186150
private Generated::Call g;
187151

188152
RegularSuperCall() { this = TRegularSuperCall(g) }
189153

190-
final override string getMethodName() {
191-
result = getMethodName(this, g.getMethod().(Generated::Super).getValue())
192-
}
154+
final override string getMethodNameImpl() { result = g.getMethod().(Generated::Super).getValue() }
193155

194156
final override Expr getReceiverImpl() { none() }
195157

0 commit comments

Comments
 (0)