@@ -1089,17 +1089,54 @@ DataFlowCallable viableCallable(DataFlowCall node) {
1089
1089
result .asSourceCallableNotExterns ( ) = node .asImpliedLambdaCall ( )
1090
1090
}
1091
1091
1092
+ private DataFlowCall getACallOnThis ( DataFlow:: ClassNode cls ) {
1093
+ result .asOrdinaryCall ( ) = cls .getAReceiverNode ( ) .getAPropertyRead ( ) .getACall ( )
1094
+ or
1095
+ result .asAccessorCall ( ) = cls .getAReceiverNode ( ) .getAPropertyRead ( )
1096
+ or
1097
+ result .asPartialCall ( ) .getACallbackNode ( ) = cls .getAReceiverNode ( ) .getAPropertyRead ( )
1098
+ }
1099
+
1100
+ private predicate downwardCall ( DataFlowCall call ) {
1101
+ exists ( DataFlow:: ClassNode cls |
1102
+ call = getACallOnThis ( cls ) and
1103
+ viableCallable ( call ) .asSourceCallable ( ) =
1104
+ cls .getADirectSubClass + ( ) .getAnInstanceMember ( ) .getFunction ( )
1105
+ )
1106
+ }
1107
+
1092
1108
/**
1093
1109
* Holds if the set of viable implementations that can be called by `call`
1094
1110
* might be improved by knowing the call context.
1095
1111
*/
1096
- predicate mayBenefitFromCallContext ( DataFlowCall call ) { none ( ) }
1112
+ predicate mayBenefitFromCallContext ( DataFlowCall call ) { downwardCall ( call ) }
1113
+
1114
+ /** Gets the type of the receiver of `call`. */
1115
+ private DataFlowType getThisArgumentType ( DataFlowCall call ) {
1116
+ exists ( DataFlow:: Node node |
1117
+ isArgumentNodeImpl ( node , call , MkThisParameter ( ) ) and
1118
+ result = getNodeType ( node )
1119
+ )
1120
+ }
1121
+
1122
+ /** Gets the type of the 'this' parameter of `call`. */
1123
+ private DataFlowType getThisParameterType ( DataFlowCallable callable ) {
1124
+ exists ( DataFlow:: Node node |
1125
+ isParameterNodeImpl ( node , callable , MkThisParameter ( ) ) and
1126
+ result = getNodeType ( node )
1127
+ )
1128
+ }
1097
1129
1098
1130
/**
1099
1131
* Gets a viable dispatch target of `call` in the context `ctx`. This is
1100
1132
* restricted to those `call`s for which a context might make a difference.
1101
1133
*/
1102
- DataFlowCallable viableImplInCallContext ( DataFlowCall call , DataFlowCall ctx ) { none ( ) }
1134
+ DataFlowCallable viableImplInCallContext ( DataFlowCall call , DataFlowCall ctx ) {
1135
+ mayBenefitFromCallContext ( call ) and
1136
+ result = viableCallable ( call ) and
1137
+ viableCallable ( ctx ) = call .getEnclosingCallable ( ) and
1138
+ compatibleTypes ( getThisArgumentType ( ctx ) , getThisParameterType ( result ) )
1139
+ }
1103
1140
1104
1141
bindingset [ node, fun]
1105
1142
pragma [ inline_late]
0 commit comments