Class AggregateWithTraitsSymbol

All Implemented Interfaces:
Serializable, IAggregateSymbol, ICanBeGeneric, ICanCaptureVariables, IScope, IScopedSymbol, ISymbol, ISymbolNature, ITokenReference

public class AggregateWithTraitsSymbol extends AggregateSymbol
An aggregate, but one that can have zero or more traits (like interfaces).
See Also:
  • Constructor Details

    • AggregateWithTraitsSymbol

      public AggregateWithTraitsSymbol(String name, IScope enclosingScope)
    • AggregateWithTraitsSymbol

      public AggregateWithTraitsSymbol(String name, Optional<ISymbol> type, IScope enclosingScope)
  • Method Details

    • cloneIntoAggregateWithTraitsSymbol

      protected AggregateWithTraitsSymbol cloneIntoAggregateWithTraitsSymbol(AggregateWithTraitsSymbol newCopy)
    • addTrait

      public void addTrait(AggregateWithTraitsSymbol traitSymbol)
      mark this aggregate as having additional 'trait'.
    • hasImmediateTrait

      public boolean hasImmediateTrait(IAggregateSymbol trait)
      Does this aggregate have the trait passed in as an immediate trait. i.e. one it implements itself. Note this is different from being compatible with the trait via hierarchy!
      Parameters:
      trait - The trait to check.
      Returns:
      true if it does false otherwise.
    • addAllowedExtender

      public void addAllowedExtender(IAggregateSymbol extenderSymbol)
      For use with constraining types to be limited to a declared set.
    • getAllowedExtenders

      public List<IAggregateSymbol> getAllowedExtenders()
    • isAllowingExtensionBy

      public boolean isAllowingExtensionBy(IAggregateSymbol extenderSymbol)
      Is the extender allowed to implement this aggregate (normally a trait).
      Parameters:
      extenderSymbol - The class (normally the one we are testing)
      Returns:
      true if extending is allowed.
    • 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 AggregateSymbol
    • clone

      public AggregateWithTraitsSymbol 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 AggregateSymbol
    • getUnCoercedAssignableCostTo

      public double getUnCoercedAssignableCostTo(ISymbol s)
      Specified by:
      getUnCoercedAssignableCostTo in interface ISymbol
      Overrides:
      getUnCoercedAssignableCostTo in class AggregateSymbol
    • getAssignableCostTo

      public double getAssignableCostTo(ISymbol s)
      Specified by:
      getAssignableCostTo in interface ISymbol
      Overrides:
      getAssignableCostTo in class Symbol
    • isImplementingInSomeWay

      public boolean isImplementingInSomeWay(IAggregateSymbol traitSymbol)
      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
      Overrides:
      isImplementingInSomeWay in class AggregateSymbol
    • getTraits

      public List<IAggregateSymbol> getTraits()
      Get the traits that this aggregates implements.
      Returns:
      The list of traits.
    • getAllExtensionConstrainedTraits

      public List<AggregateWithTraitsSymbol> getAllExtensionConstrainedTraits()
      Gets all sealed ancestors (traits AND super classes) that have extension constraints. Walks the full trait hierarchy AND the super class chain to find all ancestors where 'allow only' is declared. The caller checks whether this aggregate is permitted.
    • getAllTraits

      public List<AggregateWithTraitsSymbol> getAllTraits()
      Get all the traits this aggregate implements - this means all the traits any of these traits extends. But also going up the class supers and getting those traits and any of the traits they extend.
      Specified by:
      getAllTraits in interface IAggregateSymbol
      Overrides:
      getAllTraits in class AggregateSymbol
    • 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
      Overrides:
      getAllEffectiveMethods in class AggregateSymbol
      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
      Overrides:
      getAllMethods in class AggregateSymbol
      Returns:
      the list
    • getAllAbstractMethods

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

      public boolean isExtensionConstrained()
    • 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
      Overrides:
      getAllNonAbstractMethods in class AggregateSymbol
      Returns:
      The list.
    • 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 AggregateSymbol
    • resolveMember

      public Optional<ISymbol> resolveMember(SymbolSearch search)
      Description copied from class: AggregateSymbol
      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 AggregateSymbol
    • resolveWithParentScope

      public Optional<ISymbol> resolveWithParentScope(SymbolSearch search)
      Resolve using super aggregate and or any traits we have. Look in our traits first then go to the normal AggregateSymbol resolution.
      Overrides:
      resolveWithParentScope in class ScopedSymbol
    • 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 AggregateSymbol
    • 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 AggregateSymbol