Gets the scope that contains the given node. If {@code n} is a function name, we return the
scope that contains the function, not the function itself.
422527
public SymbolScope getEnclosingScope(Node n) {
    Node current = n.getParent();
    if (n.isName() && n.getParent().isFunction()) {
      current = current.getParent();
    }

    for (; current != null; current = current.getParent()) {
      if (scopes.containsKey(current)) {
        return scopes.get(current);
      }
    }
    return null;
  }
426955
public static Element getDeclaredElement(TreeNode node) {
    if (node instanceof AbstractTypeDeclaration) {
      return ((AbstractTypeDeclaration) node).getTypeElement();
    } else if (node instanceof MethodDeclaration) {
      return ((MethodDeclaration) node).getExecutableElement();
    } else if (node instanceof VariableDeclaration) {
      return ((VariableDeclaration) node).getVariableElement();
    }
    return null;
  }
94322
def _scope_lookup(self, node, name, offset=0):
        """"""
        try:
            stmts = node._filter_stmts(self.locals[name], self, offset)
        except KeyError:
            stmts = ()
        if stmts:
            return self, stmts
        if self.parent:  # i.e. not Module
            # nested scope: if parent scope is a function, that's fine
            # else jump to the module
            pscope = self.parent.scope()
            if not pscope.is_function:
                pscope = pscope.root()
            return pscope.scope_lookup(node, name)
        return builtin_lookup(name)
281406
private boolean isJSDocOnFunctionNode(Node n, JSDocInfo info) {
    switch (n.getToken()) {
      case FUNCTION:
      case GETTER_DEF:
      case SETTER_DEF:
      case MEMBER_FUNCTION_DEF:
      case STRING_KEY:
      case COMPUTED_PROP:
      case EXPORT:
        return true;
      case GETELEM:
      case GETPROP:
        if (n.getFirstChild().isQualifiedName()) {
          // assume qualified names may be function declarations
          return true;
        }
        return false;
      case VAR:
      case LET:
      case CONST:
      case ASSIGN:
        {
          Node lhs = n.getFirstChild();
          Node rhs = NodeUtil.getRValueOfLValue(lhs);
          if (rhs != null && isClass(rhs) && !info.isConstructor()) {
            return false;
          }

          // TODO(b/124081098): Check that the RHS of the assignment is a
          // function. Note that it can be a FUNCTION node, but it can also be
          // a call to goog.abstractMethod, goog.functions.constant, etc.
          return true;
        }
      default:
        return false;
    }
  }
611811
static boolean isTryCatchNodeContainer(Node n) {
    Node parent = n.getParent();
    return parent.isTry()
        && parent.getSecondChild() == n;
  }
1233097
private boolean inLoop(Node n) {
    Node enclosingNode = NodeUtil.getEnclosingNode(n, isLoopOrFunction);
    return enclosingNode != null && !enclosingNode.isFunction();
  }
400111
private boolean callMeetsBlockInliningRequirements(
      Reference ref, final Node fnNode, ImmutableSet<String> namesToAlias) {
    // Note: functions that contain function definitions are filtered out
    // in isCandidateFunction.

    // TODO(johnlenz): Determining if the called function contains VARs
    // or if the caller contains inner functions accounts for 20% of the
    // run-time cost of this pass.

    // Don't inline functions with var declarations into a scope with inner
    // functions as the new vars would leak into the inner function and
    // cause memory leaks.
    boolean fnContainsVars = NodeUtil.has(
        NodeUtil.getFunctionBody(fnNode),
        new NodeUtil.MatchDeclaration(),
        new NodeUtil.MatchShallowStatement());
    boolean forbidTemps = false;
    if (!ref.scope.getClosestHoistScope().isGlobal()) {
      Node fnCallerBody = ref.scope.getClosestHoistScope().getRootNode();

      // Don't allow any new vars into a scope that contains eval or one
      // that contains functions (excluding the function being inlined).
      Predicate<Node> match = new Predicate<Node>(){
        @Override
        public boolean apply(Node n) {
          if (n.isName()) {
            return n.getString().equals("eval");
          }
          if (!assumeMinimumCapture && n.isFunction()) {
            return n != fnNode;
          }
          return false;
        }
      };
      forbidTemps = NodeUtil.has(fnCallerBody, match, NodeUtil.MATCH_NOT_FUNCTION);
    }

    if (fnContainsVars && forbidTemps) {
      return false;
    }

    // If the caller contains functions or evals, verify we aren't adding any
    // additional VAR declarations because aliasing is needed.
    if (forbidTemps) {
      ImmutableMap<String, Node> args =
          FunctionArgumentInjector.getFunctionCallParameterMap(
              fnNode, ref.callNode, this.safeNameIdSupplier);
      boolean hasArgs = !args.isEmpty();
      if (hasArgs) {
        // Limit the inlining
        Set<String> allNamesToAlias = new HashSet<>(namesToAlias);
        FunctionArgumentInjector.maybeAddTempsForCallArguments(
            compiler, fnNode, args, allNamesToAlias, compiler.getCodingConvention());
        if (!allNamesToAlias.isEmpty()) {
          return false;
        }
      }
    }

    return true;
  }
