Skip to content

Commit 5219b1a

Browse files
authored
Merge pull request #310 from github/hvitved/more-instanceof
More uses of `instanceof` in the external/internal AST layer
2 parents 8018c15 + 793368d commit 5219b1a

File tree

7 files changed

+154
-138
lines changed

7 files changed

+154
-138
lines changed

ql/lib/codeql/ruby/ast/Call.qll

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplCommon
88
/**
99
* A call.
1010
*/
11-
class Call extends Expr, TCall {
11+
class Call extends Expr instanceof CallImpl {
1212
override string getAPrimaryQlClass() { result = "Call" }
1313

1414
/**
@@ -23,7 +23,7 @@ class Call extends Expr, TCall {
2323
* yield 0, bar: 1
2424
* ```
2525
*/
26-
final Expr getArgument(int n) { result = this.(CallImpl).getArgumentImpl(n) }
26+
final Expr getArgument(int n) { result = super.getArgumentImpl(n) }
2727

2828
/**
2929
* Gets an argument of this method call.
@@ -49,7 +49,7 @@ class Call extends Expr, TCall {
4949
/**
5050
* Gets the number of arguments of this method call.
5151
*/
52-
final int getNumberOfArguments() { result = this.(CallImpl).getNumberOfArgumentsImpl() }
52+
final int getNumberOfArguments() { result = super.getNumberOfArgumentsImpl() }
5353

5454
/** Gets a potential target of this call, if any. */
5555
final Callable getATarget() {
@@ -59,7 +59,7 @@ class Call extends Expr, TCall {
5959
}
6060

6161
override AstNode getAChild(string pred) {
62-
result = super.getAChild(pred)
62+
result = Expr.super.getAChild(pred)
6363
or
6464
pred = "getArgument" and result = this.getArgument(_)
6565
}
@@ -68,7 +68,7 @@ class Call extends Expr, TCall {
6868
/**
6969
* A method call.
7070
*/
71-
class MethodCall extends Call, TMethodCall {
71+
class MethodCall extends Call instanceof MethodCallImpl {
7272
override string getAPrimaryQlClass() { result = "MethodCall" }
7373

7474
/**
@@ -84,7 +84,7 @@ class MethodCall extends Call, TMethodCall {
8484
* the call to `qux` is the `Expr` for `Baz`; for the call to `corge` there
8585
* is no result.
8686
*/
87-
final Expr getReceiver() { result = this.(MethodCallImpl).getReceiverImpl() }
87+
final Expr getReceiver() { result = super.getReceiverImpl() }
8888

8989
/**
9090
* Gets the name of the method being called. For example, in:
@@ -95,20 +95,20 @@ class MethodCall extends Call, TMethodCall {
9595
*
9696
* the result is `"bar"`.
9797
*/
98-
final string getMethodName() { result = this.(MethodCallImpl).getMethodNameImpl() }
98+
final string getMethodName() { result = super.getMethodNameImpl() }
9999

100100
/**
101101
* Gets the block of this method call, if any.
102102
* ```rb
103103
* foo.each { |x| puts x }
104104
* ```
105105
*/
106-
Block getBlock() { none() }
106+
final Block getBlock() { result = super.getBlockImpl() }
107107

108108
override string toString() { result = "call to " + this.getMethodName() }
109109

110110
override AstNode getAChild(string pred) {
111-
result = super.getAChild(pred)
111+
result = Call.super.getAChild(pred)
112112
or
113113
pred = "getReceiver" and result = this.getReceiver()
114114
or
@@ -135,7 +135,7 @@ class SetterMethodCall extends MethodCall, TMethodCallSynth {
135135
* a[0]
136136
* ```
137137
*/
138-
class ElementReference extends MethodCall, TElementReference {
138+
class ElementReference extends MethodCall instanceof ElementReferenceImpl {
139139
final override string getAPrimaryQlClass() { result = "ElementReference" }
140140

141141
final override string toString() { result = "...[...]" }
@@ -147,11 +147,7 @@ class ElementReference extends MethodCall, TElementReference {
147147
* yield x, y
148148
* ```
149149
*/
150-
class YieldCall extends Call, TYieldCall {
151-
Ruby::Yield g;
152-
153-
YieldCall() { this = TYieldCall(g) }
154-
150+
class YieldCall extends Call instanceof YieldCallImpl {
155151
final override string getAPrimaryQlClass() { result = "YieldCall" }
156152

157153
final override string toString() { result = "yield ..." }
@@ -167,7 +163,7 @@ class YieldCall extends Call, TYieldCall {
167163
* end
168164
* ```
169165
*/
170-
class SuperCall extends MethodCall, TSuperCall {
166+
class SuperCall extends MethodCall instanceof SuperCallImpl {
171167
final override string getAPrimaryQlClass() { result = "SuperCall" }
172168
}
173169

ql/lib/codeql/ruby/ast/Variable.qll

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ private import internal.TreeSitter
77
private import internal.Variable
88

99
/** A variable declared in a scope. */
10-
class Variable extends TVariable {
10+
class Variable instanceof VariableImpl {
1111
/** Gets the name of this variable. */
12-
string getName() { none() }
12+
final string getName() { result = super.getNameImpl() }
1313

1414
/** Holds if the name of this variable is `name`. */
1515
final predicate hasName(string name) { this.getName() = name }
@@ -18,21 +18,23 @@ class Variable extends TVariable {
1818
final string toString() { result = this.getName() }
1919

2020
/** Gets the location of this variable. */
21-
Location getLocation() { none() }
21+
final Location getLocation() { result = super.getLocationImpl() }
2222

2323
/** Gets the scope this variable is declared in. */
24-
Scope getDeclaringScope() { none() }
24+
final Scope getDeclaringScope() {
25+
toGenerated(result) = this.(VariableReal).getDeclaringScopeImpl()
26+
}
2527

2628
/** Gets an access to this variable. */
2729
VariableAccess getAnAccess() { result.getVariable() = this }
2830
}
2931

3032
/** A local variable. */
3133
class LocalVariable extends Variable, TLocalVariable {
32-
override LocalVariableAccess getAnAccess() { none() }
34+
override LocalVariableAccess getAnAccess() { result.getVariable() = this }
3335

3436
/** Gets the access where this local variable is first introduced. */
35-
VariableAccess getDefiningAccess() { none() }
37+
VariableAccess getDefiningAccess() { result = this.(LocalVariableReal).getDefiningAccessImpl() }
3638

3739
/**
3840
* Holds if this variable is captured. For example in
@@ -52,27 +54,27 @@ class LocalVariable extends Variable, TLocalVariable {
5254
}
5355

5456
/** A global variable. */
55-
class GlobalVariable extends VariableReal, TGlobalVariable instanceof GlobalVariable::Range {
57+
class GlobalVariable extends Variable instanceof GlobalVariableImpl {
5658
final override GlobalVariableAccess getAnAccess() { result.getVariable() = this }
5759
}
5860

5961
/** An instance variable. */
60-
class InstanceVariable extends VariableReal, TInstanceVariable instanceof InstanceVariable::Range {
62+
class InstanceVariable extends Variable instanceof InstanceVariableImpl {
6163
/** Holds is this variable is a class instance variable. */
6264
final predicate isClassInstanceVariable() { super.isClassInstanceVariable() }
6365

6466
final override InstanceVariableAccess getAnAccess() { result.getVariable() = this }
6567
}
6668

6769
/** A class variable. */
68-
class ClassVariable extends VariableReal, TClassVariable instanceof ClassVariable::Range {
70+
class ClassVariable extends Variable instanceof ClassVariableImpl {
6971
final override ClassVariableAccess getAnAccess() { result.getVariable() = this }
7072
}
7173

7274
/** An access to a variable. */
73-
class VariableAccess extends Expr, TVariableAccess {
75+
class VariableAccess extends Expr instanceof VariableAccessImpl {
7476
/** Gets the variable this identifier refers to. */
75-
final Variable getVariable() { result = this.(VariableAccessImpl).getVariableImpl() }
77+
final Variable getVariable() { result = super.getVariableImpl() }
7678

7779
/**
7880
* Holds if this access is a write access belonging to the explicit
@@ -106,6 +108,8 @@ class VariableAccess extends Expr, TVariableAccess {
106108
* as is the first access to `e`.
107109
*/
108110
predicate isImplicitWrite() { implicitWriteAccess(toGenerated(this)) }
111+
112+
final override string toString() { result = VariableAccessImpl.super.toString() }
109113
}
110114

111115
/** An access to a variable where the value is updated. */
@@ -122,7 +126,7 @@ class VariableReadAccess extends VariableAccess {
122126
}
123127

124128
/** An access to a local variable. */
125-
class LocalVariableAccess extends VariableAccess, TLocalVariableAccess {
129+
class LocalVariableAccess extends VariableAccess instanceof LocalVariableAccessImpl {
126130
final override string getAPrimaryQlClass() { result = "LocalVariableAccess" }
127131

128132
/**
@@ -150,7 +154,7 @@ class LocalVariableWriteAccess extends LocalVariableAccess, VariableWriteAccess
150154
class LocalVariableReadAccess extends LocalVariableAccess, VariableReadAccess { }
151155

152156
/** An access to a global variable. */
153-
class GlobalVariableAccess extends VariableAccess, TGlobalVariableAccess {
157+
class GlobalVariableAccess extends VariableAccess instanceof GlobalVariableAccessImpl {
154158
final override string getAPrimaryQlClass() { result = "GlobalVariableAccess" }
155159
}
156160

@@ -161,7 +165,7 @@ class GlobalVariableWriteAccess extends GlobalVariableAccess, VariableWriteAcces
161165
class GlobalVariableReadAccess extends GlobalVariableAccess, VariableReadAccess { }
162166

163167
/** An access to an instance variable. */
164-
class InstanceVariableAccess extends VariableAccess, TInstanceVariableAccess {
168+
class InstanceVariableAccess extends VariableAccess instanceof InstanceVariableAccessImpl {
165169
final override string getAPrimaryQlClass() { result = "InstanceVariableAccess" }
166170
}
167171

@@ -172,7 +176,7 @@ class InstanceVariableWriteAccess extends InstanceVariableAccess, VariableWriteA
172176
class InstanceVariableReadAccess extends InstanceVariableAccess, VariableReadAccess { }
173177

174178
/** An access to a class variable. */
175-
class ClassVariableAccess extends VariableAccess, TClassVariableAccess {
179+
class ClassVariableAccess extends VariableAccess instanceof ClassVariableAccessRealImpl {
176180
final override string getAPrimaryQlClass() { result = "ClassVariableAccess" }
177181
}
178182

ql/lib/codeql/ruby/ast/internal/Call.qll

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ predicate isScopeResolutionMethodCall(Ruby::ScopeResolution g, Ruby::Identifier
1212
not exists(Ruby::Call c | c.getMethod() = g)
1313
}
1414

15-
abstract class CallImpl extends Call {
15+
abstract class CallImpl extends Expr, TCall {
1616
abstract AstNode getArgumentImpl(int n);
1717

1818
/**
@@ -27,10 +27,12 @@ abstract class CallImpl extends Call {
2727
abstract int getNumberOfArgumentsImpl();
2828
}
2929

30-
abstract class MethodCallImpl extends CallImpl, MethodCall {
30+
abstract class MethodCallImpl extends CallImpl, TMethodCall {
3131
abstract AstNode getReceiverImpl();
3232

3333
abstract string getMethodNameImpl();
34+
35+
abstract Block getBlockImpl();
3436
}
3537

3638
class MethodCallSynth extends MethodCallImpl, TMethodCallSynth {
@@ -47,6 +49,8 @@ class MethodCallSynth extends MethodCallImpl, TMethodCallSynth {
4749
final override AstNode getArgumentImpl(int n) { synthChild(this, n + 1, result) and n >= 0 }
4850

4951
final override int getNumberOfArgumentsImpl() { this = TMethodCallSynth(_, _, _, _, result) }
52+
53+
final override Block getBlockImpl() { none() }
5054
}
5155

5256
class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall {
@@ -61,6 +65,8 @@ class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall {
6165
final override Expr getArgumentImpl(int n) { none() }
6266

6367
final override int getNumberOfArgumentsImpl() { result = 0 }
68+
69+
final override Block getBlockImpl() { none() }
6470
}
6571

6672
class ScopeResolutionMethodCall extends MethodCallImpl, TScopeResolutionMethodCall {
@@ -76,6 +82,8 @@ class ScopeResolutionMethodCall extends MethodCallImpl, TScopeResolutionMethodCa
7682
final override Expr getArgumentImpl(int n) { none() }
7783

7884
final override int getNumberOfArgumentsImpl() { result = 0 }
85+
86+
final override Block getBlockImpl() { none() }
7987
}
8088

8189
class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
@@ -114,7 +122,7 @@ class RegularMethodCall extends MethodCallImpl, TRegularMethodCall {
114122
count(g.getArguments().getChild(_)) + count(g.getMethod().(Ruby::ArgumentList).getChild(_))
115123
}
116124

117-
final override Block getBlock() { toGenerated(result) = g.getBlock() }
125+
final override Block getBlockImpl() { toGenerated(result) = g.getBlock() }
118126
}
119127

120128
class ElementReferenceImpl extends MethodCallImpl, TElementReference {
@@ -129,9 +137,13 @@ class ElementReferenceImpl extends MethodCallImpl, TElementReference {
129137
final override int getNumberOfArgumentsImpl() { result = count(g.getChild(_)) }
130138

131139
final override string getMethodNameImpl() { result = "[]" }
140+
141+
final override Block getBlockImpl() { none() }
132142
}
133143

134-
class TokenSuperCall extends SuperCall, MethodCallImpl, TTokenSuperCall {
144+
abstract class SuperCallImpl extends MethodCallImpl, TSuperCall { }
145+
146+
class TokenSuperCall extends SuperCallImpl, TTokenSuperCall {
135147
private Ruby::Super g;
136148

137149
TokenSuperCall() { this = TTokenSuperCall(g) }
@@ -143,9 +155,11 @@ class TokenSuperCall extends SuperCall, MethodCallImpl, TTokenSuperCall {
143155
final override Expr getArgumentImpl(int n) { none() }
144156

145157
final override int getNumberOfArgumentsImpl() { result = 0 }
158+
159+
final override Block getBlockImpl() { none() }
146160
}
147161

148-
class RegularSuperCall extends SuperCall, MethodCallImpl, TRegularSuperCall {
162+
class RegularSuperCall extends SuperCallImpl, TRegularSuperCall {
149163
private Ruby::Call g;
150164

151165
RegularSuperCall() { this = TRegularSuperCall(g) }
@@ -158,10 +172,14 @@ class RegularSuperCall extends SuperCall, MethodCallImpl, TRegularSuperCall {
158172

159173
final override int getNumberOfArgumentsImpl() { result = count(g.getArguments().getChild(_)) }
160174

161-
final override Block getBlock() { toGenerated(result) = g.getBlock() }
175+
final override Block getBlockImpl() { toGenerated(result) = g.getBlock() }
162176
}
163177

164-
class YieldCallImpl extends CallImpl, YieldCall {
178+
class YieldCallImpl extends CallImpl, TYieldCall {
179+
Ruby::Yield g;
180+
181+
YieldCallImpl() { this = TYieldCall(g) }
182+
165183
final override Expr getArgumentImpl(int n) { toGenerated(result) = g.getChild().getChild(n) }
166184

167185
final override int getNumberOfArgumentsImpl() { result = count(g.getChild().getChild(_)) }

ql/lib/codeql/ruby/ast/internal/Module.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ private string resolveScopeExpr(ConstantReadAccess c, int priority) {
220220
)
221221
}
222222

223-
pragma[noinline]
223+
pragma[nomagic]
224224
private string resolveScopeExprConstantReadAccess(ConstantReadAccess c, int priority, string name) {
225225
result = resolveScopeExpr(c.getScopeExpr(), priority) and
226226
name = c.getName()

ql/lib/codeql/ruby/ast/internal/Operation.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ abstract class UnaryOperationImpl extends OperationImpl, MethodCallImpl, TUnaryO
2121
final override Expr getArgumentImpl(int n) { none() }
2222

2323
final override int getNumberOfArgumentsImpl() { result = 0 }
24+
25+
final override Block getBlockImpl() { none() }
2426
}
2527

2628
class UnaryOperationGenerated extends UnaryOperationImpl {
@@ -77,6 +79,8 @@ abstract class BinaryOperationImpl extends OperationImpl, MethodCallImpl, TBinar
7779
final override Expr getArgumentImpl(int n) { n = 0 and result = this.getRightOperandImpl() }
7880

7981
final override int getNumberOfArgumentsImpl() { result = 1 }
82+
83+
final override Block getBlockImpl() { none() }
8084
}
8185

8286
class BinaryOperationReal extends BinaryOperationImpl {

0 commit comments

Comments
 (0)