1 /*******************************************************************************
2  * Copyright (c) 2000, 2013 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 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 
22 /**
23  * Modifier node.
24  * <pre>
25  * Modifier:
26  *    <b>public</b>
27  *    <b>protected</b>
28  *    <b>private</b>
29  *    <b>static</b>
30  *    <b>abstract</b>
31  *    <b>final</b>
32  *    <b>native</b>
33  *    <b>synchronized</b>
34  *    <b>transient</b>
35  *    <b>volatile</b>
36  *    <b>strictfp</b>
37  *    <b>default</b>
38  * </pre>
39  * <p>
40  * The numeric values of these flags match the ones for class
41  * files as described in the Java Virtual Machine Specification
42  * (except for {@link #DEFAULT}). Note that the Java model class
43  * {@link org.eclipse.jdt.core.Flags} also provides the same
44  * constants as this class.
45  * </p>
46  *
47  * @since 2.0
48  * @noinstantiate This class is not intended to be instantiated by clients.
49  */
50 @SuppressWarnings({"rawtypes", "unchecked"})
51 public final class Modifier extends ASTNode implements IExtendedModifier {
52 
53 	/**
54  	 * Modifier keywords (typesafe enumeration).
55  	 * @since 3.0
56 	 */
57 	public static class ModifierKeyword {
58 
59 		/** "abstract" modifier with flag value {@link Modifier#ABSTRACT}. */
60 		public static final ModifierKeyword ABSTRACT_KEYWORD = new ModifierKeyword("abstract", ABSTRACT);//$NON-NLS-1$
61 
62 		/** "final" modifier with flag value {@link Modifier#FINAL}. */
63 		public static final ModifierKeyword FINAL_KEYWORD = new ModifierKeyword("final", FINAL);//$NON-NLS-1$
64 
65 		/**
66 		 * Map from token to operator (key type: <code>String</code>;
67 		 * value type: <code>Operator</code>).
68 		 */
69 		private static final Map KEYWORDS;
70 
71 		/** "native" modifier with flag value {@link Modifier#NATIVE}. */
72 		public static final ModifierKeyword NATIVE_KEYWORD = new ModifierKeyword("native", NATIVE);//$NON-NLS-1$
73 
74 		/** "private" modifier with flag value {@link Modifier#PRIVATE}. */
75 		public static final ModifierKeyword PRIVATE_KEYWORD = new ModifierKeyword("private", PRIVATE);//$NON-NLS-1$
76 
77 		/** "protected" modifier with flag value {@link Modifier#PROTECTED}. */
78 		public static final ModifierKeyword PROTECTED_KEYWORD = new ModifierKeyword("protected", PROTECTED);//$NON-NLS-1$
79 
80 		/** "public" modifier with flag value {@link Modifier#PUBLIC}. */
81 		public static final ModifierKeyword PUBLIC_KEYWORD = new ModifierKeyword("public", PUBLIC);//$NON-NLS-1$
82 
83 		/** "static" modifier with flag value {@link Modifier#STATIC}. */
84 		public static final ModifierKeyword STATIC_KEYWORD = new ModifierKeyword("static", STATIC);//$NON-NLS-1$
85 
86 		/** "strictfp" modifier with flag value {@link Modifier#STRICTFP}. */
87 		public static final ModifierKeyword STRICTFP_KEYWORD = new ModifierKeyword("strictfp", STRICTFP);//$NON-NLS-1$
88 
89 		/** "synchronized" modifier with flag value {@link Modifier#SYNCHRONIZED}. */
90 		public static final ModifierKeyword SYNCHRONIZED_KEYWORD = new ModifierKeyword("synchronized", SYNCHRONIZED);//$NON-NLS-1$
91 
92 		/** "transient" modifier with flag value {@link Modifier#TRANSIENT}. */
93 		public static final ModifierKeyword TRANSIENT_KEYWORD = new ModifierKeyword("transient", TRANSIENT);//$NON-NLS-1$
94 
95 		/** "volatile" modifier with flag value {@link Modifier#VOLATILE}. */
96 		public static final ModifierKeyword VOLATILE_KEYWORD = new ModifierKeyword("volatile", VOLATILE);//$NON-NLS-1$
97 
98 		/**
99 		 * "default" modifier with flag value {@link Modifier#DEFAULT} (added in JLS8 API).
100 		 * <p>
101 		 * Note that the value of this modifier is
102 		 * internal and is not specified in the Java Virtual Machine Specification.
103 		 * </p>
104 		 * @since 3.10
105 		 */
106 		public static final ModifierKeyword DEFAULT_KEYWORD = new ModifierKeyword("default", DEFAULT);//$NON-NLS-1$
107 
108 		static {
109 			KEYWORDS = new HashMap(20);
110 			ModifierKeyword[] ops = {
111 					PUBLIC_KEYWORD,
112 					PROTECTED_KEYWORD,
113 					PRIVATE_KEYWORD,
114 					STATIC_KEYWORD,
115 					ABSTRACT_KEYWORD,
116 					FINAL_KEYWORD,
117 					NATIVE_KEYWORD,
118 					SYNCHRONIZED_KEYWORD,
119 					TRANSIENT_KEYWORD,
120 					VOLATILE_KEYWORD,
121 					STRICTFP_KEYWORD,
122 					DEFAULT_KEYWORD
123 				};
124 			for (int i = 0; i < ops.length; i++) {
KEYWORDS.put(ops[i].toString(), ops[i])125 				KEYWORDS.put(ops[i].toString(), ops[i]);
126 			}
127 		}
128 
129 		/**
130 		 * Returns the modifier corresponding to the given single-bit flag value,
131 		 * or <code>null</code> if none or if more than one bit is set.
132 		 * <p>
133 		 * <code>fromFlagValue</code> is the converse of <code>toFlagValue</code>:
134 		 * that is, <code>ModifierKind.fromFlagValue(k.toFlagValue()) == k</code> for
135 		 * all modifier keywords <code>k</code>.
136 		 * </p>
137 		 *
138 		 * @param flagValue the single-bit flag value for the modifier
139 		 * @return the modifier keyword, or <code>null</code> if none
140 		 * @see #toFlagValue()
141 		 */
fromFlagValue(int flagValue)142 		public static ModifierKeyword fromFlagValue(int flagValue) {
143 			for (Iterator it = KEYWORDS.values().iterator(); it.hasNext(); ) {
144 				ModifierKeyword k = (ModifierKeyword) it.next();
145 				if (k.toFlagValue() == flagValue) {
146 					return k;
147 				}
148 			}
149 			return null;
150 		}
151 
152 		/**
153 		 * Returns the modifier corresponding to the given string,
154 		 * or <code>null</code> if none.
155 		 * <p>
156 		 * <code>toKeyword</code> is the converse of <code>toString</code>:
157 		 * that is, <code>ModifierKind.toKeyword(k.toString()) == k</code> for
158 		 * all modifier keywords <code>k</code>.
159 		 * </p>
160 		 *
161 		 * @param keyword the lowercase string name for the modifier
162 		 * @return the modifier keyword, or <code>null</code> if none
163 		 * @see #toString()
164 		 */
toKeyword(String keyword)165 		public static ModifierKeyword toKeyword(String keyword) {
166 			return (ModifierKeyword) KEYWORDS.get(keyword);
167 		}
168 
169 		/**
170 		 * The flag value for the modifier.
171 		 */
172 		private int flagValue;
173 
174 		/**
175 		 * The keyword modifier string.
176 		 */
177 		private String keyword;
178 
179 		/**
180 		 * Creates a new modifier with the given keyword.
181 		 * <p>
182 		 * Note: this constructor is private. The only instances
183 		 * ever created are the ones for the standard modifiers.
184 		 * </p>
185 		 *
186 		 * @param keyword the character sequence for the modifier
187 		 * @param flagValue flag value as described in the Java Virtual Machine Specification
188 		 */
ModifierKeyword(String keyword, int flagValue)189 		private ModifierKeyword(String keyword, int flagValue) {
190 			this.keyword = keyword;
191 			this.flagValue = flagValue;
192 		}
193 
194 		/**
195 		 * Returns the modifier flag value corresponding to this modifier keyword.
196 		 * These flag values are as described in the Java Virtual Machine Specification.
197 		 *
198 		 * @return one of the <code>Modifier</code> constants
199 		 * @see #fromFlagValue(int)
200 		 */
toFlagValue()201 		public int toFlagValue() {
202 			return this.flagValue;
203 		}
204 
205 		/**
206 		 * Returns the keyword for the modifier.
207 		 *
208 		 * @return the keyword for the modifier
209 		 * @see #toKeyword(String)
210 		 */
211 		@Override
toString()212 		public String toString() {
213 			return this.keyword;
214 		}
215 	}
216 
217 	/**
218 	 * "abstract" modifier constant (bit mask).
219 	 * Applicable to types and methods.
220 	 * @since 2.0
221 	 */
222 	public static final int ABSTRACT = 0x0400;
223 
224 	/**
225 	 * "final" modifier constant (bit mask).
226 	 * Applicable to types, methods, fields, and variables.
227 	 * @since 2.0
228 	 */
229 	public static final int FINAL = 0x0010;
230 
231 	/**
232 	 * The "keyword" structural property of this node type (type: {@link Modifier.ModifierKeyword}).
233 	 * @since 3.0
234 	 */
235 	public static final SimplePropertyDescriptor KEYWORD_PROPERTY =
236 		new SimplePropertyDescriptor(Modifier.class, "keyword", Modifier.ModifierKeyword.class, MANDATORY); //$NON-NLS-1$
237 
238 	/**
239 	 * "native" modifier constant (bit mask).
240 	 * Applicable only to methods.
241 	 * @since 2.0
242 	 */
243 	public static final int NATIVE = 0x0100;
244 
245 	/**
246 	 * Modifier constant (bit mask, value 0) indicating no modifiers.
247 	 * @since 2.0
248 	 */
249 	public static final int NONE = 0x0000;
250 
251 	/**
252 	 * "private" modifier constant (bit mask).
253 	 * Applicable to types, methods, constructors, and fields.
254 	 * @since 2.0
255 	 */
256 	public static final int PRIVATE = 0x0002;
257 
258 	/**
259 	 * A list of property descriptors (element type:
260 	 * {@link StructuralPropertyDescriptor}),
261 	 * or null if uninitialized.
262 	 */
263 	private static final List PROPERTY_DESCRIPTORS;
264 
265 	/**
266 	 * "protected" modifier constant (bit mask).
267 	 * Applicable to types, methods, constructors, and fields.
268 	 * @since 2.0
269 	 */
270 	public static final int PROTECTED = 0x0004;
271 
272 	/**
273 	 * "public" modifier constant (bit mask).
274 	 * Applicable to types, methods, constructors, and fields.
275 	 * @since 2.0
276 	 */
277 	public static final int PUBLIC = 0x0001;
278 
279 	/**
280 	 * "static" modifier constant (bit mask).
281 	 * Applicable to types, methods, fields, and initializers.
282 	 * @since 2.0
283 	 */
284 	public static final int STATIC = 0x0008;
285 
286 	/**
287 	 * "strictfp" modifier constant (bit mask).
288 	 * Applicable to types and methods.
289 	 * @since 2.0
290 	 */
291 	public static final int STRICTFP = 0x0800;
292 
293 	/**
294 	 * "synchronized" modifier constant (bit mask).
295 	 * Applicable only to methods.
296 	 * @since 2.0
297 	 */
298 	public static final int SYNCHRONIZED = 0x0020;
299 
300 	/**
301 	 * "transient" modifier constant (bit mask).
302 	 * Applicable only to fields.
303 	 * @since 2.0
304 	 */
305 	public static final int TRANSIENT = 0x0080;
306 
307 	/**
308 	 * "volatile" modifier constant (bit mask).
309 	 * Applicable only to fields.
310 	 * @since 2.0
311 	 */
312 	public static final int VOLATILE = 0x0040;
313 
314 	/**
315 	 * "default" modifier constant (bit mask) (added in JLS8 API).
316 	 * Applicable only to methods in interfaces (but not for annotation methods with a default value).
317 	 * <p>
318 	 * Note that the value of this flag is internal and is not
319 	 * specified in the Java Virtual Machine Specification.
320 	 * </p>
321 	 * @since 3.10
322 	 */
323 	public static final int DEFAULT = 0x10000;
324 
325 	static {
326 		List properyList = new ArrayList(2);
createPropertyList(Modifier.class, properyList)327 		createPropertyList(Modifier.class, properyList);
addProperty(KEYWORD_PROPERTY, properyList)328 		addProperty(KEYWORD_PROPERTY, properyList);
329 		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
330 	}
331 
332 	/**
333 	 * Returns whether the given flags includes the "abstract" modifier.
334 	 * Applicable to types and methods.
335 	 *
336 	 * @param flags the modifier flags
337 	 * @return <code>true</code> if the <code>ABSTRACT</code> bit is
338 	 *   set, and <code>false</code> otherwise
339 	 * @since 2.0
340 	 */
isAbstract(int flags)341 	public static boolean isAbstract(int flags) {
342 		return (flags & ABSTRACT) != 0;
343 	}
344 
345 	/**
346 	 * Returns whether the given flags includes the "final" modifier.
347 	 * Applicable to types, methods, fields, and variables.
348 	 *
349 	 * @param flags the modifier flags
350 	 * @return <code>true</code> if the <code>FINAL</code> bit is
351 	 *   set, and <code>false</code> otherwise
352 	 * @since 2.0
353 	 */
isFinal(int flags)354 	public static boolean isFinal(int flags) {
355 		return (flags & FINAL) != 0;
356 	}
357 
358 	/**
359 	 * Returns whether the given flags includes the "native" modifier.
360 	 * Applicable only to methods.
361 	 *
362 	 * @param flags the modifier flags
363 	 * @return <code>true</code> if the <code>NATIVE</code> bit is
364 	 *   set, and <code>false</code> otherwise
365 	 * @since 2.0
366 	 */
isNative(int flags)367 	public static boolean isNative(int flags) {
368 		return (flags & NATIVE) != 0;
369 	}
370 
371 	/**
372 	 * Returns whether the given flags includes the "private" modifier.
373 	 * Applicable to types, methods, constructors, and fields.
374 	 *
375 	 * @param flags the modifier flags
376 	 * @return <code>true</code> if the <code>PRIVATE</code> bit is
377 	 *   set, and <code>false</code> otherwise
378 	 * @since 2.0
379 	 */
isPrivate(int flags)380 	public static boolean isPrivate(int flags) {
381 		return (flags & PRIVATE) != 0;
382 	}
383 
384 	/**
385 	 * Returns whether the given flags includes the "protected" modifier.
386 	 * Applicable to types, methods, constructors, and fields.
387 	 *
388 	 * @param flags the modifier flags
389 	 * @return <code>true</code> if the <code>PROTECTED</code> bit is
390 	 *   set, and <code>false</code> otherwise
391 	 * @since 2.0
392 	 */
isProtected(int flags)393 	public static boolean isProtected(int flags) {
394 		return (flags & PROTECTED) != 0;
395 	}
396 
397 	/**
398 	 * Returns whether the given flags includes the "public" modifier.
399 	 * Applicable to types, methods, constructors, and fields.
400 	 *
401 	 * @param flags the modifier flags
402 	 * @return <code>true</code> if the <code>PUBLIC</code> bit is
403 	 *   set, and <code>false</code> otherwise
404 	 * @since 2.0
405 	 */
isPublic(int flags)406 	public static boolean isPublic(int flags) {
407 		return (flags & PUBLIC) != 0;
408 	}
409 
410 	/**
411 	 * Returns whether the given flags includes the "static" modifier.
412 	 * Applicable to types, methods, fields, and initializers.
413 	 *
414 	 * @param flags the modifier flags
415 	 * @return <code>true</code> if the <code>STATIC</code> bit is
416 	 *   set, and <code>false</code> otherwise
417 	 * @since 2.0
418 	 */
isStatic(int flags)419 	public static boolean isStatic(int flags) {
420 		return (flags & STATIC) != 0;
421 	}
422 
423 	/**
424 	 * Returns whether the given flags includes the "strictfp" modifier.
425 	 * Applicable to types and methods.
426 	 *
427 	 * @param flags the modifier flags
428 	 * @return <code>true</code> if the <code>STRICTFP</code> bit is
429 	 *   set, and <code>false</code> otherwise
430 	 * @since 2.0
431 	 */
isStrictfp(int flags)432 	public static boolean isStrictfp(int flags) {
433 		return (flags & STRICTFP) != 0;
434 	}
435 
436 	/**
437 	 * Returns whether the given flags includes the "synchronized" modifier.
438 	 * Applicable only to methods.
439 	 *
440 	 * @param flags the modifier flags
441 	 * @return <code>true</code> if the <code>SYNCHRONIZED</code> bit is
442 	 *   set, and <code>false</code> otherwise
443 	 * @since 2.0
444 	 */
isSynchronized(int flags)445 	public static boolean isSynchronized(int flags) {
446 		return (flags & SYNCHRONIZED) != 0;
447 	}
448 
449 	/**
450 	 * Returns whether the given flags includes the "transient" modifier.
451 	 * Applicable only to fields.
452 	 *
453 	 * @param flags the modifier flags
454 	 * @return <code>true</code> if the <code>TRANSIENT</code> bit is
455 	 *   set, and <code>false</code> otherwise
456 	 * @since 2.0
457 	 */
isTransient(int flags)458 	public static boolean isTransient(int flags) {
459 		return (flags & TRANSIENT) != 0;
460 	}
461 
462 	/**
463 	 * Returns whether the given flags includes the "volatile" modifier.
464 	 * Applicable only to fields.
465 	 *
466 	 * @param flags the modifier flags
467 	 * @return <code>true</code> if the <code>VOLATILE</code> bit is
468 	 *   set, and <code>false</code> otherwise
469 	 * @since 2.0
470 	 */
isVolatile(int flags)471 	public static boolean isVolatile(int flags) {
472 		return (flags & VOLATILE) != 0;
473 	}
474 
475 	/**
476 	 * Returns whether the given flags includes the "default" modifier.
477 	 * Applicable only to methods in interfaces.
478 	 *
479 	 * @param flags the modifier flags
480 	 * @return <code>true</code> if the <code>DEFAULT</code> bit is set
481 	 * and <code>false</code> otherwise
482 	 * @since 3.10
483 	 */
isDefault(int flags)484 	public static boolean isDefault(int flags) {
485 		return (flags & DEFAULT) != 0;
486 	}
487 
488 	/**
489 	 * Returns a list of structural property descriptors for this node type.
490 	 * Clients must not modify the result.
491 	 *
492 	 * @param apiLevel the API level; one of the
493 	 * <code>AST.JLS*</code> constants
494 
495 	 * @return a list of property descriptors (element type:
496 	 * {@link StructuralPropertyDescriptor})
497 	 * @since 3.0
498 	 */
propertyDescriptors(int apiLevel)499 	public static List propertyDescriptors(int apiLevel) {
500 		return PROPERTY_DESCRIPTORS;
501 	}
502 
503 	/**
504 	 * The modifier keyword; defaults to an unspecified modifier.
505 	 * @since 3.0
506 	 */
507 	private ModifierKeyword modifierKeyword = ModifierKeyword.PUBLIC_KEYWORD;
508 
509 	/**
510 	 * Creates a new unparented modifier node owned by the given AST.
511 	 * By default, the node has unspecified (but legal) modifier.
512 	 * <p>
513 	 * N.B. This constructor is package-private.
514 	 * </p>
515 	 *
516 	 * @param ast the AST that is to own this node
517 	 * @since 3.0
518 	 */
Modifier(AST ast)519 	Modifier(AST ast) {
520 		super(ast);
521 	    unsupportedIn2();
522 	}
523 
524 	@Override
accept0(ASTVisitor visitor)525 	void accept0(ASTVisitor visitor) {
526 		visitor.visit(this);
527 		visitor.endVisit(this);
528 	}
529 
530 	@Override
clone0(AST target)531 	ASTNode clone0(AST target) {
532 		Modifier result = new Modifier(target);
533 		result.setSourceRange(getStartPosition(), getLength());
534 		result.setKeyword(getKeyword());
535 		return result;
536 	}
537 
538 	/**
539 	 * Returns the modifier keyword of this modifier node.
540 	 *
541 	 * @return the modifier keyword
542 	 * @since 3.0
543 	 */
getKeyword()544 	public ModifierKeyword getKeyword() {
545 		return this.modifierKeyword;
546 	}
547 
548 	@Override
getNodeType0()549 	final int getNodeType0() {
550 		return MODIFIER;
551 	}
552 
553 	@Override
internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value)554 	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
555 		if (property == KEYWORD_PROPERTY) {
556 			if (get) {
557 				return getKeyword();
558 			} else {
559 				setKeyword((ModifierKeyword) value);
560 				return null;
561 			}
562 		}
563 		// allow default implementation to flag the error
564 		return super.internalGetSetObjectProperty(property, get, value);
565 	}
566 
567 	@Override
internalStructuralPropertiesForType(int apiLevel)568 	final List internalStructuralPropertiesForType(int apiLevel) {
569 		return propertyDescriptors(apiLevel);
570 	}
571 
572 	/**
573 	 * Answer true if the receiver is the abstract modifier, false otherwise.
574 	 *
575 	 * @return true if the receiver is the abstract modifier, false otherwise
576 	 * @since 3.2
577 	 */
isAbstract()578 	public boolean isAbstract() {
579 		return this.modifierKeyword == ModifierKeyword.ABSTRACT_KEYWORD;
580 	}
581 
582 	/**
583 	 * @see IExtendedModifier#isAnnotation()
584 	 */
585 	@Override
isAnnotation()586 	public boolean isAnnotation() {
587 		return false;
588 	}
589 
590 	/**
591 	 * Answer true if the receiver is the final modifier, false otherwise.
592 	 *
593 	 * @return true if the receiver is the final modifier, false otherwise
594 	 * @since 3.2
595 	 */
isFinal()596 	public boolean isFinal() {
597 		return this.modifierKeyword == ModifierKeyword.FINAL_KEYWORD;
598 	}
599 
600 	/**
601 	 * @see IExtendedModifier#isModifier()
602 	 */
603 	@Override
isModifier()604 	public boolean isModifier() {
605 		return true;
606 	}
607 
608 	/**
609 	 * Answer true if the receiver is the native modifier, false otherwise.
610 	 *
611 	 * @return true if the receiver is the native modifier, false otherwise
612 	 * @since 3.2
613 	 */
isNative()614 	public boolean isNative() {
615 		return this.modifierKeyword == ModifierKeyword.NATIVE_KEYWORD;
616 	}
617 
618 	/**
619 	 * Answer true if the receiver is the private modifier, false otherwise.
620 	 *
621 	 * @return true if the receiver is the private modifier, false otherwise
622 	 * @since 3.2
623 	 */
isPrivate()624 	public boolean isPrivate() {
625 		return this.modifierKeyword == ModifierKeyword.PRIVATE_KEYWORD;
626 	}
627 
628 	/**
629 	 * Answer true if the receiver is the protected modifier, false otherwise.
630 	 *
631 	 * @return true if the receiver is the protected modifier, false otherwise
632 	 * @since 3.2
633 	 */
isProtected()634 	public boolean isProtected() {
635 		return this.modifierKeyword == ModifierKeyword.PROTECTED_KEYWORD;
636 	}
637 
638 	/**
639 	 * Answer true if the receiver is the public modifier, false otherwise.
640 	 *
641 	 * @return true if the receiver is the public modifier, false otherwise
642 	 * @since 3.2
643 	 */
isPublic()644 	public boolean isPublic() {
645 		return this.modifierKeyword == ModifierKeyword.PUBLIC_KEYWORD;
646 	}
647 
648 	/**
649 	 * Answer true if the receiver is the static modifier, false otherwise.
650 	 *
651 	 * @return true if the receiver is the static modifier, false otherwise
652 	 * @since 3.2
653 	 */
isStatic()654 	public boolean isStatic() {
655 		return this.modifierKeyword == ModifierKeyword.STATIC_KEYWORD;
656 	}
657 
658 	/**
659 	 * Answer true if the receiver is the strictfp modifier, false otherwise.
660 	 *
661 	 * @return true if the receiver is the strictfp modifier, false otherwise
662 	 * @since 3.2
663 	 */
isStrictfp()664 	public boolean isStrictfp() {
665 		return this.modifierKeyword == ModifierKeyword.STRICTFP_KEYWORD;
666 	}
667 
668 	/**
669 	 * Answer true if the receiver is the synchronized modifier, false otherwise.
670 	 *
671 	 * @return true if the receiver is the synchronized modifier, false otherwise
672 	 * @since 3.2
673 	 */
isSynchronized()674 	public boolean isSynchronized() {
675 		return this.modifierKeyword == ModifierKeyword.SYNCHRONIZED_KEYWORD;
676 	}
677 
678 	/**
679 	 * Answer true if the receiver is the transient modifier, false otherwise.
680 	 *
681 	 * @return true if the receiver is the transient modifier, false otherwise
682 	 * @since 3.2
683 	 */
isTransient()684 	public boolean isTransient() {
685 		return this.modifierKeyword == ModifierKeyword.TRANSIENT_KEYWORD;
686 	}
687 
688 	/**
689 	 * Answer true if the receiver is the volatile modifier, false otherwise.
690 	 *
691 	 * @return true if the receiver is the volatile modifier, false otherwise
692 	 * @since 3.2
693 	 */
isVolatile()694 	public boolean isVolatile() {
695 		return this.modifierKeyword == ModifierKeyword.VOLATILE_KEYWORD;
696 	}
697 
698 	/**
699 	 * Answer true if the receiver is the default modifier, false otherwise.
700 	 * @return true if the receiver is the default modifier, false otherwise
701 	 * @since 3.10
702 	 */
isDefault()703 	public boolean isDefault() {
704 		return this.modifierKeyword == ModifierKeyword.DEFAULT_KEYWORD;
705 	}
706 
707 	@Override
memSize()708 	int memSize() {
709 		// treat ModifierKeyword as free
710 		return BASE_NODE_SIZE + 1 * 4;
711 	}
712 
713 	/**
714 	 * Sets the modifier keyword of this modifier node.
715 	 *
716 	 * @param modifierKeyord the modifier keyword
717 	 * @exception IllegalArgumentException if the argument is <code>null</code>
718 	 * @since 3.0
719 	 */
setKeyword(ModifierKeyword modifierKeyord)720 	public void setKeyword(ModifierKeyword modifierKeyord) {
721 		if (modifierKeyord == null) {
722 			throw new IllegalArgumentException();
723 		}
724 		preValueChange(KEYWORD_PROPERTY);
725 		this.modifierKeyword = modifierKeyord;
726 		postValueChange(KEYWORD_PROPERTY);
727 	}
728 
729 	@Override
subtreeMatch0(ASTMatcher matcher, Object other)730 	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
731 		// dispatch to correct overloaded match method
732 		return matcher.match(this, other);
733 	}
734 
735 	@Override
treeSize()736 	int treeSize() {
737 		return memSize();
738 	}
739 }
740