Class CallTargetResolution

java.lang.Object
org.ek9lang.compiler.phase7.calls.CallTargetResolution

public final class CallTargetResolution extends Object
THE single source of truth for the descriptor OWNER and dispatch of a resolved call: the type where a resolved method's body is actually emitted (its "defining type") and the virtual-dispatch decision. Reuse this from BOTH the resolved-method path (CallDetailsBuilder) and the chained object-access path (ObjectAccessInstrGenerator) so the two never re-derive - and drift on - the CALL descriptor owner. See docs/ir-and-codegen/EK9_UNIFIED_CALL_TARGET_RESOLUTION_DESIGN.md.

Invariant (enforced by the JVM back-end): the descriptor owner type and isTraitCall move TOGETHER - INVOKEINTERFACE iff the owner is an interface (trait / Any) - so a caller derives BOTH from the SAME definingType(ISymbol, ISymbol): targetType = definingType and isTraitCall = TraitCall.requiredFor(definingType) (never one from the defining type and the other from the static receiver).

  • Method Summary

    Modifier and Type
    Method
    Description
    static ISymbol
    definingType(ISymbol resolvedMethod, ISymbol staticType)
    The type that DECLARES the resolved method (its enclosing scope) - i.e.
    static boolean
    The compiler-synthesised LIFECYCLE methods, which are never dynamically dispatched: the constructor itself plus i_init (instance field initialisation) and c_init (class/static initialisation).
    static boolean
    Whether an aggregate type is open for extension (can have subclasses).
    static boolean
    isVirtualCall(ISymbol resolvedMethod, ISymbol targetType)
    Whether the call needs virtual (vtable) dispatch: false for constructors, private methods (cannot be overridden), and targets not open for extension (effectively final).
    static boolean
    The dispatch flag for a call the compiler SYNTHESISED, where the callee type may not have been threaded through.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • definingType

      public static ISymbol definingType(ISymbol resolvedMethod, ISymbol staticType)
      The type that DECLARES the resolved method (its enclosing scope) - i.e. where its body is emitted. For an inherited method this is the PARENT, not the static receiver: the descriptor owner must name the declaring type because the native back-end resolves by the mangled (type, member) name and the body exists only on the declaring type (the JVM tolerates either spelling). Falls back to staticType when a defining scope cannot be determined.
    • isVirtualCall

      public static boolean isVirtualCall(ISymbol resolvedMethod, ISymbol targetType)
      Whether the call needs virtual (vtable) dispatch: false for constructors, private methods (cannot be overridden), and targets not open for extension (effectively final). LLVM-only - the JVM back-end ignores the flag and always emits INVOKEVIRTUAL / INVOKEINTERFACE.
    • isNonDispatchableLifecycleMethod

      public static boolean isNonDispatchableLifecycleMethod(String methodName)
      The compiler-synthesised LIFECYCLE methods, which are never dynamically dispatched: the constructor itself plus i_init (instance field initialisation) and c_init (class/static initialisation).

      Each <init> must run ITS OWN i_init. Dispatching one dynamically would send a base constructor's field-initialisation call to the DERIVED body, running it against a half-built object whose own fields do not exist yet - and a base type must be as open to be extended at all, so openness alone says "virtual" for exactly the hierarchies where this breaks.

      These are NOT CompilerPlumbingCalls plumbing: they have real symbols and measured complexity, so they DO carry a metadata clause. They are simply not dispatchable. Keeping the two ideas apart is the point - a site that needs "no metadata" and a site that needs "no dispatch" are different questions with different answers.

    • isVirtualForSynthesisedCallee

      public static boolean isVirtualForSynthesisedCallee(ISymbol targetType)
      The dispatch flag for a call the compiler SYNTHESISED, where the callee type may not have been threaded through. Openness is a property of the target type, so it is read from the symbol whenever one is in hand.

      When no symbol reached the site there is no honest source, and a boolean still has to be emitted. false is the answer that preserves the pre-existing rendering at those sites, so migrating a site to pass its symbol is visible as churn rather than being masked by a changed default. It is NOT a claim that the type is closed - prefer threading the symbol, exactly as the metadata pass did.

    • isOpenAggregate

      public static boolean isOpenAggregate(ISymbol type)
      Whether an aggregate type is open for extension (can have subclasses). Traits are always "open" - implementations override them.