Class PolymorphicOverrideLinker
Why this is needed. A call site resolves to the method the caller can SEE — for
bumper as Bumper!; bumper.bump() that is the abstract Bumper.bump, never the
UnsafeBumper.bump that holds the code. Nothing else in the collector bridges that gap:
recordCallEdge marks an edge polymorphic only when the target is an explicit EK9
dispatcher (isMarkedAsDispatcher), which is a different language feature. Until call-graph
nodes were made unique, ordinary virtual dispatch worked only by ACCIDENT — every same-named
member in a module shared one node, so the abstract declaration and its override were literally
the same graph vertex. Giving members distinct identities removed that accident, and this class
replaces it with the real relationship.
RTA, not CHA. An override is linked only when its owning type is actually allocated
somewhere in the program, which is what the call graph already documents itself as doing and what
allocatedTypes was collected for. Linking every override regardless (class-hierarchy
analysis) would make an override on a never-constructed type look reachable and quietly suppress
genuine dead-code findings — the same under-reporting the merged nodes used to cause.
Run after every source has been walked (so allocations and callables are complete) and before anything consumes reachability — the concurrent-entry-point propagation, dead-code detection, DI ordering and interprocedural lock analysis all read these edges.
-
Constructor Summary
ConstructorsConstructorDescriptionPolymorphicOverrideLinker(CallGraph callGraph, ConcreteSubtypeFinder subtypeFinder) -
Method Summary
Modifier and TypeMethodDescriptionvoidlink()Add a polymorphic edge from each registered aggregate method to the overriding implementation on every allocated concrete subtype.
-
Constructor Details
-
PolymorphicOverrideLinker
-
-
Method Details
-
link
public void link()Add a polymorphic edge from each registered aggregate method to the overriding implementation on every allocated concrete subtype.
-