367195
function usesScopeName(scopeNames, node) {
    function usesScope(root) {
        return usesScopeName(scopeNames, root)
    }
    if (_.isEmpty(scopeNames)) {
        return false
    }
    // rt-if="x"
    if (node.type === 'Identifier') {
        return _.includes(scopeNames, node.name)
    }
    // rt-if="e({key1: value1})"
    if (node.type === 'Property') {
        return usesScope(node.value)
    }
    // rt-if="e.x" or rt-if="e1[e2]"
    if (node.type === 'MemberExpression') {
        return node.computed ? usesScope(node.object) || usesScope(node.property) : usesScope(node.object)
    }
    // rt-if="!e"
    if (node.type === 'UnaryExpression') {
        return usesScope(node.argument)
    }
    // rt-if="e1 || e2" or rt-if="e1 | e2"
    if (node.type === 'LogicalExpression' || node.type === 'BinaryExpression') {
        return usesScope(node.left) || usesScope(node.right)
    }
    // rt-if="e1(e2, ... eN)"
    if (node.type === 'CallExpression') {
        return usesScope(node.callee) || _.some(node.arguments, usesScope)
    }
    // rt-if="f({e1: e2})"
    if (node.type === 'ObjectExpression') {
        return _.some(node.properties, usesScope)
    }
    // rt-if="e1[e2]"
    if (node.type === 'ArrayExpression') {
        return _.some(node.elements, usesScope)
    }
    return false
}
625808
function fetchScope(element) {
            var scope;
            while (!scope && element.length) {
              scope = element.data('_scope');
              if (!scope) {
                element = element.parent();
              }
            }
            return scope;
          }
318588
function isScope(node, parent) {
  if (t.isBlockStatement(node) && t.isFunction(parent, { body: node })) {
    return false;
  }

  return t.isScopable(node);
}
872973
function getScope(scopeManager, currentNode) {

    // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope.
    const inner = currentNode.type !== "Program";

    for (let node = currentNode; node; node = node.parent) {
        const scope = scopeManager.acquire(node, inner);

        if (scope) {
            if (scope.type === "function-expression-name") {
                return scope.childScopes[0];
            }
            return scope;
        }
    }

    return scopeManager.scopes[0];
}
1330557
public Node getScopeRoot() {
    int roots = scopeRoots.size();
    if (roots > 0) {
      return scopeRoots.get(roots - 1);
    } else {
      AbstractScope<?, ?> s = scopes.peek();
      return s != null ? s.getRootNode() : null;
    }
  }
161628
static Node getExceptionHandler(Node n) {
    for (Node cur = n;
        !cur.isScript() && !cur.isFunction();
        cur = cur.getParent()) {
      Node catchNode = getCatchHandlerForBlock(cur);
      if (catchNode != null) {
        return catchNode;
      }
    }
    return null;
  }
944404
private void visitMemberFunctionDefInObjectLit(Node n, Node parent) {
    String name = n.getString();
    Node nameNode = n.getFirstFirstChild();
    Node stringKey = withType(IR.stringKey(name, n.getFirstChild().detach()), n.getJSType());
    stringKey.setJSDocInfo(n.getJSDocInfo());
    parent.replaceChild(n, stringKey);
    stringKey.useSourceInfoFrom(nameNode);
    compiler.reportChangeToEnclosingScope(stringKey);
  }
228429
function isSelfReference(ref, nodes) {
            let scope = ref.from;

            while (scope) {
                if (nodes.indexOf(scope.block) >= 0) {
                    return true;
                }

                scope = scope.upper;
            }

            return false;
        }
1133221
public boolean hasChildScope(ScopeType type, String name) {
        log.debug("Has child scope? {} in {}", name, this);
        return children.getBasicScope(type, name) != null;
    }
397310
private void traverseFunction(Node n, Node parent) {
    final Node fnName = n.getFirstChild();
    // NOTE: If a function declaration is the root of a traversal, then we will treat it as a
    // function expression (since 'parent' is null, even though 'n' actually has a parent node) and
    // traverse the function name before entering the scope, rather than afterwards. Removing the
    // null check for 'parent' seems safe, but causes a rare crash when traverseScopeRoots is called
    // by PeepholeOptimizationsPass on a function that somehow doesn't actually have a parent at all
    // (presumably because it's already been removed from the AST?) so that doesn't actually work.
    // This does not actually change anything, though, since rooting a traversal at a function node
    // causes the function scope to be entered twice (unless using #traverseAtScope, which doesn't
    // call this method), so that the name node is just always traversed inside the scope anyway.
    boolean isFunctionDeclaration = parent != null && NodeUtil.isFunctionDeclaration(n);

    if (isFunctionDeclaration) {
      // Function declarations are in the scope containing the declaration.
      traverseBranch(fnName, n);
    }

    curNode = n;
    pushScope(n);

    if (!isFunctionDeclaration) {
      // Function expression names are only accessible within the function
      // scope.
      traverseBranch(fnName, n);
    }

    final Node args = fnName.getNext();
    final Node body = args.getNext();

    // Args
    traverseBranch(args, n);

    // Body
    // ES6 "arrow" function may not have a block as a body.
    traverseBranch(body, n);

    popScope();
  }