KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > ClassInstanceCreation


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.core.dom;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 /**
18  * Class instance creation expression AST node type.
19  * For JLS2:
20  * <pre>
21  * ClassInstanceCreation:
22  * [ Expression <b>.</b> ] <b>new</b> Name
23  * <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
24  * [ AnonymousClassDeclaration ]
25  * </pre>
26  * For JLS3, type arguments are added
27  * and the type name is generalized to a type so that parameterized
28  * types can be instantiated:
29  * <pre>
30  * ClassInstanceCreation:
31  * [ Expression <b>.</b> ]
32  * <b>new</b> [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
33  * Type <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
34  * [ AnonymousClassDeclaration ]
35  * </pre>
36  * <p>
37  * Not all node arragements will represent legal Java constructs. In particular,
38  * it is nonsense if the type is a primitive type or an array type (primitive
39  * types cannot be instantiated, and array creations must be represented with
40  * <code>ArrayCreation</code> nodes). The normal use is when the type is a
41  * simple, qualified, or parameterized type.
42  * </p>
43  * <p>
44  * A type like "A.B" can be represented either of two ways:
45  * <ol>
46  * <li>
47  * <code>QualifiedType(SimpleType(SimpleName("A")),SimpleName("B"))</code>
48  * </li>
49  * <li>
50  * <code>SimpleType(QualifiedName(SimpleName("A"),SimpleName("B")))</code>
51  * </li>
52  * </ol>
53  * The first form is preferred when "A" is known to be a type (as opposed
54  * to a package). However, a parser cannot always determine this. Clients
55  * should be prepared to handle either rather than make assumptions.
56  * (Note also that the first form became possible as of JLS3; only the second
57  * form existed in JLS2.)
58  * </p>
59  *
60  * @since 2.0
61  */

