1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.ArrayList;
15 import java.util.List;
18 * Catch clause AST node type.
22 * <b>catch</b> <b>(</b> FormalParameter <b>)</b> Block
26 * @noinstantiate This class is not intended to be instantiated by clients.
28 public class CatchClause extends ASTNode {
31 * The "exception" structural property of this node type.
34 public static final ChildPropertyDescriptor EXCEPTION_PROPERTY =
35 new ChildPropertyDescriptor(CatchClause.class, "exception", SingleVariableDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
38 * The "body" structural property of this node type.
41 public static final ChildPropertyDescriptor BODY_PROPERTY =
42 new ChildPropertyDescriptor(CatchClause.class, "body", Block.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
45 * A list of property descriptors (element type:
46 * {@link StructuralPropertyDescriptor}),
47 * or null if uninitialized.
49 private static final List PROPERTY_DESCRIPTORS;
52 List properyList = new ArrayList(3);
53 createPropertyList(CatchClause.class, properyList);
54 addProperty(EXCEPTION_PROPERTY, properyList);
55 addProperty(BODY_PROPERTY, properyList);
56 PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
60 * Returns a list of structural property descriptors for this node type.
61 * Clients must not modify the result.
63 * @param apiLevel the API level; one of the
64 * <code>AST.JLS*</code> constants
66 * @return a list of property descriptors (element type:
67 * {@link StructuralPropertyDescriptor})
70 public static List propertyDescriptors(int apiLevel) {
71 return PROPERTY_DESCRIPTORS;
75 * The body; lazily initialized; defaults to an empty block.
77 private Block body = null;
80 * The exception variable declaration; lazily initialized; defaults to a
81 * unspecified, but legal, variable declaration.
83 private SingleVariableDeclaration exceptionDecl = null;
86 * Creates a new AST node for a catch clause owned by the given
87 * AST. By default, the catch clause declares an unspecified, but legal,
88 * exception declaration and has an empty block.
90 * N.B. This constructor is package-private.
93 * @param ast the AST that is to own this node
95 CatchClause(AST ast) {
99 /* (omit javadoc for this method)
100 * Method declared on ASTNode.
102 final List internalStructuralPropertiesForType(int apiLevel) {
103 return propertyDescriptors(apiLevel);
106 /* (omit javadoc for this method)
107 * Method declared on ASTNode.
109 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
110 if (property == EXCEPTION_PROPERTY) {
112 return getException();
114 setException((SingleVariableDeclaration) child);
118 if (property == BODY_PROPERTY) {
122 setBody((Block) child);
126 // allow default implementation to flag the error
127 return super.internalGetSetChildProperty(property, get, child);
130 /* (omit javadoc for this method)
131 * Method declared on ASTNode.
133 final int getNodeType0() {
137 /* (omit javadoc for this method)
138 * Method declared on ASTNode.
140 ASTNode clone0(AST target) {
141 CatchClause result = new CatchClause(target);
142 result.setSourceRange(this.getStartPosition(), this.getLength());
143 result.setBody((Block) getBody().clone(target));
145 (SingleVariableDeclaration) ASTNode.copySubtree(target, getException()));
149 /* (omit javadoc for this method)
150 * Method declared on ASTNode.
152 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
153 // dispatch to correct overloaded match method
154 return matcher.match(this, other);
157 /* (omit javadoc for this method)
158 * Method declared on ASTNode.
160 void accept0(ASTVisitor visitor) {
161 boolean visitChildren = visitor.visit(this);
163 // visit children in normal left to right reading order
164 acceptChild(visitor, getException());
165 acceptChild(visitor, getBody());
167 visitor.endVisit(this);
171 * Returns the exception variable declaration of this catch clause.
173 * @return the exception variable declaration node
175 public SingleVariableDeclaration getException() {
176 if (this.exceptionDecl == null) {
177 // lazy init must be thread-safe for readers
178 synchronized (this) {
179 if (this.exceptionDecl == null) {
181 this.exceptionDecl = new SingleVariableDeclaration(this.ast);
182 postLazyInit(this.exceptionDecl, EXCEPTION_PROPERTY);
186 return this.exceptionDecl;
190 * Sets the variable declaration of this catch clause.
192 * @param exception the exception variable declaration node
193 * @exception IllegalArgumentException if:
195 * <li>the node belongs to a different AST</li>
196 * <li>the node already has a parent</li>
197 * <li>a cycle in would be created</li>
200 public void setException(SingleVariableDeclaration exception) {
201 if (exception == null) {
202 throw new IllegalArgumentException();
204 ASTNode oldChild = this.exceptionDecl;
205 preReplaceChild(oldChild, exception, EXCEPTION_PROPERTY);
206 this.exceptionDecl= exception;
207 postReplaceChild(oldChild, exception, EXCEPTION_PROPERTY);
211 * Returns the body of this catch clause.
213 * @return the catch clause body
215 public Block getBody() {
216 if (this.body == null) {
217 // lazy init must be thread-safe for readers
218 synchronized (this) {
219 if (this.body == null) {
221 this.body = new Block(this.ast);
222 postLazyInit(this.body, BODY_PROPERTY);
230 * Sets the body of this catch clause.
232 * @param body the catch clause block node
233 * @exception IllegalArgumentException if:
235 * <li>the node belongs to a different AST</li>
236 * <li>the node already has a parent</li>
237 * <li>a cycle in would be created</li>
240 public void setBody(Block body) {
242 throw new IllegalArgumentException();
244 ASTNode oldChild = this.body;
245 preReplaceChild(oldChild, body, BODY_PROPERTY);
247 postReplaceChild(oldChild, body, BODY_PROPERTY);
250 /* (omit javadoc for this method)
251 * Method declared on ASTNode.
254 // treat Code as free
255 return BASE_NODE_SIZE + 2 * 4;
258 /* (omit javadoc for this method)
259 * Method declared on ASTNode.
264 + (this.exceptionDecl == null ? 0 : getException().treeSize())
265 + (this.body == null ? 0 : getBody().treeSize());