1 | /******************************************************************************* |
---|---|
2 | * Copyright (c) 2000, 2013 IBM Corporation and others. |
3 | * |
4 | * This program and the accompanying materials |
5 | * are made available under the terms of the Eclipse Public License 2.0 |
6 | * which accompanies this distribution, and is available at |
7 | * https://www.eclipse.org/legal/epl-2.0/ |
8 | * |
9 | * SPDX-License-Identifier: EPL-2.0 |
10 | * |
11 | * Contributors: |
12 | * IBM Corporation - initial API and implementation |
13 | *******************************************************************************/ |
14 | |
15 | package org.eclipse.jdt.core.dom; |
16 | |
17 | import java.util.ArrayList; |
18 | import java.util.List; |
19 | |
20 | /** |
21 | * Enumeration constant declaration AST node type (added in JLS3 API). |
22 | * |
23 | * <pre> |
24 | * EnumConstantDeclaration: |
25 | * [ Javadoc ] { ExtendedModifier } Identifier |
26 | * [ <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b> ] |
27 | * [ AnonymousClassDeclaration ] |
28 | * </pre> |
29 | * <p> |
30 | * When a Javadoc comment is present, the source |
31 | * range begins with the first character of the "/**" comment delimiter. |
32 | * When there is no Javadoc comment, the source range begins with the first |
33 | * character of the identifier. If there are class body declarations, the |
34 | * source range extends through the last character of the last character of |
35 | * the "}" token following the body declarations. If there are arguments but |
36 | * no class body declarations, the source range extends through the last |
37 | * character of the ")" token following the arguments. If there are no |
38 | * arguments and no class body declarations, the source range extends through |
39 | * the last character of the identifier. |
40 | * </p> |
41 | * |
42 | * @since 3.1 |
43 | * @noinstantiate This class is not intended to be instantiated by clients. |
44 | */ |
45 | @SuppressWarnings({"rawtypes", "unchecked"}) |
46 | public class EnumConstantDeclaration extends BodyDeclaration { |
47 | |
48 | /** |
49 | * The "javadoc" structural property of this node type (child type: {@link Javadoc}). |
50 | */ |
51 | public static final ChildPropertyDescriptor JAVADOC_PROPERTY = |
52 | internalJavadocPropertyFactory(EnumConstantDeclaration.class); |
53 | |
54 | /** |
55 | * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}). |
56 | */ |
57 | public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = |
58 | internalModifiers2PropertyFactory(EnumConstantDeclaration.class); |
59 | |
60 | /** |
61 | * The "name" structural property of this node type (child type: {@link SimpleName}). |
62 | */ |
63 | public static final ChildPropertyDescriptor NAME_PROPERTY = |
64 | new ChildPropertyDescriptor(EnumConstantDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$ |
65 | |
66 | /** |
67 | * The "arguments" structural property of this node type (element type: {@link Expression}). |
68 | */ |
69 | public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY = |
70 | new ChildListPropertyDescriptor(EnumConstantDeclaration.class, "arguments", Expression.class, NO_CYCLE_RISK); //$NON-NLS-1$ |
71 | |
72 | /** |
73 | * The "anonymousClassDeclaration" structural property of this node type (child type: {@link AnonymousClassDeclaration}). |
74 | */ |
75 | public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY = |
76 | new ChildPropertyDescriptor(EnumConstantDeclaration.class, "anonymousClassDeclaration", AnonymousClassDeclaration.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$ |
77 | |
78 | /** |
79 | * A list of property descriptors (element type: |
80 | * {@link StructuralPropertyDescriptor}), |
81 | * or null if uninitialized. |
82 | */ |
83 | private static final List PROPERTY_DESCRIPTORS; |
84 | |
85 | static { |
86 | List properyList = new ArrayList(6); |
87 | createPropertyList(EnumConstantDeclaration.class, properyList); |
88 | addProperty(JAVADOC_PROPERTY, properyList); |
89 | addProperty(MODIFIERS2_PROPERTY, properyList); |
90 | addProperty(NAME_PROPERTY, properyList); |
91 | addProperty(ARGUMENTS_PROPERTY, properyList); |
92 | addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList); |
93 | PROPERTY_DESCRIPTORS = reapPropertyList(properyList); |
94 | } |
95 | |
96 | /** |
97 | * Returns a list of structural property descriptors for this node type. |
98 | * Clients must not modify the result. |
99 | * |
100 | * @param apiLevel the API level; one of the |
101 | * <code>AST.JLS*</code> constants |
102 | |
103 | * @return a list of property descriptors (element type: |
104 | * {@link StructuralPropertyDescriptor}) |
105 | */ |
106 | public static List propertyDescriptors(int apiLevel) { |
107 | return PROPERTY_DESCRIPTORS; |
108 | } |
109 | |
110 | /** |
111 | * The constant name; lazily initialized; defaults to a unspecified, |
112 | * legal Java class identifier. |
113 | */ |
114 | private SimpleName constantName = null; |
115 | |
116 | /** |
117 | * The list of argument expressions (element type: |
118 | * {@link Expression}). Defaults to an empty list. |
119 | */ |
120 | private ASTNode.NodeList arguments = |
121 | new ASTNode.NodeList(ARGUMENTS_PROPERTY); |
122 | |
123 | /** |
124 | * The optional anonymous class declaration; <code>null</code> for none; |
125 | * defaults to none. |
126 | */ |
127 | private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null; |
128 | |
129 | /** |
130 | * Creates a new AST node for an enumeration constants declaration owned by |
131 | * the given AST. By default, the enumeration constant has an unspecified, |
132 | * but legal, name; no javadoc; an empty list of modifiers and annotations; |
133 | * an empty list of arguments; and does not declare an anonymous class. |
134 | * <p> |
135 | * N.B. This constructor is package-private; all subclasses must be |
136 | * declared in the same package; clients are unable to declare |
137 | * additional subclasses. |
138 | * </p> |
139 | * |
140 | * @param ast the AST that is to own this node |
141 | */ |
142 | EnumConstantDeclaration(AST ast) { |
143 | super(ast); |
144 | unsupportedIn2(); |
145 | } |
146 | |
147 | @Override |
148 | final List internalStructuralPropertiesForType(int apiLevel) { |
149 | return propertyDescriptors(apiLevel); |
150 | } |
151 | |
152 | @Override |
153 | final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) { |
154 | if (property == JAVADOC_PROPERTY) { |
155 | if (get) { |
156 | return getJavadoc(); |
157 | } else { |
158 | setJavadoc((Javadoc) child); |
159 | return null; |
160 | } |
161 | } |
162 | if (property == NAME_PROPERTY) { |
163 | if (get) { |
164 | return getName(); |
165 | } else { |
166 | setName((SimpleName) child); |
167 | return null; |
168 | } |
169 | } |
170 | if (property == ANONYMOUS_CLASS_DECLARATION_PROPERTY) { |
171 | if (get) { |
172 | return getAnonymousClassDeclaration(); |
173 | } else { |
174 | setAnonymousClassDeclaration((AnonymousClassDeclaration) child); |
175 | return null; |
176 | } |
177 | } |
178 | // allow default implementation to flag the error |
179 | return super.internalGetSetChildProperty(property, get, child); |
180 | } |
181 | |
182 | @Override |
183 | final List internalGetChildListProperty(ChildListPropertyDescriptor property) { |
184 | if (property == MODIFIERS2_PROPERTY) { |
185 | return modifiers(); |
186 | } |
187 | if (property == ARGUMENTS_PROPERTY) { |
188 | return arguments(); |
189 | } |
190 | // allow default implementation to flag the error |
191 | return super.internalGetChildListProperty(property); |
192 | } |
193 | |
194 | @Override |
195 | final ChildPropertyDescriptor internalJavadocProperty() { |
196 | return JAVADOC_PROPERTY; |
197 | } |
198 | |
199 | @Override |
200 | final ChildListPropertyDescriptor internalModifiers2Property() { |
201 | return MODIFIERS2_PROPERTY; |
202 | } |
203 | |
204 | @Override |
205 | final SimplePropertyDescriptor internalModifiersProperty() { |
206 | // this property will not be asked for (node type did not exist in JLS2) |
207 | return null; |
208 | } |
209 | |
210 | @Override |
211 | final int getNodeType0() { |
212 | return ENUM_CONSTANT_DECLARATION; |
213 | } |
214 | |
215 | @Override |
216 | ASTNode clone0(AST target) { |
217 | EnumConstantDeclaration result = new EnumConstantDeclaration(target); |
218 | result.setSourceRange(getStartPosition(), getLength()); |
219 | result.setJavadoc( |
220 | (Javadoc) ASTNode.copySubtree(target, getJavadoc())); |
221 | result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers())); |
222 | result.setName((SimpleName) getName().clone(target)); |
223 | result.arguments().addAll(ASTNode.copySubtrees(target, arguments())); |
224 | result.setAnonymousClassDeclaration( |
225 | (AnonymousClassDeclaration) ASTNode.copySubtree(target, getAnonymousClassDeclaration())); |
226 | return result; |
227 | } |
228 | |
229 | @Override |
230 | final boolean subtreeMatch0(ASTMatcher matcher, Object other) { |
231 | // dispatch to correct overloaded match method |
232 | return matcher.match(this, other); |
233 | } |
234 | |
235 | @Override |
236 | void accept0(ASTVisitor visitor) { |
237 | boolean visitChildren = visitor.visit(this); |
238 | if (visitChildren) { |
239 | // visit children in normal left to right reading order |
240 | acceptChild(visitor, getJavadoc()); |
241 | acceptChildren(visitor, this.modifiers); |
242 | acceptChild(visitor, getName()); |
243 | acceptChildren(visitor, this.arguments); |
244 | acceptChild(visitor, getAnonymousClassDeclaration()); |
245 | } |
246 | visitor.endVisit(this); |
247 | } |
248 | |
249 | /** |
250 | * Returns the name of the constant declared in this enum declaration. |
251 | * |
252 | * @return the constant name node |
253 | */ |
254 | public SimpleName getName() { |
255 | if (this.constantName == null) { |
256 | // lazy init must be thread-safe for readers |
257 | synchronized (this) { |
258 | if (this.constantName == null) { |
259 | preLazyInit(); |
260 | this.constantName = new SimpleName(this.ast); |
261 | postLazyInit(this.constantName, NAME_PROPERTY); |
262 | } |
263 | } |
264 | } |
265 | return this.constantName; |
266 | } |
267 | |
268 | /** |
269 | * Sets the name of the constant declared in this enum declaration to the |
270 | * given name. |
271 | * |
272 | * @param constantName the new constant name |
273 | * @exception IllegalArgumentException if: |
274 | * <ul> |
275 | * <li>the node belongs to a different AST</li> |
276 | * <li>the node already has a parent</li> |
277 | * </ul> |
278 | */ |
279 | public void setName(SimpleName constantName) { |
280 | if (constantName == null) { |
281 | throw new IllegalArgumentException(); |
282 | } |
283 | ASTNode oldChild = this.constantName; |
284 | preReplaceChild(oldChild, constantName, NAME_PROPERTY); |
285 | this.constantName = constantName; |
286 | postReplaceChild(oldChild, constantName, NAME_PROPERTY); |
287 | } |
288 | |
289 | /** |
290 | * Returns the live ordered list of argument expressions in this enumeration |
291 | * constant declaration. Note that an empty list of arguments is equivalent |
292 | * to not explicitly specifying arguments. |
293 | * |
294 | * @return the live list of argument expressions |
295 | * (element type: {@link Expression}) |
296 | */ |
297 | public List arguments() { |
298 | return this.arguments; |
299 | } |
300 | |
301 | /** |
302 | * Returns the anonymous class declaration introduced by this |
303 | * enum constant declaration, if it has one. |
304 | * |
305 | * @return the anonymous class declaration, or <code>null</code> if none |
306 | */ |
307 | public AnonymousClassDeclaration getAnonymousClassDeclaration() { |
308 | return this.optionalAnonymousClassDeclaration; |
309 | } |
310 | |
311 | /** |
312 | * Sets whether this enum constant declaration declares |
313 | * an anonymous class (that is, has class body declarations). |
314 | * |
315 | * @param decl the anonymous class declaration, or <code>null</code> |
316 | * if none |
317 | */ |
318 | public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) { |
319 | ASTNode oldChild = this.optionalAnonymousClassDeclaration; |
320 | preReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY); |
321 | this.optionalAnonymousClassDeclaration = decl; |
322 | postReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY); |
323 | } |
324 | |
325 | /** |
326 | * Resolves and returns the binding for the constructor invoked by this |
327 | * enum constant. |
328 | * <p> |
329 | * Note that bindings are generally unavailable unless requested when the |
330 | * AST is being built. |
331 | * </p> |
332 | * |
333 | * @return the constructor binding, or <code>null</code> if the binding |
334 | * cannot be resolved |
335 | */ |
336 | public IMethodBinding resolveConstructorBinding() { |
337 | return this.ast.getBindingResolver().resolveConstructor(this); |
338 | } |
339 | |
340 | /** |
341 | * Resolves and returns the field binding for this enum constant. |
342 | * <p> |
343 | * Note that bindings are generally unavailable unless requested when the |
344 | * AST is being built. |
345 | * </p> |
346 | * |
347 | * @return the binding, or <code>null</code> if the binding cannot be |
348 | * resolved |
349 | */ |
350 | public IVariableBinding resolveVariable() { |
351 | return this.ast.getBindingResolver().resolveVariable(this); |
352 | } |
353 | |
354 | @Override |
355 | int memSize() { |
356 | return super.memSize() + 3 * 4; |
357 | } |
358 | |
359 | @Override |
360 | int treeSize() { |
361 | return |
362 | memSize() |
363 | + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize()) |
364 | + this.modifiers.listSize() |
365 | + (this.constantName == null ? 0 : getName().treeSize()) |
366 | + this.arguments.listSize() |
367 | + (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize()); |
368 | } |
369 | } |
370 | |
371 |
Members