@@ -72,6 +72,7 @@ private module Internal {
72
72
not mc .isLateBound ( )
73
73
} or
74
74
TDispatchAccessorCall ( AccessorCall ac ) or
75
+ TDispatchOperatorCall ( OperatorCall oc ) { not oc .isLateBound ( ) } or
75
76
TDispatchReflectionCall ( MethodCall mc , string name , Expr object , Expr qualifier , int args ) {
76
77
isReflectionCall ( mc , name , object , qualifier , args )
77
78
} or
@@ -90,8 +91,6 @@ private module Internal {
90
91
or
91
92
c instanceof ConstructorInitializer
92
93
or
93
- c = any ( OperatorCall oc | not oc .isLateBound ( ) )
94
- or
95
94
c instanceof LocalFunctionCall
96
95
}
97
96
@@ -113,12 +112,12 @@ private module Internal {
113
112
}
114
113
115
114
cached
116
- predicate mayBenefitFromCallContext ( DispatchMethodOrAccessorCall dc ) {
115
+ predicate mayBenefitFromCallContext ( DispatchOverridableCall dc ) {
117
116
dc .mayBenefitFromCallContext ( _, _)
118
117
}
119
118
120
119
cached
121
- RuntimeCallable getADynamicTargetInCallContext ( DispatchMethodOrAccessorCall dc , DispatchCall ctx ) {
120
+ RuntimeCallable getADynamicTargetInCallContext ( DispatchOverridableCall dc , DispatchCall ctx ) {
122
121
result = dc .getADynamicTargetInCallContext ( ctx )
123
122
}
124
123
}
@@ -214,6 +213,9 @@ private module Internal {
214
213
/** Gets the qualifier of this call, if any. */
215
214
abstract Expr getQualifier ( ) ;
216
215
216
+ /** Gets the qualifier or another expression that can be used for typing purposes, if any. */
217
+ Expr getSyntheticQualifier ( ) { result = this .getQualifier ( ) }
218
+
217
219
/** Gets a static (compile-time) target of this call. */
218
220
abstract Callable getAStaticTarget ( ) ;
219
221
@@ -241,7 +243,7 @@ private module Internal {
241
243
private predicate hasCallable0 ( Gvn:: GvnType t , OverridableCallable c , OverridableCallable source ) {
242
244
c .getUnboundDeclaration ( ) = source and
243
245
any ( ValueOrRefType t0 | Gvn:: getGlobalValueNumber ( t0 ) = t ) .hasCallable ( c ) and
244
- source = any ( DispatchMethodOrAccessorCall call ) .getAStaticTargetExt ( )
246
+ source = any ( DispatchOverridableCall call ) .getAStaticTargetExt ( )
245
247
}
246
248
247
249
pragma [ noinline]
@@ -250,7 +252,7 @@ private module Internal {
250
252
hasOverrider ( t , c )
251
253
}
252
254
253
- abstract private class DispatchMethodOrAccessorCall extends DispatchCallImpl {
255
+ abstract private class DispatchOverridableCall extends DispatchCallImpl {
254
256
pragma [ noinline]
255
257
OverridableCallable getAStaticTargetExt ( ) {
256
258
exists ( OverridableCallable target | this .getAStaticTarget ( ) = target |
@@ -261,13 +263,15 @@ private module Internal {
261
263
}
262
264
263
265
pragma [ nomagic]
264
- predicate hasQualifierTypeInherited ( Type t ) { t = getAPossibleType ( this .getQualifier ( ) , _) }
266
+ predicate hasQualifierTypeInherited ( Type t ) {
267
+ t = getAPossibleType ( this .getSyntheticQualifier ( ) , _)
268
+ }
265
269
266
270
pragma [ noinline]
267
271
private predicate hasSubsumedQualifierType ( Gvn:: GvnType t ) {
268
272
hasOverrider ( t , _) and
269
273
exists ( Type t0 |
270
- t0 = getAPossibleType ( this .getQualifier ( ) , false ) and
274
+ t0 = getAPossibleType ( this .getSyntheticQualifier ( ) , false ) and
271
275
not t0 instanceof TypeParameter
272
276
|
273
277
t = Gvn:: getGlobalValueNumber ( t0 )
@@ -280,12 +284,12 @@ private module Internal {
280
284
private predicate hasConstrainedTypeParameterQualifierType (
281
285
Unification:: ConstrainedTypeParameter tp
282
286
) {
283
- tp = getAPossibleType ( this .getQualifier ( ) , false )
287
+ tp = getAPossibleType ( this .getSyntheticQualifier ( ) , false )
284
288
}
285
289
286
290
pragma [ noinline]
287
291
private predicate hasUnconstrainedTypeParameterQualifierType ( ) {
288
- getAPossibleType ( this .getQualifier ( ) , false ) instanceof
292
+ getAPossibleType ( this .getSyntheticQualifier ( ) , false ) instanceof
289
293
Unification:: UnconstrainedTypeParameter
290
294
}
291
295
@@ -313,7 +317,7 @@ private module Internal {
313
317
|
314
318
pdef = def .getDefinition ( ) and
315
319
p = pdef .getTarget ( ) and
316
- this .getQualifier ( ) = def .getARead ( ) and
320
+ this .getSyntheticQualifier ( ) = def .getARead ( ) and
317
321
p .getPosition ( ) = i and
318
322
c .getAParameter ( ) = p and
319
323
not p .isParams ( )
@@ -446,7 +450,7 @@ private module Internal {
446
450
447
451
pragma [ noinline]
448
452
NonConstructedOverridableCallable getAViableOverrider0 ( ) {
449
- getAPossibleType ( this .getQualifier ( ) , false ) instanceof TypeParameter and
453
+ getAPossibleType ( this .getSyntheticQualifier ( ) , false ) instanceof TypeParameter and
450
454
result .getAConstructingCallableOrSelf ( ) = this .getAStaticTargetExt ( )
451
455
}
452
456
@@ -775,7 +779,7 @@ private module Internal {
775
779
* The set of viable targets is determined by taking virtual dispatch
776
780
* into account.
777
781
*/
778
- private class DispatchMethodCall extends DispatchMethodOrAccessorCall , TDispatchMethodCall {
782
+ private class DispatchMethodCall extends DispatchOverridableCall , TDispatchMethodCall {
779
783
override MethodCall getCall ( ) { this = TDispatchMethodCall ( result ) }
780
784
781
785
override Expr getArgument ( int i ) {
@@ -790,13 +794,35 @@ private module Internal {
790
794
override Method getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
791
795
}
792
796
797
+ /**
798
+ * An ordinary operator call.
799
+ *
800
+ * The set of viable targets is determined by taking virtual dispatch
801
+ * into account.
802
+ */
803
+ private class DispatchOperatorCall extends DispatchOverridableCall , TDispatchOperatorCall {
804
+ override OperatorCall getCall ( ) { this = TDispatchOperatorCall ( result ) }
805
+
806
+ override Expr getArgument ( int i ) { result = this .getCall ( ) .getArgument ( i ) }
807
+
808
+ /**
809
+ * Gets the first child expression of an operator call, which can be considered the qualifier
810
+ * expression for the dispatch call use-cases.
811
+ */
812
+ override Expr getSyntheticQualifier ( ) { result = this .getCall ( ) .getChildExpr ( 0 ) }
813
+
814
+ override Expr getQualifier ( ) { none ( ) }
815
+
816
+ override Operator getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
817
+ }
818
+
793
819
/**
794
820
* A call to an accessor.
795
821
*
796
822
* The set of viable targets is determined by taking virtual dispatch
797
823
* into account.
798
824
*/
799
- private class DispatchAccessorCall extends DispatchMethodOrAccessorCall , TDispatchAccessorCall {
825
+ private class DispatchAccessorCall extends DispatchOverridableCall , TDispatchAccessorCall {
800
826
override AccessorCall getCall ( ) { this = TDispatchAccessorCall ( result ) }
801
827
802
828
override Expr getArgument ( int i ) { result = this .getCall ( ) .getArgument ( i ) }
@@ -806,7 +832,7 @@ private module Internal {
806
832
override Accessor getAStaticTarget ( ) { result = this .getCall ( ) .getTarget ( ) }
807
833
808
834
override RuntimeAccessor getADynamicTarget ( ) {
809
- result = DispatchMethodOrAccessorCall .super .getADynamicTarget ( ) and
835
+ result = DispatchOverridableCall .super .getADynamicTarget ( ) and
810
836
// Calls to accessors may have `dynamic` expression arguments,
811
837
// so we need to check that the types match
812
838
forall ( Type argumentType , int i | this .hasDynamicArg ( i , argumentType ) |
@@ -830,7 +856,7 @@ private module Internal {
830
856
831
857
pragma [ nomagic]
832
858
private predicate hasQualifierType ( Type qualifierType , boolean isExactType ) {
833
- exists ( Type t | t = getAPossibleType ( this .getQualifier ( ) , isExactType ) |
859
+ exists ( Type t | t = getAPossibleType ( this .getSyntheticQualifier ( ) , isExactType ) |
834
860
qualifierType = t and
835
861
not t instanceof TypeParameter
836
862
or
@@ -1116,7 +1142,8 @@ private module Internal {
1116
1142
1117
1143
/** A call using reflection. */
1118
1144
private class DispatchReflectionCall extends DispatchReflectionOrDynamicCall ,
1119
- TDispatchReflectionCall {
1145
+ TDispatchReflectionCall
1146
+ {
1120
1147
override MethodCall getCall ( ) { this = TDispatchReflectionCall ( result , _, _, _, _) }
1121
1148
1122
1149
override string getName ( ) { this = TDispatchReflectionCall ( _, result , _, _, _) }
@@ -1164,7 +1191,8 @@ private module Internal {
1164
1191
1165
1192
/** A method call using dynamic types. */
1166
1193
private class DispatchDynamicMethodCall extends DispatchReflectionOrDynamicCall ,
1167
- TDispatchDynamicMethodCall {
1194
+ TDispatchDynamicMethodCall
1195
+ {
1168
1196
override DynamicMethodCall getCall ( ) { this = TDispatchDynamicMethodCall ( result ) }
1169
1197
1170
1198
override string getName ( ) { result = this .getCall ( ) .getLateBoundTargetName ( ) }
@@ -1185,7 +1213,8 @@ private module Internal {
1185
1213
1186
1214
/** An operator call using dynamic types. */
1187
1215
private class DispatchDynamicOperatorCall extends DispatchReflectionOrDynamicCall ,
1188
- TDispatchDynamicOperatorCall {
1216
+ TDispatchDynamicOperatorCall
1217
+ {
1189
1218
override DynamicOperatorCall getCall ( ) { this = TDispatchDynamicOperatorCall ( result ) }
1190
1219
1191
1220
override string getName ( ) {
@@ -1202,7 +1231,8 @@ private module Internal {
1202
1231
1203
1232
/** A (potential) call to a property accessor using dynamic types. */
1204
1233
private class DispatchDynamicMemberAccess extends DispatchReflectionOrDynamicCall ,
1205
- TDispatchDynamicMemberAccess {
1234
+ TDispatchDynamicMemberAccess
1235
+ {
1206
1236
override DynamicMemberAccess getCall ( ) { this = TDispatchDynamicMemberAccess ( result ) }
1207
1237
1208
1238
override string getName ( ) {
@@ -1226,7 +1256,8 @@ private module Internal {
1226
1256
1227
1257
/** A (potential) call to an indexer accessor using dynamic types. */
1228
1258
private class DispatchDynamicElementAccess extends DispatchReflectionOrDynamicCall ,
1229
- TDispatchDynamicElementAccess {
1259
+ TDispatchDynamicElementAccess
1260
+ {
1230
1261
override DynamicElementAccess getCall ( ) { this = TDispatchDynamicElementAccess ( result ) }
1231
1262
1232
1263
override string getName ( ) {
@@ -1252,7 +1283,8 @@ private module Internal {
1252
1283
1253
1284
/** A (potential) call to an event accessor using dynamic types. */
1254
1285
private class DispatchDynamicEventAccess extends DispatchReflectionOrDynamicCall ,
1255
- TDispatchDynamicEventAccess {
1286
+ TDispatchDynamicEventAccess
1287
+ {
1256
1288
override AssignArithmeticOperation getCall ( ) {
1257
1289
this = TDispatchDynamicEventAccess ( result , _, _)
1258
1290
}
@@ -1269,7 +1301,8 @@ private module Internal {
1269
1301
1270
1302
/** A call to a constructor using dynamic types. */
1271
1303
private class DispatchDynamicObjectCreation extends DispatchReflectionOrDynamicCall ,
1272
- TDispatchDynamicObjectCreation {
1304
+ TDispatchDynamicObjectCreation
1305
+ {
1273
1306
override DynamicObjectCreation getCall ( ) { this = TDispatchDynamicObjectCreation ( result ) }
1274
1307
1275
1308
override string getName ( ) { none ( ) }
0 commit comments