@@ -39,6 +39,8 @@ predicate implicitAssignmentNode(Ruby::AstNode n) {
39
39
or
40
40
n = any ( Ruby:: HashPattern parent ) .getChild ( _) .( Ruby:: HashSplatParameter ) .getName ( )
41
41
or
42
+ n = any ( Ruby:: KeywordPattern parent | not exists ( parent .getValue ( ) ) ) .getKey ( )
43
+ or
42
44
n = any ( Ruby:: ExceptionVariable ev ) .getChild ( )
43
45
or
44
46
n = any ( Ruby:: For for ) .getPattern ( )
@@ -104,11 +106,23 @@ private predicate scopeDefinesParameterVariable(
104
106
)
105
107
}
106
108
109
+ pragma [ nomagic]
110
+ private string variableNameInScope ( Ruby:: AstNode i , Scope:: Range scope ) {
111
+ scope = scopeOf ( i ) and
112
+ (
113
+ result = i .( Ruby:: Identifier ) .getValue ( )
114
+ or
115
+ exists ( Ruby:: KeywordPattern p | i = p .getKey ( ) and not exists ( p .getValue ( ) ) |
116
+ result = i .( Ruby:: String ) .getChild ( 0 ) .( Ruby:: StringContent ) .getValue ( ) or
117
+ result = i .( Ruby:: HashKeySymbol ) .getValue ( )
118
+ )
119
+ )
120
+ }
121
+
107
122
/** Holds if `name` is assigned in `scope` at `i`. */
108
- private predicate scopeAssigns ( Scope:: Range scope , string name , Ruby:: Identifier i ) {
123
+ private predicate scopeAssigns ( Scope:: Range scope , string name , Ruby:: AstNode i ) {
109
124
( explicitAssignmentNode ( i , _) or implicitAssignmentNode ( i ) ) and
110
- name = i .getValue ( ) and
111
- scope = scopeOf ( i )
125
+ name = variableNameInScope ( i , scope )
112
126
}
113
127
114
128
cached
@@ -132,11 +146,11 @@ private module Cached {
132
146
other order by other .getLocation ( ) .getStartLine ( ) , other .getLocation ( ) .getStartColumn ( )
133
147
)
134
148
} or
135
- TLocalVariableReal ( Scope:: Range scope , string name , Ruby:: Identifier i ) {
149
+ TLocalVariableReal ( Scope:: Range scope , string name , Ruby:: AstNode i ) {
136
150
scopeDefinesParameterVariable ( scope , name , i )
137
151
or
138
152
i =
139
- min ( Ruby:: Identifier other |
153
+ min ( Ruby:: AstNode other |
140
154
scopeAssigns ( scope , name , other )
141
155
|
142
156
other order by other .getLocation ( ) .getStartLine ( ) , other .getLocation ( ) .getStartColumn ( )
@@ -295,13 +309,18 @@ private module Cached {
295
309
i = any ( Ruby:: WhileModifier x ) .getBody ( )
296
310
}
297
311
312
+ pragma [ nomagic]
313
+ private predicate hasScopeAndName ( VariableReal variable , Scope:: Range scope , string name ) {
314
+ variable .getNameImpl ( ) = name and
315
+ scope = variable .getDeclaringScopeImpl ( )
316
+ }
317
+
298
318
cached
299
- predicate access ( Ruby:: Identifier access , VariableReal variable ) {
300
- exists ( string name |
301
- variable .getNameImpl ( ) = name and
302
- name = access .getValue ( )
319
+ predicate access ( Ruby:: AstNode access , VariableReal variable ) {
320
+ exists ( string name , Scope:: Range scope |
321
+ pragma [ only_bind_into ] ( name ) = variableNameInScope ( access , scope )
303
322
|
304
- variable . getDeclaringScopeImpl ( ) = scopeOf ( access ) and
323
+ hasScopeAndName ( variable , scope , name ) and
305
324
not access .getLocation ( ) .strictlyBefore ( variable .getLocationImpl ( ) ) and
306
325
// In case of overlapping parameter names, later parameters should not
307
326
// be considered accesses to the first parameter
@@ -310,15 +329,15 @@ private module Cached {
310
329
else any ( )
311
330
or
312
331
exists ( Scope:: Range declScope |
313
- variable . getDeclaringScopeImpl ( ) = declScope and
314
- inherits ( scopeOf ( access ) , name , declScope )
332
+ hasScopeAndName ( variable , declScope , pragma [ only_bind_into ] ( name ) ) and
333
+ inherits ( scope , name , declScope )
315
334
)
316
335
)
317
336
}
318
337
319
338
private class Access extends Ruby:: Token {
320
339
Access ( ) {
321
- access ( this , _) or
340
+ access ( this . ( Ruby :: Identifier ) , _) or
322
341
this instanceof Ruby:: GlobalVariable or
323
342
this instanceof Ruby:: InstanceVariable or
324
343
this instanceof Ruby:: ClassVariable or
@@ -371,7 +390,7 @@ private predicate inherits(Scope::Range scope, string name, Scope::Range outer)
371
390
(
372
391
scopeDefinesParameterVariable ( outer , name , _)
373
392
or
374
- exists ( Ruby:: Identifier i |
393
+ exists ( Ruby:: AstNode i |
375
394
scopeAssigns ( outer , name , i ) and
376
395
i .getLocation ( ) .strictlyBefore ( scope .getLocation ( ) )
377
396
)
@@ -420,7 +439,7 @@ private class VariableRealAdapter extends VariableImpl, TVariableReal instanceof
420
439
class LocalVariableReal extends VariableReal , TLocalVariableReal {
421
440
private Scope:: Range scope ;
422
441
private string name ;
423
- private Ruby:: Identifier i ;
442
+ private Ruby:: AstNode i ;
424
443
425
444
LocalVariableReal ( ) { this = TLocalVariableReal ( scope , name , i ) }
426
445
0 commit comments