1 | /******************************************************************************* |
---|---|
2 | * Copyright (c) 2017 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 | * IBM Corporation - initial API and implementation |
12 | *******************************************************************************/ |
13 | package org.eclipse.jdt.core.dom; |
14 | |
15 | import java.util.ArrayList; |
16 | import java.util.HashMap; |
17 | import java.util.Iterator; |
18 | import java.util.List; |
19 | import java.util.Map; |
20 | |
21 | /** |
22 | * Module Modifier node - represents the modifiers for the requires directive in module declaration (added in JLS9 API). |
23 | * <pre> |
24 | * ModuleModifier: |
25 | * <b>static</b> |
26 | * <b>transitive</b> |
27 | * </pre> |
28 | * <p> |
29 | * The numeric values of these flags match the ones for class |
30 | * files as described in the Java Virtual Machine Specification. |
31 | * Note that the value of <b>static</b> does <b>not</b> correspond to the value of {@link Modifier#STATIC}! |
32 | * </p> |
33 | * |
34 | * @since 3.14 |
35 | * @noinstantiate This class is not intended to be instantiated by clients. |
36 | */ |
37 | @SuppressWarnings({"rawtypes", "unchecked"}) |
38 | public final class ModuleModifier extends ASTNode { |
39 | |
40 | /** |
41 | * Module Modifier keywords (typesafe enumeration). |
42 | */ |
43 | public static class ModuleModifierKeyword { |
44 | |
45 | /** "static" modifier with flag value {@link ModuleModifier#STATIC_PHASE}. */ |
46 | public static final ModuleModifierKeyword STATIC_KEYWORD = new ModuleModifierKeyword("static", STATIC_PHASE);//$NON-NLS-1$ |
47 | |
48 | /** "transitive" modifier with flag value {@link ModuleModifier#TRANSITIVE}. */ |
49 | public static final ModuleModifierKeyword TRANSITIVE_KEYWORD = new ModuleModifierKeyword("transitive", TRANSITIVE);//$NON-NLS-1$ |
50 | |
51 | |
52 | /** |
53 | * Map from token to operator (key type: <code>String</code>; |
54 | * value type: <code>Operator</code>). |
55 | */ |
56 | private static final Map KEYWORDS; |
57 | |
58 | static { |
59 | KEYWORDS = new HashMap(2); |
60 | ModuleModifierKeyword[] ops = { |
61 | STATIC_KEYWORD, |
62 | TRANSITIVE_KEYWORD, |
63 | }; |
64 | for (int i = 0; i < ops.length; i++) { |
65 | KEYWORDS.put(ops[i].toString(), ops[i]); |
66 | } |
67 | } |
68 | |
69 | /** |
70 | * Returns the module modifier corresponding to the given single-bit flag value, |
71 | * or <code>null</code> if none or if more than one bit is set. |
72 | * <p> |
73 | * <code>fromFlagValue</code> is the converse of <code>toFlagValue</code>: |
74 | * that is, <code>ModuleModifierKind.fromFlagValue(k.toFlagValue()) == k</code> for |
75 | * all module modifier keywords <code>k</code>. |
76 | * </p> |
77 | * |
78 | * @param flagValue the single-bit flag value for the module modifier |
79 | * @return the module modifier keyword, or <code>null</code> if none |
80 | * @see #toFlagValue() |
81 | */ |
82 | public static ModuleModifierKeyword fromFlagValue(int flagValue) { |
83 | for (Iterator it = KEYWORDS.values().iterator(); it.hasNext(); ) { |
84 | ModuleModifierKeyword k = (ModuleModifierKeyword) it.next(); |
85 | if (k.toFlagValue() == flagValue) { |
86 | return k; |
87 | } |
88 | } |
89 | return null; |
90 | } |
91 | |
92 | /** |
93 | * Returns the module modifier corresponding to the given string, |
94 | * or <code>null</code> if none. |
95 | * <p> |
96 | * <code>toKeyword</code> is the converse of <code>toString</code>: |
97 | * that is, <code>ModuleModifierKind.toKeyword(k.toString()) == k</code> for |
98 | * all module modifier keywords <code>k</code>. |
99 | * </p> |
100 | * |
101 | * @param keyword the lowercase string name for the module modifier |
102 | * @return the module modifier keyword, or <code>null</code> if none |
103 | * @see #toString() |
104 | */ |
105 | public static ModuleModifierKeyword toKeyword(String keyword) { |
106 | return (ModuleModifierKeyword) KEYWORDS.get(keyword); |
107 | } |
108 | |
109 | /** |
110 | * The flag value for the module modifier. |
111 | */ |
112 | private int flagValue; |
113 | |
114 | /** |
115 | * The keyword module modifier string. |
116 | */ |
117 | private String keyword; |
118 | |
119 | /** |
120 | * Creates a new module modifier with the given keyword. |
121 | * <p> |
122 | * Note: this constructor is private. The only instances |
123 | * ever created are the ones for the standard modifiers. |
124 | * </p> |
125 | * |
126 | * @param keyword the character sequence for the module modifier |
127 | * @param flagValue flag value as described in the Java Virtual Machine Specification |
128 | */ |
129 | private ModuleModifierKeyword(String keyword, int flagValue) { |
130 | this.keyword = keyword; |
131 | this.flagValue = flagValue; |
132 | } |
133 | |
134 | /** |
135 | * Returns the module modifier flag value corresponding to this module modifier keyword. |
136 | * These flag values are as described in the Java Virtual Machine Specification. |
137 | * |
138 | * @return one of the <code>ModuleModifier</code> constants |
139 | * @see #fromFlagValue(int) |
140 | */ |
141 | public int toFlagValue() { |
142 | return this.flagValue; |
143 | } |
144 | |
145 | /** |
146 | * Returns the keyword for the module modifier. |
147 | * |
148 | * @return the keyword for the module modifier |
149 | * @see #toKeyword(String) |
150 | */ |
151 | @Override |
152 | public String toString() { |
153 | return this.keyword; |
154 | } |
155 | } |
156 | |
157 | /** |
158 | * The "keyword" structural property of this node type (type: {@link ModuleModifier.ModuleModifierKeyword}). |
159 | */ |
160 | public static final SimplePropertyDescriptor KEYWORD_PROPERTY = |
161 | new SimplePropertyDescriptor(ModuleModifier.class, "keyword", ModuleModifier.ModuleModifierKeyword.class, MANDATORY); //$NON-NLS-1$ |
162 | |
163 | /** |
164 | * Module Modifier constant (bit mask, value 0) indicating no module modifiers. |
165 | */ |
166 | public static final int NONE = 0x0000; |
167 | |
168 | /** |
169 | * "static" module modifier constant (bit mask). |
170 | * Applicable to requires directive. |
171 | * <p> |
172 | * Note that the value of <b>static</b> does <b>not</b> correspond to the value of {@link Modifier#STATIC}! |
173 | * </p> |
174 | */ |
175 | public static final int STATIC_PHASE = 0x0040; |
176 | |
177 | /** |
178 | * "transitive" module modifier constant (bit mask). |
179 | * Applicable only to requires directive. |
180 | */ |
181 | public static final int TRANSITIVE = 0x0080; |
182 | |
183 | /** |
184 | * A list of property descriptors (element type: |
185 | * {@link StructuralPropertyDescriptor}), |
186 | * or null if uninitialized. |
187 | */ |
188 | private static final List PROPERTY_DESCRIPTORS; |
189 | |
190 | static { |
191 | List properyList = new ArrayList(2); |
192 | createPropertyList(ModuleModifier.class, properyList); |
193 | addProperty(KEYWORD_PROPERTY, properyList); |
194 | PROPERTY_DESCRIPTORS = reapPropertyList(properyList); |
195 | } |
196 | |
197 | /** |
198 | * Returns whether the given flags includes the "transitive" module modifier. |
199 | * |
200 | * @param flags the module modifier flags |
201 | * @return <code>true</code> if the <code>TRANSITIVE</code> bit is |
202 | * set, and <code>false</code> otherwise |
203 | */ |
204 | public static boolean isTransitive(int flags) { |
205 | return (flags & TRANSITIVE) != 0; |
206 | } |
207 | |
208 | /** |
209 | * Returns whether the given flags includes the "static" module modifier. |
210 | * |
211 | * @param flags the module modifier flags |
212 | * @return <code>true</code> if the <code>STATIC</code> bit is |
213 | * set, and <code>false</code> otherwise |
214 | */ |
215 | public static boolean isStatic(int flags) { |
216 | return (flags & STATIC_PHASE) != 0; |
217 | } |
218 | |
219 | /** |
220 | * Returns a list of structural property descriptors for this node type. |
221 | * Clients must not modify the result. |
222 | * |
223 | * @param apiLevel the API level; one of the |
224 | * <code>AST.JLS*</code> constants |
225 | |
226 | * @return a list of property descriptors (element type: |
227 | * {@link StructuralPropertyDescriptor}) |
228 | */ |
229 | public static List propertyDescriptors(int apiLevel) { |
230 | return PROPERTY_DESCRIPTORS; |
231 | } |
232 | |
233 | /** |
234 | * The modifier keyword; defaults to an unspecified modifier. |
235 | */ |
236 | private ModuleModifierKeyword modifierKeyword = ModuleModifierKeyword.STATIC_KEYWORD; |
237 | |
238 | /** |
239 | * Creates a new unparented MODULE modifier node owned by the given AST. |
240 | * By default, the node has unspecified (but legal) modifier. |
241 | * <p> |
242 | * N.B. This constructor is package-private. |
243 | * </p> |
244 | * |
245 | * @param ast the AST that is to own this node |
246 | */ |
247 | ModuleModifier(AST ast) { |
248 | super(ast); |
249 | unsupportedBelow9(); |
250 | } |
251 | |
252 | @Override |
253 | void accept0(ASTVisitor visitor) { |
254 | visitor.visit(this); |
255 | visitor.endVisit(this); |
256 | } |
257 | |
258 | @Override |
259 | ASTNode clone0(AST target) { |
260 | ModuleModifier result = new ModuleModifier(target); |
261 | result.setSourceRange(getStartPosition(), getLength()); |
262 | result.setKeyword(getKeyword()); |
263 | return result; |
264 | } |
265 | |
266 | /** |
267 | * Returns the modifier keyword of this modifier node. |
268 | * |
269 | * @return the modifier keyword |
270 | */ |
271 | public ModuleModifierKeyword getKeyword() { |
272 | return this.modifierKeyword; |
273 | } |
274 | |
275 | /** |
276 | * Sets the module modifier keyword of this module modifier node. |
277 | * |
278 | * @param modifierKeyord the module modifier keyword |
279 | * @exception IllegalArgumentException if the argument is <code>null</code> |
280 | */ |
281 | public void setKeyword(ModuleModifierKeyword modifierKeyord) { |
282 | if (modifierKeyord == null) { |
283 | throw new IllegalArgumentException(); |
284 | } |
285 | preValueChange(KEYWORD_PROPERTY); |
286 | this.modifierKeyword = modifierKeyord; |
287 | postValueChange(KEYWORD_PROPERTY); |
288 | } |
289 | |
290 | @Override |
291 | final int getNodeType0() { |
292 | return MODULE_MODIFIER; |
293 | } |
294 | |
295 | @Override |
296 | final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) { |
297 | if (property == KEYWORD_PROPERTY) { |
298 | if (get) { |
299 | return getKeyword(); |
300 | } else { |
301 | setKeyword((ModuleModifierKeyword) value); |
302 | return null; |
303 | } |
304 | } |
305 | // allow default implementation to flag the error |
306 | return super.internalGetSetObjectProperty(property, get, value); |
307 | } |
308 | |
309 | @Override |
310 | final List internalStructuralPropertiesForType(int apiLevel) { |
311 | return propertyDescriptors(apiLevel); |
312 | } |
313 | |
314 | /** |
315 | * Answer true if the receiver is the static module modifier, false otherwise. |
316 | * |
317 | * @return true if the receiver is the static module modifier, false otherwise |
318 | */ |
319 | public boolean isStatic() { |
320 | return this.modifierKeyword == ModuleModifierKeyword.STATIC_KEYWORD; |
321 | } |
322 | |
323 | /** |
324 | * Answer true if the receiver is the transitive module modifier, false otherwise. |
325 | * |
326 | * @return true if the receiver is the transitive module modifier, false otherwise |
327 | */ |
328 | public boolean isTransitive() { |
329 | return this.modifierKeyword == ModuleModifierKeyword.TRANSITIVE_KEYWORD; |
330 | } |
331 | |
332 | @Override |
333 | int memSize() { |
334 | // treat ModifierKeyword as free |
335 | return BASE_NODE_SIZE + 1 * 4; |
336 | } |
337 | |
338 | @Override |
339 | final boolean subtreeMatch0(ASTMatcher matcher, Object other) { |
340 | // dispatch to correct overloaded match method |
341 | return matcher.match(this, other); |
342 | } |
343 | |
344 | @Override |
345 | int treeSize() { |
346 | return memSize(); |
347 | } |
348 | } |
349 |
Members