Class ScopedSymbol

java.lang.Object
org.ek9lang.compiler.symbols.Symbol
org.ek9lang.compiler.symbols.ScopedSymbol
All Implemented Interfaces:
Serializable, IScope, IScopedSymbol, ISymbol, ISymbolNature, ITokenReference
Direct Known Subclasses:
CaptureScopedSymbol, ControlSymbol, ForSymbol, MethodSymbol, StackConsistencyScope, WhileSymbol

public class ScopedSymbol extends Symbol implements IScopedSymbol
Represents a symbol that also has a scope. Typically, this means it can have variables, methods and function declared within it. But also includes block scoped constructs like for loops for example. It's turning into a bit of a 'bitbucket' because I don't really want duplication at the FunctionSymbol and AggregateSymbol level. So some things like CaptureVariables are not really applicable (yet). But I may use them later for other constructs and controls. I may refactor the generic bits out to a new Symbol type between ScopedSymbol and Symbol
See Also:
  • Constructor Details

  • Method Details

    • clone

      public ScopedSymbol 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 IScope
      Specified by:
      clone in interface IScopedSymbol
      Specified by:
      clone in interface ISymbol
      Overrides:
      clone in class Symbol
    • cloneIntoScopeSymbol

      protected ScopedSymbol cloneIntoScopeSymbol(ScopedSymbol newCopy)
    • copyScopedSymbolProperties

      public ScopedSymbol copyScopedSymbolProperties(ScopedSymbol newCopy)
      Just copies the properties over.
    • getOuterMostTypeOrFunction

      public Optional<IScopedSymbol> getOuterMostTypeOrFunction()
    • setOuterMostTypeOrFunction

      public void setOuterMostTypeOrFunction(IScopedSymbol outerMostTypeOrFunction)
    • getActualScope

      public LocalScope getActualScope()
    • getScopeType

      public IScope.ScopeType getScopeType()
      Specified by:
      getScopeType in interface IScope
    • setScopeType

      public void setScopeType(IScope.ScopeType scopeType)
    • resolveWithParentScope

      public Optional<ISymbol> resolveWithParentScope(SymbolSearch search)
      Resolve with super type/function or via enclosing scope.
    • isMarkedPure

      public boolean isMarkedPure()
      Description copied from interface: ISymbol
      This symbol itself can be marked as pure - i.e. an operator with no side effects.
      Specified by:
      isMarkedPure in interface IScope
      Specified by:
      isMarkedPure in interface ISymbol
      Overrides:
      isMarkedPure in class Symbol
      Returns:
      true if pure, false otherwise. By default, false - lets assume the worst.
    • setMarkedPure

      public void setMarkedPure(boolean markedPure)
      Overrides:
      setMarkedPure in class Symbol
    • isNotMarkedPure

      public boolean isNotMarkedPure()
    • isMutable

      public boolean isMutable()
      Description copied from interface: ISymbol
      Even constants can be mutable until set. then they change to being none mutable. Likewise in 'pure' scopes a variable can be mutable until it is first set then none mutable.
      Specified by:
      isMutable in interface ISymbol
      Overrides:
      isMutable in class Symbol
      Returns:
      If this symbol is mutable or not.
    • isTerminatedNormally

      public boolean isTerminatedNormally()
      Description copied from interface: IScope
      Typically in a scoped block we can encounter situations (like exceptions) that cause the block to end (terminate) early.
      Specified by:
      isTerminatedNormally in interface IScope
    • getEncounteredExceptionToken

      public IToken getEncounteredExceptionToken()
      Specified by:
      getEncounteredExceptionToken in interface IScope
    • setEncounteredExceptionToken

      public void setEncounteredExceptionToken(IToken encounteredExceptionToken)
      Specified by:
      setEncounteredExceptionToken in interface IScope
    • getScopeName

      public String getScopeName()
      Specified by:
      getScopeName in interface IScope
    • getFriendlyScopeName

      public String getFriendlyScopeName()
      Description copied from interface: IScope
      Useful for printing out errors and information. The scope name might be a complex generated name used internally a bit like symbol names are. So some items are both scopes and symbols - so ideally we'd want to use a friendly name where possible.
      Specified by:
      getFriendlyScopeName in interface IScope
      Returns:
      The friendly name to be used for the developer.
    • define

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

      public IScope getEnclosingScope()
      Specified by:
      getEnclosingScope in interface IScope
    • getAnySuperTypeOrFunction

      public Optional<IScope> getAnySuperTypeOrFunction()
    • getSymbolsForThisScope

      public List<ISymbol> getSymbolsForThisScope()
      Description copied from interface: IScope
      Provide a list of all the parameters held in this scope and only this scope.
      Specified by:
      getSymbolsForThisScope in interface IScope
    • 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
    • resolveMatchingMethods

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

      public MethodSymbolSearchResult resolveMatchingMethodsInThisScopeOnly(MethodSymbolSearch search, MethodSymbolSearchResult result)
      Description copied from interface: IScope
      Look in own scope just for methods and return all those that could match. ideally there would be one in the case of ambiguities there will be more.
      Specified by:
      resolveMatchingMethodsInThisScopeOnly in interface IScope
    • resolveInThisScopeOnly

      public Optional<ISymbol> resolveInThisScopeOnly(SymbolSearch search)
      Description copied from interface: IScope
      Just look in own scope.
      Specified by:
      resolveInThisScopeOnly in interface IScope
    • resolve

      public Optional<ISymbol> resolve(SymbolSearch search)
      Description copied from interface: IScope
      Find the nearest symbol of that name up the scope tree.
      Specified by:
      resolve in interface IScope
    • resolveMember

      public Optional<ISymbol> resolveMember(SymbolSearch search)
      Description copied from interface: IScope
      Just resolve on this or supers/traits - but not anything outside of the class hierarchy.
      Specified by:
      resolveMember in interface IScope
    • findNearestNonBlockScopeInEnclosingScopes

      public Optional<ScopedSymbol> findNearestNonBlockScopeInEnclosingScopes()
      Specified by:
      findNearestNonBlockScopeInEnclosingScopes in interface IScope
    • findNearestDynamicBlockScopeInEnclosingScopes

      public Optional<ScopedSymbol> findNearestDynamicBlockScopeInEnclosingScopes()
      Specified by:
      findNearestDynamicBlockScopeInEnclosingScopes in interface IScope
    • isScopeAMatchForEnclosingScope

      public boolean isScopeAMatchForEnclosingScope(IScope toCheck)
      Specified by:
      isScopeAMatchForEnclosingScope in interface IScope
    • 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 Symbol
    • 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 Symbol