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; }