Class DispatcherHandlerLinker
Why this is needed. renderer.render(shape) with shape as Shape resolves
to the entry point render(Shape); at runtime its dispatch table sends a Circle to
render(Circle). No call site names the handler, so without these edges every handler
reached that way looked unreachable: a valid @Test failed with E81007/E81011, and
ek9_find_unused_code offered the running handlers for deletion. PolymorphicOverrideLinker does the same for ordinary virtual dispatch; a dispatcher is a
different language feature, so it has its own linker.
Which handlers - THE shared set. The entry points and handlers are exactly
DispatcherHandlers.entryPointsOf(IAggregateSymbol) and DispatcherHandlers.collectFor(IAggregateSymbol, MethodSymbol), the set phase 7
builds the dispatch table over, so the call graph cannot route over a different set.
RTA, as for overrides. A handler is linked only when every parameter it dispatches on can arrive: its type, or a concrete subtype of it, is allocated somewhere in the program. A handler for a type nothing constructs cannot run and stays reportable as dead. A parameter that is not an aggregate (a function type) is not filtered - linking is the conservative choice there.
-
Constructor Summary
ConstructorsConstructorDescriptionDispatcherHandlerLinker(CallGraph callGraph, ConcreteSubtypeFinder subtypeFinder) -
Method Summary
Modifier and TypeMethodDescriptionvoidlink()Add a polymorphic edge from each dispatcher entry point of every aggregate that owns a registered method to each of its handlers that can run.
-
Constructor Details
-
DispatcherHandlerLinker
-
-
Method Details
-
link
public void link()Add a polymorphic edge from each dispatcher entry point of every aggregate that owns a registered method to each of its handlers that can run.
-