View Javadoc
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  
26  package jdk.nashorn.internal.ir;
27  
28  import jdk.nashorn.internal.ir.annotations.Immutable;
29  import 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
36  public 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, 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       */
62      protected WhileNode(final WhileNode whileNode, final Expression test, final Block body, final boolean controlFlowEscapes) {
63          super(whileNode, test, body, controlFlowEscapes);
64          this.isDoWhile = whileNode.isDoWhile;
65      }
66  
67      @Override
68      public Node ensureUniqueLabels(final LexicalContext lc) {
69          return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
70      }
71  
72      @Override
73      public boolean hasGoto() {
74          return test == null;
75      }
76  
77      @Override
78      public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
79          if (visitor.enterWhileNode(this)) {
80              if (isDoWhile()) {
81                  return visitor.leaveWhileNode(
82                          setBody(lc, (Block)body.accept(visitor)).
83                          setTest(lc, (Expression)test.accept(visitor)));
84              }
85              return visitor.leaveWhileNode(
86                      setTest(lc, (Expression)test.accept(visitor)).
87                      setBody(lc, (Block)body.accept(visitor)));
88          }
89          return this;
90      }
91  
92      @Override
93      public Expression getTest() {
94          return test;
95      }
96  
97      @Override
98      public WhileNode setTest(final LexicalContext lc, final Expression test) {
99          if (this.test == test) {
100             return this;
101         }
102         return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
103     }
104 
105     @Override
106     public Block getBody() {
107         return body;
108     }
109 
110     @Override
111     public WhileNode setBody(final LexicalContext lc, final Block body) {
112         if (this.body == body) {
113             return this;
114         }
115         return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
116     }
117 
118     @Override
119     public WhileNode setControlFlowEscapes(final LexicalContext lc, final boolean controlFlowEscapes) {
120         if (this.controlFlowEscapes == controlFlowEscapes) {
121             return this;
122         }
123         return Node.replaceInLexicalContext(lc, this, new WhileNode(this, test, body, controlFlowEscapes));
124     }
125 
126     /**
127      * Check if this is a do while loop or a normal while loop
128      * @return true if do while
129      */
130     public boolean isDoWhile() {
131         return isDoWhile;
132     }
133 
134     @Override
135     public void toString(final StringBuilder sb) {
136         sb.append("while (");
137         test.toString(sb);
138         sb.append(')');
139     }
140 
141     @Override
142     public boolean mustEnter() {
143         if (isDoWhile()) {
144             return true;
145         }
146         return test == null;
147     }
148 }