@@ -1113,6 +1113,7 @@ def _process_call(start_idx: int, open_paren_pos: int) -> bool:
11131113 documents_of_functions = documents_of_functions ,
11141114 callee_function_name = callee_function_name ,
11151115 type_inheritance = type_inheritance ,
1116+ callee_declaring_fqcn = declaring_fqcn ,
11161117 ):
11171118 logger .debug (
11181119 "__check_identifier_resolved_to_callee_function_package resolved successfully - "
@@ -1160,6 +1161,7 @@ def _process_method_ref(dc_idx: int, ref_len: int, make_ctor: bool) -> bool:
11601161 documents_of_functions = documents_of_functions ,
11611162 callee_function_name = callee_function_name ,
11621163 type_inheritance = type_inheritance ,
1164+ callee_declaring_fqcn = declaring_fqcn ,
11631165 )
11641166
11651167 # ---------------------------
@@ -1214,7 +1216,8 @@ def __check_identifier_resolved_to_callee_function_package(
12141216 target_class_names : frozenset [str ],
12151217 documents_of_functions : list [Document ],
12161218 callee_function_name : str ,
1217- type_inheritance : dict [Tuple [str , str ], List [Tuple [str , str ]]]
1219+ type_inheritance : dict [Tuple [str , str ], List [Tuple [str , str ]]],
1220+ callee_declaring_fqcn : str = "" ,
12181221 ) -> bool :
12191222 """
12201223 Decide if the found call expression (`identifier_function`) in `function` actually targets
@@ -1658,16 +1661,28 @@ def _extract_ctor_type(expr: str) -> str:
16581661 if _type_matches_callee (iface_type ):
16591662 return True
16601663
1661- if recv_trim == 'super' :
1662- try :
1663- caller_inheritance_list = get_target_class_names (type_inheritance [(caller_fqcn , caller_src )])
1664- except KeyError :
1665- caller_inheritance_list = []
1666- for cand in caller_inheritance_list :
1667- if cand == caller_fqcn :
1668- continue
1669- if _type_token_matches_callee (cand ): # cand is already FQCN (CHANGED: fqcn-only)
1670- return True
1664+ if recv_trim == 'super' and callee_declaring_fqcn :
1665+ # Don't match super calls from root-package functions.
1666+ # super delegates to the parent's own implementation which is
1667+ # self-contained. Allowing it at the app→dependency boundary
1668+ # lets the CCA's backtracking route through the entire
1669+ # dependency hierarchy via polymorphic dispatch, producing
1670+ # false-positive chains (e.g. handler.handle() hops).
1671+ if self .is_root_package (function ):
1672+ pass # skip – super from app code is not a valid entry point
1673+ else :
1674+ try :
1675+ caller_inheritance = type_inheritance [(caller_fqcn , caller_src )]
1676+ except KeyError :
1677+ caller_inheritance = []
1678+ # super resolves to the direct parent class only; match only if the
1679+ # direct parent IS the callee's declaring class (exact match).
1680+ for cand_fqcn , _cand_src in caller_inheritance :
1681+ if cand_fqcn == caller_fqcn :
1682+ continue
1683+ if cand_fqcn == callee_declaring_fqcn or cand_fqcn == callee_declaring_fqcn .replace ('$' , '.' ):
1684+ return True
1685+ break
16711686
16721687 if recv_trim == 'this' :
16731688 if caller_fqcn and _type_token_matches_callee (caller_fqcn ):
@@ -1728,16 +1743,23 @@ def _extract_ctor_type(expr: str) -> str:
17281743 if _type_matches_callee (iface_type ):
17291744 return True
17301745
1731- if recv_raw == 'super' :
1732- try :
1733- caller_inheritance_list = get_target_class_names (type_inheritance [(caller_fqcn , caller_src )])
1734- except KeyError :
1735- caller_inheritance_list = []
1736- for cand in caller_inheritance_list :
1737- if cand == caller_fqcn :
1738- continue
1739- if _type_token_matches_callee (cand ): # fqcn-only
1740- return True
1746+ if recv_raw == 'super' and callee_declaring_fqcn :
1747+ # Don't match super calls from root-package functions (see early-path comment).
1748+ if self .is_root_package (function ):
1749+ pass # skip
1750+ else :
1751+ try :
1752+ caller_inheritance = type_inheritance [(caller_fqcn , caller_src )]
1753+ except KeyError :
1754+ caller_inheritance = []
1755+ # super resolves to the direct parent class only; match only if the
1756+ # direct parent IS the callee's declaring class (exact match).
1757+ for cand_fqcn , _cand_src in caller_inheritance :
1758+ if cand_fqcn == caller_fqcn :
1759+ continue
1760+ if cand_fqcn == callee_declaring_fqcn or cand_fqcn == callee_declaring_fqcn .replace ('$' , '.' ):
1761+ return True
1762+ break
17411763 elif recv_raw == 'this' :
17421764 if caller_fqcn and _type_token_matches_callee (caller_fqcn ):
17431765 return True
0 commit comments