diff --git a/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java b/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java index ea6b8635016..2f5660f095b 100644 --- a/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java +++ b/src/com/google/javascript/jscomp/AbstractPeepholeOptimization.java @@ -27,7 +27,8 @@ */ abstract class AbstractPeepholeOptimization { - protected AbstractCompiler compiler; + private NodeTraversal traversal; + private AbstractCompiler compiler; /** * Given a node to optimize and a traversal, optimize the node. Subclasses @@ -57,8 +58,7 @@ protected void report(DiagnosticType diagnostic, Node n) { * Subclasses must call these if they have changed the AST. */ protected void reportCodeChange() { - Preconditions.checkNotNull(compiler); - compiler.reportCodeChange(); + traversal.reportCodeChange(); } /** @@ -86,15 +86,16 @@ protected boolean isASTNormalized() { /** * Informs the optimization that a traversal will begin. */ - void beginTraversal(AbstractCompiler compiler) { - this.compiler = compiler; + void beginTraversal(NodeTraversal traversal) { + this.traversal = traversal; + this.compiler = traversal.getCompiler(); } /** * Informs the optimization that a traversal has completed. - * @param compiler The current compiler. */ - void endTraversal(AbstractCompiler compiler) { + void endTraversal() { + this.traversal = null; this.compiler = null; } @@ -147,5 +148,4 @@ CodingConvention getCodingConvention() { final boolean areDeclaredGlobalExternsOnWindow() { return compiler != null && compiler.getOptions().declaredGlobalExternsOnWindow; } - } diff --git a/src/com/google/javascript/jscomp/PeepholeFoldConstants.java b/src/com/google/javascript/jscomp/PeepholeFoldConstants.java index 7aac808cbc9..19b7a89acf7 100644 --- a/src/com/google/javascript/jscomp/PeepholeFoldConstants.java +++ b/src/com/google/javascript/jscomp/PeepholeFoldConstants.java @@ -181,7 +181,7 @@ private Node tryReduceVoid(Node n) { Node child = n.getFirstChild(); if ((!child.isNumber() || child.getDouble() != 0.0) && !mayHaveSideEffects(n)) { n.replaceChild(child, IR.number(0)); - compiler.reportCodeChange(); + reportCodeChange(); } return n; } @@ -273,7 +273,7 @@ private void tryConvertToNumber(Node n) { } n.replaceWith(replacement); - compiler.reportCodeChange(); + reportCodeChange(); } /** @@ -327,7 +327,7 @@ private Node tryFoldTypeof(Node originalTypeofNode) { if (typeNameString != null) { Node newNode = IR.string(typeNameString); originalTypeofNode.replaceWith(newNode); - compiler.reportCodeChange(); + reportCodeChange(); return newNode; } @@ -361,13 +361,13 @@ private Node tryFoldUnaryOperator(Node n) { } Node replacementNode = NodeUtil.booleanNode(!leftVal.toBoolean(true)); parent.replaceChild(n, replacementNode); - compiler.reportCodeChange(); + reportCodeChange(); return replacementNode; case POS: if (NodeUtil.isNumericResult(left)) { // POS does nothing to numeric values. parent.replaceChild(n, left.detach()); - compiler.reportCodeChange(); + reportCodeChange(); return left; } return n; @@ -380,7 +380,7 @@ private Node tryFoldUnaryOperator(Node n) { // "-NaN" is "NaN". n.removeChild(left); parent.replaceChild(n, left); - compiler.reportCodeChange(); + reportCodeChange(); return left; } } @@ -390,7 +390,7 @@ private Node tryFoldUnaryOperator(Node n) { Node negNumNode = IR.number(negNum); parent.replaceChild(n, negNumNode); - compiler.reportCodeChange(); + reportCodeChange(); return negNumNode; } else { // left is not a number node, so do not replace, but warn the @@ -405,7 +405,7 @@ private Node tryFoldUnaryOperator(Node n) { int intVal = jsConvertDoubleToBits(val); Node notIntValNode = IR.number(~intVal); parent.replaceChild(n, notIntValNode); - compiler.reportCodeChange(); + reportCodeChange(); return notIntValNode; } else { report(FRACTIONAL_BITWISE_OPERAND, left); @@ -454,7 +454,7 @@ private Node tryFoldInstanceof(Node n, Node left, Node right) { if (replacementNode != null) { n.replaceWith(replacementNode); - compiler.reportCodeChange(); + reportCodeChange(); return replacementNode; } } @@ -533,7 +533,7 @@ && areNodesEqualForInlining(left, right.getLastChild())) { left.detach(), newRight.detach()); n.replaceWith(newNode); - compiler.reportCodeChange(); + reportCodeChange(); return newNode; } @@ -558,7 +558,7 @@ private Node tryUnfoldAssignOp(Node n, Node left, Node right) { new Node(op, left.cloneTree(), right.detach()) .srcref(n)); n.replaceWith(replacement); - compiler.reportCodeChange(); + reportCodeChange(); return replacement; } @@ -605,7 +605,7 @@ private Node tryFoldAndOr(Node n, Node left, Node right) { // Fold it! n.detachChildren(); parent.replaceChild(n, result); - compiler.reportCodeChange(); + reportCodeChange(); return result; } else { @@ -641,7 +641,7 @@ private Node tryFoldChildAddString(Node n, Node left, Node right) { String result = leftString + rightString; n.replaceChild(left, ll); n.replaceChild(right, IR.string(result)); - compiler.reportCodeChange(); + reportCodeChange(); return n; } } @@ -664,7 +664,7 @@ private Node tryFoldChildAddString(Node n, Node left, Node right) { String result = leftString + rightString; n.replaceChild(right, rr); n.replaceChild(left, IR.string(result)); - compiler.reportCodeChange(); + reportCodeChange(); return n; } } @@ -685,7 +685,7 @@ private Node tryFoldAddConstantString(Node n, Node left, Node right) { if (leftString != null && rightString != null) { Node newStringNode = IR.string(leftString + rightString); n.replaceWith(newStringNode); - compiler.reportCodeChange(); + reportCodeChange(); return newStringNode; } } @@ -701,7 +701,7 @@ private Node tryFoldArithmeticOp(Node n, Node left, Node right) { if (result != null) { result.useSourceInfoIfMissingFromForTree(n); n.replaceWith(result); - compiler.reportCodeChange(); + reportCodeChange(); return result; } return n; @@ -828,7 +828,7 @@ private Node tryFoldLeftChildOp(Node n, Node left, Node right) { // added. replacement.useSourceInfoIfMissingFromForTree(right); n.replaceChild(right, replacement); - compiler.reportCodeChange(); + reportCodeChange(); } } @@ -905,7 +905,7 @@ private Node tryFoldShift(Node n, Node left, Node right) { Node newNumber = IR.number(result); n.replaceWith(newNumber); - compiler.reportCodeChange(); + reportCodeChange(); return newNumber; } @@ -924,7 +924,7 @@ private Node tryFoldComparison(Node n, Node left, Node right) { Node newNode = NodeUtil.booleanNode(result.toBoolean(true)); n.replaceWith(newNode); - compiler.reportCodeChange(); + reportCodeChange(); return newNode; } @@ -1140,7 +1140,7 @@ private Node tryFoldCall(Node n) { Node parent = n.getParent(); Node destObj = n.getSecondChild().detach(); parent.replaceChild(n, destObj); - compiler.reportCodeChange(); + reportCodeChange(); } } return n; @@ -1188,7 +1188,7 @@ private Node tryFoldInForcedStringContext(Node n) { parent.replaceChild(n, newString); newString.useSourceInfoIfMissingFrom(parent); - compiler.reportCodeChange(); + reportCodeChange(); return newString; } @@ -1247,7 +1247,7 @@ private Node tryFoldGetProp(Node n, Node left, Node right) { Preconditions.checkState(knownLength != -1); Node lengthNode = IR.number(knownLength); n.replaceWith(lengthNode); - compiler.reportCodeChange(); + reportCodeChange(); return lengthNode; } @@ -1308,7 +1308,7 @@ private Node tryFoldArrayAccess(Node n, Node left, Node right) { // Replace the entire GETELEM with the value n.replaceWith(elem); - compiler.reportCodeChange(); + reportCodeChange(); return elem; } @@ -1359,7 +1359,7 @@ private Node tryFoldStringArrayAccess(Node n, Node left, Node right) { // Replace the entire GETELEM with the value n.replaceWith(elem); - compiler.reportCodeChange(); + reportCodeChange(); return elem; } @@ -1422,7 +1422,7 @@ private Node tryFoldObjectPropAccess(Node n, Node left, Node right) { } n.replaceWith(replacement); - compiler.reportCodeChange(); + reportCodeChange(); return n; } } diff --git a/src/com/google/javascript/jscomp/PeepholeOptimizationsPass.java b/src/com/google/javascript/jscomp/PeepholeOptimizationsPass.java index 3404d44dbec..453f5f856ca 100644 --- a/src/com/google/javascript/jscomp/PeepholeOptimizationsPass.java +++ b/src/com/google/javascript/jscomp/PeepholeOptimizationsPass.java @@ -34,6 +34,9 @@ class PeepholeOptimizationsPass implements CompilerPass { private boolean retraverseOnChange; private RecentChange handler; + private FunctionCallback fnCallback; + private PeepCallback peepCallback; + private NodeTraversal traversal; /** * Creates a peephole optimization pass that runs the given @@ -45,6 +48,10 @@ class PeepholeOptimizationsPass implements CompilerPass { this.peepholeOptimizations = optimizations; this.retraverseOnChange = true; this.handler = new RecentChange(); + this.peepCallback = new PeepCallback(); + this.traversal = new NodeTraversal( + compiler, peepCallback, new Es6SyntacticScopeCreator(compiler)); + this.fnCallback = new ChangedFunctionCallback(); } void setRetraverseOnChange(boolean retraverse) { @@ -54,23 +61,25 @@ void setRetraverseOnChange(boolean retraverse) { @Override public void process(Node externs, Node root) { compiler.addChangeHandler(handler); - beginTraversal(); - NodeTraversal.traverseChangedFunctions(compiler, new FunctionCallback() { - @Override - public void enterFunction(AbstractCompiler compiler, Node root) { - if (root.isFunction()) { - root = root.getLastChild(); - } - do { - handler.reset(); - NodeTraversal.traverseEs6(compiler, root, new PeepCallback()); - } while (retraverseOnChange && handler.hasCodeChanged()); - } - }); + beginTraversal(traversal); + NodeTraversal.traverseChangedFunctions(compiler, fnCallback); endTraversal(); compiler.removeChangeHandler(handler); } + private class ChangedFunctionCallback implements FunctionCallback { + @Override + public void enterFunction(AbstractCompiler compiler, Node root) { + if (root.isFunction()) { + root = root.getLastChild(); + } + do { + handler.reset(); + traversal.traverse(root); + } while (retraverseOnChange && handler.hasCodeChanged()); + } + } + private class PeepCallback extends AbstractShallowCallback { @Override public void visit(NodeTraversal t, Node n, Node parent) { @@ -96,15 +105,15 @@ public void visit(NodeTraversal t, Node n, Node parent) { * Make sure that all the optimizations have the current traversal so they * can report errors. */ - private void beginTraversal() { + private void beginTraversal(NodeTraversal traversal) { for (AbstractPeepholeOptimization optimization : peepholeOptimizations) { - optimization.beginTraversal(compiler); + optimization.beginTraversal(traversal); } } private void endTraversal() { for (AbstractPeepholeOptimization optimization : peepholeOptimizations) { - optimization.endTraversal(compiler); + optimization.endTraversal(); } } }