Class AggregateSymbol

All Implemented Interfaces:
Serializable, IAggregateSymbol, ICanBeGeneric, ICanCaptureVariables, IScope, IScopedSymbol, ISymbol, ISymbolNature, ITokenReference
Direct Known Subclasses:
AggregateWithTraitsSymbol, AnyTypeSymbol

public class AggregateSymbol extends PossibleGenericSymbol implements IAggregateSymbol, Serializable
This is typically a 'class' or an interface type where it can include the definitions of new properties. These can then be made accessible via the symbol table to its methods. But note there is also a single super 'AggregateSymbol' that maps to a super class so here the resolve can access variables in the super class. i.e. we only support single inheritance - but see AggregateWithTraitsSymbol for 'traits' support. I've also added in a mechanism to parameterize the aggregate like Java generics. In general the resolution would be able to resolve variables in the enclosing scope because that will be module level in EK9, there are new global types and global constants that can appear to exist in the package (module) level scope. So for example it is possible to reference a 'constant' or a 'type' that is defined in the same module or if another module is drawn in through 'references'. In reality (when creating the Java code) the constants and types can just be public statics on a class. For example module "the.mod" that defines Constants could have a class called the.mod._Constants with public final statics defined. So there are two ways to resolve references first is module scope and second is super class type scope.
See Also:
  • Constructor Details

    • AggregateSymbol

      public AggregateSymbol(String name, IScope enclosingScope)
      A simple straight forward aggregate type, like a class or record.
    • AggregateSymbol

      public AggregateSymbol(String name, Optional<ISymbol> type, IScope enclosingScope)
      A simple straight forward aggregate type, like a class or record.
    • AggregateSymbol

      public AggregateSymbol(String name, IScope enclosingScope, List<ISymbol> typeParameterOrArguments)
      An aggregate that can be parameterised, i.e. like a 'List of T' So the name would be 'List' and the parameterTypes would be a single aggregate of a conceptual T.
  • Method Details

    • clone

      public AggregateSymbol clone(IScope withParentAsAppropriate)
      Description copied from interface: ISymbol
      Clone the symbol and re-parent if this symbol like a method should have a parent. Other symbols like VariableSymbols are un-parented
      Specified by:
      clone in interface IAggregateSymbol
      Specified by:
      clone in interface IScope
      Specified by:
      clone in interface IScopedSymbol
      Specified by:
      clone in interface ISymbol
      Overrides:
      clone in class PossibleGenericSymbol
    • cloneIntoAggregateSymbol

      protected AggregateSymbol cloneIntoAggregateSymbol(AggregateSymbol newCopy)
    • getApplication

      public Optional<AggregateSymbol> getApplication()
    • setApplication

      public void setApplication(AggregateSymbol application)
    • addInjectionField

      public void addInjectionField(ISymbol field)
      Record that a field on this aggregate is marked for injection.
    • addOrderingUseBuiltOnThis

      public void addOrderingUseBuiltOnThis(ConceptualAccess.OrderingUse use)
      Record, on a conceptual type parameter, an ordering of a type built on it. Use NoteOrderingUse, never this directly.
    • getOrderingUsesBuiltOnThis

      public List<ConceptualAccess.OrderingUse> getOrderingUsesBuiltOnThis()
      The orderings of a type built on this conceptual type parameter that the generic's body uses. Read through OrderingUsesOf.
    • addOrderingStep

      public void addOrderingStep(ConceptualAccess.OrderingStep step)
      Record, on a conceptual type parameter, a step towards a <=> on its values. Use phase 3's NoteTypeParameterOrdered or NoteOrderingThroughCall, never this directly.
    • getOrderingSteps

      public List<ConceptualAccess.OrderingStep> getOrderingSteps()
      The steps towards a <=> on this conceptual type parameter's values. Read through TypeParameterOrderedInOwnComparison.
    • getInjectionFields

      public Set<ISymbol> getInjectionFields()
      Get all fields marked for injection on this aggregate.
    • addRegistration

      public void addRegistration(RegistrationData registration)
      Add a registration from a 'register' statement in an application block.
    • getRegistrations

      public List<RegistrationData> getRegistrations()
      Get all registrations from 'register' statements in this application.
    • addBlockCallEntry

      public void addBlockCallEntry(BlockCallEntry entry)
      Add a block call entry from a block statement in an application block.
    • getBlockCallEntries

      public List<BlockCallEntry> getBlockCallEntries()
      Get all block call entries from block statements in this application.
    • define

      public void define(ISymbol symbol)
      Description copied from interface: IScope
      Define a Symbol in this scope.
      Specified by:
      define in interface IScope
      Overrides:
      define in class ScopedSymbol
    • getAnySuperTypeOrFunction

      public Optional<IScope> getAnySuperTypeOrFunction()
      Overrides:
      getAnySuperTypeOrFunction in class ScopedSymbol
    • getFriendlyName

      public String getFriendlyName()
      Provides a friendly name of this aggregate that could be presented to the developer.
      Specified by:
      getFriendlyName in interface ISymbol
      Overrides:
      getFriendlyName in class PossibleGenericSymbol
      Returns:
      The friendly name - especially useful for anonymous dynamic types.
    • getAggregateDescription

      public String getAggregateDescription()
      Typically used for synthetically generated aggregates.
      Specified by:
      getAggregateDescription in interface IAggregateSymbol
      Returns:
      A description or the friendly name of no description has been set.
    • setAggregateDescription

      public void setAggregateDescription(String aggregateDescription)
      Typically used for synthetically generated aggregates.
    • getPipeSinkType

      public Optional<String> getPipeSinkType()
      Specified by:
      getPipeSinkType in interface IAggregateSymbol
    • setPipeSinkType

      public void setPipeSinkType(Optional<String> pipeSinkType)
    • getPipeSourceType

      public Optional<String> getPipeSourceType()
    • setPipeSourceType

      public void setPipeSourceType(Optional<String> pipeSourceType)
    • isMarkedAsDispatcher

      public boolean isMarkedAsDispatcher()
      Description copied from interface: IAggregateSymbol
      Is this aggregate a dispatcher or just a normal class component whatever.
      Specified by:
      isMarkedAsDispatcher in interface IAggregateSymbol
      Returns:
      true if marked as a dispatcher.
    • setMarkedAsDispatcher

      public void setMarkedAsDispatcher(boolean markedAsDispatcher)
      Specified by:
      setMarkedAsDispatcher in interface IAggregateSymbol
    • getConstraint

      public ConstraintExpr getConstraint()
      The constraint model for a CLASS_CONSTRAINED aggregate, or null if none/not modellable.
    • setConstraint

      public void setConstraint(ConstraintExpr constraint)
    • isInjectable

      public boolean isInjectable()
      Description copied from interface: ISymbol
      Some classes generated can be injected and others not.
      Specified by:
      isInjectable in interface ISymbol
      Returns:
      true if this can be injected, false if not.
    • setInjectable

      public void setInjectable(boolean injectable)
    • getAllAbstractMethods

      public List<MethodSymbol> getAllAbstractMethods()
      Gets all abstract methods in this aggregate and any super classes.
      Specified by:
      getAllAbstractMethods in interface IAggregateSymbol
      Returns:
      A list of all the methods marked as abstract.
    • getProperties

      public List<ISymbol> getProperties()
      Provides access to the properties on this aggregate - but only this aggregate.
      Specified by:
      getProperties in interface IAggregateSymbol
      Returns:
      The list of properties.
    • getConstructors

      public List<MethodSymbol> getConstructors()
      Description copied from interface: IAggregateSymbol
      A list of all the defined constructors.
      Specified by:
      getConstructors in interface IAggregateSymbol
      Returns:
      The list of constructors
    • getAllEffectiveMethods

      public List<MethodSymbol> getAllEffectiveMethods()
      Description copied from interface: IAggregateSymbol
      Gets all methods that are effective, by this I mean if supers (classes or traits) have the same method name but, it has been overridden then we would only retain the 'overridden' one as that has taken effect. In the case of a trait that has multiple traits where the same method has been overridden in the trait only one method is now in effect. However, if there are multiple traits (or a super has the same method name) we would end up with 'duplicate' methods of the same name in this list 'CheckConflictingMethods' will need to detect this.
      Specified by:
      getAllEffectiveMethods in interface IAggregateSymbol
      Returns:
      A List of methods that are in effect.
    • getAllMethods

      public List<MethodSymbol> getAllMethods()
      Description copied from interface: IAggregateSymbol
      Get all methods on this and any supers or traits.
      Specified by:
      getAllMethods in interface IAggregateSymbol
      Returns:
      the list
    • getAllOperators

      public List<MethodSymbol> getAllOperators()
      Description copied from interface: IAggregateSymbol
      Get all operators on this and any supers or traits.
      Specified by:
      getAllOperators in interface IAggregateSymbol
      Returns:
      the list
    • getAllNonAbstractMethods

      public List<MethodSymbol> getAllNonAbstractMethods()
      Description copied from interface: IAggregateSymbol
      Get all methods not marked as abstract in this or any supers.
      Specified by:
      getAllNonAbstractMethods in interface IAggregateSymbol
      Returns:
      The list.
    • getAllNonAbstractMethodsInThisScopeOnly

      public List<MethodSymbol> getAllNonAbstractMethodsInThisScopeOnly()
      Description copied from interface: IAggregateSymbol
      Get all methods in this scope only that are not abstract.
      Specified by:
      getAllNonAbstractMethodsInThisScopeOnly in interface IAggregateSymbol
      Returns:
      The list
    • getAllAbstractMethodsInThisScopeOnly

      public List<MethodSymbol> getAllAbstractMethodsInThisScopeOnly()
      Description copied from interface: IAggregateSymbol
      Get all methods in this scope only that are abstract.
      Specified by:
      getAllAbstractMethodsInThisScopeOnly in interface IAggregateSymbol
      Returns:
      The list
    • getAllMethodInThisScopeOnly

      public List<MethodSymbol> getAllMethodInThisScopeOnly()
      Description copied from interface: IAggregateSymbol
      All methods abstract and non-abstract in this scope.
      Specified by:
      getAllMethodInThisScopeOnly in interface IAggregateSymbol
    • isImplementingInSomeWay

      public boolean isImplementingInSomeWay(IAggregateSymbol aggregate)
      Description copied from interface: IAggregateSymbol
      Only really used by aggregates that can have one or more traits. But also super classes or super traits. So can either be implementing directly, super, super - super or traits and supe traits.
      Specified by:
      isImplementingInSomeWay in interface IAggregateSymbol
    • getAllTraits

      public List<AggregateWithTraitsSymbol> getAllTraits()
      Specified by:
      getAllTraits in interface IAggregateSymbol
    • addTraitsIfNotPresent

      protected void addTraitsIfNotPresent(List<AggregateWithTraitsSymbol> exiting, List<AggregateWithTraitsSymbol> additions)
    • isExtensionOfInjectable

      public boolean isExtensionOfInjectable()
      Description copied from interface: ISymbol
      While this aggregate itself might not able been marked as injectable Does this extend an aggregate that is marked as injectable.
      Specified by:
      isExtensionOfInjectable in interface ISymbol
      Returns:
      true if this is injectable or any of its supers area
    • getUnCoercedAssignableCostTo

      public double getUnCoercedAssignableCostTo(ISymbol s)
      Specified by:
      getUnCoercedAssignableCostTo in interface ISymbol
      Overrides:
      getUnCoercedAssignableCostTo in class Symbol
    • getSuperAggregate

      public Optional<IAggregateSymbol> getSuperAggregate()
      Specified by:
      getSuperAggregate in interface IAggregateSymbol
    • setSuperAggregate

      public void setSuperAggregate(Optional<IAggregateSymbol> superAggregate)
      Set the 'super' of this type.
      Specified by:
      setSuperAggregate in interface IAggregateSymbol
    • setSuperAggregate

      public void setSuperAggregate(IAggregateSymbol baseSymbol)
      Specified by:
      setSuperAggregate in interface IAggregateSymbol
    • hasImmediateSuper

      public boolean hasImmediateSuper(IAggregateSymbol theSuper)
    • isInAggregateHierarchy

      public boolean isInAggregateHierarchy(IAggregateSymbol theAggregateToCheck)
      Does the aggregate passed in exist in this type hierarchy. This does include a check that this is the same aggregate.
      Specified by:
      isInAggregateHierarchy in interface IAggregateSymbol
    • setType

      public ISymbol setType(Optional<ISymbol> type)
      Specified by:
      setType in interface ISymbol
      Overrides:
      setType in class Symbol
    • getType

      public Optional<ISymbol> getType()
      Specified by:
      getType in interface ISymbol
      Overrides:
      getType in class Symbol
    • getAllSymbolsMatchingName

      public List<ISymbol> getAllSymbolsMatchingName(String symbolName)
      Description copied from interface: IScope
      Return a list of all the symbols that match the name. So for class and traits this must include supers and traits.
      Specified by:
      getAllSymbolsMatchingName in interface IScope
      Overrides:
      getAllSymbolsMatchingName in class ScopedSymbol
    • resolveMatchingMethods

      public MethodSymbolSearchResult resolveMatchingMethods(MethodSymbolSearch search, MethodSymbolSearchResult result)
      Description copied from interface: IScope
      Looks in scope and parent scopes.
      Specified by:
      resolveMatchingMethods in interface IAggregateSymbol
      Specified by:
      resolveMatchingMethods in interface IScope
      Overrides:
      resolveMatchingMethods in class ScopedSymbol
    • resolveMember

      public Optional<ISymbol> resolveMember(SymbolSearch search)
      Just try and resolve a member in this or super scopes.
      Specified by:
      resolveMember in interface IAggregateSymbol
      Specified by:
      resolveMember in interface IScope
      Overrides:
      resolveMember in class ScopedSymbol
    • methodNotPresent

      protected boolean methodNotPresent(List<MethodSymbol> defined, MethodSymbol checkMethod)
    • equals

      public boolean equals(Object o)
      Description copied from class: Symbol
      Two symbols are the same symbol when they agree on name, category, genus, mutability AND the declaration site they came from.

      The source token is part of identity deliberately. Name alone is not enough: symbol names are unqualified here, so two unrelated variables both called count, or two types called Foo in different modules, would otherwise compare equal. The compiler relies on telling those apart - CodeFlowMap keys initialisation state on Map<IScope, Map<ISymbol, SymbolAccess>>, and conflating two same-named declarations there makes flow analysis attribute one variable's initialisation to another.

      That distinction used to be present ONLY in Symbol.hashCode(), which is why this looked like it worked: two same-named symbols compared equal yet hashed apart, so hash collections usually - but not reliably - kept them separate, while any direct equals call saw them as one. Encoding it here makes the two agree. See SymbolEqualsHashCodeContractTest.

      Overrides:
      equals in class PossibleGenericSymbol
    • hashCode

      public int hashCode()
      Description copied from class: Symbol
      Mixes in exactly the fields Symbol.equals(Object) compares, and nothing else.

      A hashCode may legitimately use FEWER fields than equals (that only causes collisions, which are correct), but never MORE: any extra field makes two symbols that compare equal land in different buckets, so a HashSet silently holds visible duplicates and a HashMap lookup misses an entry that is present. This method used to mix in purity, which no equals at THIS level consults - purity belongs in FunctionSymbol, the level whose equals compares it. The source token stays, and is now matched by Symbol.equals(Object). See SymbolEqualsHashCodeContractTest.

      Overrides:
      hashCode in class PossibleGenericSymbol