static void computeEscaped(
      final Scope jsScope,
      final Set<Var> escaped,
      AbstractCompiler compiler,
      Es6SyntacticScopeCreator scopeCreator) {

    checkArgument(jsScope.isFunctionScope());

    AbstractPostOrderCallback finder =
        new AbstractPostOrderCallback() {
          @Override
          public void visit(NodeTraversal t, Node n, Node parent) {

            Node enclosingBlock = NodeUtil.getEnclosingFunction(n);
            if (jsScope.getRootNode() == enclosingBlock || !n.isName() || parent.isFunction()) {
              return;
            }

            String name = n.getString();
            Var var = t.getScope().getVar(name);
            if (var != null) {
              Node enclosingScopeNode = NodeUtil.getEnclosingFunction(var.getNode());

              if (enclosingScopeNode == jsScope.getRootNode()) {
                escaped.add(var);
              }
            }
          }
        };

    Map<String, Var> allVarsInFn = new HashMap<>();
    List<Var> orderedVars = new ArrayList<>();
    NodeUtil.getAllVarsDeclaredInFunction(
        allVarsInFn, orderedVars, compiler, scopeCreator, jsScope);
    NodeTraversal t = new NodeTraversal(compiler, finder, scopeCreator);
    t.traverseAtScope(jsScope);

    // TODO (simranarora) catch variables should not be considered escaped in ES6. Getting rid of
    // the catch check is causing breakages however
    for (Var var : allVarsInFn.values()) {
      if (var.getParentNode().isCatch()
          || compiler.getCodingConvention().isExported(var.getName())) {
        escaped.add(var);
      }
    }
  }
static void computeEscaped ( final Scope jsScope , final Set < Var > escaped , AbstractCompiler compiler , Es6SyntacticScopeCreator scopeCreator ) { checkArgument ( jsScope . isFunctionScope ( ) ) ; AbstractPostOrderCallback finder = new AbstractPostOrderCallback ( ) { @ Override public void visit ( NodeTraversal t , Node n , Node parent ) { Node enclosingBlock = NodeUtil . getEnclosingFunction ( n ) ; if ( jsScope . getRootNode ( ) == enclosingBlock || ! n . isName ( ) || parent . isFunction ( ) ) { return ; } String name = n . getString ( ) ; Var var = t . getScope ( ) . getVar ( name ) ; if ( var != null ) { Node enclosingScopeNode = NodeUtil . getEnclosingFunction ( var . getNode ( ) ) ; if ( enclosingScopeNode == jsScope . getRootNode ( ) ) { escaped . add ( var ) ; } } } } ; Map < String , Var > allVarsInFn = new HashMap < > ( ) ; List < Var > orderedVars = new ArrayList < > ( ) ; NodeUtil . getAllVarsDeclaredInFunction ( allVarsInFn , orderedVars , compiler , scopeCreator , jsScope ) ; NodeTraversal t = new NodeTraversal ( compiler , finder , scopeCreator ) ; t . traverseAtScope ( jsScope ) ; for ( Var var : allVarsInFn . values ( ) ) { if ( var . getParentNode ( ) . isCatch ( ) || compiler . getCodingConvention ( ) . isExported ( var . getName ( ) ) ) { escaped . add ( var ) ; } } }
Compute set of escaped variables. When a variable is escaped in a dataflow analysis, it can be
referenced outside of the code that we are analyzing. A variable is escaped if any of the
following is true:

1. Exported variables as they can be needed after the script terminates.
2. Names of named functions because in JavaScript, function foo(){} does not kill
foo in the dataflow.

@param jsScope Must be a function scope