11343bbaf513425e2b84f2dd9b91da2a2d4dc460
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / ParameterizedType.java
1 /*******************************************************************************
2  * Copyright (c) 2003, 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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.core.dom;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 /**
18  * Type node for a parameterized type (added in JLS3 API).
19  * These nodes are used for type references (as opposed to
20  * declarations of parameterized types.)
21  * <pre>
22  * ParameterizedType:
23  *    Type <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b>
24  * </pre>
25  * The first type may be a simple type or a qualified type;
26  * other kinds of types are meaningless.
27  * 
28  * @since 3.1
29  * @noinstantiate This class is not intended to be instantiated by clients.
30  */
31 public class ParameterizedType extends Type {
32     /**
33      * This index represents the position inside a parameterized qualified type.
34      */
35     int index;
36         
37         /**
38          * The "type" structural property of this node type.
39          */
40         public static final ChildPropertyDescriptor TYPE_PROPERTY = 
41                 new ChildPropertyDescriptor(ParameterizedType.class, "type", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
42
43         /**
44          * The "typeArguments" structural property of this node type.
45          */
46         public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
47                 new ChildListPropertyDescriptor(ParameterizedType.class, "typeArguments", Type.class, CYCLE_RISK); //$NON-NLS-1$
48         
49         /**
50          * A list of property descriptors (element type: 
51          * {@link StructuralPropertyDescriptor}),
52          * or null if uninitialized.
53          */
54         private static final List PROPERTY_DESCRIPTORS;
55         
56         static {
57                 List propertyList = new ArrayList(3);
58                 createPropertyList(ParameterizedType.class, propertyList);
59                 addProperty(TYPE_PROPERTY, propertyList);
60                 addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
61                 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
62         }
63
64         /**
65          * Returns a list of structural property descriptors for this node type.
66          * Clients must not modify the result.
67          * 
68          * @param apiLevel the API level; one of the
69          * <code>AST.JLS*</code> constants
70
71          * @return a list of property descriptors (element type: 
72          * {@link StructuralPropertyDescriptor})
73          */
74         public static List propertyDescriptors(int apiLevel) {
75                 return PROPERTY_DESCRIPTORS;
76         }
77                         
78         /** 
79          * The type node; lazily initialized; defaults to an unspecfied, but legal,
80          * type.
81          */
82         private Type type = null;
83         
84         /**
85          * The type arguments (element type: <code>Type</code>). 
86          * Defaults to an empty list.
87          */
88         private ASTNode.NodeList typeArguments =
89                 new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
90         
91         /**
92          * Creates a new unparented node for a parameterized type owned by the
93          * given AST. By default, an unspecified, but legal, type, and no type
94          * arguments.
95          * <p>
96          * N.B. This constructor is package-private.
97          * </p>
98          * 
99          * @param ast the AST that is to own this node
100          */
101         ParameterizedType(AST ast) {
102                 super(ast);
103             unsupportedIn2();
104         }
105
106         /* (omit javadoc for this method)
107          * Method declared on ASTNode.
108          */
109         final List internalStructuralPropertiesForType(int apiLevel) {
110                 return propertyDescriptors(apiLevel);
111         }
112         
113         /* (omit javadoc for this method)
114          * Method declared on ASTNode.
115          */
116         final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
117                 if (property == TYPE_PROPERTY) {
118                         if (get) {
119                                 return getType();
120                         } else {
121                                 setType((Type) child);
122                                 return null;
123                         }
124                 }
125                 // allow default implementation to flag the error
126                 return super.internalGetSetChildProperty(property, get, child);
127         }
128         
129         /* (omit javadoc for this method)
130          * Method declared on ASTNode.
131          */
132         final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
133                 if (property == TYPE_ARGUMENTS_PROPERTY) {
134                         return typeArguments();
135                 }
136                 // allow default implementation to flag the error
137                 return super.internalGetChildListProperty(property);
138         }
139
140         /* (omit javadoc for this method)
141          * Method declared on ASTNode.
142          */
143         final int getNodeType0() {
144                 return PARAMETERIZED_TYPE;
145         }
146
147         /* (omit javadoc for this method)
148          * Method declared on ASTNode.
149          */
150         ASTNode clone0(AST target) {
151                 ParameterizedType result = new ParameterizedType(target);
152                 result.setSourceRange(this.getStartPosition(), this.getLength());
153                 result.setType((Type) ((ASTNode) getType()).clone(target));
154                 result.typeArguments().addAll(
155                         ASTNode.copySubtrees(target, typeArguments()));
156                 return result;
157         }
158
159         /* (omit javadoc for this method)
160          * Method declared on ASTNode.
161          */
162         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
163                 // dispatch to correct overloaded match method
164                 return matcher.match(this, other);
165         }
166
167         /* (omit javadoc for this method)
168          * Method declared on ASTNode.
169          */
170         void accept0(ASTVisitor visitor) {
171                 boolean visitChildren = visitor.visit(this);
172                 if (visitChildren) {
173                         // visit children in normal left to right reading order
174                         acceptChild(visitor, getType());
175                         acceptChildren(visitor, this.typeArguments);
176                 }
177                 visitor.endVisit(this);
178         }
179         
180         /**
181          * Returns the type of this parameterized type.
182          * 
183          * @return the type of this parameterized type
184          */ 
185         public Type getType() {
186                 if (this.type == null) {
187                         // lazy init must be thread-safe for readers
188                         synchronized (this) {
189                                 if (this.type == null) {
190                                         preLazyInit();
191                                         this.type = new SimpleType(this.ast);
192                                         postLazyInit(this.type, TYPE_PROPERTY);
193                                 }
194                         }
195                 }
196                 return this.type;
197         }
198         
199         /**
200          * Sets the type of this parameterized type.
201          * 
202          * @param type the new type of this parameterized type
203          * @exception IllegalArgumentException if:
204          * <ul>
205          * <li>the node belongs to a different AST</li>
206          * <li>the node already has a parent</li>
207          * </ul>
208          */ 
209         public void setType(Type type) {
210                 if (type == null) {
211                         throw new IllegalArgumentException();
212                 }
213                 ASTNode oldChild = this.type;
214                 preReplaceChild(oldChild, type, TYPE_PROPERTY);
215                 this.type = type;
216                 postReplaceChild(oldChild, type, TYPE_PROPERTY);
217         }
218
219         /**
220          * Returns the live ordered list of type arguments of this parameterized 
221          * type. For the parameterized type to be plausible, the list should contain
222          * at least one element and not contain primitive types.
223          * 
224          * @return the live list of type arguments
225          *    (element type: <code>Type</code>)
226          */ 
227         public List typeArguments() {
228                 return this.typeArguments;
229         }
230         
231         /* (omit javadoc for this method)
232          * Method declared on ASTNode.
233          */
234         int memSize() {
235                 // treat Code as free
236                 return BASE_NODE_SIZE + 3 * 4;
237         }
238         
239         /* (omit javadoc for this method)
240          * Method declared on ASTNode.
241          */
242         int treeSize() {
243                 return 
244                         memSize()
245                         + (this.type == null ? 0 : getType().treeSize())
246                         + this.typeArguments.listSize();
247         }
248 }
249