EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/SimpleName.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2018 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
20import org.eclipse.jdt.core.compiler.InvalidInputException;
21import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
22import org.eclipse.jdt.internal.compiler.parser.Scanner;
23import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
24
25/**
26 * AST node for a simple name. A simple name is an identifier other than
27 * a keyword, boolean literal ("true", "false") or null literal ("null").
28 * <pre>
29 * SimpleName:
30 *     Identifier
31 * </pre>
32 *
33 * @since 2.0
34 * @noinstantiate This class is not intended to be instantiated by clients.
35 */
36@SuppressWarnings("rawtypes")
37public class SimpleName extends Name {
38
39    /**
40     * The "identifier" structural property of this node type (type: {@link String}).
41     *
42     * @since 3.0
43     */
44    public static final SimplePropertyDescriptor IDENTIFIER_PROPERTY =
45        new SimplePropertyDescriptor(SimpleName.class"identifier"String.classMANDATORY); //$NON-NLS-1$
46
47    /**
48     * The "var"  property of this node name (type: {@link Boolean}) (added in JLS10 API).
49     * @since 3.14
50     */
51    public static final SimplePropertyDescriptor VAR_PROPERTY =
52        new SimplePropertyDescriptor(SimpleName.class"var"boolean.classMANDATORY); //$NON-NLS-1$
53
54    /**
55     * A list of property descriptors (element type:
56     * {@link StructuralPropertyDescriptor}),
57     * or null if uninitialized.
58     * @since 3.0
59     */
60    private static final List PROPERTY_DESCRIPTORS;
61
62    /**
63     * A list of property descriptors (element type:
64     * {@link StructuralPropertyDescriptor}),
65     * or null if uninitialized.
66     * @since 3.14
67     */
68    private static final List PROPERTY_DESCRIPTORS_10_0;
69
70    static {
71        List propertyList = new ArrayList(2);
72        createPropertyList(SimpleName.classpropertyList);
73        addProperty(IDENTIFIER_PROPERTYpropertyList);
74        PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
75
76        propertyList = new ArrayList(3);
77        createPropertyList(SimpleName.classpropertyList);
78        addProperty(IDENTIFIER_PROPERTYpropertyList);
79        addProperty(VAR_PROPERTYpropertyList);
80        PROPERTY_DESCRIPTORS_10_0 = reapPropertyList(propertyList);
81}
82
83    /**
84     * Returns a list of structural property descriptors for this node type.
85     * Clients must not modify the result.
86     *
87     * @param apiLevel the API level; one of the AST.JLS* constants
88     * @return a list of property descriptors (element type:
89     * {@link StructuralPropertyDescriptor})
90     * @since 3.0
91     */
92    public static List propertyDescriptors(int apiLevel) {
93        if (apiLevel < AST.JLS10_INTERNAL) {
94            return PROPERTY_DESCRIPTORS;
95        } else {
96            return PROPERTY_DESCRIPTORS_10_0;
97        }
98    }
99
100    /**
101     * An unspecified (but externally observable) legal Java identifier.
102     */
103    private static final String MISSING_IDENTIFIER = "MISSING";//$NON-NLS-1$
104
105    /**
106     * The identifier; defaults to a unspecified, legal Java identifier.
107     */
108    private String identifier = MISSING_IDENTIFIER;
109
110    /**
111     * Indicates the whether this represents a var;
112     * defaults to false.
113     *
114     * @since 3.14
115     */
116    private boolean isVarType = false;
117
118    /**
119     * Creates a new AST node for a simple name owned by the given AST.
120     * The new node has an unspecified, legal Java identifier.
121     * <p>
122     * N.B. This constructor is package-private; all subclasses must be
123     * declared in the same package; clients are unable to declare
124     * additional subclasses.
125     * </p>
126     *
127     * @param ast the AST that is to own this node
128     */
129    SimpleName(AST ast) {
130        super(ast);
131    }
132
133    /* (omit javadoc for this method)
134     * Method declared on ASTNode.
135     * @since 3.0
136     */
137    @Override
138    final List internalStructuralPropertiesForType(int apiLevel) {
139        return propertyDescriptors(apiLevel);
140    }
141
142    @Override
143    final Object internalGetSetObjectProperty(SimplePropertyDescriptor propertyboolean getObject value) {
144        if (property == IDENTIFIER_PROPERTY) {
145            if (get) {
146                return getIdentifier();
147            } else {
148                setIdentifier((Stringvalue);
149                return null;
150            }
151        }
152        // allow default implementation to flag the error
153        return super.internalGetSetObjectProperty(propertygetvalue);
154    }
155
156    @Override
157    final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor propertyboolean getboolean value) {
158        if (property == VAR_PROPERTY) {
159            if (get) {
160                return isVar();
161            } else {
162                if (Long.compare(this.ast.scanner.complianceLevelClassFileConstants.JDK10) < 0) {
163                    setVar(false);
164                } else {
165                    setVar(value);
166                }
167                return false;
168            }
169        }
170        // allow default implementation to flag the error
171        return super.internalGetSetBooleanProperty(propertygetvalue);
172    }
173
174    @Override
175    final int getNodeType0() {
176        return SIMPLE_NAME;
177    }
178
179    @Override
180    ASTNode clone0(AST target) {
181        SimpleName result = new SimpleName(target);
182        result.setSourceRange(getStartPosition(), getLength());
183        result.setIdentifier(getIdentifier());
184        if (this.ast.apiLevel >= AST.JLS10_INTERNAL && Long.compare(this.ast.scanner.complianceLevel10) >= 0) {
185            result.setVar(isVar());
186        }
187        return result;
188    }
189
190    @Override
191    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
192        // dispatch to correct overloaded match method
193        return matcher.match(this, other);
194    }
195
196    @Override
197    void accept0(ASTVisitor visitor) {
198        visitor.visit(this);
199        visitor.endVisit(this);
200    }
201
202    /**
203     * Returns this node's identifier.
204     *
205     * @return the identifier of this node
206     */
207    public String getIdentifier() {
208        return this.identifier;
209    }
210
211    /**
212     * Sets the identifier of this node to the given value.
213     * The identifier should be legal according to the rules
214     * of the Java language. Note that keywords are not legal
215     * identifiers.
216     * <p>
217     * Note that the list of keywords may depend on the version of the
218     * language (determined when the AST object was created).
219     * </p>
220     *
221     * @param identifier the identifier of this node
222     * @exception IllegalArgumentException if the identifier is invalid
223     */
224    public void setIdentifier(String identifier) {
225        // update internalSetIdentifier if this is changed
226        if (identifier == null) {
227            throw new IllegalArgumentException();
228        }
229        Scanner scanner = this.ast.scanner;
230        long sourceLevel = scanner.sourceLevel;
231        long complianceLevel = scanner.complianceLevel;
232
233        try {
234            scanner.sourceLevel = ClassFileConstants.JDK1_3;
235            scanner.complianceLevel = ClassFileConstants.JDK1_5;
236            char[] source = identifier.toCharArray();
237            scanner.setSource(source);
238            final int length = source.length;
239            scanner.resetTo(0length - 1);
240            try {
241                int tokenType = scanner.scanIdentifier();
242                if (tokenType != TerminalTokens.TokenNameIdentifier) {
243                    throw new IllegalArgumentException("Invalid identifier : >" + identifier + "<");  //$NON-NLS-1$//$NON-NLS-2$
244                }
245                if (scanner.currentPosition != length) {
246                    // this is the case when there is only one identifier see 87849
247                    throw new IllegalArgumentException("Invalid identifier : >" + identifier + "<");  //$NON-NLS-1$//$NON-NLS-2$
248                }
249            } catch (InvalidInputException e) {
250                throw new IllegalArgumentException("Invalid identifier : >" + identifier + "<"e); //$NON-NLS-1$//$NON-NLS-2$
251            }
252        } finally {
253            this.ast.scanner.sourceLevel = sourceLevel;
254            this.ast.scanner.complianceLevel = complianceLevel;
255        }
256        preValueChange(IDENTIFIER_PROPERTY);
257        this.identifier = identifier;
258        postValueChange(IDENTIFIER_PROPERTY);
259    }
260
261    /**
262     * Returns whether this represents a "var"  type or not (added in JLS10 API).
263     *
264     * @return <code>true</code> if this is a var  type
265     *    and <code>false</code> otherwise
266     * @exception UnsupportedOperationException if this operation is used in
267     * an AST below JLS10
268     * @since 3.14
269     */
270    public boolean isVar() {
271        unsupportedBelow10();
272        return this.isVarType;
273    }
274
275    /* package */ void setVar(boolean isVar) {
276        unsupportedBelow10();
277        preValueChange(VAR_PROPERTY);
278        this.isVarType = isVar;
279        postValueChange(VAR_PROPERTY);
280    }
281
282    /* (omit javadoc for this method)
283     * This method is a copy of setIdentifier(String) that doesn't do any validation.
284     */
285    void internalSetIdentifier(String ident) {
286        preValueChange(IDENTIFIER_PROPERTY);
287        this.identifier = ident;
288        postValueChange(IDENTIFIER_PROPERTY);
289    }
290
291    /**
292     * Returns whether this simple name represents a name that is being defined,
293     * as opposed to one being referenced. The following positions are considered
294     * ones where a name is defined:
295     * <ul>
296     * <li>The type name in a <code>TypeDeclaration</code> node.</li>
297     * <li>The method name in a <code>MethodDeclaration</code> node
298     * providing <code>isConstructor</code> is <code>false</code>.</li>
299     * <li>The variable name in any type of <code>VariableDeclaration</code>
300     * node.</li>
301     * <li>The enum type name in a <code>EnumDeclaration</code> node.</li>
302     * <li>The enum constant name in an <code>EnumConstantDeclaration</code>
303     * node.</li>
304     * <li>The variable name in an <code>EnhancedForStatement</code>
305     * node.</li>
306     * <li>The type variable name in a <code>TypeParameter</code>
307     * node.</li>
308     * <li>The type name in an <code>AnnotationTypeDeclaration</code> node.</li>
309     * <li>The member name in an <code>AnnotationTypeMemberDeclaration</code> node.</li>
310     * </ul>
311     * <p>
312     * Note that this is a convenience method that simply checks whether
313     * this node appears in the declaration position relative to its parent.
314     * It always returns <code>false</code> if this node is unparented.
315     * </p>
316     *
317     * @return <code>true</code> if this node declares a name, and
318     *    <code>false</code> otherwise
319     */
320    public boolean isDeclaration() {
321        StructuralPropertyDescriptor d = getLocationInParent();
322        if (d == null) {
323            // unparented node
324            return false;
325        }
326        ASTNode parent = getParent();
327        if (parent instanceof TypeDeclaration) {
328            return (d == TypeDeclaration.NAME_PROPERTY);
329        }
330        if (parent instanceof MethodDeclaration) {
331            MethodDeclaration p = (MethodDeclarationparent;
332            // could be the name of the method or constructor
333            return !p.isConstructor() && (d == MethodDeclaration.NAME_PROPERTY);
334        }
335        if (parent instanceof SingleVariableDeclaration) {
336            return (d == SingleVariableDeclaration.NAME_PROPERTY);
337        }
338        if (parent instanceof VariableDeclarationFragment) {
339            return (d == VariableDeclarationFragment.NAME_PROPERTY);
340        }
341        if (parent instanceof EnumDeclaration) {
342            return (d == EnumDeclaration.NAME_PROPERTY);
343        }
344        if (parent instanceof EnumConstantDeclaration) {
345            return (d == EnumConstantDeclaration.NAME_PROPERTY);
346        }
347        if (parent instanceof TypeParameter) {
348            return (d == TypeParameter.NAME_PROPERTY);
349        }
350        if (parent instanceof AnnotationTypeDeclaration) {
351            return (d == AnnotationTypeDeclaration.NAME_PROPERTY);
352        }
353        if (parent instanceof AnnotationTypeMemberDeclaration) {
354            return (d == AnnotationTypeMemberDeclaration.NAME_PROPERTY);
355        }
356        return false;
357    }
358
359    @Override
360    void appendName(StringBuffer buffer) {
361        buffer.append(getIdentifier());
362    }
363
364    @Override
365    int memSize() {
366        int size = BASE_NAME_NODE_SIZE + 3 * 4;
367        if (this.identifier != MISSING_IDENTIFIER) {
368            // everything but our missing id costs
369            size += stringSize(this.identifier);
370        }
371        return size;
372    }
373
374    @Override
375    int treeSize() {
376        return memSize();
377    }
378}
379
380
MembersX
SimpleName:PROPERTY_DESCRIPTORS
SimpleName:isDeclaration
SimpleName:appendName
SimpleName:clone0
SimpleName:setIdentifier:Block:complianceLevel
SimpleName:setVar
SimpleName:SimpleName
SimpleName:setIdentifier:Block:scanner
SimpleName:setIdentifier:Block:Block:source
SimpleName:setIdentifier:Block:Block:length
SimpleName:isDeclaration:Block:Block:p
SimpleName:treeSize
SimpleName:subtreeMatch0
SimpleName:propertyDescriptors
SimpleName:Block:propertyList
SimpleName:internalGetSetObjectProperty
SimpleName:setIdentifier:Block:sourceLevel
SimpleName:VAR_PROPERTY
SimpleName:getNodeType0
SimpleName:accept0
SimpleName:isVarType
SimpleName:MISSING_IDENTIFIER
SimpleName:identifier
SimpleName:isVar
SimpleName:memSize
SimpleName:setIdentifier
SimpleName:isDeclaration:Block:parent
SimpleName:setIdentifier:Block:Block:Block:tokenType
SimpleName:PROPERTY_DESCRIPTORS_10_0
SimpleName:memSize:Block:size
SimpleName:internalSetIdentifier
SimpleName:IDENTIFIER_PROPERTY
SimpleName:internalGetSetBooleanProperty
SimpleName:isDeclaration:Block:d
SimpleName:getIdentifier
SimpleName:internalStructuralPropertiesForType
SimpleName:clone0:Block:result
Members
X