CatchNode.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 of a catch clause. 33 */ 34@Immutable 35public final class CatchNode extends Statement { 36 /** Exception identifier. */ 37 private final IdentNode exception; 38 39 /** Exception condition. */ 40 private final Expression exceptionCondition; 41 42 /** Catch body. */ 43 private final Block body; 44 45 private final boolean isSyntheticRethrow; 46 47 /** 48 * Constructors 49 * 50 * @param lineNumber lineNumber 51 * @param token token 52 * @param finish finish 53 * @param exception variable name of exception 54 * @param exceptionCondition exception condition 55 * @param body catch body 56 * @param isSyntheticRethrow true if this node is a synthetically generated rethrow node. 57 */ 58 public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, 59 final Expression exceptionCondition, final Block body, final boolean isSyntheticRethrow) { 60 super(lineNumber, token, finish); 61 this.exception = exception == null ? null : exception.setIsInitializedHere(); 62 this.exceptionCondition = exceptionCondition; 63 this.body = body; 64 this.isSyntheticRethrow = isSyntheticRethrow; 65 } 66 67 private CatchNode(final CatchNode catchNode, final IdentNode exception, final Expression exceptionCondition, 68 final Block body, final boolean isSyntheticRethrow) { 69 super(catchNode); 70 this.exception = exception; 71 this.exceptionCondition = exceptionCondition; 72 this.body = body; 73 this.isSyntheticRethrow = isSyntheticRethrow; 74 } 75 76 /** 77 * Assist in IR navigation. 78 * @param visitor IR navigating visitor. 79 */ 80 @Override 81 public Node accept(final NodeVisitor<? extends LexicalContext> visitor) { 82 if (visitor.enterCatchNode(this)) { 83 return visitor.leaveCatchNode( 84 setException((IdentNode)exception.accept(visitor)). 85 setExceptionCondition(exceptionCondition == null ? null : (Expression)exceptionCondition.accept(visitor)). 86 setBody((Block)body.accept(visitor))); 87 } 88 89 return this; 90 } 91 92 @Override 93 public boolean isTerminal() { 94 return body.isTerminal(); 95 } 96 97 @Override 98 public void toString(final StringBuilder sb, final boolean printTypes) { 99 sb.append(" catch ("); 100 exception.toString(sb, printTypes); 101 102 if (exceptionCondition != null) { 103 sb.append(" if "); 104 exceptionCondition.toString(sb, printTypes); 105 } 106 sb.append(')'); 107 } 108 109 /** 110 * Get the identifier representing the exception thrown 111 * @return the exception identifier 112 */ 113 public IdentNode getException() { 114 return exception; 115 } 116 117 /** 118 * Get the exception condition for this catch block 119 * @return the exception condition 120 */ 121 public Expression getExceptionCondition() { 122 return exceptionCondition; 123 } 124 125 /** 126 * Reset the exception condition for this catch block 127 * @param exceptionCondition the new exception condition 128 * @return new or same CatchNode 129 */ 130 public CatchNode setExceptionCondition(final Expression exceptionCondition) { 131 if (this.exceptionCondition == exceptionCondition) { 132 return this; 133 } 134 return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow); 135 } 136 137 /** 138 * Get the body for this catch block 139 * @return the catch block body 140 */ 141 public Block getBody() { 142 return body; 143 } 144 145 /** 146 * Resets the exception of a catch block 147 * @param exception new exception 148 * @return new catch node if changed, same otherwise 149 */ 150 public CatchNode setException(final IdentNode exception) { 151 if (this.exception == exception) { 152 return this; 153 } 154 return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow); 155 } 156 157 private CatchNode setBody(final Block body) { 158 if (this.body == body) { 159 return this; 160 } 161 return new CatchNode(this, exception, exceptionCondition, body, isSyntheticRethrow); 162 } 163 164 /** 165 * Is this catch block a non-JavaScript constructor, for example created as 166 * part of the rethrow mechanism of a finally block in Lower? Then we just 167 * pass the exception on and need not unwrap whatever is in the ECMAException 168 * object catch symbol 169 * @return true if a finally synthetic rethrow 170 */ 171 public boolean isSyntheticRethrow() { 172 return isSyntheticRethrow; 173 } 174} 175