62 public class ClassInstanceCreation extends Expression {
63
64     /**
65      * The "typeArguments" structural property of this node type (added in JLS3 API).
66      * @since 3.1
67      */

68     public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
69         new ChildListPropertyDescriptor(ClassInstanceCreation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
70

71     /**
72      * The "expression" structural property of this node type.
73      * @since 3.0
74      */

75     public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
76         new ChildPropertyDescriptor(ClassInstanceCreation.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
77

78     /**
79      * The "name" structural property of this node type (JLS2 API only).
80      * @since 3.0
81      */

82     public static final ChildPropertyDescriptor NAME_PROPERTY =
83         new ChildPropertyDescriptor(ClassInstanceCreation.class, "name", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
84

85     /**
86      * The "type" structural property of this node type (added in JLS3 API).
87      * @since 3.1
88      */

89     public static final ChildPropertyDescriptor TYPE_PROPERTY =
90         new ChildPropertyDescriptor(ClassInstanceCreation.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
91

92     /**
93      * The "arguments" structural property of this node type.
94      * @since 3.0
95      */

96     public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
97         new ChildListPropertyDescriptor(ClassInstanceCreation.class, "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
98

99     /**
100      * The "anonymousClassDeclaration" structural property of this node type.
101      * @since 3.0
102      */

103     public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY =
104         new ChildPropertyDescriptor(ClassInstanceCreation.class, "anonymousClassDeclaration", AnonymousClassDeclaration.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
105

106     /**
107      * A list of property descriptors (element type:
108      * {@link StructuralPropertyDescriptor}),
109      * or null if uninitialized.
110      * @since 3.0
111      */

112     private static final List JavaDoc PROPERTY_DESCRIPTORS_2_0;
113     
114     /**
115      * A list of property descriptors (element type:
116      * {@link StructuralPropertyDescriptor}),
117      * or null if uninitialized.
118      * @since 3.1
119      */

120     private static final List JavaDoc PROPERTY_DESCRIPTORS_3_0;
121     
122     static {
123         List JavaDoc properyList = new ArrayList JavaDoc(5);
124         createPropertyList(ClassInstanceCreation.class, properyList);
125         addProperty(EXPRESSION_PROPERTY, properyList);
126         addProperty(NAME_PROPERTY, properyList);
127         addProperty(ARGUMENTS_PROPERTY, properyList);
128         addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
129         PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
130         
131         properyList = new ArrayList JavaDoc(6);
132         createPropertyList(ClassInstanceCreation.class, properyList);
133         addProperty(EXPRESSION_PROPERTY, properyList);
134         addProperty(TYPE_ARGUMENTS_PROPERTY, properyList);
135         addProperty(TYPE_PROPERTY, properyList);
136         addProperty(ARGUMENTS_PROPERTY, properyList);
137         addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
138         PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
139     }
140
141     /**
142      * Returns a list of structural property descriptors for this node type.
143      * Clients must not modify the result.
144      *
145      * @param apiLevel the API level; one of the
146      * <code>AST.JLS*</code> constants
147
148      * @return a list of property descriptors (element type:
149      * {@link StructuralPropertyDescriptor})
150      * @since 3.0
151      */

152     public static List JavaDoc propertyDescriptors(int apiLevel) {
153         if (apiLevel == AST.JLS2_INTERNAL) {
154             return PROPERTY_DESCRIPTORS_2_0;
155         } else {
156             return PROPERTY_DESCRIPTORS_3_0;
157         }
158     }
159             
160     /**
161      * The optional expression; <code>null</code> for none; defaults to none.
162      */

163     private Expression optionalExpression = null;
164     
165     /**
166      * The type arguments (element type: <code>Type</code>).
167      * Null in JLS2. Added in JLS3; defaults to an empty list
168      * (see constructor).
169      * @since 3.1
170      */

171     private ASTNode.NodeList typeArguments = null;
172
173     /**
174      * The type name; lazily initialized; defaults to a unspecified,
175      * legal type name. Not used in JLS3.
176      */

177     private Name typeName = null;
178     
179     /**
180      * The type; lazily initialized; defaults to a unspecified type.
181      * @since 3.0
182      */

183     private Type type = null;
184     
185     /**
186      * The list of argument expressions (element type:
187      * <code>Expression</code>). Defaults to an empty list.
188      */

189     private ASTNode.NodeList arguments =
190         new ASTNode.NodeList(ARGUMENTS_PROPERTY);
191         
192     /**
193      * The optional anonymous class declaration; <code>null</code> for none;
194      * defaults to none.
195      */

196     private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null;
197     
198     /**
199      * Creates a new AST node for a class instance creation expression owned
200      * by the given AST. By default, there is no qualifying expression,
201      * an empty list of type parameters, an unspecified type, an empty
202      * list of arguments, and does not declare an anonymous class.
203      * <p>
204      * N.B. This constructor is package-private; all subclasses must be
205      * declared in the same package; clients are unable to declare
206      * additional subclasses.
207      * </p>
208      *
209      * @param ast the AST that is to own this node
210      */

211     ClassInstanceCreation (AST ast) {
212         super(ast);
213         if (ast.apiLevel >= AST.JLS3) {
214             this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
215         }
216     }
217
218     /* (omit javadoc for this method)
219      * Method declared on ASTNode.
220      * @since 3.0
221      */

222     final List JavaDoc internalStructuralPropertiesForType(int apiLevel) {
223         return propertyDescriptors(apiLevel);
224     }
225     
226
227     /* (omit javadoc for this method)
228      * Method declared on ASTNode.
229      */

230     final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
231         if (property == EXPRESSION_PROPERTY) {
232             if (get) {
233                 return getExpression();
234             } else {
235                 setExpression((Expression) child);
236                 return null;
237             }
238         }
239         if (property == NAME_PROPERTY) {
240             if (get) {
241                 return getName();
242             } else {
243                 setName((Name) child);
244                 return null;
245             }
246         }
247         if (property == TYPE_PROPERTY) {
248             if (get) {
249                 return getType();
250             } else {
251                 setType((Type) child);
252                 return null;
253             }
254         }
255         if (property == ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
256             if (get) {
257                 return getAnonymousClassDeclaration();
258             } else {
259                 setAnonymousClassDeclaration((AnonymousClassDeclaration) child);
260                 return null;
261             }
262         }
263         // allow default implementation to flag the error
264
return super.internalGetSetChildProperty(property, get, child);
265     }
266     
267     /* (omit javadoc for this method)
268      * Method declared on ASTNode.
269      */

270     final List JavaDoc internalGetChildListProperty(ChildListPropertyDescriptor property) {
271         if (property == ARGUMENTS_PROPERTY) {
272             return arguments();
273         }
274         if (property == TYPE_ARGUMENTS_PROPERTY) {
275             return typeArguments();
276         }
277         // allow default implementation to flag the error
278
return super.internalGetChildListProperty(property);
279     }
280     
281     /* (omit javadoc for this method)
282      * Method declared on ASTNode.
283      */

284     final int getNodeType0() {
285         return CLASS_INSTANCE_CREATION;
286     }
287
288     /* (omit javadoc for this method)
289      * Method declared on ASTNode.
290      */

291     ASTNode clone0(AST target) {
292         ClassInstanceCreation result = new ClassInstanceCreation(target);
293         result.setSourceRange(this.getStartPosition(), this.getLength());
294         result.setExpression(
295             (Expression) ASTNode.copySubtree(target, getExpression()));
296         if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
297             result.setName((Name) getName().clone(target));
298         }
299         if (this.ast.apiLevel >= AST.JLS3) {
300             result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
301             result.setType((Type) getType().clone(target));
302         }
303         result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
304         result.setAnonymousClassDeclaration(
305             (AnonymousClassDeclaration)
306                ASTNode.copySubtree(target, getAnonymousClassDeclaration()));
307         return result;
308     }
309
310     /* (omit javadoc for this method)
311      * Method declared on ASTNode.
312      */

313     final boolean subtreeMatch0(ASTMatcher matcher, Object JavaDoc other) {
314         // dispatch to correct overloaded match method
315
return matcher.match(this, other);
316     }
317
318     /* (omit javadoc for this method)
319      * Method declared on ASTNode.
320      */

321     void accept0(ASTVisitor visitor) {
322         boolean visitChildren = visitor.visit(this);
323         if (visitChildren) {
324             // visit children in normal left to right reading order
325
acceptChild(visitor, getExpression());
326             if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
327                 acceptChild(visitor, getName());
328             }
329             if (this.ast.apiLevel >= AST.JLS3) {
330                 acceptChildren(visitor, this.typeArguments);
331                 acceptChild(visitor, getType());
332             }
333             acceptChildren(visitor, this.arguments);
334             acceptChild(visitor, getAnonymousClassDeclaration());
335         }
336         visitor.endVisit(this);
337     }
338     
339     /**
340      * Returns the expression of this class instance creation expression, or
341      * <code>null</code> if there is none.
342      *
343      * @return the expression node, or <code>null</code> if there is none
344      */

345     public Expression getExpression() {
346         return this.optionalExpression;
347     }
348     
349     /**
350      * Sets or clears the expression of this class instance creation expression.
351      *
352      * @param expression the expression node, or <code>null</code> if
353      * there is none
354      * @exception IllegalArgumentException if:
355      * <ul>
356      * <li>the node belongs to a different AST</li>
357      * <li>the node already has a parent</li>
358      * <li>a cycle in would be created</li>
359      * </ul>
360      */

361     public void setExpression(Expression expression) {
362         // a ClassInstanceCreation may occur inside an Expression
363
// must check cycles
364
ASTNode oldChild = this.optionalExpression;
365         preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
366         this.optionalExpression = expression;
367         postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
368     }
369
370     /**
371      * Returns the live ordered list of type arguments of this class
372      * instance creation (added in JLS3 API).
373      *
374      * @return the live list of type arguments
375      * (element type: <code>Type</code>)
376      * @exception UnsupportedOperationException if this operation is used in
377      * a JLS2 AST
378      * @since 3.1
379      */

380     public List JavaDoc typeArguments() {
381         // more efficient than just calling unsupportedIn2() to check
382
if (this.typeArguments == null) {
383             unsupportedIn2();
384         }
385         return this.typeArguments;
386     }
387     
388     /**
389      * Returns the name of the type instantiated in this class instance
390      * creation expression (JLS2 API only).
391      *
392      * @return the type name node
393      * @exception UnsupportedOperationException if this operation is used in
394      * an AST later than JLS2
395      * @deprecated In the JLS3 API, this method is replaced by
396      * {@link #getType()}, which returns a <code>Type</code> instead of a
397      * <code>Name</code>.
398      */

399     public Name getName() {
400         return internalGetName();
401     }
402
403     /**
404      * Internal synonym for deprecated method. Used to avoid
405      * deprecation warnings.
406      * @since 3.1
407      */

408     /*package*/ Name internalGetName() {
409         supportedOnlyIn2();
410         if (this.typeName == null) {
411             // lazy init must be thread-safe for readers
412
synchronized (this) {
413                 if (this.typeName == null) {
414                     preLazyInit();
415                     this.typeName = new SimpleName(this.ast);
416                     postLazyInit(this.typeName, NAME_PROPERTY);
417                 }
418             }
419         }
420         return typeName;
421     }
422     
423     /**
424      * Sets the name of the type instantiated in this class instance
425      * creation expression (JLS2 API only).
426      *
427      * @param name the new type name
428      * @exception IllegalArgumentException if:
429      * <ul>
430      * <li>the node belongs to a different AST</li>
431      * <li>the node already has a parent</li>`
432      * </ul>
433      * @exception UnsupportedOperationException if this operation is used in
434      * an AST later than JLS2
435      * @deprecated In the JLS3 API, this method is replaced by
436      * {@link #setType(Type)}, which expects a <code>Type</code> instead of
437      * a <code>Name</code>.
438      */

439     public void setName(Name name) {
440         internalSetName(name);
441     }
442
443     /**
444      * Internal synonym for deprecated method. Used to avoid
445      * deprecation warnings.
446      * @since 3.1
447      */

448     /*package*/ void internalSetName(Name name) {
449         supportedOnlyIn2();
450         if (name == null) {
451             throw new IllegalArgumentException JavaDoc();
452         }
453         ASTNode oldChild = this.typeName;
454         preReplaceChild(oldChild, name, NAME_PROPERTY);
455         this.typeName = name;
456         postReplaceChild(oldChild, name, NAME_PROPERTY);
457     }
458
459     /**
460      * Returns the type instantiated in this class instance creation
461      * expression (added in JLS3 API).
462      *
463      * @return the type node
464      * @exception UnsupportedOperationException if this operation is used in
465      * a JLS2 AST
466      * @since 3.1
467      */

468     public Type getType() {
469         unsupportedIn2();
470         if (this.type == null) {
471             // lazy init must be thread-safe for readers
472
synchronized (this) {
473                 if (this.type == null) {
474                     preLazyInit();
475                     this.type = new SimpleType(this.ast);
476                     postLazyInit(this.type, TYPE_PROPERTY);
477                 }
478             }
479         }
480         return this.type;
481     }
482     
483     /**
484      * Sets the type instantiated in this class instance creation
485      * expression (added in JLS3 API).
486      *
487      * @param type the new type
488      * @exception IllegalArgumentException if:
489      * <ul>
490      * <li>the node belongs to a different AST</li>
491      * <li>the node already has a parent</li>`
492      * </ul>
493      * @exception UnsupportedOperationException if this operation is used in
494      * a JLS2 AST
495      * @since 3.1
496      */

497     public void setType(Type type) {
498         unsupportedIn2();
499         if (type == null) {
500             throw new IllegalArgumentException JavaDoc();
501         }
502         ASTNode oldChild = this.type;
503         preReplaceChild(oldChild, type, TYPE_PROPERTY);
504         this.type = type;
505         postReplaceChild(oldChild, type, TYPE_PROPERTY);
506     }
507
508     /**
509      * Returns the live ordered list of argument expressions in this class
510      * instance creation expression.
511      *
512      * @return the live list of argument expressions (possibly empty)
513      * (element type: <code>Expression</code>)
514      */

515     public List JavaDoc arguments() {
516         return this.arguments;
517     }
518     
519     /**
520      * Returns the anonymous class declaration introduced by this
521      * class instance creation expression, if it has one.
522      *
523      * @return the anonymous class declaration, or <code>null</code> if none
524      */

525     public AnonymousClassDeclaration getAnonymousClassDeclaration() {
526         return this.optionalAnonymousClassDeclaration;
527     }
528     
529     /**
530      * Sets whether this class instance creation expression declares
531      * an anonymous class (that is, has class body declarations).
532      *
533      * @param decl the anonymous class declaration, or <code>null</code>
534      * if none
535      */

536     public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) {
537         ASTNode oldChild = this.optionalAnonymousClassDeclaration;
538         preReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
539         this.optionalAnonymousClassDeclaration = decl;
540         postReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
541     }
542
543     /**
544      * Resolves and returns the binding for the constructor invoked by this
545      * expression. For anonymous classes, the binding is that of the anonymous
546      * constructor.
547      * <p>
548      * Note that bindings are generally unavailable unless requested when the
549      * AST is being built.
550      * </p>
551      *
552      * @return the constructor binding, or <code>null</code> if the binding
553      * cannot be resolved
554      */

555     public IMethodBinding resolveConstructorBinding() {
556         return this.ast.getBindingResolver().resolveConstructor(this);
557     }
558
559     /* (omit javadoc for this method)
560      * Method declared on ASTNode.
561      */

562     int memSize() {
563         // treat Code as free
564
return BASE_NODE_SIZE + 6 * 4;
565     }
566     
567     /* (omit javadoc for this method)
568      * Method declared on ASTNode.
569      */

570     int treeSize() {
571         // n.b. type == null for ast.API_LEVEL == JLS2
572
// n.b. typeArguments == null for ast.API_LEVEL == JLS2
573
// n.b. typeName == null for ast.API_LEVEL >= JLS3
574
return
575             memSize()
576             + (this.typeName == null ? 0 : getName().treeSize())
577             + (this.type == null ? 0 : getType().treeSize())
578             + (this.optionalExpression == null ? 0 : getExpression().treeSize())
579             + (this.typeArguments == null ? 0 : this.typeArguments.listSize())
580             + (this.arguments == null ? 0 : this.arguments.listSize())
581             + (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize());
582     }
583 }
584
585
Popular Tags