@@ -1089,17 +1089,54 @@ DataFlowCallable viableCallable(DataFlowCall node) {
10891089 result .asSourceCallableNotExterns ( ) = node .asImpliedLambdaCall ( )
10901090}
10911091
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+
10921108/**
10931109 * Holds if the set of viable implementations that can be called by `call`
10941110 * might be improved by knowing the call context.
10951111 */
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+ }
10971129
10981130/**
10991131 * Gets a viable dispatch target of `call` in the context `ctx`. This is
11001132 * restricted to those `call`s for which a context might make a difference.
11011133 */
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+ }
11031140
11041141bindingset [ node, fun]
11051142pragma [ inline_late]
0 commit comments