001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.core.dom;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: /**
016: * Field declaration node type.
017: * <p>
018: * This kind of node collects several variable declaration fragments
019: * (<code>VariableDeclarationFragment</code>) into a single body declaration
020: * (<code>BodyDeclaration</code>), all sharing the same modifiers and base type.
021: * </p>
022: * <pre>
023: * FieldDeclaration:
024: * [Javadoc] { ExtendedModifier } Type VariableDeclarationFragment
025: * { <b>,</b> VariableDeclarationFragment } <b>;</b>
026: * </pre>
027: * <p>
028: * When a Javadoc comment is present, the source range begins with the first
029: * character of the "/**" comment delimiter. When there is no Javadoc comment,
030: * the source range begins with the first character of the initial modifier or
031: * type. The source range extends through the last character of the final ";".
032: * </p>
033: *
034: * @since 2.0
035: */
036: public class FieldDeclaration extends BodyDeclaration {
037:
038: /**
039: * The "javadoc" structural property of this node type.
040: * @since 3.0
041: */
042: public static final ChildPropertyDescriptor JAVADOC_PROPERTY = internalJavadocPropertyFactory(FieldDeclaration.class);
043:
044: /**
045: * The "modifiers" structural property of this node type (JLS2 API only).
046: * @since 3.0
047: */
048: public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = internalModifiersPropertyFactory(FieldDeclaration.class);
049:
050: /**
051: * The "modifiers" structural property of this node type (added in JLS3 API).
052: * @since 3.1
053: */
054: public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = internalModifiers2PropertyFactory(FieldDeclaration.class);
055:
056: /**
057: * The "type" structural property of this node type.
058: * @since 3.0
059: */
060: public static final ChildPropertyDescriptor TYPE_PROPERTY = new ChildPropertyDescriptor(
061: FieldDeclaration.class,
062: "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
063:
064: /**
065: * The "fragments" structural property of this node type).
066: * @since 3.0
067: */
068: public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY = new ChildListPropertyDescriptor(
069: FieldDeclaration.class,
070: "fragments", VariableDeclarationFragment.class, CYCLE_RISK); //$NON-NLS-1$
071:
072: /**
073: * A list of property descriptors (element type:
074: * {@link StructuralPropertyDescriptor}),
075: * or null if uninitialized.
076: * @since 3.0
077: */
078: private static final List PROPERTY_DESCRIPTORS_2_0;
079:
080: /**
081: * A list of property descriptors (element type:
082: * {@link StructuralPropertyDescriptor}),
083: * or null if uninitialized.
084: * @since 3.1
085: */
086: private static final List PROPERTY_DESCRIPTORS_3_0;
087:
088: static {
089: List properyList = new ArrayList(5);
090: createPropertyList(FieldDeclaration.class, properyList);
091: addProperty(JAVADOC_PROPERTY, properyList);
092: addProperty(MODIFIERS_PROPERTY, properyList);
093: addProperty(TYPE_PROPERTY, properyList);
094: addProperty(FRAGMENTS_PROPERTY, properyList);
095: PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
096:
097: properyList = new ArrayList(5);
098: createPropertyList(FieldDeclaration.class, properyList);
099: addProperty(JAVADOC_PROPERTY, properyList);
100: addProperty(MODIFIERS2_PROPERTY, properyList);
101: addProperty(TYPE_PROPERTY, properyList);
102: addProperty(FRAGMENTS_PROPERTY, properyList);
103: PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
104: }
105:
106: /**
107: * Returns a list of structural property descriptors for this node type.
108: * Clients must not modify the result.
109: *
110: * @param apiLevel the API level; one of the
111: * <code>AST.JLS*</code> constants
112:
113: * @return a list of property descriptors (element type:
114: * {@link StructuralPropertyDescriptor})
115: * @since 3.0
116: */
117: public static List propertyDescriptors(int apiLevel) {
118: if (apiLevel == AST.JLS2_INTERNAL) {
119: return PROPERTY_DESCRIPTORS_2_0;
120: } else {
121: return PROPERTY_DESCRIPTORS_3_0;
122: }
123: }
124:
125: /**
126: * The base type; lazily initialized; defaults to an unspecified,
127: * legal type.
128: */
129: private Type baseType = null;
130:
131: /**
132: * The list of variable declaration fragments (element type:
133: * <code VariableDeclarationFragment</code>). Defaults to an empty list.
134: */
135: private ASTNode.NodeList variableDeclarationFragments = new ASTNode.NodeList(
136: FRAGMENTS_PROPERTY);
137:
138: /**
139: * Creates a new unparented field declaration statement node owned
140: * by the given AST. By default, the field declaration has: no modifiers,
141: * an unspecified (but legal) type, and an empty list of variable
142: * declaration fragments (which is syntactically illegal).
143: * <p>
144: * N.B. This constructor is package-private.
145: * </p>
146: *
147: * @param ast the AST that is to own this node
148: */
149: FieldDeclaration(AST ast) {
150: super (ast);
151: }
152:
153: /* (omit javadoc for this method)
154: * Method declared on ASTNode.
155: * @since 3.0
156: */
157: final List internalStructuralPropertiesForType(int apiLevel) {
158: return propertyDescriptors(apiLevel);
159: }
160:
161: /* (omit javadoc for this method)
162: * Method declared on ASTNode.
163: */
164: final int internalGetSetIntProperty(
165: SimplePropertyDescriptor property, boolean get, int value) {
166: if (property == MODIFIERS_PROPERTY) {
167: if (get) {
168: return getModifiers();
169: } else {
170: internalSetModifiers(value);
171: return 0;
172: }
173: }
174: // allow default implementation to flag the error
175: return super .internalGetSetIntProperty(property, get, value);
176: }
177:
178: /* (omit javadoc for this method)
179: * Method declared on ASTNode.
180: */
181: final ASTNode internalGetSetChildProperty(
182: ChildPropertyDescriptor property, boolean get, ASTNode child) {
183: if (property == JAVADOC_PROPERTY) {
184: if (get) {
185: return getJavadoc();
186: } else {
187: setJavadoc((Javadoc) child);
188: return null;
189: }
190: }
191: if (property == TYPE_PROPERTY) {
192: if (get) {
193: return getType();
194: } else {
195: setType((Type) child);
196: return null;
197: }
198: }
199: // allow default implementation to flag the error
200: return super .internalGetSetChildProperty(property, get, child);
201: }
202:
203: /* (omit javadoc for this method)
204: * Method declared on ASTNode.
205: */
206: final List internalGetChildListProperty(
207: ChildListPropertyDescriptor property) {
208: if (property == MODIFIERS2_PROPERTY) {
209: return modifiers();
210: }
211: if (property == FRAGMENTS_PROPERTY) {
212: return fragments();
213: }
214: // allow default implementation to flag the error
215: return super .internalGetChildListProperty(property);
216: }
217:
218: /* (omit javadoc for this method)
219: * Method declared on BodyDeclaration.
220: */
221: final ChildPropertyDescriptor internalJavadocProperty() {
222: return JAVADOC_PROPERTY;
223: }
224:
225: /* (omit javadoc for this method)
226: * Method declared on BodyDeclaration.
227: */
228: final SimplePropertyDescriptor internalModifiersProperty() {
229: return MODIFIERS_PROPERTY;
230: }
231:
232: /* (omit javadoc for this method)
233: * Method declared on BodyDeclaration.
234: */
235: final ChildListPropertyDescriptor internalModifiers2Property() {
236: return MODIFIERS2_PROPERTY;
237: }
238:
239: /* (omit javadoc for this method)
240: * Method declared on ASTNode.
241: */
242: final int getNodeType0() {
243: return FIELD_DECLARATION;
244: }
245:
246: /* (omit javadoc for this method)
247: * Method declared on ASTNode.
248: */
249: ASTNode clone0(AST target) {
250: FieldDeclaration result = new FieldDeclaration(target);
251: result
252: .setSourceRange(this .getStartPosition(), this
253: .getLength());
254: result.setJavadoc((Javadoc) ASTNode.copySubtree(target,
255: getJavadoc()));
256: if (this .ast.apiLevel == AST.JLS2_INTERNAL) {
257: result.internalSetModifiers(getModifiers());
258: }
259: if (this .ast.apiLevel >= AST.JLS3) {
260: result.modifiers().addAll(
261: ASTNode.copySubtrees(target, modifiers()));
262: }
263: result.setType((Type) getType().clone(target));
264: result.fragments().addAll(
265: ASTNode.copySubtrees(target, fragments()));
266: return result;
267: }
268:
269: /* (omit javadoc for this method)
270: * Method declared on ASTNode.
271: */
272: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
273: // dispatch to correct overloaded match method
274: return matcher.match(this , other);
275: }
276:
277: /* (omit javadoc for this method)
278: * Method declared on ASTNode.
279: */
280: void accept0(ASTVisitor visitor) {
281: boolean visitChildren = visitor.visit(this );
282: if (visitChildren) {
283: // visit children in normal left to right reading order
284: acceptChild(visitor, getJavadoc());
285: if (this .ast.apiLevel >= AST.JLS3) {
286: acceptChildren(visitor, this .modifiers);
287: }
288: acceptChild(visitor, getType());
289: acceptChildren(visitor, this .variableDeclarationFragments);
290: }
291: visitor.endVisit(this );
292: }
293:
294: /**
295: * Returns the base type declared in this field declaration.
296: * <p>
297: * N.B. The individual child variable declaration fragments may specify
298: * additional array dimensions. So the type of the variable are not
299: * necessarily exactly this type.
300: * </p>
301: *
302: * @return the base type
303: */
304: public Type getType() {
305: if (this .baseType == null) {
306: // lazy init must be thread-safe for readers
307: synchronized (this ) {
308: if (this .baseType == null) {
309: preLazyInit();
310: this .baseType = this .ast
311: .newPrimitiveType(PrimitiveType.INT);
312: postLazyInit(this .baseType, TYPE_PROPERTY);
313: }
314: }
315: }
316: return this .baseType;
317: }
318:
319: /**
320: * Sets the base type declared in this field declaration to the given type.
321: *
322: * @param type the new base type
323: * @exception IllegalArgumentException if:
324: * <ul>
325: * <li>the node belongs to a different AST</li>
326: * <li>the node already has a parent</li>
327: * </ul>
328: */
329: public void setType(Type type) {
330: if (type == null) {
331: throw new IllegalArgumentException();
332: }
333: ASTNode oldChild = this .baseType;
334: preReplaceChild(oldChild, type, TYPE_PROPERTY);
335: this .baseType = type;
336: postReplaceChild(oldChild, type, TYPE_PROPERTY);
337: }
338:
339: /**
340: * Returns the live list of variable declaration fragments in this field
341: * declaration. Adding and removing nodes from this list affects this node
342: * dynamically. All nodes in this list must be
343: * <code>VariableDeclarationFragment</code>s; attempts to add any other
344: * type of node will trigger an exception.
345: *
346: * @return the live list of variable declaration fragments in this
347: * statement (element type: <code>VariableDeclarationFragment</code>)
348: */
349: public List fragments() {
350: return this .variableDeclarationFragments;
351: }
352:
353: /* (omit javadoc for this method)
354: * Method declared on ASTNode.
355: */
356: int memSize() {
357: return super .memSize() + 2 * 4;
358: }
359:
360: /* (omit javadoc for this method)
361: * Method declared on ASTNode.
362: */
363: int treeSize() {
364: return memSize()
365: + (this .optionalDocComment == null ? 0 : getJavadoc()
366: .treeSize())
367: + (this .modifiers == null ? 0 : this .modifiers
368: .listSize())
369: + (this .baseType == null ? 0 : getType().treeSize())
370: + this.variableDeclarationFragments.listSize();
371: }
372: }
|