1 | /******************************************************************************* |
---|---|
2 | * Copyright (c) 2004, 2019 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 | package org.eclipse.jdt.core.dom; |
15 | |
16 | /** |
17 | * Abstract base class of AST nodes that represent annotations. |
18 | * <pre> |
19 | * Annotation: |
20 | * NormalAnnotation |
21 | * MarkerAnnotation |
22 | * SingleMemberAnnotation |
23 | * </pre> |
24 | * @since 3.1 |
25 | */ |
26 | @SuppressWarnings("rawtypes") |
27 | public abstract class Annotation extends Expression implements IExtendedModifier { |
28 | |
29 | /** |
30 | * Returns structural property descriptor for the "typeName" property |
31 | * of this node (child type: {@link Name}). |
32 | * |
33 | * @return the property descriptor |
34 | */ |
35 | abstract ChildPropertyDescriptor internalTypeNameProperty(); |
36 | |
37 | /** |
38 | * Returns structural property descriptor for the "typeName" property |
39 | * of this node (child type: {@link Name}). |
40 | * |
41 | * @return the property descriptor |
42 | */ |
43 | public final ChildPropertyDescriptor getTypeNameProperty() { |
44 | return internalTypeNameProperty(); |
45 | } |
46 | |
47 | /** |
48 | * Creates and returns a structural property descriptor for the |
49 | * "typeName" property declared on the given concrete node type (child type: {@link Name}). |
50 | * |
51 | * @return the property descriptor |
52 | */ |
53 | static final ChildPropertyDescriptor internalTypeNamePropertyFactory(Class nodeClass) { |
54 | return new ChildPropertyDescriptor(nodeClass, "typeName", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$ |
55 | } |
56 | |
57 | /** |
58 | * The annotation type name; lazily initialized; defaults to an unspecified, |
59 | * legal Java identifier. |
60 | */ |
61 | Name typeName = null; |
62 | |
63 | /** |
64 | * Creates a new AST node for an annotation node owned by the |
65 | * given AST. |
66 | * <p> |
67 | * N.B. This constructor is package-private. |
68 | * </p> |
69 | * |
70 | * @param ast the AST that is to own this node |
71 | */ |
72 | Annotation(AST ast) { |
73 | super(ast); |
74 | } |
75 | |
76 | /** |
77 | * @see IExtendedModifier#isModifier() |
78 | */ |
79 | @Override |
80 | public boolean isModifier() { |
81 | return false; |
82 | } |
83 | |
84 | /** |
85 | * @see IExtendedModifier#isAnnotation() |
86 | */ |
87 | @Override |
88 | public boolean isAnnotation() { |
89 | return true; |
90 | } |
91 | |
92 | /** |
93 | * Returns the annotation type name of this annotation. |
94 | * |
95 | * @return the annotation type name |
96 | */ |
97 | public Name getTypeName() { |
98 | if (this.typeName == null) { |
99 | // lazy init must be thread-safe for readers |
100 | synchronized (this) { |
101 | if (this.typeName == null) { |
102 | preLazyInit(); |
103 | this.typeName = new SimpleName(this.ast); |
104 | postLazyInit(this.typeName, internalTypeNameProperty()); |
105 | } |
106 | } |
107 | } |
108 | return this.typeName; |
109 | } |
110 | |
111 | /** |
112 | * Sets the annotation type name of this annotation. |
113 | * |
114 | * @param typeName the annotation type name |
115 | * @exception IllegalArgumentException if: |
116 | * <ul> |
117 | * <li>the node belongs to a different AST</li> |
118 | * <li>the node already has a parent</li> |
119 | * </ul> |
120 | */ |
121 | public void setTypeName(Name typeName) { |
122 | if (typeName == null) { |
123 | throw new IllegalArgumentException(); |
124 | } |
125 | ChildPropertyDescriptor p = internalTypeNameProperty(); |
126 | ASTNode oldChild = this.typeName; |
127 | preReplaceChild(oldChild, typeName, p); |
128 | this.typeName = typeName; |
129 | postReplaceChild(oldChild, typeName, p); |
130 | } |
131 | |
132 | /** |
133 | * Returns whether this is a normal annotation |
134 | * ({@link NormalAnnotation}). |
135 | * |
136 | * @return <code>true</code> if this is a normal annotation, |
137 | * and <code>false</code> otherwise |
138 | */ |
139 | public boolean isNormalAnnotation() { |
140 | return (this instanceof NormalAnnotation); |
141 | } |
142 | |
143 | /** |
144 | * Returns whether this is a marker annotation |
145 | * ({@link MarkerAnnotation}). |
146 | * |
147 | * @return <code>true</code> if this is a marker annotation, |
148 | * and <code>false</code> otherwise |
149 | */ |
150 | public boolean isMarkerAnnotation() { |
151 | return (this instanceof MarkerAnnotation); |
152 | } |
153 | |
154 | /** |
155 | * Returns whether this is a single member annotation. |
156 | * ({@link SingleMemberAnnotation}). |
157 | * |
158 | * @return <code>true</code> if this is a single member annotation, |
159 | * and <code>false</code> otherwise |
160 | */ |
161 | public boolean isSingleMemberAnnotation() { |
162 | return (this instanceof SingleMemberAnnotation); |
163 | } |
164 | |
165 | @Override |
166 | int memSize() { |
167 | return BASE_NODE_SIZE + 1 * 4; |
168 | } |
169 | |
170 | /** |
171 | * Resolves and returns the resolved annotation for this annotation. |
172 | * <p> |
173 | * Note that bindings (which includes resolved annotations) are generally unavailable unless |
174 | * requested when the AST is being built. |
175 | * </p> |
176 | * |
177 | * @return the resolved annotation, or <code>null</code> if the annotation cannot be resolved |
178 | * @since 3.2 |
179 | */ |
180 | public IAnnotationBinding resolveAnnotationBinding() { |
181 | return this.ast.getBindingResolver().resolveAnnotation(this); |
182 | } |
183 | } |
184 |
Members