1 /*******************************************************************************
2 * Copyright (c) 2000, 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;
17 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
18 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
19 import net.sourceforge.phpdt.internal.compiler.parser.TerminalTokens;
22 * AST node for a simple name. A simple name is an identifier other than
23 * a keyword, boolean literal ("true", "false") or null literal ("null").
30 * @noinstantiate This class is not intended to be instantiated by clients.
32 public class SimpleName extends Name {
35 * The "identifier" structural property of this node type.
39 public static final SimplePropertyDescriptor IDENTIFIER_PROPERTY =
40 new SimplePropertyDescriptor(SimpleName.class, "identifier", String.class, MANDATORY); //$NON-NLS-1$
43 * A list of property descriptors (element type:
44 * {@link StructuralPropertyDescriptor}),
45 * or null if uninitialized.
48 private static final List PROPERTY_DESCRIPTORS;
51 List propertyList = new ArrayList(2);
52 createPropertyList(SimpleName.class, propertyList);
53 addProperty(IDENTIFIER_PROPERTY, propertyList);
54 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
58 * Returns a list of structural property descriptors for this node type.
59 * Clients must not modify the result.
61 * @param apiLevel the API level; one of the AST.JLS* constants
62 * @return a list of property descriptors (element type:
63 * {@link StructuralPropertyDescriptor})
66 public static List propertyDescriptors(int apiLevel) {
67 return PROPERTY_DESCRIPTORS;
71 * An unspecified (but externally observable) legal Java identifier.
73 private static final String MISSING_IDENTIFIER = "MISSING";//$NON-NLS-1$
76 * The identifier; defaults to a unspecified, legal Java identifier.
78 private String identifier = MISSING_IDENTIFIER;
81 * Creates a new AST node for a simple name owned by the given AST.
82 * The new node has an unspecified, legal Java identifier.
84 * N.B. This constructor is package-private; all subclasses must be
85 * declared in the same package; clients are unable to declare
86 * additional subclasses.
89 * @param ast the AST that is to own this node
95 /* (omit javadoc for this method)
96 * Method declared on ASTNode.
99 final List internalStructuralPropertiesForType(int apiLevel) {
100 return propertyDescriptors(apiLevel);
103 /* (omit javadoc for this method)
104 * Method declared on ASTNode.
106 final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
107 if (property == IDENTIFIER_PROPERTY) {
109 return getIdentifier();
111 setIdentifier((String) value);
115 // allow default implementation to flag the error
116 return super.internalGetSetObjectProperty(property, get, value);
119 /* (omit javadoc for this method)
120 * Method declared on ASTNode.
122 final int getNodeType0() {
126 /* (omit javadoc for this method)
127 * Method declared on ASTNode.
129 ASTNode clone0(AST target) {
130 SimpleName result = new SimpleName(target);
131 result.setSourceRange(this.getStartPosition(), this.getLength());
132 result.setIdentifier(getIdentifier());
136 /* (omit javadoc for this method)
137 * Method declared on ASTNode.
139 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
140 // dispatch to correct overloaded match method
141 return matcher.match(this, other);
144 /* (omit javadoc for this method)
145 * Method declared on ASTNode.
147 void accept0(ASTVisitor visitor) {
149 visitor.endVisit(this);
153 * Returns this node's identifier.
155 * @return the identifier of this node
157 public String getIdentifier() {
158 return this.identifier;
162 * Sets the identifier of this node to the given value.
163 * The identifier should be legal according to the rules
164 * of the Java language. Note that keywords are not legal
167 * Note that the list of keywords may depend on the version of the
168 * language (determined when the AST object was created).
171 * @param identifier the identifier of this node
172 * @exception IllegalArgumentException if the identifier is invalid
174 public void setIdentifier(String identifier) {
175 // update internalSetIdentifier if this is changed
176 if (identifier == null) {
177 throw new IllegalArgumentException();
179 Scanner scanner = this.ast.scanner;
180 char[] source = identifier.toCharArray();
181 scanner.setSource(source);
182 final int length = source.length;
183 scanner.resetTo(0, length - 1);
185 int tokenType = scanner.scanIdentifier();
186 if (tokenType != TerminalTokens.TokenNameIdentifier) {
187 throw new IllegalArgumentException();
189 if (scanner.currentPosition != length) {
190 // this is the case when there is only one identifier see 87849
191 throw new IllegalArgumentException();
193 } catch(InvalidInputException e) {
194 throw new IllegalArgumentException();
196 preValueChange(IDENTIFIER_PROPERTY);
197 this.identifier = identifier;
198 postValueChange(IDENTIFIER_PROPERTY);
201 /* (omit javadoc for this method)
202 * This method is a copy of setIdentifier(String) that doesn't do any validation.
204 void internalSetIdentifier(String ident) {
205 preValueChange(IDENTIFIER_PROPERTY);
206 this.identifier = ident;
207 postValueChange(IDENTIFIER_PROPERTY);
211 * Returns whether this simple name represents a name that is being defined,
212 * as opposed to one being referenced. The following positions are considered
213 * ones where a name is defined:
215 * <li>The type name in a <code>TypeDeclaration</code> node.</li>
216 * <li>The method name in a <code>MethodDeclaration</code> node
217 * providing <code>isConstructor</code> is <code>false</code>.</li>
218 * <li>The variable name in any type of <code>VariableDeclaration</code>
220 * <li>The enum type name in a <code>EnumDeclaration</code> node.</li>
221 * <li>The enum constant name in an <code>EnumConstantDeclaration</code>
223 * <li>The variable name in an <code>EnhancedForStatement</code>
225 * <li>The type variable name in a <code>TypeParameter</code>
227 * <li>The type name in an <code>AnnotationTypeDeclaration</code> node.</li>
228 * <li>The member name in an <code>AnnotationTypeMemberDeclaration</code> node.</li>
231 * Note that this is a convenience method that simply checks whether
232 * this node appears in the declaration position relative to its parent.
233 * It always returns <code>false</code> if this node is unparented.
236 * @return <code>true</code> if this node declares a name, and
237 * <code>false</code> otherwise
239 public boolean isDeclaration() {
240 StructuralPropertyDescriptor d = getLocationInParent();
245 ASTNode parent = getParent();
246 if (parent instanceof TypeDeclaration) {
247 return (d == TypeDeclaration.NAME_PROPERTY);
249 if (parent instanceof MethodDeclaration) {
250 MethodDeclaration p = (MethodDeclaration) parent;
251 // could be the name of the method or constructor
252 return !p.isConstructor() && (d == MethodDeclaration.NAME_PROPERTY);
254 if (parent instanceof SingleVariableDeclaration) {
255 return (d == SingleVariableDeclaration.NAME_PROPERTY);
257 if (parent instanceof VariableDeclarationFragment) {
258 return (d == VariableDeclarationFragment.NAME_PROPERTY);
260 if (parent instanceof EnumDeclaration) {
261 return (d == EnumDeclaration.NAME_PROPERTY);
263 if (parent instanceof EnumConstantDeclaration) {
264 return (d == EnumConstantDeclaration.NAME_PROPERTY);
266 if (parent instanceof TypeParameter) {
267 return (d == TypeParameter.NAME_PROPERTY);
269 if (parent instanceof AnnotationTypeDeclaration) {
270 return (d == AnnotationTypeDeclaration.NAME_PROPERTY);
272 if (parent instanceof AnnotationTypeMemberDeclaration) {
273 return (d == AnnotationTypeMemberDeclaration.NAME_PROPERTY);
278 /* (omit javadoc for this method)
279 * Method declared on Name.
281 void appendName(StringBuffer buffer) {
282 buffer.append(getIdentifier());
285 /* (omit javadoc for this method)
286 * Method declared on ASTNode.
289 int size = BASE_NAME_NODE_SIZE + 2 * 4;
290 if (identifier != MISSING_IDENTIFIER) {
291 // everything but our missing id costs
292 size += stringSize(identifier);
297 /* (omit javadoc for this method)
298 * Method declared on ASTNode.