@@ -39,6 +39,8 @@ predicate implicitAssignmentNode(Ruby::AstNode n) {
3939 or
4040 n = any ( Ruby:: HashPattern parent ) .getChild ( _) .( Ruby:: HashSplatParameter ) .getName ( )
4141 or
42+ n = any ( Ruby:: KeywordPattern parent | not exists ( parent .getValue ( ) ) ) .getKey ( )
43+ or
4244 n = any ( Ruby:: ExceptionVariable ev ) .getChild ( )
4345 or
4446 n = any ( Ruby:: For for ) .getPattern ( )
@@ -104,11 +106,23 @@ private predicate scopeDefinesParameterVariable(
104106 )
105107}
106108
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+
107122/** 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 ) {
109124 ( explicitAssignmentNode ( i , _) or implicitAssignmentNode ( i ) ) and
110- name = i .getValue ( ) and
111- scope = scopeOf ( i )
125+ name = variableNameInScope ( i , scope )
112126}
113127
114128cached
@@ -132,11 +146,11 @@ private module Cached {
132146 other order by other .getLocation ( ) .getStartLine ( ) , other .getLocation ( ) .getStartColumn ( )
133147 )
134148 } or
135- TLocalVariableReal ( Scope:: Range scope , string name , Ruby:: Identifier i ) {
149+ TLocalVariableReal ( Scope:: Range scope , string name , Ruby:: AstNode i ) {
136150 scopeDefinesParameterVariable ( scope , name , i )
137151 or
138152 i =
139- min ( Ruby:: Identifier other |
153+ min ( Ruby:: AstNode other |
140154 scopeAssigns ( scope , name , other )
141155 |
142156 other order by other .getLocation ( ) .getStartLine ( ) , other .getLocation ( ) .getStartColumn ( )
@@ -295,13 +309,18 @@ private module Cached {
295309 i = any ( Ruby:: WhileModifier x ) .getBody ( )
296310 }
297311
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+
298318 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 )
303322 |
304- variable . getDeclaringScopeImpl ( ) = scopeOf ( access ) and
323+ hasScopeAndName ( variable , scope , name ) and
305324 not access .getLocation ( ) .strictlyBefore ( variable .getLocationImpl ( ) ) and
306325 // In case of overlapping parameter names, later parameters should not
307326 // be considered accesses to the first parameter
@@ -310,15 +329,15 @@ private module Cached {
310329 else any ( )
311330 or
312331 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 )
315334 )
316335 )
317336 }
318337
319338 private class Access extends Ruby:: Token {
320339 Access ( ) {
321- access ( this , _) or
340+ access ( this . ( Ruby :: Identifier ) , _) or
322341 this instanceof Ruby:: GlobalVariable or
323342 this instanceof Ruby:: InstanceVariable or
324343 this instanceof Ruby:: ClassVariable or
@@ -371,7 +390,7 @@ private predicate inherits(Scope::Range scope, string name, Scope::Range outer)
371390 (
372391 scopeDefinesParameterVariable ( outer , name , _)
373392 or
374- exists ( Ruby:: Identifier i |
393+ exists ( Ruby:: AstNode i |
375394 scopeAssigns ( outer , name , i ) and
376395 i .getLocation ( ) .strictlyBefore ( scope .getLocation ( ) )
377396 )
@@ -420,7 +439,7 @@ private class VariableRealAdapter extends VariableImpl, TVariableReal instanceof
420439class LocalVariableReal extends VariableReal , TLocalVariableReal {
421440 private Scope:: Range scope ;
422441 private string name ;
423- private Ruby:: Identifier i ;
442+ private Ruby:: AstNode i ;
424443
425444 LocalVariableReal ( ) { this = TLocalVariableReal ( scope , name , i ) }
426445
0 commit comments