Class AbstractScope<S extends AbstractScope<S,​V>,​V extends AbstractVar<S,​V>>

  • All Implemented Interfaces:
    StaticScope, java.io.Serializable
    Direct Known Subclasses:
    Scope, TypedScope

    public abstract class AbstractScope<S extends AbstractScope<S,​V>,​V extends AbstractVar<S,​V>>
    extends java.lang.Object
    implements StaticScope, java.io.Serializable
    Scope contains information about a variable scope in JavaScript. Scopes can be nested, a scope points back to its parent scope. A Scope contains information about variables defined in that scope.

    ES 2015 introduces new scoping rules, which adds some complexity to this class. In particular, scopes fall into two mutually exclusive categories: block and container. Block scopes are all scopes whose roots are blocks, as well as any control structures whose optional blocks are omitted. These scopes did not exist at all prior to ES 2015. Container scopes comprise function scopes, global scopes, and module scopes, and (aside from modules, which didn't exist in ES5) corresponds to the ES5 scope rules. This corresponds roughly to one container scope per CFG root (but not exactly, due to SCRIPT-level CFGs).

    All container scopes, plus the outermost block scope within a function (i.e. the function block scope) are considered hoist scopes. All functions thus have two hoist scopes: the function scope and the function block scope. Hoist scopes are relevant because "var" declarations are hoisted to the closest hoist scope, as opposed to "let" and "const" which always apply to the specific scope in which they occur.

    Note that every function actually has two distinct hoist scopes: a container scope on the FUNCTION node, and a block-scope on the top-level BLOCK in the function (the "function block"). Local variables are declared on the function block, while parameters and optionally the function name (if it bleeds, i.e. from a named function expression) are declared on the container scope. This is required so that default parameter initializers can refer to names from outside the function that could possibly be shadowed in the function block. But these scopes are not fully independent of one another, since the language does not allow a top-level local variable to shadow a parameter name - so in some situations these scopes must be treated as a single scope.

    See Also:
    NodeTraversal, Serialized Form
    • Method Detail

      • getDepth

        public abstract int getDepth()
        The depth of the scope. The global scope has depth 0.
      • getParent

        public abstract S getParent()
        Returns the parent scope, or null if this is the global scope.
      • toString

        public final java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • untyped

        public Scope untyped()
      • getRootNode

        public Node getRootNode()
        Gets the container node of the scope. This is typically the FUNCTION node or the global BLOCK/SCRIPT node.
        Specified by:
        getRootNode in interface StaticScope
      • getGlobalScope

        public final S getGlobalScope()
        Walks up the tree to find the global scope.
      • getParentScope

        public final S getParentScope()
        Description copied from interface: StaticScope
        Returns the scope enclosing this one or null if none.
        Specified by:
        getParentScope in interface StaticScope
      • hasOwnImplicitSlot

        protected boolean hasOwnImplicitSlot​(@Nullable
                                             com.google.javascript.jscomp.AbstractScope.ImplicitVar name)
        Returns true iff this scope implies a slot with the given name.
      • hasOwnSlot

        public final boolean hasOwnSlot​(java.lang.String name)
        Returns true if a variable is declared in this scope, with no recursion.
      • hasSlot

        public final boolean hasSlot​(java.lang.String name)
        Returns true if a variable is declared in this or any parent scope.
      • getOwnSlot

        public final V getOwnSlot​(java.lang.String name)
        Description copied from interface: StaticScope
        Like getSlot but does not recurse into parent scopes.
        Specified by:
        getOwnSlot in interface StaticScope
      • getSlot

        public final V getSlot​(java.lang.String name)
        Description copied from interface: StaticScope
        Returns any defined slot within this scope for this name. This call continues searching through parent scopes if a slot with this name is not found in the current scope.
        Specified by:
        getSlot in interface StaticScope
        Parameters:
        name - The name of the variable slot to look up.
        Returns:
        The defined slot for the variable, or null if no definition exists.
      • getVar

        public V getVar​(java.lang.String name)
        Returns the variable, may be null

        Non-final for TypedScope which needs to handle qualified names.

      • getArgumentsVar

        public final V getArgumentsVar()
        Get a unique Var object to represent "arguments" within this scope.

        This explicitly excludes user declared variables that are names "arguments". It only returns special "arguments" variable that is inherent to a function.

      • getVarIterable

        public java.lang.Iterable<V> getVarIterable()
        Return an iterable over all of the variables declared in this scope (except the special 'arguments' variable).
      • getAllAccessibleVariables

        public final java.lang.Iterable<V> getAllAccessibleVariables()
        Return an iterable over all of the variables accessible to this scope (i.e. the variables in this scope and its parent scopes). Any variables declared in the local scope with the same name as a variable declared in a parent scope gain precedence - if let x exists in the block scope, a declaration let x from the parent scope would not be included because the parent scope's variable gets shadowed.

        The iterable contains variables from inner scopes before adding variables from outer parent scopes.

        We do not include the special 'arguments' variable.

      • getAllSymbols

        public java.lang.Iterable<V> getAllSymbols()
      • getVarCount

        public int getVarCount()
        Returns number of variables in this scope (excluding the special 'arguments' variable)
      • isGlobal

        public boolean isGlobal()
        Returns whether this is the global scope.
      • isLocal

        public boolean isLocal()
        Returns whether this is a local scope (i.e. not the global scope).
      • isBlockScope

        public final boolean isBlockScope()
      • isFunctionBlockScope

        public final boolean isFunctionBlockScope()
      • isFunctionScope

        public final boolean isFunctionScope()
      • isModuleScope

        public final boolean isModuleScope()
      • isCatchScope

        public final boolean isCatchScope()
      • getClosestHoistScope

        public final S getClosestHoistScope()
        If a var were declared in this scope, return the scope it would be hoisted to.

        For function scopes, we return back the scope itself, since even though there is no way to declare a var inside function parameters, it would make even less sense to say that such declarations would be "hoisted" somewhere else.

      • getClosestContainerScope

        public final S getClosestContainerScope()
        Returns the closest container scope. This is equivalent to what the current scope would have been for non-ES6 scope creators, and is thus useful for migrating code to use block scopes.