IfNode.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 an IF statement. 33 */ 34@Immutable 35public final class IfNode extends Statement implements JoinPredecessor { 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 * Local variable conversions that need to be performed after test if it evaluates to false, and there's no else 47 * branch. 48 */ 49 private final LocalVariableConversion conversion; 50 51 /** 52 * Constructor 53 * 54 * @param lineNumber line number 55 * @param token token 56 * @param finish finish 57 * @param test test 58 * @param pass block to execute when test passes 59 * @param fail block to execute when test fails or null 60 */ 61 public IfNode(final int lineNumber, final long token, final int finish, final Expression test, final Block pass, final Block fail) { 62 super(lineNumber, token, finish); 63 this.test = test; 64 this.pass = pass; 65 this.fail = fail; 66 this.conversion = null; 67 } 68 69 private IfNode(final IfNode ifNode, final Expression test, final Block pass, final Block fail, final LocalVariableConversion conversion) { 70 super(ifNode); 71 this.test = test; 72 this.pass = pass; 73 this.fail = fail; 74 this.conversion = conversion; 75 } 76 77 @Override 78 public boolean isTerminal() { 79 return pass.isTerminal() && fail != null && fail.isTerminal(); 80 } 81 82 @Override 83 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 84 if (visitor.enterIfNode(this)) { 85 return visitor.leaveIfNode( 86 setTest((Expression)test.accept(visitor)). 87 setPass((Block)pass.accept(visitor)). 88 setFail(fail == null ? null : (Block)fail.accept(visitor))); 89 } 90 91 return this; 92 } 93 94 @Override 95 public void toString(final StringBuilder sb, final boolean printTypes) { 96 sb.append("if ("); 97 test.toString(sb, printTypes); 98 sb.append(')'); 99 } 100 101 /** 102 * Get the else block of this IfNode 103 * @return the else block, or null if none exists 104 */ 105 public Block getFail() { 106 return fail; 107 } 108 109 private IfNode setFail(final Block fail) { 110 if (this.fail == fail) { 111 return this; 112 } 113 return new IfNode(this, test, pass, fail, conversion); 114 } 115 116 /** 117 * Get the then block for this IfNode 118 * @return the then block 119 */ 120 public Block getPass() { 121 return pass; 122 } 123 124 private IfNode setPass(final Block pass) { 125 if (this.pass == pass) { 126 return this; 127 } 128 return new IfNode(this, test, pass, fail, conversion); 129 } 130 131 /** 132 * Get the test expression for this IfNode 133 * @return the test expression 134 */ 135 public Expression getTest() { 136 return test; 137 } 138 139 /** 140 * Reset the test expression for this IfNode 141 * @param test a new test expression 142 * @return new or same IfNode 143 */ 144 public IfNode setTest(final Expression test) { 145 if (this.test == test) { 146 return this; 147 } 148 return new IfNode(this, test, pass, fail, conversion); 149 } 150 151 @Override 152 public IfNode setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) { 153 if(this.conversion == conversion) { 154 return this; 155 } 156 return new IfNode(this, test, pass, fail, conversion); 157 } 158 159 @Override 160 public LocalVariableConversion getLocalVariableConversion() { 161 return conversion; 162 } 163} 164