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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.ArrayList;
15 import java.util.List;
18 * Type node for a qualified type (added in JLS3 API).
21 * Type <b>.</b> SimpleName
24 * Not all node arragements will represent legal Java constructs. In particular,
25 * it is nonsense if the type is an array type or primitive type. The normal use
26 * is when the type is a simple or parameterized type.
29 * A type like "A.B" can be represented either of two ways:
32 * <code>QualifiedType(SimpleType(SimpleName("A")),SimpleName("B"))</code>
35 * <code>SimpleType(QualifiedName(SimpleName("A"),SimpleName("B")))</code>
38 * The first form is preferred when "A" is known to be a type. However, a
39 * parser cannot always determine this. Clients should be prepared to handle
40 * either rather than make assumptions. (Note also that the first form
41 * became possible as of JLS3; only the second form existed in JLS2 API.)
45 * @noinstantiate This class is not intended to be instantiated by clients.
47 public class QualifiedType extends Type {
49 * This index represents the position inside a parameterized qualified type.
54 * The "qualifier" structural property of this node type.
56 public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
57 new ChildPropertyDescriptor(QualifiedType.class, "qualifier", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
60 * The "name" structural property of this node type.
62 public static final ChildPropertyDescriptor NAME_PROPERTY =
63 new ChildPropertyDescriptor(QualifiedType.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
66 * A list of property descriptors (element type:
67 * {@link StructuralPropertyDescriptor}),
68 * or null if uninitialized.
70 private static final List PROPERTY_DESCRIPTORS;
73 List propertyList = new ArrayList(3);
74 createPropertyList(QualifiedType.class, propertyList);
75 addProperty(QUALIFIER_PROPERTY, propertyList);
76 addProperty(NAME_PROPERTY, propertyList);
77 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
81 * Returns a list of structural property descriptors for this node type.
82 * Clients must not modify the result.
84 * @param apiLevel the API level; one of the
85 * <code>AST.JLS*</code> constants
86 * @return a list of property descriptors (element type:
87 * {@link StructuralPropertyDescriptor})
89 public static List propertyDescriptors(int apiLevel) {
90 return PROPERTY_DESCRIPTORS;
94 * The type node; lazily initialized; defaults to a type with
95 * an unspecfied, but legal, simple name.
97 private Type qualifier = null;
100 * The name being qualified; lazily initialized; defaults to a unspecified,
101 * legal Java identifier.
103 private SimpleName name = null;
106 * Creates a new unparented node for a qualified type owned by the
107 * given AST. By default, an unspecified, but legal, qualifier and name.
109 * N.B. This constructor is package-private.
112 * @param ast the AST that is to own this node
114 QualifiedType(AST ast) {
119 /* (omit javadoc for this method)
120 * Method declared on ASTNode.
122 final List internalStructuralPropertiesForType(int apiLevel) {
123 return propertyDescriptors(apiLevel);
126 /* (omit javadoc for this method)
127 * Method declared on ASTNode.
129 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
130 if (property == QUALIFIER_PROPERTY) {
132 return getQualifier();
134 setQualifier((Type) child);
138 if (property == NAME_PROPERTY) {
142 setName((SimpleName) child);
146 // allow default implementation to flag the error
147 return super.internalGetSetChildProperty(property, get, child);
150 /* (omit javadoc for this method)
151 * Method declared on ASTNode.
153 final int getNodeType0() {
154 return QUALIFIED_TYPE;
157 /* (omit javadoc for this method)
158 * Method declared on ASTNode.
160 ASTNode clone0(AST target) {
161 QualifiedType result = new QualifiedType(target);
162 result.setSourceRange(this.getStartPosition(), this.getLength());
163 result.setQualifier((Type) ((ASTNode) getQualifier()).clone(target));
164 result.setName((SimpleName) ((ASTNode) getName()).clone(target));
168 /* (omit javadoc for this method)
169 * Method declared on ASTNode.
171 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
172 // dispatch to correct overloaded match method
173 return matcher.match(this, other);
176 /* (omit javadoc for this method)
177 * Method declared on ASTNode.
179 void accept0(ASTVisitor visitor) {
180 boolean visitChildren = visitor.visit(this);
182 // visit children in normal left to right reading order
183 acceptChild(visitor, getQualifier());
184 acceptChild(visitor, getName());
186 visitor.endVisit(this);
190 * Returns the qualifier of this qualified type.
192 * @return the qualifier of this qualified type
194 public Type getQualifier() {
195 if (this.qualifier == null) {
196 // lazy init must be thread-safe for readers
197 synchronized (this) {
198 if (this.qualifier == null) {
200 this.qualifier = new SimpleType(this.ast);
201 postLazyInit(this.qualifier, QUALIFIER_PROPERTY);
205 return this.qualifier;
209 * Sets the qualifier of this qualified type to the given type.
211 * @param type the new qualifier of this qualified type
212 * @exception IllegalArgumentException if:
214 * <li>the node belongs to a different AST</li>
215 * <li>the node already has a parent</li>
218 public void setQualifier(Type type) {
220 throw new IllegalArgumentException();
222 ASTNode oldChild = this.qualifier;
223 preReplaceChild(oldChild, type, QUALIFIER_PROPERTY);
224 this.qualifier = type;
225 postReplaceChild(oldChild, type, QUALIFIER_PROPERTY);
229 * Returns the name part of this qualified type.
231 * @return the name being qualified
233 public SimpleName getName() {
234 if (this.name == null) {
235 // lazy init must be thread-safe for readers
236 synchronized (this) {
237 if (this.name == null) {
239 this.name = new SimpleName(this.ast);
240 postLazyInit(this.name, NAME_PROPERTY);
248 * Sets the name part of this qualified type to the given simple name.
250 * @param name the identifier of this qualified name
251 * @exception IllegalArgumentException if:
253 * <li>the node belongs to a different AST</li>
254 * <li>the node already has a parent</li>
257 public void setName(SimpleName name) {
259 throw new IllegalArgumentException();
261 ASTNode oldChild = this.name;
262 preReplaceChild(oldChild, name, NAME_PROPERTY);
264 postReplaceChild(oldChild, name, NAME_PROPERTY);
267 /* (omit javadoc for this method)
268 * Method declared on ASTNode.
271 // treat Code as free
272 return BASE_NODE_SIZE + 3 * 4;
275 /* (omit javadoc for this method)
276 * Method declared on ASTNode.
281 + (this.qualifier == null ? 0 : getQualifier().treeSize())
282 + (this.name == null ? 0 : getName().treeSize());