Class ScopeStack
java.lang.Object
org.ek9lang.compiler.common.ScopeStack
This stack object is only designed to be used when first parsing.
The idea is to actually associate the scope with the specific contexts by
putting them in a ParseTreeProperty of Scope, this tree is held in the
ParsedModule. So why do we need this stack? That is because as we
listen/visit the parse tree we need to both create the scope and record it in
the parsed module. But also put it on to a stack so that when we return for
each level of the parse tree we can get back to the right scope. I don't want
to use a 'getEnclosingScope' method on each scope as the very top level has
to be thread safe. Plus it exposes information that should only be available
to the scope itself - not any other bit of code.
This class also has logic and code to be able to traverse back up the 'structure stack'.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanisEmpty()True if stack has no contents.booleanChecks if the current scope is within a loop (for or while).peek()Take a look at the top of the stack.pop()Pop a scope of the stack (exception is empty.Push a scope on to this stack.traverseBackUpStack(IScope.ScopeType scopeType) Navigates back up the scope stack to find the first match of the scope type passed in.traverseBackUpStackBeyond(IScope beyond, IScope.ScopeType scopeType) LiketraverseBackUpStack(IScope.ScopeType), but only considers the scopes OUTSIDEbeyond- the ones pushed before it.Navigate back up the scope stack to find the first enclosing method (there may not be one).LiketraverseBackUpStackToMethodOrFunction()but skips dynamic (anonymous) functions/classes — those introduced by dynamic function/class declarations such as MutexKey bodies and closures (markedIScope.ScopeType.DYNAMIC_BLOCK).Locates the outer function or method (if possible, not always possible Applications for example).The nearest enclosing aggregate - a dynamic class when the scope is inside one, otherwise the named class, component, service, trait, record or program around it.LiketraverseBackUpStackToNearestAggregate(), but only considers the scopes OUTSIDEbeyond- the ones pushed before it (anull, or a scope not on the stack, means the whole stack).The nearest enclosing GENERIC type or function - the one whose type parameters a body here can name.
-
Constructor Details
-
ScopeStack
-
-
Method Details
-
getVeryBaseScope
-
push
-
peek
Take a look at the top of the stack. -
pop
Pop a scope of the stack (exception is empty. -
isEmpty
public boolean isEmpty()True if stack has no contents. -
traverseBackUpStack
Navigates back up the scope stack to find the first match of the scope type passed in. This is useful because dynamic classes and functions do not use an enclosing scope of the scope they are in. They get pulled out to module level (by design). -
traverseBackUpStackBeyond
LiketraverseBackUpStack(IScope.ScopeType), but only considers the scopes OUTSIDEbeyond- the ones pushed before it. Anull(or a scope not on the stack) means the whole stack, from the top.This is how code that is evaluated in the scope AROUND a construct is judged there: a dynamic function's or class's capture list is visited with the dynamic construct already on the stack, yet each capture expression is evaluated where the construct is created (the enclosing method, function or dynamic body).
-
traverseBackUpStackToMethodOrFunction
Locates the outer function or method (if possible, not always possible Applications for example). -
traverseBackUpStackToEnclosingNamedMethodOrFunction
LiketraverseBackUpStackToMethodOrFunction()but skips dynamic (anonymous) functions/classes — those introduced by dynamic function/class declarations such as MutexKey bodies and closures (markedIScope.ScopeType.DYNAMIC_BLOCK). Returns the nearest *named* enclosing method or function, so a construct lexically inside an anonymous body (e.g. aMutexLock.enter()call within a MutexKey lambda) is attributed to the enclosing named callable rather than to the anonymous body itself — the latter only has a synthetic name (e.g._Function_<hash>, displayed asfn). -
traverseBackUpStackToNearestAggregate
The nearest enclosing aggregate - a dynamic class when the scope is inside one, otherwise the named class, component, service, trait, record or program around it. A method, a block and a dynamic function are passed through (none of them holds fields), so a dynamic function inside a class method answers the class. There is none inside a standalone function. -
traverseBackUpStackToNearestAggregateBeyond
LiketraverseBackUpStackToNearestAggregate(), but only considers the scopes OUTSIDEbeyond- the ones pushed before it (anull, or a scope not on the stack, means the whole stack). A dynamic class's capture list is visited with that dynamic class already pushed, yet it is evaluated by the code around it. -
traverseBackUpStackToNearestGeneric
The nearest enclosing GENERIC type or function - the one whose type parameters a body here can name. A method, a block, a dynamic function and a dynamic class are passed through (none of them is generic), so a dynamic function inside a generic class's method answers the generic class. -
traverseBackUpStackToEnclosingMethod
Navigate back up the scope stack to find the first enclosing method (there may not be one). So if this were called in a function or an application for example - there will not be an enclosing method.- Returns:
- The Optional method located.
-
isWithinLoopScope
public boolean isWithinLoopScope()Checks if the current scope is within a loop (for or while). This is useful for determining whether a variable assignment inside a loop should suppress the "not referenced after assignment" check.- Returns:
- true if currently within a ForSymbol or WhileSymbol scope.
-