public void testGetCurrentNode() {
    Compiler compiler = new Compiler();
    ScopeCreator creator = new SyntacticScopeCreator(compiler);
    ExpectNodeOnEnterScope callback = new ExpectNodeOnEnterScope();
    NodeTraversal t = new NodeTraversal(compiler, callback, creator);

    String code = "" + "var a; " + "function foo() {" + "  var b;" + "}";

    Node tree = parse(compiler, code);
    Scope topScope = creator.createScope(tree, null);

    // Calling #traverseWithScope uses the given scope but starts traversal at
    // the given node.
    callback.expect(tree.getFirstChild(), tree);
    t.traverseWithScope(tree.getFirstChild(), topScope);
    callback.assertEntered();

    // Calling #traverse creates a new scope with the given node as the root.
    callback.expect(tree.getFirstChild(), tree.getFirstChild());
    t.traverse(tree.getFirstChild());
    callback.assertEntered();

    // Calling #traverseAtScope starts traversal from the scope's root.
    Node fn = tree.getFirstChild().getNext();
    Scope fnScope = creator.createScope(fn, topScope);
    callback.expect(fn, fn);
    t.traverseAtScope(fnScope);
    callback.assertEntered();
  }
 /** Creates a node traversal using the specified callback interface and the scope creator. */
 public NodeTraversal(AbstractCompiler compiler, Callback cb, ScopeCreator scopeCreator) {
   this.callback = cb;
   if (cb instanceof ScopedCallback) {
     this.scopeCallback = (ScopedCallback) cb;
   }
   this.compiler = compiler;
   this.inputId = null;
   this.sourceName = "";
   this.scopeCreator = scopeCreator;
   this.useBlockScope = scopeCreator.hasBlockScope();
 }
  /** Gets the current scope. */
  public Scope getScope() {
    Scope scope = scopes.isEmpty() ? null : scopes.peek();
    if (scopeRoots.isEmpty()) {
      return scope;
    }

    Iterator<Node> it = scopeRoots.descendingIterator();
    while (it.hasNext()) {
      scope = scopeCreator.createScope(it.next(), scope);
      scopes.push(scope);
    }
    scopeRoots.clear();
    cfgRoots.clear();
    // No need to call compiler.setScope; the top scopeRoot is now the top scope
    return scope;
  }