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 an IF statement.
33   */
34  @Immutable
35  public final class IfNode extends Statement {
36      /** Test expression. */
37      private final Expression test;
38  
39      /** Pass statements. */
40      private final Block pass;
41  
42      /** Fail statements. */
43      private final Block fail;
44  
45      /**
46       * Constructor
47       *
48       * @param lineNumber line number
49       * @param token      token
50       * @param finish     finish
51       * @param test       test
52       * @param pass       block to execute when test passes
53       * @param fail       block to execute when test fails or null
54       */
55      public IfNode(final int lineNumber, final long token, final int finish, final Expression test, final Block pass, final Block fail) {
56          super(lineNumber, token, finish);
57          this.test = test;
58          this.pass = pass;
59          this.fail = fail;
60      }
61  
62      private IfNode(final IfNode ifNode, final Expression test, final Block pass, final Block fail) {
63          super(ifNode);
64          this.test = test;
65          this.pass = pass;
66          this.fail = fail;
67      }
68  
69      @Override
70      public boolean isTerminal() {
71          return pass.isTerminal() && fail != null && fail.isTerminal();
72      }
73  
74      @Override
75      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
76          if (visitor.enterIfNode(this)) {
77              return visitor.leaveIfNode(
78                  setTest((Expression)test.accept(visitor)).
79                  setPass((Block)pass.accept(visitor)).
80                  setFail(fail == null ? null : (Block)fail.accept(visitor)));
81          }
82  
83          return this;
84      }
85  
86      @Override
87      public void toString(final StringBuilder sb) {
88          sb.append("if (");
89          test.toString(sb);
90          sb.append(')');
91      }
92  
93      /**
94       * Get the else block of this IfNode
95       * @return the else block, or null if none exists
96       */
97      public Block getFail() {
98          return fail;
99      }
100 
101     private IfNode setFail(final Block fail) {
102         if (this.fail == fail) {
103             return this;
104         }
105         return new IfNode(this, test, pass, fail);
106     }
107 
108     /**
109      * Get the then block for this IfNode
110      * @return the then block
111      */
112     public Block getPass() {
113         return pass;
114     }
115 
116     private IfNode setPass(final Block pass) {
117         if (this.pass == pass) {
118             return this;
119         }
120         return new IfNode(this, test, pass, fail);
121     }
122 
123     /**
124      * Get the test expression for this IfNode
125      * @return the test expression
126      */
127     public Expression getTest() {
128         return test;
129     }
130 
131     /**
132      * Reset the test expression for this IfNode
133      * @param test a new test expression
134      * @return new or same IfNode
135      */
136     public IfNode setTest(final Expression test) {
137         if (this.test == test) {
138             return this;
139         }
140         return new IfNode(this, test, pass, fail);
141     }
142 }