@@ -1164,15 +1164,27 @@ class DataFlowCall extends TDataFlowCall {
11641164 Function getStaticCallSourceTarget ( ) { none ( ) }
11651165
11661166 /**
1167- * Gets the target of this call. If a summarized callable exists for the
1168- * target this is chosen, and otherwise the callable is the implementation
1169- * from the source code.
1167+ * Gets the target of this call. We use the following strategy for deciding
1168+ * between the source callable and a summarized callable:
1169+ * - If there is a manual summary then we always use the manual summary.
1170+ * - If there is a source callable and we only have generated summaries
1171+ * we use the source callable.
1172+ * - If there is no source callable then we use the summary regardless of
1173+ * whether is it manual or generated.
11701174 */
1171- DataFlowCallable getStaticCallTarget ( ) {
1175+ final DataFlowCallable getStaticCallTarget ( ) {
11721176 exists ( Function target | target = this .getStaticCallSourceTarget ( ) |
1173- not exists ( TSummarizedCallable ( target ) ) and
1177+ // Don't use the source callable if there is a manual model for the
1178+ // target
1179+ not exists ( SummarizedCallable sc |
1180+ sc .asSummarizedCallable ( ) = target and
1181+ sc .asSummarizedCallable ( ) .applyManualModel ( )
1182+ ) and
11741183 result .asSourceCallable ( ) = target
11751184 or
1185+ // When there is no function body, or when we have a manual model then
1186+ // we dispatch to the summary.
1187+ ( not target .hasDefinition ( ) or result .asSummarizedCallable ( ) .applyManualModel ( ) ) and
11761188 result .asSummarizedCallable ( ) = target
11771189 )
11781190 }
0 commit comments