@@ -9,6 +9,45 @@ private Generated::AstNode parent(Generated::AstNode n) {
9
9
not n = any ( VariableScope s ) .getScopeElement ( )
10
10
}
11
11
12
+ private predicate instanceVariableAccess (
13
+ Generated:: InstanceVariable var , string name , VariableScope scope , boolean instance
14
+ ) {
15
+ name = var .getValue ( ) and
16
+ scope = enclosingModuleOrClass ( var ) and
17
+ if hasEnclosingMethod ( var ) then instance = true else instance = false
18
+ }
19
+
20
+ private predicate classVariableAccess ( Generated:: ClassVariable var , string name , VariableScope scope ) {
21
+ name = var .getValue ( ) and
22
+ scope = enclosingModuleOrClass ( var )
23
+ }
24
+
25
+ predicate hasEnclosingMethod ( Generated:: AstNode node ) {
26
+ exists ( Callable method | parentCallableScope * ( enclosingScope ( node ) ) = TCallableScope ( method ) |
27
+ method instanceof Method or
28
+ method instanceof SingletonMethod
29
+ )
30
+ }
31
+
32
+ private TCallableScope parentCallableScope ( TCallableScope scope ) {
33
+ exists ( Callable c |
34
+ scope = TCallableScope ( c ) and
35
+ not c instanceof Method and
36
+ not c instanceof SingletonMethod
37
+ |
38
+ result = scope .( VariableScope ) .getOuterScope ( )
39
+ )
40
+ }
41
+
42
+ private VariableScope parentScope ( VariableScope scope ) {
43
+ not scope instanceof ModuleOrClassScope and
44
+ result = scope .getOuterScope ( )
45
+ }
46
+
47
+ private ModuleOrClassScope enclosingModuleOrClass ( Generated:: AstNode node ) {
48
+ result = parentScope * ( enclosingScope ( node ) )
49
+ }
50
+
12
51
private predicate parameterAssignment (
13
52
CallableScope:: Range scope , string name , Generated:: Identifier i
14
53
) {
@@ -20,7 +59,6 @@ private predicate parameterAssignment(
20
59
private predicate scopeDefinesParameterVariable (
21
60
CallableScope:: Range scope , string name , Generated:: Identifier i
22
61
) {
23
- parameterAssignment ( scope , name , i ) and
24
62
// In case of overlapping parameter names (e.g. `_`), only the first
25
63
// parameter will give rise to a variable
26
64
i =
@@ -69,9 +107,6 @@ private class CapturingScope extends VariableScope {
69
107
)
70
108
}
71
109
72
- /** Gets the scope in which this scope is nested, if any. */
73
- private VariableScope getOuterScope ( ) { result = enclosingScope ( this .getScopeElement ( ) ) }
74
-
75
110
/** Holds if this scope inherits `name` from an outer scope `outer`. */
76
111
predicate inherits ( string name , VariableScope outer ) {
77
112
not scopeDefinesParameterVariable ( this , name , _) and
@@ -112,10 +147,25 @@ private module Cached {
112
147
cached
113
148
newtype TVariable =
114
149
TGlobalVariable ( string name ) { name = any ( Generated:: GlobalVariable var ) .getValue ( ) } or
150
+ TClassVariable ( VariableScope scope , string name , Generated:: AstNode decl ) {
151
+ decl =
152
+ min ( Generated:: ClassVariable other |
153
+ classVariableAccess ( other , name , scope )
154
+ |
155
+ other order by other .getLocation ( ) .getStartLine ( ) , other .getLocation ( ) .getStartColumn ( )
156
+ )
157
+ } or
158
+ TInstanceVariable ( VariableScope scope , string name , boolean instance , Generated:: AstNode decl ) {
159
+ decl =
160
+ min ( Generated:: InstanceVariable other |
161
+ instanceVariableAccess ( other , name , scope , instance )
162
+ |
163
+ other order by other .getLocation ( ) .getStartLine ( ) , other .getLocation ( ) .getStartColumn ( )
164
+ )
165
+ } or
115
166
TLocalVariable ( VariableScope scope , string name , Generated:: Identifier i ) {
116
167
scopeDefinesParameterVariable ( scope , name , i )
117
168
or
118
- scopeAssigns ( scope , name , i ) and
119
169
i =
120
170
min ( Generated:: Identifier other |
121
171
scopeAssigns ( scope , name , other )
@@ -307,6 +357,22 @@ private module Cached {
307
357
predicate isCapturedAccess ( LocalVariableAccess:: Range access ) {
308
358
access .getVariable ( ) .getDeclaringScope ( ) != enclosingScope ( access )
309
359
}
360
+
361
+ cached
362
+ predicate instanceVariableAccess ( Generated:: InstanceVariable var , InstanceVariable v ) {
363
+ exists ( string name , VariableScope scope , boolean instance |
364
+ v = TInstanceVariable ( scope , name , instance , _) and
365
+ instanceVariableAccess ( var , name , scope , instance )
366
+ )
367
+ }
368
+
369
+ cached
370
+ predicate classVariableAccess ( Generated:: ClassVariable var , ClassVariable variable ) {
371
+ exists ( VariableScope scope , string name |
372
+ variable = TClassVariable ( scope , name , _) and
373
+ classVariableAccess ( var , name , scope )
374
+ )
375
+ }
310
376
}
311
377
312
378
import Cached
@@ -416,6 +482,43 @@ module GlobalVariable {
416
482
}
417
483
}
418
484
485
+ private class ModuleOrClassScope = TClassScope or TModuleScope or TTopLevelScope ;
486
+
487
+ module InstanceVariable {
488
+ class Range extends Variable:: Range , TInstanceVariable {
489
+ private ModuleOrClassScope scope ;
490
+ private boolean instance ;
491
+ private string name ;
492
+ private Generated:: AstNode decl ;
493
+
494
+ Range ( ) { this = TInstanceVariable ( scope , name , instance , decl ) }
495
+
496
+ final override string getName ( ) { result = name }
497
+
498
+ final predicate isClassInstanceVariable ( ) { instance = false }
499
+
500
+ final override Location getLocation ( ) { result = decl .getLocation ( ) }
501
+
502
+ final override VariableScope getDeclaringScope ( ) { result = scope }
503
+ }
504
+ }
505
+
506
+ module ClassVariable {
507
+ class Range extends Variable:: Range , TClassVariable {
508
+ private ModuleOrClassScope scope ;
509
+ private string name ;
510
+ private Generated:: AstNode decl ;
511
+
512
+ Range ( ) { this = TClassVariable ( scope , name , decl ) }
513
+
514
+ final override string getName ( ) { result = name }
515
+
516
+ final override Location getLocation ( ) { result = decl .getLocation ( ) }
517
+
518
+ final override VariableScope getDeclaringScope ( ) { result = scope }
519
+ }
520
+ }
521
+
419
522
module VariableAccess {
420
523
abstract class Range extends Expr:: Range {
421
524
abstract Variable getVariable ( ) ;
@@ -451,3 +554,23 @@ module GlobalVariableAccess {
451
554
final override GlobalVariable getVariable ( ) { result = variable }
452
555
}
453
556
}
557
+
558
+ module InstanceVariableAccess {
559
+ class Range extends VariableAccess:: Range , @token_instance_variable {
560
+ InstanceVariable variable ;
561
+
562
+ Range ( ) { instanceVariableAccess ( this , variable ) }
563
+
564
+ final override InstanceVariable getVariable ( ) { result = variable }
565
+ }
566
+ }
567
+
568
+ module ClassVariableAccess {
569
+ class Range extends VariableAccess:: Range , @token_class_variable {
570
+ ClassVariable variable ;
571
+
572
+ Range ( ) { classVariableAccess ( this , variable ) }
573
+
574
+ final override ClassVariable getVariable ( ) { result = variable }
575
+ }
576
+ }
0 commit comments