You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
merge-graphs / global add finish a member call whose receiver type lives in
another repository for Java, C++, C# and Swift (#3152). Objective-C has a member-call
resolver with full receiver typing — self/super, an explicit class name, the
file's Foo *f local table, and the class's @property/ivar table with the inherits walk from #3151 — but it parks nothing, so an ObjC corpus split across
repositories gets no cross-repo call edges at all.
The reason is one bail. _resolve_objc_member_calls ends each typing arm with
so "declared nowhere in this corpus" — the parking case — is indistinguishable from
"declared more than once", which must stay dropped. Java splits the same guard into
a park arm and an ambiguity arm; the three ObjC arms do not.
Build each repo, then merge-graphs app/graphify-out/graph.json lib/graphify-out/graph.json.
Observed: grep unresolved_calls app/graphify-out/graph.json finds nothing, and the
merged graph has no context: "cross_repo" edge. The same two files in one corpus do
produce the -run -> -greet call, so the receiver typing is not what is missing.
Expected: App.m parks {"callee": "greet", "receiver_type": "Greeter", "lang": "objc"}
and the merge emits the calls edge, as the Java/C++/C#/Swift equivalents do.
Two ObjC-specific things the merge side has to handle
An ObjC method label keeps its +/- sigil (-greet), where every other
extractor writes .greet(). _key strips . and () only, so a parked selector greet never matches -greet. Normalizing the sigil away is the wrong fix: .h is
in the C++ suffix set and would be in the ObjC one, so keeping the sigil is what
keeps an ObjC -greet and a C++ .greet() from answering for each other inside one
shared header. Trying both sigils and treating a class that declares +greet and -greet as ambiguous keeps them disjoint without a new field in the parked payload.
Scope note
Measured on a 15,754-file ObjC corpus split into 26 units: of 12,866 sends whose
receiver is typed to a class absent from its own unit, 5,127 are framework classes
(UIKit/Foundation, in no unit), 1,911 are business classes declared in no unit at all,
2,634 find the class but the selector is not on it, 2,769 are ambiguous across units,
and 425 are genuinely cross-unit resolvable. The builtin-globals filter the Swift
and C++ resolvers already apply keeps the framework names out of the parked payload.
What happens
merge-graphs/global addfinish a member call whose receiver type lives inanother repository for Java, C++, C# and Swift (#3152). Objective-C has a member-call
resolver with full receiver typing —
self/super, an explicit class name, thefile's
Foo *flocal table, and the class's@property/ivar table with theinheritswalk from #3151 — but it parks nothing, so an ObjC corpus split acrossrepositories gets no cross-repo call edges at all.
The reason is one bail.
_resolve_objc_member_callsends each typing arm withso "declared nowhere in this corpus" — the parking case — is indistinguishable from
"declared more than once", which must stay dropped. Java splits the same guard into
a park arm and an ambiguity arm; the three ObjC arms do not.
Minimal reproduction
Build each repo, then
merge-graphs app/graphify-out/graph.json lib/graphify-out/graph.json.Observed:
grep unresolved_calls app/graphify-out/graph.jsonfinds nothing, and themerged graph has no
context: "cross_repo"edge. The same two files in one corpus doproduce the
-run -> -greetcall, so the receiver typing is not what is missing.Expected:
App.mparks{"callee": "greet", "receiver_type": "Greeter", "lang": "objc"}and the merge emits the
callsedge, as the Java/C++/C#/Swift equivalents do.Two ObjC-specific things the merge side has to handle
_callable_class/_callableare absent fromextractors/objc.py(ObjC declarations carry no _callable / _callable_class markers, so marker-gated passes skip ObjC entirely #3228), andcross_repo_calls._index_declarationsindexes declarations by those markers, soevery ObjC type is skipped even once parking exists.
An ObjC method label keeps its
+/-sigil (-greet), where every otherextractor writes
.greet()._keystrips.and()only, so a parked selectorgreetnever matches-greet. Normalizing the sigil away is the wrong fix:.hisin the C++ suffix set and would be in the ObjC one, so keeping the sigil is what
keeps an ObjC
-greetand a C++.greet()from answering for each other inside oneshared header. Trying both sigils and treating a class that declares
+greetand-greetas ambiguous keeps them disjoint without a new field in the parked payload.Scope note
Measured on a 15,754-file ObjC corpus split into 26 units: of 12,866 sends whose
receiver is typed to a class absent from its own unit, 5,127 are framework classes
(UIKit/Foundation, in no unit), 1,911 are business classes declared in no unit at all,
2,634 find the class but the selector is not on it, 2,769 are ambiguous across units,
and 425 are genuinely cross-unit resolvable. The builtin-globals filter the Swift
and C++ resolvers already apply keeps the framework names out of the parked payload.
PR: paired with this issue.