WhileNode.java revision 953:221a84ef44c0
1/* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.nashorn.internal.ir; 27 28import jdk.nashorn.internal.ir.annotations.Immutable; 29import jdk.nashorn.internal.ir.visitor.NodeVisitor; 30 31/** 32 * IR representation for a WHILE statement. This is the superclass of all 33 * loop nodes 34 */ 35@Immutable 36public final class WhileNode extends LoopNode { 37 38 /** is this a do while node ? */ 39 private final boolean isDoWhile; 40 41 /** 42 * Constructor 43 * 44 * @param lineNumber line number 45 * @param token token 46 * @param finish finish 47 * @param isDoWhile is this a do while loop? 48 */ 49 public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile) { 50 super(lineNumber, token, finish, null, false); 51 this.isDoWhile = isDoWhile; 52 } 53 54 /** 55 * Internal copy constructor 56 * 57 * @param whileNode while node 58 * @param test test 59 * @param body body 60 * @param controlFlowEscapes control flow escapes? 61 * @param conversion TODO 62 */ 63 private WhileNode(final WhileNode whileNode, final JoinPredecessorExpression test, final Block body, final boolean controlFlowEscapes, final LocalVariableConversion conversion) { 64 super(whileNode, test, body, controlFlowEscapes, conversion); 65 this.isDoWhile = whileNode.isDoWhile; 66 } 67 68 @Override 69 public Node ensureUniqueLabels(final LexicalContext lc) { 70 return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion)); 71 } 72 73 @Override 74 public boolean hasGoto() { 75 return test == null; 76 } 77 78 @Override 79 public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) { 80 if (visitor.enterWhileNode(this)) { 81 if (isDoWhile()) { 82 return visitor.leaveWhileNode( 83 setBody(lc, (Block)body.accept(visitor)). 84 setTest(lc, (JoinPredecessorExpression)test.accept(visitor))); 85 } 86 return visitor.leaveWhileNode( 87 setTest(lc, (JoinPredecessorExpression)test.accept(visitor)). 88 setBody(lc, (Block)body.accept(visitor))); 89 } 90 return this; 91 } 92 93 @Override 94 public WhileNode setTest(final LexicalContext lc, final JoinPredecessorExpression test) { 95 if (this.test == test) { 96 return this; 97 } 98 return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion)); 99 } 100 101 @Override 102 public Block getBody() { 103 return body; 104 } 105 106 @Override 107 public WhileNode setBody(final LexicalContext lc, final Block body) { 108 if (this.body == body) { 109 return this; 110 } 111 return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion)); 112 } 113 114 @Override 115 public WhileNode setControlFlowEscapes(final LexicalContext lc, final boolean controlFlowEscapes) { 116 if (this.controlFlowEscapes == controlFlowEscapes) { 117 return this; 118 } 119 return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion)); 120 } 121 122 @Override 123 JoinPredecessor setLocalVariableConversionChanged(final LexicalContext lc, final LocalVariableConversion conversion) { 124 return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes, conversion)); 125 } 126 127 /** 128 * Check if this is a do while loop or a normal while loop 129 * @return true if do while 130 */ 131 public boolean isDoWhile() { 132 return isDoWhile; 133 } 134 135 @Override 136 public void toString(final StringBuilder sb, final boolean printType) { 137 sb.append("while ("); 138 test.toString(sb, printType); 139 sb.append(')'); 140 } 141 142 @Override 143 public boolean mustEnter() { 144 if (isDoWhile()) { 145 return true; 146 } 147 return test == null; 148 } 149} 150