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