Class DispatcherHandlers

java.lang.Object
org.ek9lang.compiler.support.DispatcherHandlers

public final class DispatcherHandlers extends Object
THE single source of truth for the handler set of a dispatcher entry point.

A dispatcher method (marked as dispatcher) routes each call to the most specific matching handler — a same-named overload with the same arity. The handler set is drawn from the FULL inheritance chain (IAggregateSymbol.getAllMethods()), because a concrete class commonly overrides an abstract entry point as dispatcher while inheriting all the typed handlers from its supertypes (e.g. Intersector extends SpecialIntersector in DispatcherClass.ek9).

Phase 5 (DispatcherAmbiguityOrError, the "no two handlers tie at equal cost" check) and phase 7 (DispatchTableGenerator, which records the winning handler per concrete type) MUST use this exact set — otherwise phase 5's "no ambiguity" guarantee does not transfer to the set phase 7 actually dispatches over, and inherited handlers silently drop to the fallback body at runtime. Do not re-derive a variant of this filter.

  • Method Details

    • entryPointsOf

      public static List<MethodSymbol> entryPointsOf(IAggregateSymbol aggregate)
      THE dispatcher entry points of an aggregate: every non-operator method marked as dispatcher, drawn from the FULL inheritance chain.

      Why non-abstract, and why that removes the need to de-duplicate. The common shape is an abstract entry point declared as dispatcher in a supertype and overridden by the concrete class. IAggregateSymbol.getAllNonAbstractMethods() drops the abstract declaration and keeps the override, so one logical dispatcher yields exactly one method. A de-duplication pass over getAllMethods() would be re-deriving that for free.

      What phase 3 has already guaranteed (ValidDispatcherMethodsOrError) for any program that compiles: at most one method of a given name carries the marker (E07820), a private entry point inherited from a super is rejected (E05180), and arity, purity, return covariance and parameter genus all agree across the chain. Callers may therefore treat this set as clean rather than re-checking it.

      ⚠️ Do NOT fold ValidDispatcherMethodsOrError.getAllOtherMethodsWithSameName into this or into collectFor(IAggregateSymbol, MethodSymbol). That one deliberately does not filter on arity or on the dispatcher marker, because a wrong arity and a second marked entry point are precisely the violations it exists to report - pre-filtering them would silence it.

      Parameters:
      aggregate - the type to read entry points from
      Returns:
      the dispatcher entry points, supertypes included
    • collectFor

      public static List<MethodSymbol> collectFor(IAggregateSymbol aggregate, MethodSymbol dispatcher)
      The handlers for dispatcher on aggregate: every non-abstract, non-constructor, non-operator, non-dispatcher method across the inheritance chain with the same name and arity.