@@ -950,6 +950,40 @@ private module DestructuredAssignDesugar {
950950 }
951951 }
952952
953+ abstract private class LhsWithReceiver extends Expr {
954+ abstract Expr getReceiver ( ) ;
955+
956+ abstract SynthKind getSynthKind ( ) ;
957+ }
958+
959+ private class LhsCall extends LhsWithReceiver instanceof MethodCall {
960+ final override Expr getReceiver ( ) { result = MethodCall .super .getReceiver ( ) }
961+
962+ final override SynthKind getSynthKind ( ) {
963+ result = MethodCallKind ( super .getMethodName ( ) , false , super .getNumberOfArguments ( ) )
964+ }
965+ }
966+
967+ private class LhsScopedConstant extends LhsWithReceiver , TScopeResolutionConstantAccess {
968+ private Ruby:: AstNode receiver ;
969+ private string name ;
970+
971+ LhsScopedConstant ( ) {
972+ exists ( Ruby:: ScopeResolution e , Ruby:: Constant c |
973+ this = TScopeResolutionConstantAccess ( e , c )
974+ |
975+ receiver = e .getScope ( ) and
976+ name = c .getValue ( )
977+ )
978+ }
979+
980+ final string getName ( ) { result = name }
981+
982+ final override Expr getReceiver ( ) { toGenerated ( result ) = receiver }
983+
984+ final override SynthKind getSynthKind ( ) { result = ConstantWriteAccessKind ( name ) }
985+ }
986+
953987 pragma [ nomagic]
954988 private predicate destructuredAssignSynthesis ( AstNode parent , int i , Child child ) {
955989 exists ( DestructuredAssignExpr tae |
@@ -958,7 +992,7 @@ private module DestructuredAssignDesugar {
958992 child = SynthChild ( StmtSequenceKind ( ) )
959993 or
960994 exists ( AstNode seq | seq = TStmtSequenceSynth ( tae , - 1 ) |
961- exists ( MethodCall mc , int j | mc = tae .getElement ( j ) |
995+ exists ( LhsWithReceiver mc , int j | mc = tae .getElement ( j ) |
962996 parent = seq and
963997 i = j and
964998 child = SynthChild ( AssignExprKind ( ) )
@@ -1005,25 +1039,29 @@ private module DestructuredAssignDesugar {
10051039 exists ( AstNode assign |
10061040 assign = TAssignExprSynth ( seq , j + 1 + tae .getNumberOfElements ( ) )
10071041 |
1008- exists ( MethodCall mc | mc = elem |
1042+ exists ( LhsWithReceiver mc | mc = elem |
10091043 parent = assign and
10101044 i = 0 and
1011- child =
1012- SynthChild ( MethodCallKind ( mc .getMethodName ( ) , false , mc .getNumberOfArguments ( ) ) )
1045+ child = SynthChild ( mc .getSynthKind ( ) )
10131046 or
1014- exists ( AstNode call | call = TMethodCallSynth ( assign , 0 , _ , _ , _ ) |
1047+ exists ( AstNode call | synthChild ( assign , 0 , call ) |
10151048 parent = call and
10161049 i = 0 and
10171050 child = SynthChild ( LocalVariableAccessSynthKind ( TLocalVariableSynth ( tae , j ) ) )
10181051 or
10191052 parent = call and
1020- child = childRef ( mc .getArgument ( i - 1 ) )
1053+ child = childRef ( mc .( MethodCall ) . getArgument ( i - 1 ) )
10211054 )
10221055 )
10231056 or
10241057 (
1025- elem instanceof VariableAccess or
1026- elem instanceof ConstantAccess or
1058+ elem instanceof VariableAccess
1059+ or
1060+ elem instanceof ConstantAccess and
1061+ not exists ( Ruby:: ScopeResolution g |
1062+ elem = TScopeResolutionConstantAccess ( g , _) and exists ( g .getScope ( ) )
1063+ )
1064+ or
10271065 elem instanceof DestructuredLhsExpr
10281066 ) and
10291067 parent = assign and
@@ -1096,7 +1134,7 @@ private module DestructuredAssignDesugar {
10961134 synthChild ( seq , tae .getNumberOfElements ( ) , n ) and
10971135 hasLocation ( tae .getRightOperand ( ) , l )
10981136 or
1099- exists ( MethodCall elem , int j |
1137+ exists ( LhsWithReceiver elem , int j |
11001138 elem = tae .getElement ( j ) and
11011139 synthChild ( seq , j , n ) and
11021140 hasLocation ( elem .getReceiver ( ) , l )
@@ -1113,6 +1151,13 @@ private module DestructuredAssignDesugar {
11131151 i = [ 0 .. n .( DestructuredAssignExpr ) .getNumberOfElements ( ) ]
11141152 }
11151153
1154+ final override predicate constantWriteAccess ( string name ) {
1155+ exists ( DestructuredAssignExpr tae , LhsScopedConstant ca |
1156+ ca = tae .getElement ( _) and
1157+ name = ca .getName ( )
1158+ )
1159+ }
1160+
11161161 final override predicate methodCall ( string name , boolean setter , int arity ) {
11171162 name = "[]" and
11181163 setter = false and
@@ -1127,7 +1172,7 @@ private module DestructuredAssignDesugar {
11271172 }
11281173
11291174 final override predicate excludeFromControlFlowTree ( AstNode n ) {
1130- n = any ( DestructuredAssignExpr tae ) .getElement ( _) .( MethodCall )
1175+ n = any ( DestructuredAssignExpr tae ) .getElement ( _) .( LhsWithReceiver )
11311176 }
11321177 }
11331178}
0 commit comments