EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2019 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
15package org.eclipse.jdt.core.dom;
16
17import java.util.ArrayList;
18import java.util.List;
19
20/**
21 * Class instance creation expression AST node type.
22 * <pre>
23 * ClassInstanceCreation:
24 *        [ Expression <b>.</b> ]
25 *            <b>new</b> [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
26 *            Type <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
27 *            [ AnonymousClassDeclaration ]
28 * </pre>
29 * <p>
30 * Not all node arrangements will represent legal Java constructs. In particular,
31 * it is nonsense if the type is a primitive type or an array type (primitive
32 * types cannot be instantiated, and array creations must be represented with
33 * <code>ArrayCreation</code> nodes). The normal use is when the type is a
34 * simple, qualified, or parameterized type.
35 * </p>
36 * <p>
37 * {@link QualifiedType} discusses typical representations of qualified type references.
38 * </p>
39 *
40 * @since 2.0
41 * @noinstantiate This class is not intended to be instantiated by clients.
42 */
43@SuppressWarnings({"rawtypes""unchecked"})
44public class ClassInstanceCreation extends Expression {
45
46    /**
47     * The "typeArguments" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
48     * @since 3.1
49     */
50    public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
51        new ChildListPropertyDescriptor(ClassInstanceCreation.class"typeArguments"Type.classNO_CYCLE_RISK); //$NON-NLS-1$
52
53    /**
54     * The "expression" structural property of this node type (child type: {@link Expression}).
55     * @since 3.0
56     */
57    public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
58        new ChildPropertyDescriptor(ClassInstanceCreation.class"expression"Expression.classOPTIONALCYCLE_RISK); //$NON-NLS-1$
59
60    /**
61     * The "name" structural property of this node type (child type: {@link Name}) (JLS2 API only).
62     * @since 3.0
63     * @deprecated In the JLS3 API, this property is replaced by {@link #TYPE_PROPERTY}.
64     */
65    public static final ChildPropertyDescriptor NAME_PROPERTY =
66        new ChildPropertyDescriptor(ClassInstanceCreation.class"name"Name.classMANDATORYNO_CYCLE_RISK); //$NON-NLS-1$
67
68    /**
69     * The "type" structural property of this node type (child type: {@link Type}) (added in JLS3 API).
70     * @since 3.1
71     */
72    public static final ChildPropertyDescriptor TYPE_PROPERTY =
73        new ChildPropertyDescriptor(ClassInstanceCreation.class"type"Type.classMANDATORYNO_CYCLE_RISK); //$NON-NLS-1$
74
75    /**
76     * The "arguments" structural property of this node type (element type: {@link Expression}).
77     * @since 3.0
78     */
79    public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
80        new ChildListPropertyDescriptor(ClassInstanceCreation.class"arguments"Expression.classCYCLE_RISK); //$NON-NLS-1$
81
82    /**
83     * The "anonymousClassDeclaration" structural property of this node type (child type: {@link AnonymousClassDeclaration}).
84     * @since 3.0
85     */
86    public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY =
87        new ChildPropertyDescriptor(ClassInstanceCreation.class"anonymousClassDeclaration"AnonymousClassDeclaration.classOPTIONALCYCLE_RISK); //$NON-NLS-1$
88
89    /**
90     * A list of property descriptors (element type:
91     * {@link StructuralPropertyDescriptor}),
92     * or null if uninitialized.
93     * @since 3.0
94     */
95    private static final List PROPERTY_DESCRIPTORS_2_0;
96
97    /**
98     * A list of property descriptors (element type:
99     * {@link StructuralPropertyDescriptor}),
100     * or null if uninitialized.
101     * @since 3.1
102     */
103    private static final List PROPERTY_DESCRIPTORS_3_0;
104
105    static {
106        List properyList = new ArrayList(5);
107        createPropertyList(ClassInstanceCreation.classproperyList);
108        addProperty(EXPRESSION_PROPERTYproperyList);
109        addProperty(NAME_PROPERTYproperyList);
110        addProperty(ARGUMENTS_PROPERTYproperyList);
111        addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTYproperyList);
112        PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
113
114        properyList = new ArrayList(6);
115        createPropertyList(ClassInstanceCreation.classproperyList);
116        addProperty(EXPRESSION_PROPERTYproperyList);
117        addProperty(TYPE_ARGUMENTS_PROPERTYproperyList);
118        addProperty(TYPE_PROPERTYproperyList);
119        addProperty(ARGUMENTS_PROPERTYproperyList);
120        addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTYproperyList);
121        PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
122    }
123
124    /**
125     * Returns a list of structural property descriptors for this node type.
126     * Clients must not modify the result.
127     *
128     * @param apiLevel the API level; one of the
129     * <code>AST.JLS*</code> constants
130
131     * @return a list of property descriptors (element type:
132     * {@link StructuralPropertyDescriptor})
133     * @since 3.0
134     */
135    public static List propertyDescriptors(int apiLevel) {
136        if (apiLevel == AST.JLS2_INTERNAL) {
137            return PROPERTY_DESCRIPTORS_2_0;
138        } else {
139            return PROPERTY_DESCRIPTORS_3_0;
140        }
141    }
142
143    /**
144     * The optional expression; <code>null</code> for none; defaults to none.
145     */
146    private Expression optionalExpression = null;
147
148    /**
149     * The type arguments (element type: {@link Type}).
150     * Null in JLS2. Added in JLS3; defaults to an empty list
151     * (see constructor).
152     * @since 3.1
153     */
154    private ASTNode.NodeList typeArguments = null;
155
156    /**
157     * The type name; lazily initialized; defaults to a unspecified,
158     * legal type name. Not used in JLS3.
159     */
160    private Name typeName = null;
161
162    /**
163     * The type; lazily initialized; defaults to a unspecified type.
164     * @since 3.0
165     */
166    private Type type = null;
167
168    /**
169     * The list of argument expressions (element type:
170     * {@link Expression}). Defaults to an empty list.
171     */
172    private ASTNode.NodeList arguments =
173        new ASTNode.NodeList(ARGUMENTS_PROPERTY);
174
175    /**
176     * The optional anonymous class declaration; <code>null</code> for none;
177     * defaults to none.
178     */
179    private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null;
180
181    /**
182     * Creates a new AST node for a class instance creation expression owned
183     * by the given AST. By default, there is no qualifying expression,
184     * an empty list of type parameters, an unspecified type, an empty
185     * list of arguments, and does not declare an anonymous class.
186     * <p>
187     * N.B. This constructor is package-private; all subclasses must be
188     * declared in the same package; clients are unable to declare
189     * additional subclasses.
190     * </p>
191     *
192     * @param ast the AST that is to own this node
193     */
194    ClassInstanceCreation (AST ast) {
195        super(ast);
196        if (ast.apiLevel >= AST.JLS3_INTERNAL) {
197            this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
198        }
199    }
200
201    /* (omit javadoc for this method)
202     * Method declared on ASTNode.
203     * @since 3.0
204     */
205    @Override
206    final List internalStructuralPropertiesForType(int apiLevel) {
207        return propertyDescriptors(apiLevel);
208    }
209
210    @Override
211    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
212        if (property == EXPRESSION_PROPERTY) {
213            if (get) {
214                return getExpression();
215            } else {
216                setExpression((Expressionchild);
217                return null;
218            }
219        }
220        if (property == NAME_PROPERTY) {
221            if (get) {
222                return getName();
223            } else {
224                setName((Namechild);
225                return null;
226            }
227        }
228        if (property == TYPE_PROPERTY) {
229            if (get) {
230                return getType();
231            } else {
232                setType((Typechild);
233                return null;
234            }
235        }
236        if (property == ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
237            if (get) {
238                return getAnonymousClassDeclaration();
239            } else {
240                setAnonymousClassDeclaration((AnonymousClassDeclarationchild);
241                return null;
242            }
243        }
244        // allow default implementation to flag the error
245        return super.internalGetSetChildProperty(propertygetchild);
246    }
247
248    @Override
249    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
250        if (property == ARGUMENTS_PROPERTY) {
251            return arguments();
252        }
253        if (property == TYPE_ARGUMENTS_PROPERTY) {
254            return typeArguments();
255        }
256        // allow default implementation to flag the error
257        return super.internalGetChildListProperty(property);
258    }
259
260    @Override
261    final int getNodeType0() {
262        return CLASS_INSTANCE_CREATION;
263    }
264
265    @Override
266    ASTNode clone0(AST target) {
267        ClassInstanceCreation result = new ClassInstanceCreation(target);
268        result.setSourceRange(getStartPosition(), getLength());
269        result.setExpression(
270            (ExpressionASTNode.copySubtree(targetgetExpression()));
271        if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
272            result.setName((NamegetName().clone(target));
273        }
274        if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
275            result.typeArguments().addAll(ASTNode.copySubtrees(targettypeArguments()));
276            result.setType((TypegetType().clone(target));
277        }
278        result.arguments().addAll(ASTNode.copySubtrees(targetarguments()));
279        result.setAnonymousClassDeclaration(
280            (AnonymousClassDeclaration)
281               ASTNode.copySubtree(targetgetAnonymousClassDeclaration()));
282        return result;
283    }
284
285    @Override
286    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
287        // dispatch to correct overloaded match method
288        return matcher.match(this, other);
289    }
290
291    @Override
292    void accept0(ASTVisitor visitor) {
293        boolean visitChildren = visitor.visit(this);
294        if (visitChildren) {
295            // visit children in normal left to right reading order
296            acceptChild(visitorgetExpression());
297            if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
298                acceptChild(visitorgetName());
299            }
300            if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
301                acceptChildren(visitor, this.typeArguments);
302                acceptChild(visitorgetType());
303            }
304            acceptChildren(visitor, this.arguments);
305            acceptChild(visitorgetAnonymousClassDeclaration());
306        }
307        visitor.endVisit(this);
308    }
309
310    /**
311     * Returns the expression of this class instance creation expression, or
312     * <code>null</code> if there is none.
313     *
314     * @return the expression node, or <code>null</code> if there is none
315     */
316    public Expression getExpression() {
317        return this.optionalExpression;
318    }
319
320    /**
321     * Sets or clears the expression of this class instance creation expression.
322     *
323     * @param expression the expression node, or <code>null</code> if
324     *    there is none
325     * @exception IllegalArgumentException if:
326     * <ul>
327     * <li>the node belongs to a different AST</li>
328     * <li>the node already has a parent</li>
329     * <li>a cycle in would be created</li>
330     * </ul>
331     */
332    public void setExpression(Expression expression) {
333        // a ClassInstanceCreation may occur inside an Expression
334        // must check cycles
335        ASTNode oldChild = this.optionalExpression;
336        preReplaceChild(oldChildexpressionEXPRESSION_PROPERTY);
337        this.optionalExpression = expression;
338        postReplaceChild(oldChildexpressionEXPRESSION_PROPERTY);
339    }
340
341    /**
342     * Returns the live ordered list of type arguments of this class
343     * instance creation (added in JLS3 API).
344     *
345     * @return the live list of type arguments
346     *    (element type: {@link Type})
347     * @exception UnsupportedOperationException if this operation is used in
348     * a JLS2 AST
349     * @since 3.1
350     */
351    public List typeArguments() {
352        // more efficient than just calling unsupportedIn2() to check
353        if (this.typeArguments == null) {
354            unsupportedIn2();
355        }
356        return this.typeArguments;
357    }
358
359    /**
360     * Returns the name of the type instantiated in this class instance
361     * creation expression (JLS2 API only).
362     *
363     * @return the type name node
364     * @exception UnsupportedOperationException if this operation is used in
365     * an AST later than JLS2
366     * @deprecated In the JLS3 API, this method is replaced by
367     * {@link #getType()}, which returns a <code>Type</code> instead of a
368     * <code>Name</code>.
369     */
370    public Name getName() {
371        return internalGetName();
372    }
373
374    /**
375     * Internal synonym for deprecated method. Used to avoid
376     * deprecation warnings.
377     * @since 3.1
378     */
379    /*package*/ Name internalGetName() {
380        supportedOnlyIn2();
381        if (this.typeName == null) {
382            // lazy init must be thread-safe for readers
383            synchronized (this) {
384                if (this.typeName == null) {
385                    preLazyInit();
386                    this.typeName = new SimpleName(this.ast);
387                    postLazyInit(this.typeNameNAME_PROPERTY);
388                }
389            }
390        }
391        return this.typeName;
392    }
393
394    /**
395     * Sets the name of the type instantiated in this class instance
396     * creation expression (JLS2 API only).
397     *
398     * @param name the new type name
399     * @exception IllegalArgumentException if:
400     * <ul>
401     * <li>the node belongs to a different AST</li>
402     * <li>the node already has a parent</li>
403     * </ul>
404     * @exception UnsupportedOperationException if this operation is used in
405     * an AST later than JLS2
406     * @deprecated In the JLS3 API, this method is replaced by
407     * {@link #setType(Type)}, which expects a <code>Type</code> instead of
408     * a <code>Name</code>.
409     */
410    public void setName(Name name) {
411        internalSetName(name);
412    }
413
414    /**
415     * Internal synonym for deprecated method. Used to avoid
416     * deprecation warnings.
417     * @since 3.1
418     */
419    /*package*/ void internalSetName(Name name) {
420        supportedOnlyIn2();
421        if (name == null) {
422            throw new IllegalArgumentException();
423        }
424        ASTNode oldChild = this.typeName;
425        preReplaceChild(oldChildnameNAME_PROPERTY);
426        this.typeName = name;
427        postReplaceChild(oldChildnameNAME_PROPERTY);
428    }
429
430    /**
431     * Returns the type instantiated in this class instance creation
432     * expression (added in JLS3 API).
433     *
434     * @return the type node
435     * @exception UnsupportedOperationException if this operation is used in
436     * a JLS2 AST
437     * @since 3.1
438     */
439    public Type getType() {
440        unsupportedIn2();
441        if (this.type == null) {
442            // lazy init must be thread-safe for readers
443            synchronized (this) {
444                if (this.type == null) {
445                    preLazyInit();
446                    this.type = new SimpleType(this.ast);
447                    postLazyInit(this.typeTYPE_PROPERTY);
448                }
449            }
450        }
451        return this.type;
452    }
453
454    /**
455     * Sets the type instantiated in this class instance creation
456     * expression (added in JLS3 API).
457     *
458     * @param type the new type
459     * @exception IllegalArgumentException if:
460     * <ul>
461     * <li>the node belongs to a different AST</li>
462     * <li>the node already has a parent</li>
463     * </ul>
464     * @exception UnsupportedOperationException if this operation is used in
465     * a JLS2 AST
466     * @since 3.1
467     */
468    public void setType(Type type) {
469        unsupportedIn2();
470        if (type == null) {
471            throw new IllegalArgumentException();
472        }
473        ASTNode oldChild = this.type;
474        preReplaceChild(oldChildtypeTYPE_PROPERTY);
475        this.type = type;
476        postReplaceChild(oldChildtypeTYPE_PROPERTY);
477    }
478
479    /**
480     * Returns the live ordered list of argument expressions in this class
481     * instance creation expression.
482     *
483     * @return the live list of argument expressions (possibly empty)
484     *    (element type: {@link Expression})
485     */
486    public List arguments() {
487        return this.arguments;
488    }
489
490    /**
491     * Returns the anonymous class declaration introduced by this
492     * class instance creation expression, if it has one.
493     *
494     * @return the anonymous class declaration, or <code>null</code> if none
495     */
496    public AnonymousClassDeclaration getAnonymousClassDeclaration() {
497        return this.optionalAnonymousClassDeclaration;
498    }
499
500    /**
501     * Sets whether this class instance creation expression declares
502     * an anonymous class (that is, has class body declarations).
503     *
504     * @param decl the anonymous class declaration, or <code>null</code>
505     *    if none
506     */
507    public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) {
508        ASTNode oldChild = this.optionalAnonymousClassDeclaration;
509        preReplaceChild(oldChilddeclANONYMOUS_CLASS_DECLARATION_PROPERTY);
510        this.optionalAnonymousClassDeclaration = decl;
511        postReplaceChild(oldChilddeclANONYMOUS_CLASS_DECLARATION_PROPERTY);
512    }
513
514    /**
515     * Resolves and returns the binding for the constructor invoked by this
516     * expression. For anonymous classes, the binding is that of the anonymous
517     * constructor.
518     * <p>
519     * Note that bindings are generally unavailable unless requested when the
520     * AST is being built.
521     * </p>
522     *
523     * @return the constructor binding, or <code>null</code> if the binding
524     *    cannot be resolved
525     */
526    public IMethodBinding resolveConstructorBinding() {
527        return this.ast.getBindingResolver().resolveConstructor(this);
528    }
529
530    /**
531     * Returns <code>true</code> if the resolved class type has been inferred
532     * from the assignment context (JLS4 15.12.2.8), <code>false</code> otherwise.
533     * <p>
534     * This information is available only when bindings are requested when the AST is being built.
535     *
536     * @return <code>true</code> if the resolved class type has been inferred
537     *     from the assignment context (JLS3 15.12.2.8), <code>false</code> otherwise
538     * @since 3.7.1
539     */
540    public boolean isResolvedTypeInferredFromExpectedType() {
541        return this.ast.getBindingResolver().isResolvedTypeInferredFromExpectedType(this);
542    }
543
544    @Override
545    int memSize() {
546        // treat Code as free
547        return BASE_NODE_SIZE + 6 * 4;
548    }
549
550    @Override
551    int treeSize() {
552        // n.b. type == null for ast.API_LEVEL == JLS2
553        // n.b. typeArguments == null for ast.API_LEVEL == JLS2
554        // n.b. typeName == null for ast.API_LEVEL >= JLS3
555        return
556            memSize()
557            + (this.typeName == null ? 0 : getName().treeSize())
558            + (this.type == null ? 0 : getType().treeSize())
559            + (this.optionalExpression == null ? 0 : getExpression().treeSize())
560            + (this.typeArguments == null ? 0 : this.typeArguments.listSize())
561            + (this.arguments == null ? 0 : this.arguments.listSize())
562            + (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize());
563    }
564}
565
566
MembersX
ClassInstanceCreation:ANONYMOUS_CLASS_DECLARATION_PROPERTY
ClassInstanceCreation:treeSize
ClassInstanceCreation:ClassInstanceCreation
ClassInstanceCreation:getType
ClassInstanceCreation:getAnonymousClassDeclaration
ClassInstanceCreation:setAnonymousClassDeclaration:Block:oldChild
ClassInstanceCreation:optionalExpression
ClassInstanceCreation:setType
ClassInstanceCreation:optionalAnonymousClassDeclaration
ClassInstanceCreation:setExpression
ClassInstanceCreation:internalGetChildListProperty
ClassInstanceCreation:arguments
ClassInstanceCreation:accept0
ClassInstanceCreation:propertyDescriptors
ClassInstanceCreation:NAME_PROPERTY
ClassInstanceCreation:clone0
ClassInstanceCreation:subtreeMatch0
ClassInstanceCreation:getName
ClassInstanceCreation:typeArguments
ClassInstanceCreation:accept0:Block:visitChildren
ClassInstanceCreation:getNodeType0
ClassInstanceCreation:memSize
ClassInstanceCreation:PROPERTY_DESCRIPTORS_3_0
ClassInstanceCreation:PROPERTY_DESCRIPTORS_2_0
ClassInstanceCreation:isResolvedTypeInferredFromExpectedType
ClassInstanceCreation:setType:Block:oldChild
ClassInstanceCreation:Block:properyList
ClassInstanceCreation:resolveConstructorBinding
ClassInstanceCreation:typeName
ClassInstanceCreation:getExpression
ClassInstanceCreation:type
ClassInstanceCreation:internalSetName:Block:oldChild
ClassInstanceCreation:internalSetName
ClassInstanceCreation:ARGUMENTS_PROPERTY
ClassInstanceCreation:internalGetName
ClassInstanceCreation:TYPE_PROPERTY
ClassInstanceCreation:internalGetSetChildProperty
ClassInstanceCreation:EXPRESSION_PROPERTY
ClassInstanceCreation:setAnonymousClassDeclaration
ClassInstanceCreation:setName
ClassInstanceCreation:clone0:Block:result
ClassInstanceCreation:setExpression:Block:oldChild
ClassInstanceCreation:TYPE_ARGUMENTS_PROPERTY
ClassInstanceCreation:internalStructuralPropertiesForType
Members
X