public final class Es6RewriteGenerators extends NodeTraversal.AbstractPostOrderCallback implements HotSwapCompilerPass
Modifier and Type | Class and Description |
---|---|
private static class |
Es6RewriteGenerators.ControlExitsCheck |
private class |
Es6RewriteGenerators.DecomposeYields
Decomposes expressions with yields inside of them to equivalent
sequence of expressions in which all non-statement yields are
of the form:
|
private static class |
Es6RewriteGenerators.ExceptionContext |
private static class |
Es6RewriteGenerators.LoopContext |
Modifier and Type | Field and Description |
---|---|
private AbstractCompiler |
compiler |
private java.util.List<Es6RewriteGenerators.ExceptionContext> |
currentExceptionContext |
private java.util.List<Es6RewriteGenerators.LoopContext> |
currentLoopContext |
private Node |
currentStatement |
private Node |
enclosingBlock |
private static java.lang.String |
GENERATOR_ARGUMENTS |
private static java.lang.String |
GENERATOR_DO_WHILE_INITIAL |
private static java.lang.String |
GENERATOR_ERROR |
private static java.lang.String |
GENERATOR_FINALLY_JUMP |
private static java.lang.String |
GENERATOR_FOR_IN_ARRAY |
private static java.lang.String |
GENERATOR_FOR_IN_ITER |
private static java.lang.String |
GENERATOR_FOR_IN_VAR |
private static java.lang.String |
GENERATOR_LOOP_GUARD |
private static java.lang.String |
GENERATOR_NEXT_ARG |
private static java.lang.String |
GENERATOR_STATE |
private static java.lang.String |
GENERATOR_SWITCH_ENTERED |
private static java.lang.String |
GENERATOR_SWITCH_VAL |
private static java.lang.String |
GENERATOR_THIS |
private static java.lang.String |
GENERATOR_THROW_ARG |
private static java.lang.String |
GENERATOR_YIELD_ALL_ENTRY |
private static java.lang.String |
GENERATOR_YIELD_ALL_NAME |
private static int |
generatorCaseCount |
private com.google.common.base.Supplier<java.lang.String> |
generatorCounter |
private boolean |
hasTranslatedTry |
private Node |
hoistRoot |
private Node |
originalGeneratorBody |
Constructor and Description |
---|
Es6RewriteGenerators(AbstractCompiler compiler) |
Modifier and Type | Method and Description |
---|---|
private boolean |
controlCanExit(Node n) |
private static Node |
createFinallyJumpBlock(Node finallyName,
int finallyStartState) |
private static Node |
createIteratorResult(Node value,
boolean done) |
private static Node |
createSafeBreak() |
private static Node |
createStateUpdate() |
private static Node |
createStateUpdate(int state) |
private Es6RewriteGenerators.LoopContext |
getLoopContext(java.lang.String label) |
private Node |
getUnique(Node node,
int type)
Finds the only child of the
node of the given type. |
void |
hotSwapScript(Node scriptRoot,
Node originalRoot)
Process the JS with root node root.
|
private void |
insertAll(Node node,
int type,
java.util.List<Node> matchingNodes)
Adds all children of the
node of the given type to given list. |
private static Node |
makeGeneratorMarker(int i) |
void |
process(Node externs,
Node root)
Process the JS with root node root.
|
private boolean |
translateStatementInOriginalBody()
Returns
true if a new case node should be added |
void |
visit(NodeTraversal t,
Node n,
Node parent)
Visits a node in postorder (after its children have been visited).
|
private void |
visitBlock()
Lifts all children to the body of the original generator to flatten the block.
|
private void |
visitBreak() |
private void |
visitContinue() |
private void |
visitForIn()
Translates for in loops to a for in loop which produces an array of
values iterated over followed by a plain for loop which performs the logic
contained in the body of the original for in.
|
private void |
visitFunctionStatement() |
private void |
visitGenerator(Node n,
Node parent) |
private void |
visitGeneratorMarker()
Pops the loop information off of our stack if we reach the marker cooresponding
to the end of the current loop.
|
private void |
visitIf()
Uses a case statement to jump over the body if the condition of the
if statement is false.
|
private void |
visitLabel() |
private void |
visitLoop(java.lang.String label)
Translates loops to a case statement followed by an if statement
containing the loop body.
|
private void |
visitReturn()
Translates
return statements to set the state to done before returning the
desired value. |
private void |
visitSwitch()
Translates switch statements into a series of if statements.
|
private void |
visitThrow() |
private void |
visitTry() |
private void |
visitVar()
Hoists
var statements into the closure containing the iterator
to preserve their state across
multiple calls to next(). |
private void |
visitYieldExpr(Node n,
Node parent) |
private void |
visitYieldExprResult()
Translates
yield to set the state so that execution resume at the next statement
when the function is next called and then returns an iterator result with
the desired value. |
private void |
visitYieldFor(NodeTraversal t,
Node n,
Node parent)
Translates expressions using the new yield-for syntax.
|
private void |
visitYieldThrows(Node n,
Node parent) |
shouldTraverse
private static final java.lang.String GENERATOR_STATE
private static final java.lang.String GENERATOR_DO_WHILE_INITIAL
private static final java.lang.String GENERATOR_YIELD_ALL_NAME
private static final java.lang.String GENERATOR_YIELD_ALL_ENTRY
private static final java.lang.String GENERATOR_ARGUMENTS
private static final java.lang.String GENERATOR_THIS
private static final java.lang.String GENERATOR_NEXT_ARG
private static final java.lang.String GENERATOR_THROW_ARG
private static final java.lang.String GENERATOR_SWITCH_ENTERED
private static final java.lang.String GENERATOR_SWITCH_VAL
private static final java.lang.String GENERATOR_FINALLY_JUMP
private static final java.lang.String GENERATOR_ERROR
private static final java.lang.String GENERATOR_FOR_IN_ARRAY
private static final java.lang.String GENERATOR_FOR_IN_VAR
private static final java.lang.String GENERATOR_FOR_IN_ITER
private static final java.lang.String GENERATOR_LOOP_GUARD
private final AbstractCompiler compiler
private final java.util.List<Es6RewriteGenerators.LoopContext> currentLoopContext
private final java.util.List<Es6RewriteGenerators.ExceptionContext> currentExceptionContext
private static int generatorCaseCount
private com.google.common.base.Supplier<java.lang.String> generatorCounter
private Node enclosingBlock
private Node hoistRoot
private Node originalGeneratorBody
private Node currentStatement
private boolean hasTranslatedTry
public Es6RewriteGenerators(AbstractCompiler compiler)
public void process(Node externs, Node root)
CompilerPass
process
in interface CompilerPass
externs
- Top of external JS treeroot
- Top of JS treepublic void hotSwapScript(Node scriptRoot, Node originalRoot)
HotSwapCompilerPass
hotSwapScript
in interface HotSwapCompilerPass
scriptRoot
- Root node corresponding to the file that is modified,
should be of type Token.SCRIPT
.originalRoot
- Root node corresponding to the original version of the
file that is modified. Should be of type token.SCRIPT
.public void visit(NodeTraversal t, Node n, Node parent)
NodeTraversal.Callback
Visits a node in postorder (after its children have been visited).
A node is visited only if all its parents should be traversed
(NodeTraversal.Callback.shouldTraverse(NodeTraversal, Node, Node)
).
Implementations can have side effects (e.g. modifying the parse tree).
visit
in interface NodeTraversal.Callback
private void visitYieldFor(NodeTraversal t, Node n, Node parent)
Sample translation:
var i = yield * gen();
Is rewritten to:
var $jscomp$generator$yield$all = gen(); var $jscomp$generator$yield$entry; while (!($jscomp$generator$yield$entry = $jscomp$generator$yield$all.next($jscomp$generator$next$arg)).done) { yield $jscomp$generator$yield$entry.value; } var i = $jscomp$generator$yield$entry.value;
private boolean translateStatementInOriginalBody()
true
if a new case node should be addedprivate void visitFunctionStatement()
private void visitTry()
private void visitContinue()
private void visitThrow()
private void visitBreak()
private void visitLabel()
private void visitGeneratorMarker()
private void visitIf()
if
statement to the top level.private void visitSwitch()
Sample translation:
switch (i) { case 1: s; case 2: t; ... }
Is eventually rewritten to:
$jscomp$generator$switch$entered0 = false; if ($jscomp$generator$switch$entered0 || i == 1) { $jscomp$generator$switch$entered0 = true; s; } if ($jscomp$generator$switch$entered0 || i == 2) { $jscomp$generator$switch$entered0 = true; t; } ...
private void visitBlock()
private void visitForIn()
Sample translation:
for (i in j) { s; }
Is eventually rewritten to:
$jscomp$arr = []; $jscomp$iter = j; for (i in $jscomp$iter) { $jscomp$arr.push(i); } for ($jscomp$var = 0; $jscomp$var < $jscomp$arr.length; $jscomp$var++) { i = $jscomp$arr[$jscomp$var]; if (!(i in $jscomp$iter)) { continue; } s; }
private void visitLoop(java.lang.String label)
Sample translation:
while (b) { s; }
Is eventually rewritten to:
case n: if (b) { s; state = n; break; }
private void visitVar()
var
statements into the closure containing the iterator
to preserve their state across
multiple calls to next().private void visitYieldExprResult()
yield
to set the state so that execution resume at the next statement
when the function is next called and then returns an iterator result with
the desired value.private void visitReturn()
return
statements to set the state to done before returning the
desired value.private static Node createStateUpdate()
private static Node createStateUpdate(int state)
private static Node createSafeBreak()
private static Node createFinallyJumpBlock(Node finallyName, int finallyStartState)
private Es6RewriteGenerators.LoopContext getLoopContext(java.lang.String label)
private boolean controlCanExit(Node n)
private Node getUnique(Node node, int type)
node
of the given type.private void insertAll(Node node, int type, java.util.List<Node> matchingNodes)
node
of the given type to given list.private static Node makeGeneratorMarker(int i)