001: /*******************************************************************************
002: * Copyright (c) 2003, 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: * Type node for a parameterized type (added in JLS3 API).
017: * These nodes are used for type references (as opposed to
018: * declarations of parameterized types.)
019: * <pre>
020: * ParameterizedType:
021: * Type <b><</b> Type { <b>,</b> Type } <b>></b>
022: * </pre>
023: * The first type may be a simple type or a qualified type;
024: * other kinds of types are meaningless.
025: *
026: * @since 3.1
027: */
028: public class ParameterizedType extends Type {
029: /**
030: * This index represents the position inside a parameterized qualified type.
031: */
032: int index;
033:
034: /**
035: * The "type" structural property of this node type.
036: */
037: public static final ChildPropertyDescriptor TYPE_PROPERTY = new ChildPropertyDescriptor(
038: ParameterizedType.class,
039: "type", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
040:
041: /**
042: * The "typeArguments" structural property of this node type.
043: */
044: public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = new ChildListPropertyDescriptor(
045: ParameterizedType.class,
046: "typeArguments", Type.class, CYCLE_RISK); //$NON-NLS-1$
047:
048: /**
049: * A list of property descriptors (element type:
050: * {@link StructuralPropertyDescriptor}),
051: * or null if uninitialized.
052: */
053: private static final List PROPERTY_DESCRIPTORS;
054:
055: static {
056: List propertyList = new ArrayList(3);
057: createPropertyList(ParameterizedType.class, propertyList);
058: addProperty(TYPE_PROPERTY, propertyList);
059: addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
060: PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
061: }
062:
063: /**
064: * Returns a list of structural property descriptors for this node type.
065: * Clients must not modify the result.
066: *
067: * @param apiLevel the API level; one of the
068: * <code>AST.JLS*</code> constants
069:
070: * @return a list of property descriptors (element type:
071: * {@link StructuralPropertyDescriptor})
072: */
073: public static List propertyDescriptors(int apiLevel) {
074: return PROPERTY_DESCRIPTORS;
075: }
076:
077: /**
078: * The type node; lazily initialized; defaults to an unspecfied, but legal,
079: * type.
080: */
081: private Type type = null;
082:
083: /**
084: * The type arguments (element type: <code>Type</code>).
085: * Defaults to an empty list.
086: */
087: private ASTNode.NodeList typeArguments = new ASTNode.NodeList(
088: TYPE_ARGUMENTS_PROPERTY);
089:
090: /**
091: * Creates a new unparented node for a parameterized type owned by the
092: * given AST. By default, an unspecified, but legal, type, and no type
093: * arguments.
094: * <p>
095: * N.B. This constructor is package-private.
096: * </p>
097: *
098: * @param ast the AST that is to own this node
099: */
100: ParameterizedType(AST ast) {
101: super (ast);
102: unsupportedIn2();
103: }
104:
105: /* (omit javadoc for this method)
106: * Method declared on ASTNode.
107: */
108: final List internalStructuralPropertiesForType(int apiLevel) {
109: return propertyDescriptors(apiLevel);
110: }
111:
112: /* (omit javadoc for this method)
113: * Method declared on ASTNode.
114: */
115: final ASTNode internalGetSetChildProperty(
116: 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(
133: ChildListPropertyDescriptor property) {
134: if (property == TYPE_ARGUMENTS_PROPERTY) {
135: return typeArguments();
136: }
137: // allow default implementation to flag the error
138: return super .internalGetChildListProperty(property);
139: }
140:
141: /* (omit javadoc for this method)
142: * Method declared on ASTNode.
143: */
144: final int getNodeType0() {
145: return PARAMETERIZED_TYPE;
146: }
147:
148: /* (omit javadoc for this method)
149: * Method declared on ASTNode.
150: */
151: ASTNode clone0(AST target) {
152: ParameterizedType result = new ParameterizedType(target);
153: result
154: .setSourceRange(this .getStartPosition(), this
155: .getLength());
156: result.setType((Type) ((ASTNode) getType()).clone(target));
157: result.typeArguments().addAll(
158: ASTNode.copySubtrees(target, typeArguments()));
159: return result;
160: }
161:
162: /* (omit javadoc for this method)
163: * Method declared on ASTNode.
164: */
165: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
166: // dispatch to correct overloaded match method
167: return matcher.match(this , other);
168: }
169:
170: /* (omit javadoc for this method)
171: * Method declared on ASTNode.
172: */
173: void accept0(ASTVisitor visitor) {
174: boolean visitChildren = visitor.visit(this );
175: if (visitChildren) {
176: // visit children in normal left to right reading order
177: acceptChild(visitor, getType());
178: acceptChildren(visitor, this .typeArguments);
179: }
180: visitor.endVisit(this );
181: }
182:
183: /**
184: * Returns the type of this parameterized type.
185: *
186: * @return the type of this parameterized type
187: */
188: public Type getType() {
189: if (this .type == null) {
190: // lazy init must be thread-safe for readers
191: synchronized (this ) {
192: if (this .type == null) {
193: preLazyInit();
194: this .type = new SimpleType(this .ast);
195: postLazyInit(this .type, TYPE_PROPERTY);
196: }
197: }
198: }
199: return this .type;
200: }
201:
202: /**
203: * Sets the type of this parameterized type.
204: *
205: * @param type the new type of this parameterized type
206: * @exception IllegalArgumentException if:
207: * <ul>
208: * <li>the node belongs to a different AST</li>
209: * <li>the node already has a parent</li>
210: * </ul>
211: */
212: public void setType(Type type) {
213: if (type == null) {
214: throw new IllegalArgumentException();
215: }
216: ASTNode oldChild = this .type;
217: preReplaceChild(oldChild, type, TYPE_PROPERTY);
218: this .type = type;
219: postReplaceChild(oldChild, type, TYPE_PROPERTY);
220: }
221:
222: /**
223: * Returns the live ordered list of type arguments of this parameterized
224: * type. For the parameterized type to be plausible, the list should contain
225: * at least one element and not contain primitive types.
226: *
227: * @return the live list of type arguments
228: * (element type: <code>Type</code>)
229: */
230: public List typeArguments() {
231: return this .typeArguments;
232: }
233:
234: /* (omit javadoc for this method)
235: * Method declared on ASTNode.
236: */
237: int memSize() {
238: // treat Code as free
239: return BASE_NODE_SIZE + 3 * 4;
240: }
241:
242: /* (omit javadoc for this method)
243: * Method declared on ASTNode.
244: */
245: int treeSize() {
246: return memSize()
247: + (this .type == null ? 0 : getType().treeSize())
248: + this.typeArguments.listSize();
249: }
250: }
|