28 import jdk.nashorn.internal.ir.annotations.Immutable; 29 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 30 31 /** 32 * IR representing a FOR statement. 33 */ 34 @Immutable 35 public final class ForNode extends LoopNode { 36 private static final long serialVersionUID = 1L; 37 38 /** Initialize expression for an ordinary for statement, or the LHS expression receiving iterated-over values in a 39 * for-in statement. */ 40 private final Expression init; 41 42 /** Modify expression for an ordinary statement, or the source of the iterator in the for-in statement. */ 43 private final JoinPredecessorExpression modify; 44 45 /** Iterator symbol. */ 46 private Symbol iterator; 47 48 /** Is this a normal for loop? */ 49 public static final int IS_FOR = 1 << 0; 50 51 /** Is this a normal for in loop? */ 52 public static final int IS_FOR_IN = 1 << 1; 53 54 /** Is this a normal for each in loop? */ 55 public static final int IS_FOR_EACH = 1 << 2; 56 57 private final int flags; 58 59 /** 60 * Constructor 61 * 62 * @param lineNumber line number 63 * @param token token 64 * @param finish finish 65 * @param body body 66 * @param flags flags 67 */ 68 public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags) { 69 super(lineNumber, token, finish, body, false); 70 this.flags = flags; 71 this.init = null; 72 this.modify = null; 73 } 74 75 private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test, 255 } 256 257 @Override 258 public ForNode setControlFlowEscapes(final LexicalContext lc, final boolean controlFlowEscapes) { 259 if (this.controlFlowEscapes == controlFlowEscapes) { 260 return this; 261 } 262 return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); 263 } 264 265 private ForNode setFlags(final LexicalContext lc, final int flags) { 266 if (this.flags == flags) { 267 return this; 268 } 269 return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); 270 } 271 272 @Override 273 JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) { 274 return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); 275 } 276 } | 28 import jdk.nashorn.internal.ir.annotations.Immutable; 29 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 30 31 /** 32 * IR representing a FOR statement. 33 */ 34 @Immutable 35 public final class ForNode extends LoopNode { 36 private static final long serialVersionUID = 1L; 37 38 /** Initialize expression for an ordinary for statement, or the LHS expression receiving iterated-over values in a 39 * for-in statement. */ 40 private final Expression init; 41 42 /** Modify expression for an ordinary statement, or the source of the iterator in the for-in statement. */ 43 private final JoinPredecessorExpression modify; 44 45 /** Iterator symbol. */ 46 private Symbol iterator; 47 48 /** Is this a normal for in loop? */ 49 public static final int IS_FOR_IN = 1 << 0; 50 51 /** Is this a normal for each in loop? */ 52 public static final int IS_FOR_EACH = 1 << 1; 53 54 /** Does this loop need a per-iteration scope because its init contain a LET declaration? */ 55 public static final int PER_ITERATION_SCOPE = 1 << 2; 56 57 private final int flags; 58 59 /** 60 * Constructor 61 * 62 * @param lineNumber line number 63 * @param token token 64 * @param finish finish 65 * @param body body 66 * @param flags flags 67 */ 68 public ForNode(final int lineNumber, final long token, final int finish, final Block body, final int flags) { 69 super(lineNumber, token, finish, body, false); 70 this.flags = flags; 71 this.init = null; 72 this.modify = null; 73 } 74 75 private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test, 255 } 256 257 @Override 258 public ForNode setControlFlowEscapes(final LexicalContext lc, final boolean controlFlowEscapes) { 259 if (this.controlFlowEscapes == controlFlowEscapes) { 260 return this; 261 } 262 return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); 263 } 264 265 private ForNode setFlags(final LexicalContext lc, final int flags) { 266 if (this.flags == flags) { 267 return this; 268 } 269 return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); 270 } 271 272 @Override 273 JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) { 274 return Node.replaceInLexicalContext(lc, this, new ForNode(this, init, test, body, modify, flags, controlFlowEscapes, conversion)); 275 } 276 277 @Override 278 public boolean hasPerIterationScope() { 279 return (flags & PER_ITERATION_SCOPE) != 0; 280 } 281 282 /** 283 * Set the per-iteration-scope flag on this node. 284 * @param lc lexical context 285 * @return the node with flag set 286 */ 287 public ForNode setPerIterationScope(final LexicalContext lc) { 288 return setFlags(lc, flags | PER_ITERATION_SCOPE); 289 } 290 } |