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 * Local type declaration statement AST node type.
20 * This kind of node is used to convert a type declaration
21 * node into a statement node by wrapping it.
25 * TypeDeclarationStatement:
28 * For JLS3, the kinds of type declarations grew to include enum declarations:
30 * TypeDeclarationStatement:
34 * Although allowed at the AST, not all arrangements of AST nodes are meaningful;
35 * in particular, only class and enum declarations are meaningful in the context of
39 * @noinstantiate This class is not intended to be instantiated by clients.
41 public class TypeDeclarationStatement extends Statement {
44 * The "typeDeclaration" structural property of this node type (JLS2 API only).
47 public static final ChildPropertyDescriptor TYPE_DECLARATION_PROPERTY =
48 new ChildPropertyDescriptor(TypeDeclarationStatement.class, "typeDeclaration", TypeDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
51 * The "declaration" structural property of this node type (added in JLS3 API).
54 public static final ChildPropertyDescriptor DECLARATION_PROPERTY =
55 new ChildPropertyDescriptor(TypeDeclarationStatement.class, "declaration", AbstractTypeDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
58 * A list of property descriptors (element type:
59 * {@link StructuralPropertyDescriptor}),
60 * or null if uninitialized.
63 private static final List PROPERTY_DESCRIPTORS_2_0;
66 * A list of property descriptors (element type:
67 * {@link StructuralPropertyDescriptor}),
68 * or null if uninitialized.
71 private static final List PROPERTY_DESCRIPTORS_3_0;
74 List propertyList = new ArrayList(2);
75 createPropertyList(TypeDeclarationStatement.class, propertyList);
76 addProperty(TYPE_DECLARATION_PROPERTY, propertyList);
77 PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
79 propertyList = new ArrayList(2);
80 createPropertyList(TypeDeclarationStatement.class, propertyList);
81 addProperty(DECLARATION_PROPERTY, propertyList);
82 PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
86 * Returns a list of structural property descriptors for this node type.
87 * Clients must not modify the result.
89 * @param apiLevel the API level; one of the
90 * <code>AST.JLS*</code> constants
92 * @return a list of property descriptors (element type:
93 * {@link StructuralPropertyDescriptor})
96 public static List propertyDescriptors(int apiLevel) {
97 if (apiLevel == AST.JLS2_INTERNAL) {
98 return PROPERTY_DESCRIPTORS_2_0;
100 return PROPERTY_DESCRIPTORS_3_0;
105 * The type declaration; lazily initialized; defaults to a unspecified,
106 * but legal, type declaration. In JLS2, corresponds to TYPE_DECLARATION_PROPERTY.
107 * After JLS2, corresponds to DECLARATION_PROPERTY.
108 * @see #typeDeclProperty
110 private AbstractTypeDeclaration typeDecl = null;
113 * The child property stored on the <code>typeDecl</code> instance variable.
114 * In JLS2, corresponds to TYPE_DECLARATION_PROPERTY. After JLS2, corresponds to
115 * DECLARATION_PROPERTY.
117 * @return the property corresponding to the <code>typeDecl</code> instance variable;
118 * never <code>null</code>
120 private ChildPropertyDescriptor typeDeclProperty () {
121 if (getAST().apiLevel() == AST.JLS2_INTERNAL) {
122 return TYPE_DECLARATION_PROPERTY;
124 return DECLARATION_PROPERTY;
130 * Creates a new unparented local type declaration statement node owned
131 * by the given AST. By default, the local type declaration is an
132 * unspecified, but legal, type declaration.
134 * N.B. This constructor is package-private.
137 * @param ast the AST that is to own this node
139 TypeDeclarationStatement(AST ast) {
143 /* (omit javadoc for this method)
144 * Method declared on ASTNode.
147 final List internalStructuralPropertiesForType(int apiLevel) {
148 return propertyDescriptors(apiLevel);
151 /* (omit javadoc for this method)
152 * Method declared on ASTNode.
154 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
155 if (property == TYPE_DECLARATION_PROPERTY) {
157 return getTypeDeclaration();
159 setTypeDeclaration((TypeDeclaration) child);
163 if (property == DECLARATION_PROPERTY) {
165 return getDeclaration();
167 setDeclaration((AbstractTypeDeclaration) child);
171 // allow default implementation to flag the error
172 return super.internalGetSetChildProperty(property, get, child);
175 /* (omit javadoc for this method)
176 * Method declared on ASTNode.
178 final int getNodeType0() {
179 return TYPE_DECLARATION_STATEMENT;
182 /* (omit javadoc for this method)
183 * Method declared on ASTNode.
185 ASTNode clone0(AST target) {
186 TypeDeclarationStatement result =
187 new TypeDeclarationStatement(target);
188 result.setSourceRange(this.getStartPosition(), this.getLength());
189 result.copyLeadingComment(this);
190 result.setDeclaration(
191 (AbstractTypeDeclaration) getDeclaration().clone(target));
195 /* (omit javadoc for this method)
196 * Method declared on ASTNode.
198 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
199 // dispatch to correct overloaded match method
200 return matcher.match(this, other);
203 /* (omit javadoc for this method)
204 * Method declared on ASTNode.
206 void accept0(ASTVisitor visitor) {
207 boolean visitChildren = visitor.visit(this);
209 acceptChild(visitor, getDeclaration());
211 visitor.endVisit(this);
215 * Returns the abstract type declaration of this local type declaration
216 * statement (added in JLS3 API).
218 * @return the type declaration node
221 public AbstractTypeDeclaration getDeclaration() {
222 if (this.typeDecl == null) {
223 // lazy init must be thread-safe for readers
224 synchronized (this) {
225 if (this.typeDecl == null) {
227 this.typeDecl = new TypeDeclaration(this.ast);
228 postLazyInit(this.typeDecl, typeDeclProperty());
232 return this.typeDecl;
236 * Sets the abstract type declaration of this local type declaration
237 * statement (added in JLS3 API).
239 * @param decl the type declaration node
240 * @exception IllegalArgumentException if:
242 * <li>the node belongs to a different AST</li>
243 * <li>the node already has a parent</li>
244 * <li>a cycle in would be created</li>
248 public void setDeclaration(AbstractTypeDeclaration decl) {
250 throw new IllegalArgumentException();
252 // a TypeDeclarationStatement may occur inside an
253 // TypeDeclaration - must check cycles
254 ASTNode oldChild = this.typeDecl;
255 ChildPropertyDescriptor typeDeclProperty = typeDeclProperty();
256 preReplaceChild(oldChild, decl, typeDeclProperty);
258 postReplaceChild(oldChild, decl, typeDeclProperty);
262 * Returns the type declaration of this local type declaration
263 * statement (JLS2 API only).
265 * @return the type declaration node
266 * @exception UnsupportedOperationException if this operation is used in
267 * an AST later than JLS2
268 * @deprecated In the JLS3 API, this method is replaced by
269 * {@link #getDeclaration()}, which returns <code>AbstractTypeDeclaration</code>
270 * instead of <code>TypeDeclaration</code>.
272 public TypeDeclaration getTypeDeclaration() {
273 return internalGetTypeDeclaration();
277 * Internal synonym for deprecated method. Used to avoid
278 * deprecation warnings.
281 /*package*/ final TypeDeclaration internalGetTypeDeclaration() {
283 return (TypeDeclaration) getDeclaration();
287 * Sets the type declaration of this local type declaration
288 * statement (JLS2 API only).
290 * @param decl the type declaration node
291 * @exception IllegalArgumentException if:
293 * <li>the node belongs to a different AST</li>
294 * <li>the node already has a parent</li>
295 * <li>a cycle in would be created</li>
297 * @exception UnsupportedOperationException if this operation is used in
298 * an AST later than JLS2
299 * @deprecated In the JLS3 API, this method is replaced by
300 * {@link #setDeclaration(AbstractTypeDeclaration)} which takes
301 * <code>AbstractTypeDeclaration</code> instead of
302 * <code>TypeDeclaration</code>.
304 public void setTypeDeclaration(TypeDeclaration decl) {
305 internalSetTypeDeclaration(decl);
309 * Internal synonym for deprecated method. Used to avoid
310 * deprecation warnings.
313 /*package*/ final void internalSetTypeDeclaration(TypeDeclaration decl) {
315 // forward to non-deprecated replacement method
316 setDeclaration(decl);
320 * Resolves and returns the binding for the class or interface declared in
321 * this type declaration statement.
323 * Note that bindings are generally unavailable unless requested when the
324 * AST is being built.
327 * @return the binding, or <code>null</code> if the binding cannot be
330 public ITypeBinding resolveBinding() {
331 // forward request to the wrapped type declaration
332 AbstractTypeDeclaration d = getDeclaration();
333 if (d instanceof TypeDeclaration) {
334 return ((TypeDeclaration) d).resolveBinding();
335 } else if (d instanceof AnnotationTypeDeclaration) {
336 return ((AnnotationTypeDeclaration) d).resolveBinding();
343 /* (omit javadoc for this method)
344 * Method declared on ASTNode.
347 return super.memSize() + 1 * 4;
350 /* (omit javadoc for this method)
351 * Method declared on ASTNode.
356 + (this.typeDecl == null ? 0 : getDeclaration().treeSize());