Class TraitCall

java.lang.Object
org.ek9lang.compiler.phase7.support.TraitCall

public final class TraitCall extends Object
THE single source of truth for "does a call on this target need INVOKEINTERFACE?".

A method/operator call whose target type compiles to a JVM interface must be emitted as invokeinterface, not invokevirtual - otherwise the JVM rejects the class with IncompatibleClassChangeError: Found interface X, but class was expected. Every CallDetails construction that could target an interface-typed value must set its isTraitCall flag from this predicate; hard-coding false is the Theme-3 interface-dispatch bug. Use requiredFor(ISymbol) when you hold the target type, requiredForValue(ISymbol) when you hold a value symbol whose declared type is the call target.

Two EK9 genera compile to JVM interfaces: SymbolGenus.CLASS_TRAIT (user traits AND built-in traits like Clock/StringInput/HTTPRequest) and SymbolGenus.ANY (the universal org.ek9.lang.Any, which is a hand-written Java interface). Any's genus is NOT CLASS_TRAIT, so a genus-CLASS_TRAIT-only check misses calls dispatched on an Any-typed value (e.g. anyValue?) - reproduced as the Found interface org.ek9.lang.Any crash. FUNCTION_TRAIT is deliberately excluded: it compiles to an abstract class, not an interface.

  • Method Details

    • requiredFor

      public static boolean requiredFor(ISymbol targetType)
      Parameters:
      targetType - the type the call is dispatched on
      Returns:
      true if that type compiles to a JVM interface (trait or Any), so the call needs INVOKEINTERFACE
    • requiredForValue

      public static boolean requiredForValue(ISymbol targetValue)
      As requiredFor(ISymbol) but for a value symbol (field/variable/expression) whose declared type is the call target.
      Parameters:
      targetValue - the value whose declared type the call is dispatched on
      Returns:
      true if that value's type is a trait