Class PolymorphicCopy

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

public final class PolymorphicCopy extends Object
THE rule for a copy (:=:) through a super-typed reference (Steve, Q5b, 2026-10-08). Use it - never a private reading of "who owns this copy" or "which inherited signatures does it override".

A class that DECLARES :=: is a copy OWNER (E07238 guarantees a class adding fields is one). The object decides which copy runs (N07), so a GENERATED :=: on an owner:

  • also OVERRIDES each inherited :=:(Super) signature (inheritedSignatures(IAggregateSymbol, ISymbol)), so a Base-typed target :=: source on a Leaf runs the Leaf's copy, not Base's;
  • comes with a generated virtual _copyAccepts(target as Any) <- Boolean (COPY_ACCEPTS_METHOD) = "is target an instance of my owner?";
  • copies in full only when the source is an instance of the owner (INSTANCEOF, a SUBTYPE test) AND the source accepts the target (source._copyAccepts(this)) - i.e. both have the SAME copy owner; else it THROWS an EK9 Exception. Leaf<-Leaf copies; Leaf<-Middle and Leaf<-SubLeaf (which adds fields) throw; a field-less PlainLeaf<-Leaf copies (its owner IS Leaf).

A copy that cannot fail skips the check (needsRuntimeCheck(IAggregateSymbol)): an owner that is CLOSED has no sub-type, so its own :=:(Owner) only ever meets an Owner, and its overrides need only the INSTANCEOF.

A HAND-WRITTEN :=: is never touched and gets no overrides: its author decides what a copy means. A generated :=: BELOW a hand-written one still overrides the hand-written signature; its super part calls the hand-written copy (Contract 19), which runs unchecked as written. _copyAccepts is given to every owner, hand-written or generated, where one can be asked (needsCopyAccepts(IAggregateSymbol, ISymbol)), because it is a separate method and is what a generated copy below or above asks. Back-end contract: Contract 20 in EK9_BACKEND_IR_CONTRACTS.md.

_copyAccepts is not an EK9 name: a leading _ cannot start an EK9 identifier, so it can never be called from source nor clash with a user's method (as _fieldSetStatus). Its symbol is DETACHED - created for the IR construct and never defined into the aggregate's scope (F37).

  • Field Details

    • COPY_OPERATOR

      public static final String COPY_OPERATOR
      The EK9 copy operator.
      See Also:
    • COPY_ACCEPTS_METHOD

      public static final String COPY_ACCEPTS_METHOD
      THE generated virtual "would my owner accept this target?" method - an IR/back-end name only.
      See Also:
    • COPY_ACCEPTS_PARAMETER

      public static final String COPY_ACCEPTS_PARAMETER
      The name of _copyAccepts's single parameter.
      See Also:
  • Method Details

    • selfCopy

      public static Optional<MethodSymbol> selfCopy(IAggregateSymbol aggregate)
      The :=: the aggregate declares in its OWN scope that takes the aggregate itself - its self copy.
    • isCopyOwner

      public static boolean isCopyOwner(IAggregateSymbol aggregate)
      Is the aggregate a copy OWNER - does it declare its own :=: taking itself?
    • hasGeneratedSelfCopy

      public static boolean hasGeneratedSelfCopy(IAggregateSymbol aggregate)
      Is the aggregate's self copy GENERATED (default operator :=:, or the bare default operator)? Only a generated copy is checked and gets overrides.
    • isGenerated

      public static boolean isGenerated(MethodSymbol copy)
      Is this :=: generated rather than written by hand?
    • needsRuntimeCheck

      public static boolean needsRuntimeCheck(IAggregateSymbol owner)
      Can a copy into this owner meet an object of a different class? Only when the owner may have sub-types.
    • needsCopyAccepts

      public static boolean needsCopyAccepts(IAggregateSymbol owner, ISymbol ek9Any)
      Does the owner get a _copyAccepts? Only where one can be asked. A GENERATED copy asks it of its source, typed as (or cast to) the generated owner, and that source may be any owner at or below - so an owner answers when its own generated copy is open (it asks itself), or when a GENERATED copy above it may ask. Owners in a hierarchy of hand-written copies, and a closed owner with nothing generated above, are never asked and keep their IR.
    • inheritedSignatures

      public static List<MethodSymbol> inheritedSignatures(IAggregateSymbol owner, ISymbol ek9Any)
      The inherited :=:(Super) signatures a GENERATED owner overrides: every :=: declared up its super CLASS chain (InheritedOperators.allAbove(IAggregateSymbol, String, ISymbol)) whose single parameter is a super type of the owner - one per distinct parameter type, nearest first - unless the owner itself already declares that signature.
      Parameters:
      owner - the copy owner
      ek9Any - the Any type, which never contributes
      Returns:
      the inherited copies whose signatures the owner overrides
    • singleParameterType

      public static Optional<ISymbol> singleParameterType(MethodSymbol copy)
      The single parameter type of a :=:, if it has exactly one.