@@ -950,6 +950,40 @@ private module DestructuredAssignDesugar {
950
950
}
951
951
}
952
952
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
+
953
987
pragma [ nomagic]
954
988
private predicate destructuredAssignSynthesis ( AstNode parent , int i , Child child ) {
955
989
exists ( DestructuredAssignExpr tae |
@@ -958,7 +992,7 @@ private module DestructuredAssignDesugar {
958
992
child = SynthChild ( StmtSequenceKind ( ) )
959
993
or
960
994
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 ) |
962
996
parent = seq and
963
997
i = j and
964
998
child = SynthChild ( AssignExprKind ( ) )
@@ -1005,25 +1039,29 @@ private module DestructuredAssignDesugar {
1005
1039
exists ( AstNode assign |
1006
1040
assign = TAssignExprSynth ( seq , j + 1 + tae .getNumberOfElements ( ) )
1007
1041
|
1008
- exists ( MethodCall mc | mc = elem |
1042
+ exists ( LhsWithReceiver mc | mc = elem |
1009
1043
parent = assign and
1010
1044
i = 0 and
1011
- child =
1012
- SynthChild ( MethodCallKind ( mc .getMethodName ( ) , false , mc .getNumberOfArguments ( ) ) )
1045
+ child = SynthChild ( mc .getSynthKind ( ) )
1013
1046
or
1014
- exists ( AstNode call | call = TMethodCallSynth ( assign , 0 , _ , _ , _ ) |
1047
+ exists ( AstNode call | synthChild ( assign , 0 , call ) |
1015
1048
parent = call and
1016
1049
i = 0 and
1017
1050
child = SynthChild ( LocalVariableAccessSynthKind ( TLocalVariableSynth ( tae , j ) ) )
1018
1051
or
1019
1052
parent = call and
1020
- child = childRef ( mc .getArgument ( i - 1 ) )
1053
+ child = childRef ( mc .( MethodCall ) . getArgument ( i - 1 ) )
1021
1054
)
1022
1055
)
1023
1056
or
1024
1057
(
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
1027
1065
elem instanceof DestructuredLhsExpr
1028
1066
) and
1029
1067
parent = assign and
@@ -1096,7 +1134,7 @@ private module DestructuredAssignDesugar {
1096
1134
synthChild ( seq , tae .getNumberOfElements ( ) , n ) and
1097
1135
hasLocation ( tae .getRightOperand ( ) , l )
1098
1136
or
1099
- exists ( MethodCall elem , int j |
1137
+ exists ( LhsWithReceiver elem , int j |
1100
1138
elem = tae .getElement ( j ) and
1101
1139
synthChild ( seq , j , n ) and
1102
1140
hasLocation ( elem .getReceiver ( ) , l )
@@ -1113,6 +1151,13 @@ private module DestructuredAssignDesugar {
1113
1151
i = [ 0 .. n .( DestructuredAssignExpr ) .getNumberOfElements ( ) ]
1114
1152
}
1115
1153
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
+
1116
1161
final override predicate methodCall ( string name , boolean setter , int arity ) {
1117
1162
name = "[]" and
1118
1163
setter = false and
@@ -1127,7 +1172,7 @@ private module DestructuredAssignDesugar {
1127
1172
}
1128
1173
1129
1174
final override predicate excludeFromControlFlowTree ( AstNode n ) {
1130
- n = any ( DestructuredAssignExpr tae ) .getElement ( _) .( MethodCall )
1175
+ n = any ( DestructuredAssignExpr tae ) .getElement ( _) .( LhsWithReceiver )
1131
1176
}
1132
1177
}
1133
1178
}
0 commit comments