@Override public Node leaveForNode(final ForNode forNode) { ForNode newForNode = forNode; final Expression test = forNode.getTest(); if (!forNode.isForIn() && isAlwaysTrue(test)) { newForNode = forNode.setTest(lc, null); } newForNode = checkEscape(newForNode); if(newForNode.isForIn()) { // Wrap it in a block so its internally created iterator is restricted in scope addStatementEnclosedInBlock(newForNode); } else { addStatement(newForNode); } return newForNode; }
@Override public boolean enterForNode(final ForNode forNode) { if(!reachable) { return false; } final Expression init = forNode.getInit(); if(forNode.isForIn()) { final JoinPredecessorExpression iterable = forNode.getModify(); iterable.accept(this); enterTestFirstLoop(forNode, null, init, // If we're iterating over property names, and we can discern from the runtime environment // of the compilation that the object being iterated over must use strings for property // names (e.g., it is a native JS object or array), then we'll not bother trying to treat // the property names optimistically. !compiler.useOptimisticTypes() || (!forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression()))); } else { if(init != null) { init.accept(this); } enterTestFirstLoop(forNode, forNode.getModify(), null, false); } return false; }
@Override public boolean enterForNode(final ForNode forNode) { if(!method.isReachable()) { return false; } enterStatement(forNode); if (forNode.isForIn()) { enterForIn(forNode); } else { final Expression init = forNode.getInit(); if (init != null) { loadAndDiscard(init); } enterForOrWhile(forNode, forNode.getModify()); } return false; }
@Override public boolean enterForNode(final ForNode forNode) { if (forNode.isForIn()) { curStat = new ForInLoopTreeImpl(forNode, translateExpr(forNode.getInit()), translateExpr(forNode.getModify()), translateBlock(forNode.getBody())); } else if (forNode.isForOf()) { curStat = new ForOfLoopTreeImpl(forNode, translateExpr(forNode.getInit()), translateExpr(forNode.getModify()), translateBlock(forNode.getBody())); } else { curStat = new ForLoopTreeImpl(forNode, translateExpr(forNode.getInit()), translateExpr(forNode.getTest()), translateExpr(forNode.getModify()), translateBlock(forNode.getBody())); } return false; }
@Override public Node leaveForNode(final ForNode forNode) { ForNode newForNode = forNode; final Expression test = forNode.getTest(); if (!forNode.isForInOrOf() && isAlwaysTrue(test)) { newForNode = forNode.setTest(lc, null); } newForNode = checkEscape(newForNode); if(!es6 && newForNode.isForInOrOf()) { // Wrap it in a block so its internally created iterator is restricted in scope, unless we are running // in ES6 mode, in which case the parser already created a block to capture let/const declarations. addStatementEnclosedInBlock(newForNode); } else { addStatement(newForNode); } return newForNode; }
@Override public boolean enterForNode(final ForNode forNode) { if(!reachable) { return false; } final Expression init = forNode.getInit(); if(forNode.isForInOrOf()) { final JoinPredecessorExpression iterable = forNode.getModify(); visitExpression(iterable); enterTestFirstLoop(forNode, null, init, // If we're iterating over property names, and we can discern from the runtime environment // of the compilation that the object being iterated over must use strings for property // names (e.g., it is a native JS object or array), then we'll not bother trying to treat // the property names optimistically. !compiler.useOptimisticTypes() || (!forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression()))); } else { if(init != null) { visitExpressionOnEmptyStack(init); } enterTestFirstLoop(forNode, forNode.getModify(), null, false); } assertTypeStackIsEmpty(); return false; }
@Override public boolean enterForNode(final ForNode forNode) { if(!method.isReachable()) { return false; } enterStatement(forNode); if (forNode.isForInOrOf()) { enterForIn(forNode); } else { final Expression init = forNode.getInit(); if (init != null) { loadAndDiscard(init); } enterForOrWhile(forNode, forNode.getModify()); } return false; }
@Override public boolean enterForNode(final ForNode forNode) { if (forNode.isForIn()) { curStat = new ForInLoopTreeImpl(forNode, translateExpr(forNode.getInit()), translateExpr(forNode.getModify()), translateBlock(forNode.getBody())); } else { curStat = new ForLoopTreeImpl(forNode, translateExpr(forNode.getInit()), translateExpr(forNode.getTest()), translateExpr(forNode.getModify()), translateBlock(forNode.getBody())); } return false; }
@Override public boolean enterForNode(final ForNode forNode) { if(!reachable) { return false; } final Expression init = forNode.getInit(); if(forNode.isForIn()) { final JoinPredecessorExpression iterable = forNode.getModify(); visitExpression(iterable); enterTestFirstLoop(forNode, null, init, // If we're iterating over property names, and we can discern from the runtime environment // of the compilation that the object being iterated over must use strings for property // names (e.g., it is a native JS object or array), then we'll not bother trying to treat // the property names optimistically. !compiler.useOptimisticTypes() || (!forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression()))); } else { if(init != null) { visitExpressionOnEmptyStack(init); } enterTestFirstLoop(forNode, forNode.getModify(), null, false); } assertTypeStackIsEmpty(); return false; }
@Override public Node leaveForNode(final ForNode forNode) { if (forNode.isForIn()) { forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.typeFor(ITERATOR_PREFIX.type()))); //NASHORN-73 /* * Iterators return objects, so we need to widen the scope of the * init variable if it, for example, has been assigned double type * see NASHORN-50 */ newType(forNode.getInit().getSymbol(), Type.OBJECT); } end(forNode); return forNode; }
@Override public Node leaveForNode(final ForNode forNode) { if (forNode.isForIn()) { return forNode; } final Expression init = forNode.getInit(); final Expression test = forNode.getTest(); final Expression modify = forNode.getModify(); assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + lc.getCurrentFunction(); return forNode. setInit(lc, init == null ? null : discard(init)). setModify(lc, modify == null ? null : discard(modify)); }
@Override public Node leaveForNode(final ForNode forNode) { final Expression init = forNode.getInit(); final Expression test = forNode.getTest(); final Expression modify = forNode.getModify(); if (forNode.isForIn()) { return forNode.setModify(lc, convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400 } assert test != null || forNode.hasGoto() : "forNode " + forNode + " needs goto and is missing it in " + lc.getCurrentFunction(); return forNode. setInit(lc, init == null ? null : discard(init)). setTest(lc, test == null ? null : convert(test, Type.BOOLEAN)). setModify(lc, modify == null ? null : discard(modify)); }
@Override public Node leaveForNode(final ForNode forNode) { if (forNode.isForIn()) { forNode.setIterator(newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73 } return end(forNode); }
@Override public Node leaveWhileNode(final WhileNode whileNode) { final Expression test = whileNode.getTest(); final Block body = whileNode.getBody(); if (isAlwaysTrue(test)) { //turn it into a for node without a test. final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), body, 0).accept(this); lc.replace(whileNode, forNode); return forNode; } return addStatement(checkEscape(whileNode)); }
@Override public boolean enterForNode(final ForNode forNode) { if(forNode.isForIn()) { // for..in has the iterable in its "modify" tagNeverOptimistic(forNode.getModify()); } else { // Test is never optimistic (always coerced to boolean). tagNeverOptimisticLoopTest(forNode); } return true; }
ForOfLoopTreeImpl(final ForNode node, final ExpressionTree lhsExpr, final ExpressionTree expr, final StatementTree stat) { super(node); assert node.isForIn() : "for ..in expected"; this.lhsExpr = lhsExpr; this.expr = expr; this.stat = stat; }
ForLoopTreeImpl(final ForNode node, final ExpressionTree init, final ExpressionTree cond, final ExpressionTree update, final StatementTree stat) { super(node); assert !node.isForIn() : "for statement expected"; this.init = init; this.cond = cond; this.update = update; this.stat = stat; }
ForInLoopTreeImpl(final ForNode node, final ExpressionTree lhsExpr, final ExpressionTree expr, final StatementTree stat) { super(node); assert node.isForIn() : "for ..in expected"; this.lhsExpr = lhsExpr; this.expr = expr; this.stat = stat; this.forEach = node.isForEach(); }
@Override public Node leaveForNode(final ForNode forNode) { if (forNode.isForInOrOf()) { return forNode.setIterator(lc, newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73 } return end(forNode); }
@Override public boolean enterForNode(final ForNode forNode) { if (es6 && (forNode.getInit() instanceof ObjectNode || forNode.getInit() instanceof ArrayLiteralNode)) { throwNotImplementedYet("es6.destructuring", forNode); } return super.enterForNode(forNode); }
@Override public boolean enterForNode(final ForNode forNode) { if(forNode.isForInOrOf()) { // for..in has the iterable in its "modify" tagNeverOptimistic(forNode.getModify()); } else { // Test is never optimistic (always coerced to boolean). tagNeverOptimisticLoopTest(forNode); } return true; }