EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/ASTNode.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2022 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.AbstractList;
18import java.util.ArrayList;
19import java.util.Collections;
20import java.util.HashMap;
21import java.util.Iterator;
22import java.util.List;
23import java.util.Map;
24
25import org.eclipse.jdt.internal.core.dom.NaiveASTFlattener;
26
27/**
28 * Abstract superclass of all Abstract Syntax Tree (AST) node types.
29 * <p>
30 * An AST node represents a Java source code construct, such
31 * as a name, type, expression, statement, or declaration.
32 * </p>
33 * <p>
34 * Each AST node belongs to a unique AST instance, called the owning AST.
35 * The children of an AST node always have the same owner as their parent node.
36 * If a node from one AST is to be added to a different AST, the subtree must
37 * be cloned first to ensure that the added nodes have the correct owning AST.
38 * </p>
39 * <p>
40 * When an AST node is part of an AST, it has a unique parent node.
41 * Clients can navigate upwards, from child to parent, as well as downwards,
42 * from parent to child. Newly created nodes are unparented. When an
43 * unparented node is set as a child of a node (using a
44 * <code>set<i>CHILD</i></code> method), its parent link is set automatically
45 * and the parent link of the former child is set to <code>null</code>.
46 * For nodes with properties that include a list of children (for example,
47 * <code>Block</code> whose <code>statements</code> property is a list
48 * of statements), adding or removing an element to/for the list property
49 * automatically updates the parent links. These lists support the
50 * <code>List.set</code> method; however, the constraint that the same
51 * node cannot appear more than once means that this method cannot be used
52 * to swap elements without first removing the node.
53 * </p>
54 * <p>
55 * ASTs must not contain cycles. All operations that could create a cycle
56 * detect this possibility and fail.
57 * </p>
58 * <p>
59 * ASTs do not contain "holes" (missing subtrees). If a node is required to
60 * have a certain property, a syntactically plausible initial value is
61 * always supplied.
62 * </p>
63 * <p>
64 * The hierarchy of AST node types has some convenient groupings marked
65 * by abstract superclasses:
66 * <ul>
67 * <li>expressions - <code>Expression</code></li>
68 * <li>names - <code>Name</code> (a sub-kind of expression)</li>
69 * <li>statements - <code>Statement</code></li>
70 * <li>types - <code>Type</code></li>
71 * <li>type body declarations - <code>BodyDeclaration</code></li>
72 * </ul>
73 * <p>
74 * Abstract syntax trees may be hand constructed by clients, using the
75 * <code>new<i>TYPE</i></code> factory methods (see <code>AST</code>) to
76 * create new nodes, and the various <code>set<i>CHILD</i></code> methods
77 * to connect them together.
78 * </p>
79 * <p>
80 * The class {@link ASTParser} parses a string
81 * containing a Java source code and returns an abstract syntax tree
82 * for it. The resulting nodes carry source ranges relating the node back to
83 * the original source characters. The source range covers the construct
84 * as a whole.
85 * </p>
86 * <p>
87 * Each AST node carries bit flags, which may convey additional information about
88 * the node. For instance, the parser uses a flag to indicate a syntax error.
89 * Newly created nodes have no flags set.
90 * </p>
91 * <p>
92 * Each AST node is capable of carrying an open-ended collection of
93 * client-defined properties. Newly created nodes have none.
94 * <code>getProperty</code> and <code>setProperty</code> are used to access
95 * these properties.
96 * </p>
97 * <p>
98 * AST nodes are thread-safe for readers provided there are no active writers.
99 * If one thread is modifying an AST, including creating new nodes or cloning
100 * existing ones, it is <b>not</b> safe for another thread to read, visit,
101 * write, create, or clone <em>any</em> of the nodes on the same AST.
102 * When synchronization is required, consider using the common AST
103 * object that owns the node; that is, use
104 * <code>synchronize (node.getAST()) {...}</code>.
105 * </p>
106 * <p>
107 * ASTs also support the visitor pattern; see the class <code>ASTVisitor</code>
108 * for details. The <code>NodeFinder</code> class can be used to find a specific
109 * node inside a tree.
110 * </p>
111 * <p>
112 * Compilation units created by <code>ASTParser</code> from a
113 * source document can be serialized after arbitrary modifications
114 * with minimal loss of original formatting. See
115 * {@link CompilationUnit#recordModifications()} for details.
116 * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
117 * an alternative way to describe and serialize changes to a
118 * read-only AST.
119 * </p>
120 *
121 * @see ASTParser
122 * @see ASTVisitor
123 * @see NodeFinder
124 * @since 2.0
125 * @noextend This class is not intended to be subclassed by clients.
126 */
127@SuppressWarnings({ "rawtypes""unchecked" })
128public abstract class ASTNode {
129    /*
130     * ATTENTION: When doing anything to the ASTNode hierarchy, do not try to
131     * reinvent the wheel.
132     *
133     * Look out for precedents with
134     * - the same structural property type
135     * - for child node properties: the same optionality (can be null / lazy initialization blurbs and impl.)
136     * - the same declaring node type kind (abstract supertype or concrete type)
137     * - a similar history (added in JLSx API, below JLSx only, replaced by {@link #xx})
138     * ..., and copy what was done there. Most of the code and
139     * Javadoc in this package should look like it was created by a code generator.
140     *
141     * In subclasses of ASTNode, order properties by order of occurrence in source.
142     * In general classes that list all AST node types, order alphabetically.
143     */
144
145    /*
146     * INSTRUCTIONS FOR ADDING NEW CONCRETE AST NODE TYPES
147     *
148     * There are several things that need to be changed when a
149     * new concrete AST node type (call it "FooBar") is added:
150     *
151     * 1. Create the FooBar AST node type class.
152     * The most effective way to do this is to copy a similar
153     * existing concrete node class to get a template that
154     * includes all the framework methods that must be implemented.
155     *
156     * 2. Add node type constant ASTNode.FOO_BAR.
157     * Node constants are numbered consecutively. Add the
158     * constant after the existing ones.
159     *
160     * 3. Add entry to ASTNode.nodeClassForType(int).
161     *
162     * 4. Add AST.newFooBar() factory method.
163     *
164     * 5. Add ASTVisitor.visit(FooBar) and endVisit(FooBar) methods. Same for DefaultASTVisitor.
165     *
166     * 6. Add ASTMatcher.match(FooBar,Object) method.
167     *
168     * 7. Ensure that SimpleName.isDeclaration() covers FooBar
169     * nodes if required.
170     *
171     * 8. Add NaiveASTFlattener.visit(FooBar) method to illustrate
172     * how these nodes should be serialized.
173     *
174     * 9. Update the AST test suites (ASTVisitorTest, etc.)
175     *
176     * The next steps are to update AST.parse* to start generating
177     * the new type of nodes, and ASTRewrite to serialize them back out.
178     */
179
180    /*
181     * INSTRUCTIONS FOR ADDING A NEW PROPERTY TO AN AST NODE TYPE
182     *
183     * For concrete node types, use e.g. properties of SimpleName or ClassInstanceCreation
184     * as templates:
185     *
186     * 1. Copy/paste the field, property descriptor, and getter/setter.
187     *
188     * 2. Adjust everything to the new property name and type. In the field's
189     * Javadoc, properly document default value, initialization, and applicable
190     * API levels.
191     *
192     * 3. Add/remove @since tags as necessary.
193     *
194     * 4. Search for references to the members in the template, and add similar
195     * references in corresponding places for the new property.
196     *
197     *
198     * For abstract node types, use AbstractTypeDeclaration as a template:
199     *
200     * 1. Same steps as above, but take extra care to copy and adjust the
201     * *internal*() methods as well.
202     *
203     * 2. Search for references to the members in the template, and add similar
204     * references in corresponding places for the new property (e.g. property
205     * descriptor in each leaf type).
206     */
207
208    /*
209     * INSTRUCTIONS FOR REPLACING/DEPRECATING A PROPERTY OF AN AST NODE
210     *
211     * To replace a simple property with a child list property, see e.g. how
212     * SingleVariableDeclaration replaced MODIFIERS_PROPERTY with
213     * MODIFIERS2_PROPERTY.
214     *
215     * 1. Reuse the old property id.
216     *
217     * 2. Deprecate all references to the old property, except for the old
218     * getter, which should compute the value from the new property in
219     * later API levels.
220     *
221     * To completely replace a property, see how ClassInstanceCreation replaced
222     * NAME_PROPERTY with TYPE_PROPERTY.
223     */
224
225    /**
226     * Node type constant indicating a node of type
227     * <code>AnonymousClassDeclaration</code>.
228     * @see AnonymousClassDeclaration
229     */
230    public static final int ANONYMOUS_CLASS_DECLARATION = 1;
231
232    /**
233     * Node type constant indicating a node of type
234     * <code>ArrayAccess</code>.
235     * @see ArrayAccess
236     */
237    public static final int ARRAY_ACCESS = 2;
238
239    /**
240     * Node type constant indicating a node of type
241     * <code>ArrayCreation</code>.
242     * @see ArrayCreation
243     */
244    public static final int ARRAY_CREATION = 3;
245
246    /**
247     * Node type constant indicating a node of type
248     * <code>ArrayInitializer</code>.
249     * @see ArrayInitializer
250     */
251    public static final int ARRAY_INITIALIZER = 4;
252
253    /**
254     * Node type constant indicating a node of type
255     * <code>ArrayType</code>.
256     * @see ArrayType
257     */
258    public static final int ARRAY_TYPE = 5;
259
260    /**
261     * Node type constant indicating a node of type
262     * <code>AssertStatement</code>.
263     * @see AssertStatement
264     */
265    public static final int ASSERT_STATEMENT = 6;
266
267    /**
268     * Node type constant indicating a node of type
269     * <code>Assignment</code>.
270     * @see Assignment
271     */
272    public static final int ASSIGNMENT = 7;
273
274    /**
275     * Node type constant indicating a node of type
276     * <code>Block</code>.
277     * @see Block
278     */
279    public static final int BLOCK = 8;
280
281    /**
282     * Node type constant indicating a node of type
283     * <code>BooleanLiteral</code>.
284     * @see BooleanLiteral
285     */
286    public static final int BOOLEAN_LITERAL = 9;
287
288    /**
289     * Node type constant indicating a node of type
290     * <code>BreakStatement</code>.
291     * @see BreakStatement
292     */
293    public static final int BREAK_STATEMENT = 10;
294
295    /**
296     * Node type constant indicating a node of type
297     * <code>CastExpression</code>.
298     * @see CastExpression
299     */
300    public static final int CAST_EXPRESSION = 11;
301
302    /**
303     * Node type constant indicating a node of type
304     * <code>CatchClause</code>.
305     * @see CatchClause
306     */
307    public static final int CATCH_CLAUSE = 12;
308
309    /**
310     * Node type constant indicating a node of type
311     * <code>CharacterLiteral</code>.
312     * @see CharacterLiteral
313     */
314    public static final int CHARACTER_LITERAL = 13;
315
316    /**
317     * Node type constant indicating a node of type
318     * <code>ClassInstanceCreation</code>.
319     * @see ClassInstanceCreation
320     */
321    public static final int CLASS_INSTANCE_CREATION = 14;
322
323    /**
324     * Node type constant indicating a node of type
325     * <code>CompilationUnit</code>.
326     * @see CompilationUnit
327     */
328    public static final int COMPILATION_UNIT = 15;
329
330    /**
331     * Node type constant indicating a node of type
332     * <code>ConditionalExpression</code>.
333     * @see ConditionalExpression
334     */
335    public static final int CONDITIONAL_EXPRESSION = 16;
336
337    /**
338     * Node type constant indicating a node of type
339     * <code>ConstructorInvocation</code>.
340     * @see ConstructorInvocation
341     */
342    public static final int CONSTRUCTOR_INVOCATION = 17;
343
344    /**
345     * Node type constant indicating a node of type
346     * <code>ContinueStatement</code>.
347     * @see ContinueStatement
348     */
349    public static final int CONTINUE_STATEMENT = 18;
350
351    /**
352     * Node type constant indicating a node of type
353     * <code>DoStatement</code>.
354     * @see DoStatement
355     */
356    public static final int DO_STATEMENT = 19;
357
358    /**
359     * Node type constant indicating a node of type
360     * <code>EmptyStatement</code>.
361     * @see EmptyStatement
362     */
363    public static final int EMPTY_STATEMENT = 20;
364
365    /**
366     * Node type constant indicating a node of type
367     * <code>ExpressionStatement</code>.
368     * @see ExpressionStatement
369     */
370    public static final int EXPRESSION_STATEMENT = 21;
371
372    /**
373     * Node type constant indicating a node of type
374     * <code>FieldAccess</code>.
375     * @see FieldAccess
376     */
377    public static final int FIELD_ACCESS = 22;
378
379    /**
380     * Node type constant indicating a node of type
381     * <code>FieldDeclaration</code>.
382     * @see FieldDeclaration
383     */
384    public static final int FIELD_DECLARATION = 23;
385
386    /**
387     * Node type constant indicating a node of type
388     * <code>ForStatement</code>.
389     * @see ForStatement
390     */
391    public static final int FOR_STATEMENT = 24;
392
393    /**
394     * Node type constant indicating a node of type
395     * <code>IfStatement</code>.
396     * @see IfStatement
397     */
398    public static final int IF_STATEMENT = 25;
399
400    /**
401     * Node type constant indicating a node of type
402     * <code>ImportDeclaration</code>.
403     * @see ImportDeclaration
404     */
405    public static final int IMPORT_DECLARATION = 26;
406
407    /**
408     * Node type constant indicating a node of type
409     * <code>InfixExpression</code>.
410     * @see InfixExpression
411     */
412    public static final int INFIX_EXPRESSION = 27;
413
414    /**
415     * Node type constant indicating a node of type
416     * <code>Initializer</code>.
417     * @see Initializer
418     */
419    public static final int INITIALIZER = 28;
420
421    /**
422     * Node type constant indicating a node of type
423     * <code>Javadoc</code>.
424     * @see Javadoc
425     */
426    public static final int JAVADOC = 29;
427
428    /**
429     * Node type constant indicating a node of type
430     * <code>LabeledStatement</code>.
431     * @see LabeledStatement
432     */
433    public static final int LABELED_STATEMENT = 30;
434
435    /**
436     * Node type constant indicating a node of type
437     * <code>MethodDeclaration</code>.
438     * @see MethodDeclaration
439     */
440    public static final int METHOD_DECLARATION = 31;
441
442    /**
443     * Node type constant indicating a node of type
444     * <code>MethodInvocation</code>.
445     * @see MethodInvocation
446     */
447    public static final int METHOD_INVOCATION = 32;
448
449    /**
450     * Node type constant indicating a node of type
451     * <code>NullLiteral</code>.
452     * @see NullLiteral
453     */
454    public static final int NULL_LITERAL = 33;
455
456    /**
457     * Node type constant indicating a node of type
458     * <code>NumberLiteral</code>.
459     * @see NumberLiteral
460     */
461    public static final int NUMBER_LITERAL = 34;
462
463    /**
464     * Node type constant indicating a node of type
465     * <code>PackageDeclaration</code>.
466     * @see PackageDeclaration
467     */
468    public static final int PACKAGE_DECLARATION = 35;
469
470    /**
471     * Node type constant indicating a node of type
472     * <code>ParenthesizedExpression</code>.
473     * @see ParenthesizedExpression
474     */
475    public static final int PARENTHESIZED_EXPRESSION = 36;
476
477    /**
478     * Node type constant indicating a node of type
479     * <code>PostfixExpression</code>.
480     * @see PostfixExpression
481     */
482    public static final int POSTFIX_EXPRESSION = 37;
483
484    /**
485     * Node type constant indicating a node of type
486     * <code>PrefixExpression</code>.
487     * @see PrefixExpression
488     */
489    public static final int PREFIX_EXPRESSION = 38;
490
491    /**
492     * Node type constant indicating a node of type
493     * <code>PrimitiveType</code>.
494     * @see PrimitiveType
495     */
496    public static final int PRIMITIVE_TYPE = 39;
497
498    /**
499     * Node type constant indicating a node of type
500     * <code>QualifiedName</code>.
501     * @see QualifiedName
502     */
503    public static final int QUALIFIED_NAME = 40;
504
505    /**
506     * Node type constant indicating a node of type
507     * <code>ReturnStatement</code>.
508     * @see ReturnStatement
509     */
510    public static final int RETURN_STATEMENT = 41;
511
512    /**
513     * Node type constant indicating a node of type
514     * <code>SimpleName</code>.
515     * @see SimpleName
516     */
517    public static final int SIMPLE_NAME = 42;
518
519    /**
520     * Node type constant indicating a node of type
521     * <code>SimpleType</code>.
522     * @see SimpleType
523     */
524    public static final int SIMPLE_TYPE = 43;
525
526    /**
527     * Node type constant indicating a node of type
528     * <code>SingleVariableDeclaration</code>.
529     * @see SingleVariableDeclaration
530     */
531    public static final int SINGLE_VARIABLE_DECLARATION = 44;
532
533    /**
534     * Node type constant indicating a node of type
535     * <code>StringLiteral</code>.
536     * @see StringLiteral
537     */
538    public static final int STRING_LITERAL = 45;
539
540    /**
541     * Node type constant indicating a node of type
542     * <code>SuperConstructorInvocation</code>.
543     * @see SuperConstructorInvocation
544     */
545    public static final int SUPER_CONSTRUCTOR_INVOCATION = 46;
546
547    /**
548     * Node type constant indicating a node of type
549     * <code>SuperFieldAccess</code>.
550     * @see SuperFieldAccess
551     */
552    public static final int SUPER_FIELD_ACCESS = 47;
553
554    /**
555     * Node type constant indicating a node of type
556     * <code>SuperMethodInvocation</code>.
557     * @see SuperMethodInvocation
558     */
559    public static final int SUPER_METHOD_INVOCATION = 48;
560
561    /**
562     * Node type constant indicating a node of type
563     * <code>SwitchCase</code>.
564     * @see SwitchCase
565     */
566    public static final int SWITCH_CASE = 49;
567
568    /**
569     * Node type constant indicating a node of type
570     * <code>SwitchStatement</code>.
571     * @see SwitchStatement
572     */
573    public static final int SWITCH_STATEMENT = 50;
574
575    /**
576     * Node type constant indicating a node of type
577     * <code>SynchronizedStatement</code>.
578     * @see SynchronizedStatement
579     */
580    public static final int SYNCHRONIZED_STATEMENT = 51;
581
582    /**
583     * Node type constant indicating a node of type
584     * <code>ThisExpression</code>.
585     * @see ThisExpression
586     */
587    public static final int THIS_EXPRESSION = 52;
588
589    /**
590     * Node type constant indicating a node of type
591     * <code>ThrowStatement</code>.
592     * @see ThrowStatement
593     */
594    public static final int THROW_STATEMENT = 53;
595
596    /**
597     * Node type constant indicating a node of type
598     * <code>TryStatement</code>.
599     * @see TryStatement
600     */
601    public static final int TRY_STATEMENT = 54;
602
603    /**
604     * Node type constant indicating a node of type
605     * <code>TypeDeclaration</code>.
606     * @see TypeDeclaration
607     */
608    public static final int TYPE_DECLARATION = 55;
609
610    /**
611     * Node type constant indicating a node of type
612     * <code>TypeDeclarationStatement</code>.
613     * @see TypeDeclarationStatement
614     */
615    public static final int TYPE_DECLARATION_STATEMENT = 56;
616
617    /**
618     * Node type constant indicating a node of type
619     * <code>TypeLiteral</code>.
620     * @see TypeLiteral
621     */
622    public static final int TYPE_LITERAL = 57;
623
624    /**
625     * Node type constant indicating a node of type
626     * <code>VariableDeclarationExpression</code>.
627     * @see VariableDeclarationExpression
628     */
629    public static final int VARIABLE_DECLARATION_EXPRESSION = 58;
630
631    /**
632     * Node type constant indicating a node of type
633     * <code>VariableDeclarationFragment</code>.
634     * @see VariableDeclarationFragment
635     */
636    public static final int VARIABLE_DECLARATION_FRAGMENT = 59;
637
638    /**
639     * Node type constant indicating a node of type
640     * <code>VariableDeclarationStatement</code>.
641     * @see VariableDeclarationStatement
642     */
643    public static final int VARIABLE_DECLARATION_STATEMENT = 60;
644
645    /**
646     * Node type constant indicating a node of type
647     * <code>WhileStatement</code>.
648     * @see WhileStatement
649     */
650    public static final int WHILE_STATEMENT = 61;
651
652    /**
653     * Node type constant indicating a node of type
654     * <code>InstanceofExpression</code>.
655     * @see InstanceofExpression
656     */
657    public static final int INSTANCEOF_EXPRESSION = 62;
658
659    /**
660     * Node type constant indicating a node of type
661     * <code>LineComment</code>.
662     * @see LineComment
663     * @since 3.0
664     */
665    public static final int LINE_COMMENT = 63;
666
667    /**
668     * Node type constant indicating a node of type
669     * <code>BlockComment</code>.
670     * @see BlockComment
671     * @since 3.0
672     */
673    public static final int BLOCK_COMMENT = 64;
674
675    /**
676     * Node type constant indicating a node of type
677     * <code>TagElement</code>.
678     * @see TagElement
679     * @since 3.0
680     */
681    public static final int TAG_ELEMENT = 65;
682
683    /**
684     * Node type constant indicating a node of type
685     * <code>TextElement</code>.
686     * @see TextElement
687     * @since 3.0
688     */
689    public static final int TEXT_ELEMENT = 66;
690
691    /**
692     * Node type constant indicating a node of type
693     * <code>MemberRef</code>.
694     * @see MemberRef
695     * @since 3.0
696     */
697    public static final int MEMBER_REF = 67;
698
699    /**
700     * Node type constant indicating a node of type
701     * <code>MethodRef</code>.
702     * @see MethodRef
703     * @since 3.0
704     */
705    public static final int METHOD_REF = 68;
706
707    /**
708     * Node type constant indicating a node of type
709     * <code>MethodRefParameter</code>.
710     * @see MethodRefParameter
711     * @since 3.0
712     */
713    public static final int METHOD_REF_PARAMETER = 69;
714
715    /**
716     * Node type constant indicating a node of type
717     * <code>EnhancedForStatement</code>.
718     * @see EnhancedForStatement
719     * @since 3.1
720     */
721    public static final int ENHANCED_FOR_STATEMENT = 70;
722
723    /**
724     * Node type constant indicating a node of type
725     * <code>EnumDeclaration</code>.
726     * @see EnumDeclaration
727     * @since 3.1
728     */
729    public static final int ENUM_DECLARATION = 71;
730
731    /**
732     * Node type constant indicating a node of type
733     * <code>EnumConstantDeclaration</code>.
734     * @see EnumConstantDeclaration
735     * @since 3.1
736     */
737    public static final int ENUM_CONSTANT_DECLARATION = 72;
738
739    /**
740     * Node type constant indicating a node of type
741     * <code>TypeParameter</code>.
742     * @see TypeParameter
743     * @since 3.1
744     */
745    public static final int TYPE_PARAMETER = 73;
746
747    /**
748     * Node type constant indicating a node of type
749     * <code>ParameterizedType</code>.
750     * @see ParameterizedType
751     * @since 3.1
752     */
753    public static final int PARAMETERIZED_TYPE = 74;
754
755    /**
756     * Node type constant indicating a node of type
757     * <code>QualifiedType</code>.
758     * @see QualifiedType
759     * @since 3.1
760     */
761    public static final int QUALIFIED_TYPE = 75;
762
763    /**
764     * Node type constant indicating a node of type
765     * <code>WildcardType</code>.
766     * @see WildcardType
767     * @since 3.1
768     */
769    public static final int WILDCARD_TYPE = 76;
770
771    /**
772     * Node type constant indicating a node of type
773     * <code>NormalAnnotation</code>.
774     * @see NormalAnnotation
775     * @since 3.1
776     */
777    public static final int NORMAL_ANNOTATION = 77;
778
779    /**
780     * Node type constant indicating a node of type
781     * <code>MarkerAnnotation</code>.
782     * @see MarkerAnnotation
783     * @since 3.1
784     */
785    public static final int MARKER_ANNOTATION = 78;
786
787    /**
788     * Node type constant indicating a node of type
789     * <code>SingleMemberAnnotation</code>.
790     * @see SingleMemberAnnotation
791     * @since 3.1
792     */
793    public static final int SINGLE_MEMBER_ANNOTATION = 79;
794
795    /**
796     * Node type constant indicating a node of type
797     * <code>MemberValuePair</code>.
798     * @see MemberValuePair
799     * @since 3.1
800     */
801    public static final int MEMBER_VALUE_PAIR = 80;
802
803    /**
804     * Node type constant indicating a node of type
805     * <code>AnnotationTypeDeclaration</code>.
806     * @see AnnotationTypeDeclaration
807     * @since 3.1
808     */
809    public static final int ANNOTATION_TYPE_DECLARATION = 81;
810
811    /**
812     * Node type constant indicating a node of type
813     * <code>AnnotationTypeMemberDeclaration</code>.
814     * @see AnnotationTypeMemberDeclaration
815     * @since 3.1
816     */
817    public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
818
819    /**
820     * Node type constant indicating a node of type
821     * <code>Modifier</code>.
822     * @see Modifier
823     * @since 3.1
824     */
825    public static final int MODIFIER = 83;
826
827    /**
828     * Node type constant indicating a node of type
829     * <code>UnionType</code>.
830     * @see UnionType
831     * @since 3.7.1
832     */
833    public static final int UNION_TYPE = 84;
834
835    /**
836     * Node type constant indicating a node of type
837     * <code>Dimension</code>.
838     *
839     * @see Dimension
840     * @since 3.10
841     */
842    public static final int DIMENSION = 85;
843
844    /**
845     * Node type constant indicating a node of type
846     * <code>LambdaExpression</code>.
847     * @see LambdaExpression
848     * @since 3.10
849     */
850    public static final int LAMBDA_EXPRESSION = 86;
851
852    /**
853     * Node type constant indicating a node of type
854     * <code>IntersectionType</code>.
855     *
856     * @see IntersectionType
857     * @since 3.10
858     */
859    public static final int INTERSECTION_TYPE = 87;
860
861    /**
862     * Node type constant indicating a node of type
863     * <code>NameQualifiedType</code>.
864     * @see NameQualifiedType
865     * @since 3.10
866     */
867    public static final int NAME_QUALIFIED_TYPE = 88;
868
869    /**
870     * Node type constant indicating a node of type
871     * <code>CreationReference</code>.
872     * @see CreationReference
873     * @since 3.10
874     */
875    public static final int CREATION_REFERENCE = 89;
876
877    /**
878     * Node type constant indicating a node of type
879     * <code>ExpressionMethodReference</code>.
880     * @see ExpressionMethodReference
881     * @since 3.10
882     */
883    public static final int EXPRESSION_METHOD_REFERENCE = 90;
884
885    /**
886     * Node type constant indicating a node of type
887     * <code>SuperMethhodReference</code>.
888     * @see SuperMethodReference
889     * @since 3.10
890     */
891    public static final int SUPER_METHOD_REFERENCE = 91;
892
893    /**
894     * Node type constant indicating a node of type
895     * <code>TypeMethodReference</code>.
896     * @see TypeMethodReference
897     * @since 3.10
898     */
899    public static final int TYPE_METHOD_REFERENCE = 92;
900
901    /**
902     * Node type constant indicating a node of type
903     * <code>ModuleDeclaration</code>.
904     * @see ModuleDeclaration
905     * @since 3.14
906     */
907    public static final int MODULE_DECLARATION = 93;
908
909    /**
910     * Node type constant indicating a node of type
911     * <code>RequiresDirective</code>.
912     * @see RequiresDirective
913     * @since 3.14
914     */
915    public static final int REQUIRES_DIRECTIVE = 94;
916
917    /**
918     * Node type constant indicating a node of type
919     * <code>ExportsDirective</code>.
920     * @see ExportsDirective
921     * @since 3.14
922     */
923    public static final int EXPORTS_DIRECTIVE = 95;
924
925    /**
926     * Node type constant indicating a node of type
927     * <code>OpensDirective</code>.
928     * @see OpensDirective
929     * @since 3.14
930     */
931    public static final int OPENS_DIRECTIVE = 96;
932
933    /**
934     * Node type constant indicating a node of type
935     * <code>UsesDirective</code>.
936     * @see UsesDirective
937     * @since 3.14
938     */
939    public static final int USES_DIRECTIVE = 97;
940
941    /**
942     * Node type constant indicating a node of type
943     * <code>ProvidesDirective</code>.
944     * @see ProvidesDirective
945     * @since 3.14
946     */
947    public static final int PROVIDES_DIRECTIVE = 98;
948
949    /**
950     * Node type constant indicating a node of type
951     * <code>ModuleModifier</code>.
952     * @see ModuleModifier
953     * @since 3.14
954     */
955    public static final int MODULE_MODIFIER = 99;
956
957    /**
958     * Node type constant indicating a node of type
959     * <code>SwitchExpression</code>.
960     * @see SwitchExpression
961     * @since 3.18
962     */
963    public static final int SWITCH_EXPRESSION = 100;
964
965    /**
966     * Node type constant indicating a node of type
967     * <code>YieldStatement</code>.
968     * @see YieldStatement
969     * @since 3.20
970     */
971    public static final int YIELD_STATEMENT = 101;
972
973    /**
974     * Node type constant indicating a node of type
975     * <code>TextBlock</code>.
976     * @see TextBlock
977     * @since 3.20
978     */
979    public static final int TEXT_BLOCK = 102;
980
981    /**
982     * Node type constant indicating a node of type
983     * <code>RecordDeclaration</code>.
984     * @see RecordDeclaration
985     * @since 3.22
986     */
987    public static final int RECORD_DECLARATION = 103;
988
989    /**
990     * Node type constant indicating a node of type
991     * <code>PatternInstanceofExpression</code>.
992     * @see PatternInstanceofExpression
993     * @since 3.26
994     */
995    public static final int PATTERN_INSTANCEOF_EXPRESSION = 104;
996
997    /**
998     * Node type constant indicating a node of type
999     * <code>ModuleQualifiedName</code>.
1000     * @see ModuleQualifiedName
1001     * @since 3.24
1002     */
1003    public static final int MODULE_QUALIFIED_NAME = 105;
1004
1005
1006    /**
1007     * Node type constant indicating a node of type
1008     * <code>TypePattern</code>.
1009     * @see TypePattern
1010     * @since 3.28
1011     */
1012    public static final int TYPE_PATTERN = 106;
1013
1014    /**
1015     * Node type constant indicating a node of type
1016     * <code>GuardedPattern</code>.
1017     * @see GuardedPattern
1018     * @since 3.28
1019     */
1020    public static final int GUARDED_PATTERN = 107;
1021
1022    /**
1023     * Node type constant indicating a node of type
1024     * <code>NullPattern</code>.
1025     * @see NullPattern
1026     * @since 3.28
1027     */
1028    public static final int NULL_PATTERN = 108;
1029
1030    /**
1031     * Node type constant indicating a node of type
1032     * <code>CaseDefaultExpression</code>.
1033     * @see CaseDefaultExpression
1034     * @since 3.28
1035     */
1036    public static final int CASE_DEFAULT_EXPRESSION = 109;
1037
1038    /**
1039     * Node type constant indicating a node of type
1040     * <code>TagProperty</code>.
1041     * @see TagProperty
1042     * @since 3.30
1043     */
1044    public static final int TAG_PROPERTY = 110;
1045
1046    /**
1047     * Node type constant indicating a node of type
1048     * <code>JavaDocRegion</code>.
1049     * @see JavaDocRegion
1050     * @since 3.30
1051     */
1052    public static final int JAVADOC_REGION = 111;
1053
1054
1055    /**
1056     * Returns the node class for the corresponding node type.
1057     *
1058     * @param nodeType AST node type
1059     * @return the corresponding <code>ASTNode</code> subclass
1060     * @exception IllegalArgumentException if <code>nodeType</code> is
1061     * not a legal AST node type
1062     * @see #getNodeType()
1063     * @since 3.0
1064     */
1065    public static Class nodeClassForType(int nodeType) {
1066        switch (nodeType) {
1067            case ANNOTATION_TYPE_DECLARATION :
1068                return AnnotationTypeDeclaration.class;
1069            case ANNOTATION_TYPE_MEMBER_DECLARATION :
1070                return AnnotationTypeMemberDeclaration.class;
1071            case ANONYMOUS_CLASS_DECLARATION :
1072                return AnonymousClassDeclaration.class;
1073            case ARRAY_ACCESS :
1074                return ArrayAccess.class;
1075            case ARRAY_CREATION :
1076                return ArrayCreation.class;
1077            case ARRAY_INITIALIZER :
1078                return ArrayInitializer.class;
1079            case ARRAY_TYPE :
1080                return ArrayType.class;
1081            case ASSERT_STATEMENT :
1082                return AssertStatement.class;
1083            case ASSIGNMENT :
1084                return Assignment.class;
1085            case BLOCK :
1086                return Block.class;
1087            case BLOCK_COMMENT :
1088                return BlockComment.class;
1089            case BOOLEAN_LITERAL :
1090                return BooleanLiteral.class;
1091            case BREAK_STATEMENT :
1092                return BreakStatement.class;
1093            case CASE_DEFAULT_EXPRESSION :
1094                return CaseDefaultExpression.class;
1095            case CAST_EXPRESSION :
1096                return CastExpression.class;
1097            case CATCH_CLAUSE :
1098                return CatchClause.class;
1099            case CHARACTER_LITERAL :
1100                return CharacterLiteral.class;
1101            case CLASS_INSTANCE_CREATION :
1102                return ClassInstanceCreation.class;
1103            case COMPILATION_UNIT :
1104                return CompilationUnit.class;
1105            case CONDITIONAL_EXPRESSION :
1106                return ConditionalExpression.class;
1107            case CONSTRUCTOR_INVOCATION :
1108                return ConstructorInvocation.class;
1109            case CONTINUE_STATEMENT :
1110                return ContinueStatement.class;
1111            case CREATION_REFERENCE :
1112                return CreationReference.class;
1113            case DIMENSION:
1114                return Dimension.class;
1115            case DO_STATEMENT :
1116                return DoStatement.class;
1117            case EMPTY_STATEMENT :
1118                return EmptyStatement.class;
1119            case ENHANCED_FOR_STATEMENT :
1120                return EnhancedForStatement.class;
1121            case ENUM_CONSTANT_DECLARATION :
1122                return EnumConstantDeclaration.class;
1123            case ENUM_DECLARATION :
1124                return EnumDeclaration.class;
1125            case EXPORTS_DIRECTIVE :
1126                return ExportsDirective.class;
1127            case EXPRESSION_METHOD_REFERENCE :
1128                return ExpressionMethodReference.class;
1129            case EXPRESSION_STATEMENT :
1130                return ExpressionStatement.class;
1131            case FIELD_ACCESS :
1132                return FieldAccess.class;
1133            case FIELD_DECLARATION :
1134                return FieldDeclaration.class;
1135            case FOR_STATEMENT :
1136                return ForStatement.class;
1137            case GUARDED_PATTERN :
1138                return GuardedPattern.class;
1139            case IF_STATEMENT :
1140                return IfStatement.class;
1141            case IMPORT_DECLARATION :
1142                return ImportDeclaration.class;
1143            case INFIX_EXPRESSION :
1144                return InfixExpression.class;
1145            case INITIALIZER :
1146                return Initializer.class;
1147            case INSTANCEOF_EXPRESSION :
1148                return InstanceofExpression.class;
1149            case INTERSECTION_TYPE:
1150                return IntersectionType.class;
1151            case JAVADOC :
1152                return Javadoc.class;
1153            case JAVADOC_REGION :
1154                return JavaDocRegion.class;
1155            case LABELED_STATEMENT :
1156                return LabeledStatement.class;
1157            case LAMBDA_EXPRESSION :
1158                return LambdaExpression.class;
1159            case LINE_COMMENT :
1160                return LineComment.class;
1161            case MARKER_ANNOTATION :
1162                return MarkerAnnotation.class;
1163            case MEMBER_REF :
1164                return MemberRef.class;
1165            case MEMBER_VALUE_PAIR :
1166                return MemberValuePair.class;
1167            case METHOD_DECLARATION :
1168                return MethodDeclaration.class;
1169            case METHOD_INVOCATION :
1170                return MethodInvocation.class;
1171            case METHOD_REF :
1172                return MethodRef.class;
1173            case METHOD_REF_PARAMETER :
1174                return MethodRefParameter.class;
1175            case MODIFIER :
1176                return Modifier.class;
1177            case MODULE_DECLARATION :
1178                return ModuleDeclaration.class;
1179            case MODULE_MODIFIER :
1180                return ModuleModifier.class;
1181            case MODULE_QUALIFIED_NAME :
1182                return ModuleQualifiedName.class;
1183            case NAME_QUALIFIED_TYPE :
1184                return NameQualifiedType.class;
1185            case NORMAL_ANNOTATION :
1186                return NormalAnnotation.class;
1187            case NULL_LITERAL :
1188                return NullLiteral.class;
1189            case NULL_PATTERN :
1190                return NullPattern.class;
1191            case NUMBER_LITERAL :
1192                return NumberLiteral.class;
1193            case OPENS_DIRECTIVE :
1194                return OpensDirective.class;
1195            case PACKAGE_DECLARATION :
1196                return PackageDeclaration.class;
1197            case PARAMETERIZED_TYPE :
1198                return ParameterizedType.class;
1199            case PARENTHESIZED_EXPRESSION :
1200                return ParenthesizedExpression.class;
1201            case PATTERN_INSTANCEOF_EXPRESSION :
1202                return PatternInstanceofExpression.class;
1203            case POSTFIX_EXPRESSION :
1204                return PostfixExpression.class;
1205            case PREFIX_EXPRESSION :
1206                return PrefixExpression.class;
1207            case PRIMITIVE_TYPE :
1208                return PrimitiveType.class;
1209            case PROVIDES_DIRECTIVE :
1210                return ProvidesDirective.class;
1211            case QUALIFIED_NAME :
1212                return QualifiedName.class;
1213            case QUALIFIED_TYPE :
1214                return QualifiedType.class;
1215            case RECORD_DECLARATION :
1216                return RecordDeclaration.class;
1217            case REQUIRES_DIRECTIVE :
1218                return RequiresDirective.class;
1219            case RETURN_STATEMENT :
1220                return ReturnStatement.class;
1221            case SIMPLE_NAME :
1222                return SimpleName.class;
1223            case SIMPLE_TYPE :
1224                return SimpleType.class;
1225            case SINGLE_MEMBER_ANNOTATION :
1226                return SingleMemberAnnotation.class;
1227            case SINGLE_VARIABLE_DECLARATION :
1228                return SingleVariableDeclaration.class;
1229            case STRING_LITERAL :
1230                return StringLiteral.class;
1231            case SUPER_CONSTRUCTOR_INVOCATION :
1232                return SuperConstructorInvocation.class;
1233            case SUPER_FIELD_ACCESS :
1234                return SuperFieldAccess.class;
1235            case SUPER_METHOD_INVOCATION :
1236                return SuperMethodInvocation.class;
1237            case SUPER_METHOD_REFERENCE :
1238                return SuperMethodReference.class;
1239            case SWITCH_CASE:
1240                return SwitchCase.class;
1241            case SWITCH_STATEMENT :
1242                return SwitchStatement.class;
1243            case SWITCH_EXPRESSION :
1244                return SwitchExpression.class;
1245            case SYNCHRONIZED_STATEMENT :
1246                return SynchronizedStatement.class;
1247            case TAG_ELEMENT :
1248                return TagElement.class;
1249            case TAG_PROPERTY :
1250                return TagProperty.class;
1251            case TEXT_BLOCK :
1252                return TextBlock.class;
1253            case TEXT_ELEMENT :
1254                return TextElement.class;
1255            case THIS_EXPRESSION :
1256                return ThisExpression.class;
1257            case THROW_STATEMENT :
1258                return ThrowStatement.class;
1259            case TRY_STATEMENT :
1260                return TryStatement.class;
1261            case TYPE_DECLARATION :
1262                return TypeDeclaration.class;
1263            case TYPE_DECLARATION_STATEMENT :
1264                return TypeDeclarationStatement.class;
1265            case TYPE_METHOD_REFERENCE :
1266                return TypeMethodReference.class;
1267            case TYPE_LITERAL :
1268                return TypeLiteral.class;
1269            case TYPE_PARAMETER :
1270                return TypeParameter.class;
1271            case TYPE_PATTERN :
1272                return TypePattern.class;
1273            case UNION_TYPE :
1274                return UnionType.class;
1275            case USES_DIRECTIVE :
1276                return UsesDirective.class;
1277            case VARIABLE_DECLARATION_EXPRESSION :
1278                return VariableDeclarationExpression.class;
1279            case VARIABLE_DECLARATION_FRAGMENT :
1280                return VariableDeclarationFragment.class;
1281            case VARIABLE_DECLARATION_STATEMENT :
1282                return VariableDeclarationStatement.class;
1283            case WHILE_STATEMENT :
1284                return WhileStatement.class;
1285            case WILDCARD_TYPE :
1286                return WildcardType.class;
1287            case YIELD_STATEMENT :
1288                return YieldStatement.class;
1289        }
1290        throw new IllegalArgumentException();
1291    }
1292
1293    /**
1294     * Owning AST.
1295     * <p>
1296     * N.B. This is a private field, but declared as package-visible
1297     * for more efficient access from inner classes.
1298     * </p>
1299     */
1300    final AST ast;
1301
1302    /**
1303     * Parent AST node, or <code>null</code> if this node is a root.
1304     * Initially <code>null</code>.
1305     */
1306    private ASTNode parent = null;
1307
1308    /**
1309     * An unmodifiable empty map (used to implement <code>properties()</code>).
1310     */
1311    private static final Map UNMODIFIABLE_EMPTY_MAP
1312        = Collections.unmodifiableMap(new HashMap(1));
1313
1314    /**
1315     * Primary field used in representing node properties efficiently.
1316     * If <code>null</code>, this node has no properties.
1317     * If a {@link String}, this is the name of this node's sole property,
1318     * and <code>property2</code> contains its value.
1319     * If a {@link Map}, this is the table of property name-value
1320     * mappings; <code>property2</code>, if non-null is its unmodifiable
1321     * equivalent.
1322     * Initially <code>null</code>.
1323     *
1324     * @see #property2
1325     */
1326    private Object property1 = null;
1327
1328    /**
1329     * Auxiliary field used in representing node properties efficiently.
1330     *
1331     * @see #property1
1332     */
1333    private Object property2 = null;
1334
1335    /**
1336     * A character index into the original source string,
1337     * or <code>-1</code> if no source position information is available
1338     * for this node; <code>-1</code> by default.
1339     */
1340    private int startPosition = -1;
1341
1342    /**
1343     * A character length, or <code>0</code> if no source position
1344     * information is recorded for this node; <code>0</code> by default.
1345     */
1346    private int length = 0;
1347
1348    /**
1349     * Flag constant (bit mask, value 1) indicating that there is something
1350     * not quite right with this AST node.
1351     * <p>
1352     * The standard parser (<code>ASTParser</code>) sets this
1353     * flag on a node to indicate a syntax error detected in the vicinity.
1354     * </p>
1355     */
1356    public static final int MALFORMED = 1;
1357
1358    /**
1359     * Flag constant (bit mask, value 2) indicating that this is a node
1360     * that was created by the parser (as opposed to one created by another
1361     * party).
1362     * <p>
1363     * The standard parser (<code>ASTParser</code>) sets this
1364     * flag on the nodes it creates.
1365     * </p>
1366     * @since 3.0
1367     */
1368    public static final int ORIGINAL = 2;
1369
1370    /**
1371     * Flag constant (bit mask, value 4) indicating that this node
1372     * is unmodifiable. When a node is marked unmodifiable, the
1373     * following operations result in a runtime exception:
1374     * <ul>
1375     * <li>Change a simple property of this node.</li>
1376     * <li>Add or remove a child node from this node.</li>
1377     * <li>Parent (or reparent) this node.</li>
1378     * </ul>
1379     * <p>
1380     * The standard parser (<code>ASTParser</code>) does not set
1381     * this flag on the nodes it creates. However, clients may set
1382     * this flag on a node to prevent further modification of the
1383     * its structural properties.
1384     * </p>
1385     * @since 3.0
1386     */
1387    public static final int PROTECT = 4;
1388
1389    /**
1390     * Flag constant (bit mask, value 8) indicating that this node
1391     * or a part of this node is recovered from source that contains
1392     * a syntax error detected in the vicinity.
1393     * <p>
1394     * The standard parser (<code>ASTParser</code>) sets this
1395     * flag on a node to indicate a recovered node.
1396     * </p>
1397     * @since 3.2
1398     */
1399    public static final int RECOVERED = 8;
1400
1401    /**
1402     * int containing the node type in the top 16 bits and
1403     * flags in the bottom 16 bits; none set by default.
1404     * <p>
1405     * N.B. This is a private field, but declared as package-visible
1406     * for more efficient access from inner classes.
1407     * </p>
1408     *
1409     * @see #MALFORMED
1410     */
1411    int typeAndFlags = 0;
1412
1413    /**
1414     * Property of parent in which this node is a child, or <code>null</code>
1415     * if this node is a root. Initially <code>null</code>.
1416     *
1417     * @see #getLocationInParent
1418     * @since 3.0
1419     */
1420    private StructuralPropertyDescriptor location = null;
1421
1422    /** Internal convenience constant indicating that there is definite risk of cycles.
1423     * @see ChildPropertyDescriptor#cycleRisk()
1424     * @see ChildListPropertyDescriptor#cycleRisk()
1425     * @since 3.0
1426     */
1427    static final boolean CYCLE_RISK = true;
1428
1429    /** Internal convenience constant indicating that there is no risk of cycles.
1430     * @see ChildPropertyDescriptor#cycleRisk()
1431     * @see ChildListPropertyDescriptor#cycleRisk()
1432     * @since 3.0
1433     */
1434    static final boolean NO_CYCLE_RISK = false;
1435
1436    /** Internal convenience constant indicating that a structural property is mandatory.
1437     * @since 3.0
1438     */
1439    static final boolean MANDATORY = true;
1440
1441    /** Internal convenience constant indicating that a structural property is optional.
1442     * @since 3.0
1443     */
1444    static final boolean OPTIONAL = false;
1445
1446    /**
1447     * A specialized implementation of a list of ASTNodes. The
1448     * implementation is based on an ArrayList.
1449     */
1450    class NodeList extends AbstractList {
1451
1452        /**
1453         * The underlying list in which the nodes of this list are
1454         * stored (element type: {@link ASTNode}).
1455         * <p>
1456         * Be stingy on storage - assume that list will be empty.
1457         * </p>
1458         * <p>
1459         * This field declared default visibility (rather than private)
1460         * so that accesses from <code>NodeList.Cursor</code> do not require
1461         * a synthetic accessor method.
1462         * </p>
1463         */
1464        ArrayList store = new ArrayList(0);
1465
1466        /**
1467         * The property descriptor for this list.
1468         */
1469        ChildListPropertyDescriptor propertyDescriptor;
1470
1471        /**
1472         * A cursor for iterating over the elements of the list.
1473         * Does not lose its position if the list is changed during
1474         * the iteration.
1475         */
1476        class Cursor implements Iterator {
1477            /**
1478             * The position of the cursor between elements. If the value
1479             * is N, then the cursor sits between the element at positions
1480             * N-1 and N. Initially just before the first element of the
1481             * list.
1482             */
1483            private int position = 0;
1484
1485            @Override
1486            public boolean hasNext() {
1487                return this.position < NodeList.this.store.size();
1488            }
1489
1490            @Override
1491            public Object next() {
1492                Object result = NodeList.this.store.get(this.position);
1493                this.position++;
1494                return result;
1495            }
1496
1497            @Override
1498            public void remove() {
1499                throw new UnsupportedOperationException();
1500            }
1501
1502            /**
1503             * Adjusts this cursor to accommodate an add/remove at the given
1504             * index.
1505             *
1506             * @param index the position at which the element was added
1507             *    or removed
1508             * @param delta +1 for add, and -1 for remove
1509             */
1510            void update(int indexint delta) {
1511                if (this.position > index) {
1512                    // the cursor has passed the added or removed element
1513                    this.position += delta;
1514                }
1515            }
1516        }
1517
1518        /**
1519         * A list of currently active cursors (element type:
1520         * {@link Cursor}), or <code>null</code> if there are no
1521         * active cursors.
1522         * <p>
1523         * It is important for storage considerations to maintain the
1524         * null-means-empty invariant; otherwise, every NodeList instance
1525         * will waste a lot of space. A cursor is needed only for the duration
1526         * of a visit to the child nodes. Under normal circumstances, only a
1527         * single cursor is needed; multiple cursors are only required if there
1528         * are multiple visits going on at the same time.
1529         * </p>
1530         */
1531        private List cursors = null;
1532
1533        /**
1534         * Creates a new empty list of nodes owned by this node.
1535         * This node will be the common parent of all nodes added to
1536         * this list.
1537         *
1538         * @param property the property descriptor
1539         * @since 3.0
1540         */
1541        NodeList(ChildListPropertyDescriptor property) {
1542            super();
1543            this.propertyDescriptor = property;
1544        }
1545
1546        @Override
1547        public int size() {
1548            return this.store.size();
1549        }
1550
1551        @Override
1552        public Object get(int index) {
1553            return this.store.get(index);
1554        }
1555
1556        @Override
1557        public Object set(int indexObject element) {
1558            if (element == null) {
1559                throw new IllegalArgumentException();
1560            }
1561            if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
1562                // this node is protected => cannot gain or lose children
1563                throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1564            }
1565            // delink old child from parent, and link new child to parent
1566            ASTNode newChild = (ASTNodeelement;
1567            ASTNode oldChild = (ASTNode) this.store.get(index);
1568            if (oldChild == newChild) {
1569                return oldChild;
1570            }
1571            if ((oldChild.typeAndFlags & PROTECT) != 0) {
1572                // old child is protected => cannot be unparented
1573                throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1574            }
1575            ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
1576            ASTNode.this.ast.preReplaceChildEvent(ASTNode.this, oldChildnewChild, this.propertyDescriptor);
1577
1578            Object result = this.store.set(indexnewChild);
1579            // n.b. setParent will call ast.modifying()
1580            oldChild.setParent(nullnull);
1581            newChild.setParent(ASTNode.this, this.propertyDescriptor);
1582            ASTNode.this.ast.postReplaceChildEvent(ASTNode.this, oldChildnewChild, this.propertyDescriptor);
1583            return result;
1584        }
1585
1586        @Override
1587        public void add(int indexObject element) {
1588            if (element == null) {
1589                throw new IllegalArgumentException();
1590            }
1591            if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
1592                // this node is protected => cannot gain or lose children
1593                throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1594            }
1595            // link new child to parent
1596            ASTNode newChild = (ASTNodeelement;
1597            ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
1598            ASTNode.this.ast.preAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
1599
1600
1601            this.store.add(indexelement);
1602            updateCursors(index, +1);
1603            // n.b. setParent will call ast.modifying()
1604            newChild.setParent(ASTNode.this, this.propertyDescriptor);
1605            ASTNode.this.ast.postAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
1606        }
1607
1608        @Override
1609        public Object remove(int index) {
1610            if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
1611                // this node is protected => cannot gain or lose children
1612                throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1613            }
1614            // delink old child from parent
1615            ASTNode oldChild = (ASTNode) this.store.get(index);
1616            if ((oldChild.typeAndFlags & PROTECT) != 0) {
1617                // old child is protected => cannot be unparented
1618                throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1619            }
1620
1621            ASTNode.this.ast.preRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
1622            // n.b. setParent will call ast.modifying()
1623            oldChild.setParent(nullnull);
1624            Object result = this.store.remove(index);
1625            updateCursors(index, -1);
1626            ASTNode.this.ast.postRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
1627            return result;
1628
1629        }
1630
1631        /**
1632         * Allocate a cursor to use for a visit. The client must call
1633         * <code>releaseCursor</code> when done.
1634         * <p>
1635         * This method is internally synchronized on this NodeList.
1636         * It is thread-safe to create a cursor.
1637         * </p>
1638         *
1639         * @return a new cursor positioned before the first element
1640         *    of the list
1641         */
1642        Cursor newCursor() {
1643            synchronized (this) {
1644                // serialize cursor management on this NodeList
1645                if (this.cursors == null) {
1646                    // convert null to empty list
1647                    this.cursors = new ArrayList(1);
1648                }
1649                Cursor result = new Cursor();
1650                this.cursors.add(result);
1651                return result;
1652            }
1653        }
1654
1655        /**
1656         * Releases the given cursor at the end of a visit.
1657         * <p>
1658         * This method is internally synchronized on this NodeList.
1659         * It is thread-safe to release a cursor.
1660         * </p>
1661         *
1662         * @param cursor the cursor
1663         */
1664        void releaseCursor(Cursor cursor) {
1665            synchronized (this) {
1666                // serialize cursor management on this NodeList
1667                this.cursors.remove(cursor);
1668                if (this.cursors.isEmpty()) {
1669                    // important: convert empty list back to null
1670                    // otherwise the node will hang on to needless junk
1671                    this.cursors = null;
1672                }
1673            }
1674        }
1675
1676        /**
1677         * Adjusts all cursors to accommodate an add/remove at the given
1678         * index.
1679         * <p>
1680         * This method is only used when the list is being modified.
1681         * The AST is not thread-safe if any of the clients are modifying it.
1682         * </p>
1683         *
1684         * @param index the position at which the element was added
1685         *    or removed
1686         * @param delta +1 for add, and -1 for remove
1687         */
1688        private synchronized void updateCursors(int indexint delta) {
1689            if (this.cursors == null) {
1690                // there are no cursors to worry about
1691                return;
1692            }
1693            for (Iterator it = this.cursors.iterator(); it.hasNext(); ) {
1694                Cursor c = (Cursorit.next();
1695                c.update(indexdelta);
1696            }
1697        }
1698
1699        /**
1700         * Returns an estimate of the memory footprint of this node list
1701         * instance in bytes.
1702         * <ul>
1703         * <li>1 object header for the NodeList instance</li>
1704         * <li>5 4-byte fields of the NodeList instance</li>
1705         * <li>0 for cursors since null unless walk in progress</li>
1706         * <li>1 object header for the ArrayList instance</li>
1707         * <li>2 4-byte fields of the ArrayList instance</li>
1708         * <li>1 object header for an Object[] instance</li>
1709         * <li>4 bytes in array for each element</li>
1710         * </ul>
1711          *
1712         * @return the size of this node list in bytes
1713         */
1714        int memSize() {
1715            int result = HEADERS + 5 * 4;
1716            result += HEADERS + 2 * 4;
1717            result += HEADERS + 4 * size();
1718            return result;
1719        }
1720
1721        /**
1722         * Returns an estimate of the memory footprint in bytes of this node
1723         * list and all its subtrees.
1724         *
1725         * @return the size of this list of subtrees in bytes
1726         */
1727        int listSize() {
1728            int result = memSize();
1729            for (Iterator it = iterator(); it.hasNext(); ) {
1730                ASTNode child = (ASTNodeit.next();
1731                result += child.treeSize();
1732            }
1733            return result;
1734        }
1735    }
1736
1737    /**
1738     * Creates a new AST node owned by the given AST. Once established,
1739     * the relationship between an AST node and its owning AST does not change
1740     * over the lifetime of the node. The new node has no parent node,
1741     * and no properties.
1742     * <p>
1743     * N.B. This constructor is package-private; all subclasses my be
1744     * declared in the same package; clients are unable to declare
1745     * additional subclasses.
1746     * </p>
1747     *
1748     * @param ast the AST that is to own this node
1749     */
1750    ASTNode(AST ast) {
1751        if (ast == null) {
1752            throw new IllegalArgumentException();
1753        }
1754
1755        this.ast = ast;
1756        setNodeType(getNodeType0());
1757        setFlags(ast.getDefaultNodeFlag());
1758        // setFlags calls modifying();
1759    }
1760
1761    /**
1762     * Returns this node's AST.
1763     * <p>
1764     * Note that the relationship between an AST node and its owing AST does
1765     * not change over the lifetime of a node.
1766     * </p>
1767     *
1768     * @return the AST that owns this node
1769     */
1770    public final AST getAST() {
1771        return this.ast;
1772    }
1773
1774    /**
1775     * Returns this node's parent node, or <code>null</code> if this is the
1776     * root node.
1777     * <p>
1778     * Note that the relationship between an AST node and its parent node
1779     * may change over the lifetime of a node.
1780     * </p>
1781     *
1782     * @return the parent of this node, or <code>null</code> if none
1783     */
1784    public final ASTNode getParent() {
1785        return this.parent;
1786    }
1787
1788    /**
1789     * Returns the location of this node within its parent,
1790     * or <code>null</code> if this is a root node.
1791     * <pre>
1792     * ASTNode node = ...;
1793     * ASTNode parent = node.getParent();
1794     * StructuralPropertyDescriptor location = node.getLocationInParent();
1795     * assert (parent != null) == (location != null);
1796     * if ((location != null) && location.isChildProperty())
1797     *    assert parent.getStructuralProperty(location) == node;
1798     * if ((location != null) && location.isChildListProperty())
1799     *    assert ((List) parent.getStructuralProperty(location)).contains(node);
1800     * </pre>
1801     * <p>
1802     * Note that the relationship between an AST node and its parent node
1803     * may change over the lifetime of a node.
1804     * </p>
1805     *
1806     * @return the location of this node in its parent,
1807     * or <code>null</code> if this node has no parent
1808     * @since 3.0
1809     */
1810    public final StructuralPropertyDescriptor getLocationInParent() {
1811        return this.location;
1812    }
1813
1814    /**
1815     * Returns the root node at or above this node; returns this node if
1816     * it is a root.
1817     *
1818     * @return the root node at or above this node
1819     */
1820    public final ASTNode getRoot() {
1821        ASTNode candidate = this;
1822        while (true) {
1823            ASTNode p = candidate.getParent();
1824            if (p == null) {
1825                // candidate has no parent - that's the guy
1826                return candidate;
1827            }
1828            candidate = p;
1829        }
1830    }
1831
1832    /**
1833     * Returns the value of the given structural property for this node. The value
1834     * returned depends on the kind of property:
1835     * <ul>
1836     * <li>{@link SimplePropertyDescriptor} - the value of the given simple property,
1837     * or <code>null</code> if none; primitive values are "boxed"</li>
1838     * <li>{@link ChildPropertyDescriptor} - the child node (type <code>ASTNode</code>),
1839     * or <code>null</code> if none</li>
1840     * <li>{@link ChildListPropertyDescriptor} - the list (element type: {@link ASTNode})</li>
1841     * </ul>
1842     *
1843     * @param property the property
1844     * @return the value, or <code>null</code> if none
1845     * @exception RuntimeException if this node does not have the given property
1846     * @since 3.0
1847     */
1848    public final Object getStructuralProperty(StructuralPropertyDescriptor property) {
1849        if (property instanceof SimplePropertyDescriptor) {
1850            SimplePropertyDescriptor p = (SimplePropertyDescriptorproperty;
1851            if (p.getValueType() == int.class) {
1852                int result = internalGetSetIntProperty(ptrue0);
1853                return Integer.valueOf(result);
1854            } else if (p.getValueType() == boolean.class) {
1855                boolean result = internalGetSetBooleanProperty(ptruefalse);
1856                return Boolean.valueOf(result);
1857            } else {
1858                return internalGetSetObjectProperty(ptruenull);
1859            }
1860        }
1861        if (property instanceof ChildPropertyDescriptor) {
1862            return internalGetSetChildProperty((ChildPropertyDescriptorpropertytruenull);
1863        }
1864        if (property instanceof ChildListPropertyDescriptor) {
1865            return internalGetChildListProperty((ChildListPropertyDescriptorproperty);
1866        }
1867        throw new IllegalArgumentException();
1868    }
1869
1870    /**
1871     * Sets the value of the given structural property for this node. The value
1872     * passed depends on the kind of property:
1873     * <ul>
1874     * <li>{@link SimplePropertyDescriptor} - the new value of the given simple property,
1875     * or <code>null</code> if none; primitive values are "boxed"</li>
1876     * <li>{@link ChildPropertyDescriptor} - the new child node (type <code>ASTNode</code>),
1877     * or <code>null</code> if none</li>
1878     * <li>{@link ChildListPropertyDescriptor} - not allowed</li>
1879     * </ul>
1880     *
1881     * @param property the property
1882     * @param value the property value
1883     * @exception RuntimeException if this node does not have the
1884     * given property, or if the given property cannot be set
1885     * @since 3.0
1886     */
1887    public final void setStructuralProperty(StructuralPropertyDescriptor propertyObject value) {
1888        if (property instanceof SimplePropertyDescriptor) {
1889            SimplePropertyDescriptor p = (SimplePropertyDescriptorproperty;
1890            if (p.getValueType() == int.class) {
1891                int arg = ((Integervalue).intValue();
1892                internalGetSetIntProperty(pfalsearg);
1893                return;
1894            } else if (p.getValueType() == boolean.class) {
1895                boolean arg = ((Booleanvalue).booleanValue();
1896                internalGetSetBooleanProperty(pfalsearg);
1897                return;
1898            } else {
1899                if (value == null && p.isMandatory()) {
1900                    throw new IllegalArgumentException();
1901                }
1902                internalGetSetObjectProperty(pfalsevalue);
1903                return;
1904            }
1905        }
1906        if (property instanceof ChildPropertyDescriptor) {
1907            ChildPropertyDescriptor p = (ChildPropertyDescriptorproperty;
1908            ASTNode child = (ASTNodevalue;
1909            if (child == null && p.isMandatory()) {
1910                throw new IllegalArgumentException();
1911            }
1912            internalGetSetChildProperty(pfalsechild);
1913            return;
1914        }
1915        if (property instanceof ChildListPropertyDescriptor) {
1916            throw new IllegalArgumentException("Cannot set the list of child list property");  //$NON-NLS-1$
1917        }
1918    }
1919
1920    /**
1921     * Sets the value of the given int-valued property for this node.
1922     * The default implementation of this method throws an exception explaining
1923     * that this node does not have such a property. This method should be
1924     * extended in subclasses that have at least one simple property whose value
1925     * type is int.
1926     *
1927     * @param property the property
1928     * @param get <code>true</code> for a get operation, and
1929     * <code>false</code> for a set operation
1930     * @param value the new property value; ignored for get operations
1931     * @return the value; always returns
1932     * <code>0</code> for set operations
1933     * @exception RuntimeException if this node does not have the
1934     * given property, or if the given value cannot be set as specified
1935     * @since 3.0
1936     */
1937    int internalGetSetIntProperty(SimplePropertyDescriptor propertyboolean getint value) {
1938        throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1939    }
1940
1941    /**
1942     * Sets the value of the given boolean-valued property for this node.
1943     * The default implementation of this method throws an exception explaining
1944     * that this node does not have such a property. This method should be
1945     * extended in subclasses that have at least one simple property whose value
1946     * type is boolean.
1947     *
1948     * @param property the property
1949     * @param get <code>true</code> for a get operation, and
1950     * <code>false</code> for a set operation
1951     * @param value the new property value; ignored for get operations
1952     * @return the value; always returns
1953     * <code>false</code> for set operations
1954     * @exception RuntimeException if this node does not have the
1955     * given property, or if the given value cannot be set as specified
1956     * @since 3.0
1957     */
1958    boolean internalGetSetBooleanProperty(SimplePropertyDescriptor propertyboolean getboolean value) {
1959        throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1960    }
1961
1962    /**
1963     * Sets the value of the given property for this node.
1964     * The default implementation of this method throws an exception explaining
1965     * that this node does not have such a property. This method should be
1966     * extended in subclasses that have at least one simple property whose value
1967     * type is a reference type.
1968     *
1969     * @param property the property
1970     * @param get <code>true</code> for a get operation, and
1971     * <code>false</code> for a set operation
1972     * @param value the new property value, or <code>null</code> if none;
1973     * ignored for get operations
1974     * @return the value, or <code>null</code> if none; always returns
1975     * <code>null</code> for set operations
1976     * @exception RuntimeException if this node does not have the
1977     * given property, or if the given value cannot be set as specified
1978     * @since 3.0
1979     */
1980    Object internalGetSetObjectProperty(SimplePropertyDescriptor propertyboolean getObject value) {
1981        throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1982    }
1983
1984    /**
1985     * Sets the child value of the given property for this node.
1986     * The default implementation of this method throws an exception explaining
1987     * that this node does not have such a property. This method should be
1988     * extended in subclasses that have at least one child property.
1989     *
1990     * @param property the property
1991     * @param get <code>true</code> for a get operation, and
1992     * <code>false</code> for a set operation
1993     * @param child the new child value, or <code>null</code> if none;
1994     * always <code>null</code> for get operations
1995     * @return the child, or <code>null</code> if none; always returns
1996     * <code>null</code> for set operations
1997     * @exception RuntimeException if this node does not have the
1998     * given property, or if the given child cannot be set as specified
1999     * @since 3.0
2000     */
2001    ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
2002        throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
2003    }
2004
2005    /**
2006     * Returns the list value of the given property for this node.
2007     * The default implementation of this method throws an exception explaining
2008     * that this node does not have such a property. This method should be
2009     * extended in subclasses that have at least one child list property.
2010     *
2011     * @param property the property
2012     * @return the list (element type: {@link ASTNode})
2013     * @exception RuntimeException if the given node does not have the
2014     * given property
2015     * @since 3.0
2016     */
2017    List internalGetChildListProperty(ChildListPropertyDescriptor property) {
2018        throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
2019    }
2020
2021    /**
2022     * Returns a list of structural property descriptors for nodes of the
2023     * same type as this node. Clients must not modify the result.
2024     * <p>
2025     * Note that property descriptors are a meta-level mechanism
2026     * for manipulating ASTNodes in a generic way. They are
2027     * unrelated to <code>get/setProperty</code>.
2028     * </p>
2029     *
2030     * @return a list of property descriptors (element type:
2031     * {@link StructuralPropertyDescriptor})
2032     * @since 3.0
2033     */
2034    public final List structuralPropertiesForType() {
2035        return internalStructuralPropertiesForType(this.ast.apiLevel, this.ast.isPreviewEnabled());
2036    }
2037
2038    /**
2039     * Returns a list of property descriptors for this node type.
2040     * Clients must not modify the result. This abstract method
2041     * must be implemented in each concrete AST node type.
2042     * <p>
2043     * N.B. This method is package-private, so that the implementations
2044     * of this method in each of the concrete AST node types do not
2045     * clutter up the API doc.
2046     * </p>
2047     *
2048     * @param apiLevel the API level; one of the <code>AST.JLS*</code> constants
2049     * @return a list of property descriptors (element type:
2050     * {@link StructuralPropertyDescriptor})
2051     * @since 3.0
2052     */
2053    abstract List internalStructuralPropertiesForType(int apiLevel);
2054
2055
2056    /**
2057     * Returns a list of property descriptors for this node type.
2058     * Clients must not modify the result. This abstract method
2059     * must be implemented in each concrete AST node type.
2060     * <p>
2061     * N.B. This method is package-private, so that the implementations
2062     * of this method in each of the concrete AST node types do not
2063     * clutter up the API doc.
2064     * </p>
2065     *
2066     * @param apiLevel the API level; one of the <code>AST.JLS*</code> constants
2067     * @param previewEnabled the previewEnabled flag
2068     * @return a list of property descriptors (element type:
2069     * {@link StructuralPropertyDescriptor})
2070     * @since 3.19
2071     */
2072    List internalStructuralPropertiesForType(int apiLevelboolean previewEnabled) {
2073        return internalStructuralPropertiesForType(apiLevel);
2074    }
2075
2076    /**
2077     * Internal helper method that starts the building a list of
2078     * property descriptors for the given node type.
2079     *
2080     * @param nodeClass the class for a concrete node type with n properties
2081     * @param propertyList empty list, with capacity for n+1 elements
2082     */
2083    static void createPropertyList(Class nodeClassList propertyList) {
2084        // stuff nodeClass at head of list for future ref
2085        propertyList.add(nodeClass);
2086    }
2087
2088    /**
2089     * Internal helper method that adding a property descriptor.
2090     *
2091     * @param property the structural property descriptor
2092     * @param propertyList list beginning with the AST node class
2093     * followed by accumulated structural property descriptors
2094     */
2095    static void addProperty(StructuralPropertyDescriptor propertyList propertyList) {
2096        Class nodeClass = (ClasspropertyList.get(0);
2097        if (property.getNodeClass() != nodeClass) {
2098            // easily made cut-and-paste mistake
2099            throw new RuntimeException("Structural property descriptor has wrong node class!");  //$NON-NLS-1$
2100        }
2101        propertyList.add(property);
2102    }
2103
2104    /**
2105     * Internal helper method that completes the building of
2106     * a node type's structural property descriptor list.
2107     *
2108     * @param propertyList list beginning with the AST node class
2109     * followed by accumulated structural property descriptors
2110     * @return unmodifiable list of structural property descriptors
2111     * (element type: {@link StructuralPropertyDescriptor})
2112     */
2113    static List reapPropertyList(List propertyList) {
2114        propertyList.remove(0); // remove nodeClass
2115        // compact
2116        ArrayList a = new ArrayList(propertyList.size());
2117        a.addAll(propertyList);
2118        return Collections.unmodifiableList(a);
2119    }
2120
2121    /**
2122     * Checks that this AST operation is not used when
2123     * building JLS2 level ASTs.
2124     * <p>
2125     * Use this method to prevent access to new properties that have been added in JLS3.
2126     * </p>
2127     *
2128     * @exception UnsupportedOperationException if this operation is used in a JLS2 AST
2129     * @since 3.0
2130     */
2131    final void unsupportedIn2() {
2132      if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
2133          throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
2134      }
2135    }
2136
2137    /**
2138     * Checks that this AST operation is not used when
2139     * building JLS2 or JLS3 level ASTs.
2140     * <p>
2141     * Use this method to prevent access to new properties that have been added in JLS4.
2142     * </p>
2143     *
2144     * @exception UnsupportedOperationException if this operation is used in a JLS2 or JLS3 AST
2145     * @since 3.7
2146     */
2147    final void unsupportedIn2_3() {
2148        if (this.ast.apiLevel <= AST.JLS3_INTERNAL) {
2149            throw new UnsupportedOperationException("Operation only supported in JLS4 and later AST"); //$NON-NLS-1$
2150        }
2151    }
2152
2153    /**
2154     * Checks that this AST operation is not used when
2155     * building JLS2 or JLS3 or JLS4 level ASTs.
2156     * <p>
2157     * Use this method to prevent access to new properties that have been added in JLS8.
2158     * </p>
2159     *
2160     * @exception UnsupportedOperationException if this operation is used below JLS8
2161     * @since 3.10
2162     */
2163    final void unsupportedIn2_3_4() {
2164        if (this.ast.apiLevel < AST.JLS8_INTERNAL) {
2165            throw new UnsupportedOperationException("Operation only supported in JLS8 and later AST"); //$NON-NLS-1$
2166        }
2167    }
2168
2169    /**
2170     * Checks that this AST operation is not used when
2171     * building JLS2, JLS3, JLS4 or JLS8 level ASTs.
2172     * <p>
2173     * Use this method to prevent access to new properties that have been added in JLS9.
2174     * </p>
2175     *
2176     * @exception UnsupportedOperationException if this operation is used below JLS9
2177     * @since 3.14
2178     */
2179    final void unsupportedBelow9() {
2180        if (this.ast.apiLevel < AST.JLS9_INTERNAL) {
2181            throw new UnsupportedOperationException("Operation only supported in JLS9 and later AST"); //$NON-NLS-1$
2182        }
2183    }
2184    /**
2185     * Checks that this AST operation is not used when
2186     * building JLS2, JLS3, JLS4, JLS8 or JLS9 level ASTs.
2187     * <p>
2188     * Use this method to prevent access to new properties that have been added in JLS10
2189     * </p>
2190     *
2191     * @exception UnsupportedOperationException if this operation is used below JLS10
2192     * @since 3.14
2193     */
2194    final void unsupportedBelow10() {
2195        if (this.ast.apiLevel < AST.JLS10_INTERNAL) {
2196            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS10 and above"); //$NON-NLS-1$
2197        }
2198    }
2199    /**
2200     * Checks that this AST operation is not used when
2201     * building JLS2, JLS3, JLS4, JLS8, JLS9 or JLS10 level ASTs.
2202     * <p>
2203     * Use this method to prevent access to new properties that have been added in JLS11
2204     * </p>
2205     *
2206     * @exception UnsupportedOperationException if this operation is used below JLS11
2207     * @since 3.14
2208     */
2209    final void unsupportedBelow11() {
2210        if (this.ast.apiLevel < AST.JLS11_INTERNAL) {
2211            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS11 and above"); //$NON-NLS-1$
2212        }
2213    }
2214
2215    /**
2216     * Checks that this AST operation is not used when
2217     * building JLS2, JLS3, JLS4, JLS8, JLS9,JLS10 or JLS11 level ASTs.
2218     * <p>
2219     * Use this method to prevent access to new properties that have been added in JLS12
2220     * </p>
2221     *
2222     * @exception UnsupportedOperationException if this operation is used below JLS12
2223     * @deprecated
2224     * @since 3.16
2225     */
2226    final void unsupportedBelow12() {
2227        if (this.ast.apiLevel < AST.JLS12_INTERNAL) {
2228            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS12 and above"); //$NON-NLS-1$
2229        }
2230    }
2231
2232    /**
2233     * Checks that this AST operation is not used when
2234     * building JLS2, JLS3, JLS4, JLS8, JLS9, JLS10, JLS11, JLS12 or JSL13 level ASTs.
2235     * <p>
2236     * Use this method to prevent access to new properties that have been added in JLS14
2237     * </p>
2238     *
2239     * @exception UnsupportedOperationException if this operation is used below JLS14
2240     * @since 3.22
2241     */
2242    final void unsupportedBelow14() {
2243        if (this.ast.apiLevel < AST.JLS14_INTERNAL) {
2244            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS14 and above"); //$NON-NLS-1$
2245        }
2246    }
2247
2248    /**
2249     * Checks that this AST operation is not used when
2250     * building JLS2, JLS3, JLS4, JLS8, JLS9, JLS10, JLS11, JLS12, JLS13 or JSL14 level ASTs.
2251     * <p>
2252     * Use this method to prevent access to new properties that have been added in JLS15
2253     * </p>
2254     *
2255     * @exception UnsupportedOperationException if this operation is used below JLS15
2256     * @since 3.22
2257     */
2258    final void unsupportedBelow15() {
2259        if (this.ast.apiLevel < AST.JLS15_INTERNAL) {
2260            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS15 and above"); //$NON-NLS-1$
2261        }
2262    }
2263
2264    /**
2265     * Checks that this AST operation is not used when
2266     * building JLS2, JLS3, JLS4, JLS8, JLS9, JLS10, JLS11, JLS12, JLS13, JSL14 or JSL15 level ASTs.
2267     * <p>
2268     * Use this method to prevent access to new properties that have been added in JLS16
2269     * </p>
2270     *
2271     * @exception UnsupportedOperationException if this operation is used below JLS16
2272     * @since 3.26
2273     */
2274    final void unsupportedBelow16() {
2275        if (this.ast.apiLevel < AST.JLS16_INTERNAL) {
2276            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS16 and above"); //$NON-NLS-1$
2277        }
2278    }
2279
2280    /**
2281     * Checks that this AST operation is not used when
2282     * building JLS2, JLS3, JLS4, JLS8, JLS9, JLS10, JLS11, JLS12, JLS13, JSL14, JSL15 or JLS16 level ASTs.
2283     * <p>
2284     * Use this method to prevent access to new properties that have been added in JLS17
2285     * </p>
2286     *
2287     * @exception UnsupportedOperationException if this operation is used below JLS17
2288     * @since 3.27
2289     */
2290    final void unsupportedBelow17() {
2291        if (this.ast.apiLevel < AST.JLS17_INTERNAL) {
2292            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS17 and above"); //$NON-NLS-1$
2293        }
2294    }
2295
2296    /**
2297     * Checks that this AST operation is not used when
2298     * building JLS2, JLS3, JLS4, JLS8, JLS9, JLS10, JLS11, JLS12, JLS13, JSL14, JSL15, JLS16 or JLS17 level ASTs.
2299     * <p>
2300     * Use this method to prevent access to new properties that have been added in JLS18
2301     * </p>
2302     *
2303     * @exception UnsupportedOperationException if this operation is used below JLS18
2304     * @since 3.30
2305     */
2306    final void unsupportedBelow18() {
2307        if (this.ast.apiLevel < AST.JLS18_INTERNAL) {
2308            throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS17 and above"); //$NON-NLS-1$
2309        }
2310    }
2311
2312
2313    /**
2314     * Checks that this AST operation is not used when
2315     * building ASTs without previewEnabled flag.
2316     * <p>
2317     * Use this method to prevent access to new properties that have been added with preview feature
2318     * </p>
2319     *
2320     * @exception UnsupportedOperationException if this operation is used with previewEnabled flag as false
2321     * @since 3.19
2322     */
2323    final void unsupportedWithoutPreviewError() {
2324        if (!this.ast.isPreviewEnabled()) {
2325            throw new UnsupportedOperationException("Operation only supported in ASTs with previewEnabled flag as true"); //$NON-NLS-1$
2326        }
2327    }
2328
2329    /**
2330     * Checks that this AST operation is only used when
2331     * building JLS2 level ASTs.
2332     * <p>
2333     * Use this method to prevent access to deprecated properties (deprecated in JLS3).
2334     * </p>
2335     *
2336     * @exception UnsupportedOperationException if this operation is used in an AST later than JLS2
2337     * @since 3.0
2338     */
2339    // In API Javadocs, add: * @deprecated In the JLS3 API, this method is replaced by {@link #replacement()}.
2340    final void supportedOnlyIn2() {
2341      if (this.ast.apiLevel != AST.JLS2_INTERNAL) {
2342          throw new UnsupportedOperationException("Operation only supported in JLS2 AST"); //$NON-NLS-1$
2343      }
2344    }
2345
2346    /**
2347     * Checks that this AST operation is only used when
2348     * building JLS2, JLS3 or JLS4 level ASTs.
2349     * <p>
2350     * Use this method to prevent access to deprecated properties (deprecated in JLS8).
2351     * </p>
2352     *
2353     * @exception UnsupportedOperationException if this operation is used in an AST later than JLS4
2354     * @since 3.10
2355     */
2356    // In API Javadocs, add: * @deprecated In the JLS8 API, this method is replaced by {@link #replacement()}.
2357    final void supportedOnlyIn2_3_4() {
2358      if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
2359          throw new UnsupportedOperationException("Operation only supported in JLS2, JLS3 and JLS4 ASTs"); //$NON-NLS-1$
2360      }
2361    }
2362
2363    /**
2364     * Checks that this AST operation is only used when
2365     * building JLS12 level ASTs.
2366     * <p>
2367     * Use this method to prevent access to properties available only in JLS12.
2368     * </p>
2369     *
2370     * @exception UnsupportedOperationException if this operation is is not used in JLS12
2371     * @since 3.20
2372     */
2373    // In API Javadocs, add: * @deprecated In the JLS13 API, this method is replaced by {@link #replacement()}.
2374    final void supportedOnlyIn12() {
2375      if (this.ast.apiLevel != AST.JLS12_INTERNAL) {
2376          throw new UnsupportedOperationException("Operation only supported in JLS12 AST"); //$NON-NLS-1$
2377      }
2378    }
2379
2380    /**
2381      * Checks that this AST operation is only used when
2382     * building JLS13 level ASTs.
2383     * <p>
2384     * Use this method to prevent access to new properties available only in JLS13.
2385     * </p>
2386     *
2387     * @exception UnsupportedOperationException if this operation is not used in JLS13
2388     * @since 3.20
2389     */
2390    final void supportedOnlyIn13() {
2391        if (this.ast.apiLevel != AST.JLS13_INTERNAL) {
2392            throw new UnsupportedOperationException("Operation only supported in JLS13 AST"); //$NON-NLS-1$
2393        }
2394    }
2395
2396    /**
2397      * Checks that this AST operation is only used when
2398     * building JLS14 level ASTs.
2399     * <p>
2400     * Use this method to prevent access to new properties available only in JLS14.
2401     * </p>
2402     *
2403     * @exception UnsupportedOperationException if this operation is not used in JLS14
2404     * @since 3.20
2405     */
2406    final void supportedOnlyIn14() {
2407        if (this.ast.apiLevel != AST.JLS14_INTERNAL) {
2408            throw new UnsupportedOperationException("Operation only supported in JLS14 AST"); //$NON-NLS-1$
2409        }
2410    }
2411
2412    /**
2413      * Checks that this AST operation is only used when
2414     * building JLS15 level ASTs.
2415     * <p>
2416     * Use this method to prevent access to new properties available only in JLS15.
2417     * </p>
2418     *
2419     * @exception UnsupportedOperationException if this operation is not used in JLS15
2420     * @since 3.22
2421     */
2422    final void supportedOnlyIn15() {
2423        if (this.ast.apiLevel != AST.JLS15_INTERNAL) {
2424            throw new UnsupportedOperationException("Operation only supported in JLS15 AST"); //$NON-NLS-1$
2425        }
2426    }
2427
2428    /**
2429      * Checks that this AST operation is only used when
2430     * building JLS16 level ASTs.
2431     * <p>
2432     * Use this method to prevent access to new properties available only in JLS15.
2433     * </p>
2434     *
2435     * @exception UnsupportedOperationException if this operation is not used in JLS15
2436     * @since 3.26
2437     */
2438    final void supportedOnlyIn16() {
2439        if (this.ast.apiLevel != AST.JLS16_INTERNAL) {
2440            throw new UnsupportedOperationException("Operation only supported in JLS16 AST"); //$NON-NLS-1$
2441        }
2442    }
2443
2444    /**
2445      * Checks that this AST operation is only used when
2446     * building JLS17 level ASTs.
2447     * <p>
2448     * Use this method to prevent access to new properties available only in JLS17.
2449     * </p>
2450     *
2451     * @exception UnsupportedOperationException if this operation is not used in JLS17
2452     * @since 3.27
2453     */
2454    final void supportedOnlyIn17() {
2455        if (this.ast.apiLevel != AST.JLS17_INTERNAL) {
2456            throw new UnsupportedOperationException("Operation only supported in JLS17 AST"); //$NON-NLS-1$
2457        }
2458    }
2459    /**
2460      * Checks that this AST operation is only used when
2461     * building JLS18 level ASTs.
2462     * <p>
2463     * Use this method to prevent access to new properties available only in JLS18.
2464     * </p>
2465     *
2466     * @exception UnsupportedOperationException if this operation is not used in JLS18
2467     * @since 3.30
2468     */
2469    final void supportedOnlyIn18() {
2470        if (this.ast.apiLevel != AST.JLS18_INTERNAL) {
2471            throw new UnsupportedOperationException("Operation only supported in JLS17 AST"); //$NON-NLS-1$
2472        }
2473    }
2474
2475    /**
2476     * Sets or clears this node's parent node and location.
2477     * <p>
2478     * Note that this method is package-private. The pointer from a node
2479     * to its parent is set implicitly as a side effect of inserting or
2480     * removing the node as a child of another node. This method calls
2481     * <code>ast.modifying()</code>.
2482     * </p>
2483     *
2484     * @param parent the new parent of this node, or <code>null</code> if none
2485     * @param property the location of this node in its parent,
2486     * or <code>null</code> if <code>parent</code> is <code>null</code>
2487     * @see #getLocationInParent
2488     * @see #getParent
2489     * @since 3.0
2490     */
2491    final void setParent(ASTNode parentStructuralPropertyDescriptor property) {
2492        this.ast.modifying();
2493        this.parent = parent;
2494        this.location = property;
2495    }
2496
2497    /**
2498     * Removes this node from its parent. Has no effect if this node
2499     * is unparented. If this node appears as an element of a child list
2500     * property of its parent, then this node is removed from the
2501     * list using <code>List.remove</code>.
2502     * If this node appears as the value of a child property of its
2503     * parent, then this node is detached from its parent
2504     * by passing <code>null</code> to the appropriate setter method;
2505     * this operation fails if this node is in a mandatory property.
2506     *
2507     * @since 3.0
2508     */
2509    public final void delete() {
2510        StructuralPropertyDescriptor p = getLocationInParent();
2511        if (p == null) {
2512            // node is unparented
2513            return;
2514        }
2515        if (p.isChildProperty()) {
2516            getParent().setStructuralProperty(this.locationnull);
2517            return;
2518        }
2519        if (p.isChildListProperty()) {
2520            List l = (ListgetParent().getStructuralProperty(this.location);
2521            l.remove(this);
2522        }
2523    }
2524
2525    /**
2526     * Checks whether the given new child node is a node
2527     * in a different AST from its parent-to-be, whether it is
2528     * already has a parent, whether adding it to its
2529     * parent-to-be would create a cycle, and whether the child is of
2530     * the right type. The parent-to-be is the enclosing instance.
2531     *
2532     * @param node the parent-to-be node
2533     * @param newChild the new child of the parent
2534     * @param cycleCheck <code>true</code> if cycles are possible and need
2535     *   to be checked, <code>false</code> if cycles are impossible and do
2536     *   not need to be checked
2537     * @param nodeType a type constraint on child nodes, or <code>null</code>
2538     *   if no special check is required
2539     * @exception IllegalArgumentException if:
2540     * <ul>
2541     * <li>the child is null</li>
2542     * <li>the node belongs to a different AST</li>
2543     * <li>the child has the incorrect node type</li>
2544     * <li>the node already has a parent</li>
2545     * <li>a cycle in would be created</li>
2546     * </ul>
2547     */
2548    static void checkNewChild(ASTNode nodeASTNode newChild,
2549            boolean cycleCheckClass nodeType) {
2550        if (newChild.ast != node.ast) {
2551            // new child is from a different AST
2552            throw new IllegalArgumentException();
2553        }
2554        if (newChild.getParent() != null) {
2555            // new child currently has a different parent
2556            throw new IllegalArgumentException();
2557        }
2558        if (cycleCheck && newChild == node.getRoot()) {
2559            // inserting new child would create a cycle
2560            throw new IllegalArgumentException();
2561        }
2562        Class childClass = newChild.getClass();
2563        if (nodeType != null && !nodeType.isAssignableFrom(childClass)) {
2564            // new child is not of the right type
2565            throw new ClassCastException(childClass + " is not an instance of " + nodeType); //$NON-NLS-1$
2566        }
2567        if ((newChild.typeAndFlags & PROTECT) != 0) {
2568            // new child node is protected => cannot be parented
2569            throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2570        }
2571    }
2572
2573    /**
2574     * Prelude portion of the "3 step program" for replacing the
2575     * old child of this node with another node.
2576     * Here is the code pattern found in all AST node subclasses:
2577     * <pre>
2578     * ASTNode oldChild = this.foo;
2579     * preReplaceChild(oldChild, newFoo, FOO_PROPERTY);
2580     * this.foo = newFoo;
2581     * postReplaceChild(oldChild, newFoo, FOO_PROPERTY);
2582     * </pre>
2583     * The first part (preReplaceChild) does all the precondition checks,
2584     * reports pre-delete events, and changes parent links.
2585     * The old child is delinked from its parent (making it a root node),
2586     * and the new child node is linked to its parent. The new child node
2587     * must be a root node in the same AST as its new parent, and must not
2588     * be an ancestor of this node. All three nodes must be
2589     * modifiable (not PROTECTED). The replace operation must fail
2590     * atomically; so it is crucial that all precondition checks
2591     * be done before any linking and delinking happens.
2592     * The final part (postReplaceChild )reports post-add events.
2593     * <p>
2594     * This method calls <code>ast.modifying()</code> for the nodes affected.
2595     * </p>
2596     *
2597     * @param oldChild the old child of this node, or <code>null</code> if
2598     *   there was no old child to replace
2599     * @param newChild the new child of this node, or <code>null</code> if
2600     *   there is no replacement child
2601     * @param property the property descriptor of this node describing
2602     * the relationship between node and child
2603     * @exception RuntimeException if:
2604     * <ul>
2605     * <li>the node belongs to a different AST</li>
2606     * <li>the node already has a parent</li>
2607     * <li>a cycle in would be created</li>
2608     * <li>any of the nodes involved are unmodifiable</li>
2609     * </ul>
2610     * @since 3.0
2611     */
2612    final void preReplaceChild(ASTNode oldChildASTNode newChildChildPropertyDescriptor property) {
2613        if ((this.typeAndFlags & PROTECT) != 0) {
2614            // this node is protected => cannot gain or lose children
2615            throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2616        }
2617        if (newChild != null) {
2618            checkNewChild(this, newChildproperty.cycleRisknull);
2619        }
2620        // delink old child from parent
2621        if (oldChild != null) {
2622            if ((oldChild.typeAndFlags & PROTECT) != 0) {
2623                // old child node is protected => cannot be unparented
2624                throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2625            }
2626            if (newChild != null) {
2627                this.ast.preReplaceChildEvent(this, oldChildnewChildproperty);
2628            } else {
2629                this.ast.preRemoveChildEvent(this, oldChildproperty);
2630            }
2631            oldChild.setParent(nullnull);
2632        } else {
2633            if(newChild != null) {
2634                this.ast.preAddChildEvent(this, newChildproperty);
2635            }
2636        }
2637        // link new child to parent
2638        if (newChild != null) {
2639            newChild.setParent(this, property);
2640            // cannot notify postAddChildEvent until parent is linked to child too
2641        }
2642    }
2643
2644    /**
2645     * Postlude portion of the "3 step program" for replacing the
2646     * old child of this node with another node.
2647     * See {@link #preReplaceChild(ASTNode, ASTNode, ChildPropertyDescriptor)}
2648     * for details.
2649     * @since 3.0
2650     */
2651    final void postReplaceChild(ASTNode oldChildASTNode newChildChildPropertyDescriptor property) {
2652        // link new child to parent
2653        if (newChild != null) {
2654            if (oldChild != null) {
2655                this.ast.postReplaceChildEvent(this, oldChildnewChildproperty);
2656            } else {
2657                this.ast.postAddChildEvent(this, newChildproperty);
2658            }
2659        } else {
2660            this.ast.postRemoveChildEvent(this, oldChildproperty);
2661        }
2662    }
2663
2664    /**
2665     * Prelude portion of the "3 step program" for changing the
2666     * value of a simple property of this node.
2667     * Here is the code pattern found in all AST node subclasses:
2668     * <pre>
2669     * preValueChange(FOO_PROPERTY);
2670     * this.foo = newFoo;
2671     * postValueChange(FOO_PROPERTY);
2672     * </pre>
2673     * The first part (preValueChange) does the precondition check
2674     * to make sure the node is modifiable (not PROTECTED).
2675     * The change operation must fail atomically; so it is crucial
2676     * that the precondition checks are done before the field is
2677     * hammered. The final part (postValueChange)reports post-change
2678     * events.
2679     * <p>
2680     * This method calls <code>ast.modifying()</code> for the node affected.
2681     * </p>
2682     *
2683     * @param property the property descriptor of this node
2684     * @exception RuntimeException if:
2685     * <ul>
2686     * <li>this node is unmodifiable</li>
2687     * </ul>
2688     * @since 3.0
2689     */
2690    final void preValueChange(SimplePropertyDescriptor property) {
2691        if ((this.typeAndFlags & PROTECT) != 0) {
2692            // this node is protected => cannot change value of properties
2693            throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2694        }
2695        this.ast.preValueChangeEvent(this, property);
2696        this.ast.modifying();
2697    }
2698
2699    /**
2700     * Postlude portion of the "3 step program" for replacing the
2701     * old child of this node with another node.
2702     * See {@link #preValueChange(SimplePropertyDescriptor)} for details.
2703     * @since 3.0
2704     */
2705    final void postValueChange(SimplePropertyDescriptor property) {
2706        this.ast.postValueChangeEvent(this, property);
2707    }
2708
2709    /**
2710     * Ensures that this node is modifiable (that is, not marked PROTECTED).
2711     * If successful, calls ast.modifying().
2712     * @exception RuntimeException is not modifiable
2713     */
2714    final void checkModifiable() {
2715        if ((this.typeAndFlags & PROTECT) != 0) {
2716            throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2717        }
2718        this.ast.modifying();
2719    }
2720
2721    /**
2722     * Begin lazy initialization of this node.
2723     * Here is the code pattern found in all AST
2724     * node subclasses:
2725     * <pre>
2726     * if (this.foo == null) {
2727     *    // lazy init must be thread-safe for readers
2728     *    synchronized (this) {
2729     *       if (this.foo == null) {
2730     *          preLazyInit();
2731     *          this.foo = ...; // code to create new node
2732     *          postLazyInit(this.foo, FOO_PROPERTY);
2733     *       }
2734     *    }
2735     * }
2736     * </pre>
2737     * @since 3.0
2738     */
2739    final void preLazyInit() {
2740        // IMPORTANT: this method is called by readers
2741        // ASTNode.this is locked at this point
2742        this.ast.disableEvents();
2743        // will turn events back on in postLasyInit
2744    }
2745
2746    /**
2747     * End lazy initialization of this node.
2748     *
2749     * @param newChild the new child of this node, or <code>null</code> if
2750     *   there is no replacement child
2751     * @param property the property descriptor of this node describing
2752     * the relationship between node and child
2753     * @since 3.0
2754     */
2755    final void postLazyInit(ASTNode newChildChildPropertyDescriptor property) {
2756        // IMPORTANT: this method is called by readers
2757        // ASTNode.this is locked at this point
2758        // newChild is brand new (so no chance of concurrent access)
2759        newChild.setParent(this, property);
2760        // turn events back on (they were turned off in corresponding preLazyInit)
2761        this.ast.reenableEvents();
2762    }
2763
2764    /**
2765     * Returns the value of the named property of this node, or <code>null</code> if none.
2766     *
2767     * @param propertyName the property name
2768     * @return the property value, or <code>null</code> if none
2769     * @see #setProperty(String,Object)
2770     */
2771    public final Object getProperty(String propertyName) {
2772        if (propertyName == null) {
2773            throw new IllegalArgumentException();
2774        }
2775        if (this.property1 == null) {
2776            // node has no properties at all
2777            return null;
2778        }
2779        if (this.property1 instanceof String) {
2780            // node has only a single property
2781            if (propertyName.equals(this.property1)) {
2782                return this.property2;
2783            } else {
2784                return null;
2785            }
2786        }
2787        // otherwise node has table of properties
2788        Map m = (Map) this.property1;
2789        return m.get(propertyName);
2790    }
2791
2792    /**
2793     * Sets the named property of this node to the given value,
2794     * or to <code>null</code> to clear it.
2795     * <p>
2796     * Clients should employ property names that are sufficiently unique
2797     * to avoid inadvertent conflicts with other clients that might also be
2798     * setting properties on the same node.
2799     * </p>
2800     * <p>
2801     * Note that modifying a property is not considered a modification to the
2802     * AST itself. This is to allow clients to decorate existing nodes with
2803     * their own properties without jeopardizing certain things (like the
2804     * validity of bindings), which rely on the underlying tree remaining static.
2805     * </p>
2806     *
2807     * @param propertyName the property name
2808     * @param data the new property value, or <code>null</code> if none
2809     * @see #getProperty(String)
2810     * @throws IllegalArgumentException if the given property name is <code>null</code>
2811     */
2812    public final void setProperty(String propertyNameObject data) {
2813        if (propertyName == null) {
2814            throw new IllegalArgumentException();
2815        }
2816        // N.B. DO NOT CALL ast.modifying();
2817
2818        if (this.property1 == null) {
2819            // node has no properties at all
2820            if (data == null) {
2821                // we already know this
2822                return;
2823            }
2824            // node gets its fist property
2825            this.property1 = propertyName;
2826            this.property2 = data;
2827            return;
2828        }
2829
2830        if (this.property1 instanceof String) {
2831            // node has only a single property
2832            if (propertyName.equals(this.property1)) {
2833                // we're in luck
2834                if (data == null) {
2835                    // just deleted last property
2836                    this.property1 = null;
2837                    this.property2 = null;
2838                } else {
2839                    this.property2 = data;
2840                }
2841                return;
2842            }
2843            if (data == null) {
2844                // we already know this
2845                return;
2846            }
2847            // node already has one property - getting its second
2848            // convert to more flexible representation
2849            Map m = new HashMap(3);
2850            m.put(this.property1, this.property2);
2851            m.put(propertyNamedata);
2852            this.property1 = m;
2853            this.property2 = null;
2854            return;
2855        }
2856
2857        // node has two or more properties
2858        Map m = (Map) this.property1;
2859        if (data == null) {
2860            m.remove(propertyName);
2861            // check for just one property left
2862            if (m.size() == 1) {
2863                // convert to more efficient representation
2864                Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]);
2865                this.property1 = entries[0].getKey();
2866                this.property2 = entries[0].getValue();
2867            }
2868            return;
2869        } else {
2870            m.put(propertyNamedata);
2871            // still has two or more properties
2872            return;
2873        }
2874    }
2875
2876    /**
2877     * Returns an unmodifiable table of the properties of this node with
2878     * non-<code>null</code> values.
2879     *
2880     * @return the table of property values keyed by property name
2881     *   (key type: <code>String</code>; value type: <code>Object</code>)
2882     */
2883    public final Map properties() {
2884        if (this.property1 == null) {
2885            // node has no properties at all
2886            return UNMODIFIABLE_EMPTY_MAP;
2887        }
2888        if (this.property1 instanceof String) {
2889            // node has a single property
2890            return Collections.singletonMap(this.property1, this.property2);
2891        }
2892
2893        // node has two or more properties
2894        if (this.property2 == null) {
2895            this.property2 = Collections.unmodifiableMap((Map) this.property1);
2896        }
2897        // property2 is unmodifiable wrapper for map in property1
2898        return (Map) this.property2;
2899    }
2900
2901    /**
2902     * Returns the flags associated with this node.
2903     * <p>
2904     * No flags are associated with newly created nodes.
2905     * </p>
2906     * <p>
2907     * The flags are the bitwise-or of individual flags.
2908     * The following flags are currently defined:
2909     * <ul>
2910     * <li>{@link #MALFORMED} - indicates node is syntactically
2911     *   malformed</li>
2912     * <li>{@link #ORIGINAL} - indicates original node
2913     * created by ASTParser</li>
2914     * <li>{@link #PROTECT} - indicates node is protected
2915     * from further modification</li>
2916     * <li>{@link #RECOVERED} - indicates node or a part of this node
2917     *  is recovered from source that contains a syntax error</li>
2918     * </ul>
2919     * Other bit positions are reserved for future use.
2920     *
2921     * @return the bitwise-or of individual flags
2922     * @see #setFlags(int)
2923     */
2924    public final int getFlags() {
2925        return this.typeAndFlags & 0xFFFF;
2926    }
2927
2928    /**
2929     * Sets the flags associated with this node to the given value.
2930     * <p>
2931     * The flags are the bitwise-or of individual flags.
2932     * The following flags are currently defined:
2933     * <ul>
2934     * <li>{@link #MALFORMED} - indicates node is syntactically
2935     *   malformed</li>
2936     * <li>{@link #ORIGINAL} - indicates original node
2937     * created by ASTParser</li>
2938     * <li>{@link #PROTECT} - indicates node is protected
2939     * from further modification</li>
2940     * <li>{@link #RECOVERED} - indicates node or a part of this node
2941     *  is recovered from source that contains a syntax error</li>
2942     * </ul>
2943     * Other bit positions are reserved for future use.
2944     * <p>
2945     * Note that the flags are <em>not</em> considered a structural
2946     * property of the node, and can be changed even if the
2947     * node is marked as protected.
2948     * </p>
2949     *
2950     * @param flags the bitwise-or of individual flags
2951     * @see #getFlags()
2952     */
2953    public final void setFlags(int flags) {
2954        this.ast.modifying();
2955        int old = this.typeAndFlags & 0xFFFF0000;
2956        this.typeAndFlags = old | (flags & 0xFFFF);
2957    }
2958
2959    /**
2960     * Returns an integer value identifying the type of this concrete AST node.
2961     * The values are small positive integers, suitable for use in switch statements.
2962     * <p>
2963     * For each concrete node type there is a unique node type constant (name
2964     * and value). The unique node type constant for a concrete node type such as
2965     * <code>CastExpression</code> is <code>ASTNode.CAST_EXPRESSION</code>.
2966     * </p>
2967     *
2968     * @return one of the node type constants
2969     */
2970    public final int getNodeType() {
2971        return this.typeAndFlags >>> 16;
2972    }
2973
2974    /**
2975     * Sets the integer value identifying the type of this concrete AST node.
2976     * The values are small positive integers, suitable for use in switch statements.
2977     *
2978     * @param nodeType one of the node type constants
2979     */
2980    private void setNodeType(int nodeType) {
2981        int old = this.typeAndFlags & 0xFFFF0000;
2982        this.typeAndFlags = old | (nodeType << 16);
2983    }
2984
2985    /**
2986     * Returns an integer value identifying the type of this concrete AST node.
2987     * <p>
2988     * This internal method is implemented in each of the
2989     * concrete node subclasses.
2990     * </p>
2991     *
2992     * @return one of the node type constants
2993     */
2994    abstract int getNodeType0();
2995
2996    /**
2997     * The <code>ASTNode</code> implementation of this <code>Object</code>
2998     * method uses object identity (==). Use <code>subtreeMatch</code> to
2999     * compare two subtrees for equality.
3000     *
3001     * @param obj {@inheritDoc}
3002     * @return {@inheritDoc}
3003     * @see #subtreeMatch(ASTMatcher matcher, Object other)
3004     */
3005    @Override
3006    public final boolean equals(Object obj) {
3007        return this == obj// equivalent to Object.equals
3008    }
3009
3010    /*
3011     * (non-Javadoc)
3012     * This makes it consistent with the fact that a equals methods has been provided.
3013     * @see java.lang.Object#hashCode()
3014     */
3015    @Override
3016    public final int hashCode() {
3017        return super.hashCode();
3018    }
3019
3020    /**
3021     * Returns whether the subtree rooted at the given node matches the
3022     * given other object as decided by the given matcher.
3023     *
3024     * @param matcher the matcher
3025     * @param other the other object, or <code>null</code>
3026     * @return <code>true</code> if the subtree matches, or
3027     * <code>false</code> if they do not match
3028     */
3029    public final boolean subtreeMatch(ASTMatcher matcherObject other) {
3030        return subtreeMatch0(matcherother);
3031    }
3032
3033    /**
3034     * Returns whether the subtree rooted at the given node matches the
3035     * given other object as decided by the given matcher.
3036     * <p>
3037     * This internal method is implemented in each of the
3038     * concrete node subclasses.
3039     * </p>
3040     *
3041     * @param matcher the matcher
3042     * @param other the other object, or <code>null</code>
3043     * @return <code>true</code> if the subtree matches, or
3044     * <code>false</code> if they do not match
3045     */
3046    abstract boolean subtreeMatch0(ASTMatcher matcherObject other);
3047
3048    /**
3049     * Returns a deep copy of the subtree of AST nodes rooted at the
3050     * given node. The resulting nodes are owned by the given AST,
3051     * which may be different from the ASTs of the given node.
3052     * Even if the given node has a parent, the result node will be unparented.
3053     * <p>
3054     * Source range information on the original nodes is automatically copied to the new
3055     * nodes. Client properties (<code>properties</code>) are not carried over.
3056     * </p>
3057     * <p>
3058     * The node's <code>AST</code> and the target <code>AST</code> must support
3059     * the same API level.
3060     * </p>
3061     *
3062     * @param target the AST that is to own the nodes in the result
3063     * @param node the node to copy, or <code>null</code> if none
3064     * @return the copied node, or <code>null</code> if <code>node</code>
3065     *    is <code>null</code>
3066     */
3067    public static ASTNode copySubtree(AST targetASTNode node) {
3068        if (node == null) {
3069            return null;
3070        }
3071        if (target == null) {
3072            throw new IllegalArgumentException();
3073        }
3074        if (target.apiLevel() != node.getAST().apiLevel()) {
3075            throw new UnsupportedOperationException();
3076        }
3077        ASTNode newNode = node.clone(target);
3078        return newNode;
3079    }
3080
3081    /**
3082     * Returns a deep copy of the subtrees of AST nodes rooted at the
3083     * given list of nodes. The resulting nodes are owned by the given AST,
3084     * which may be different from the ASTs of the nodes in the list.
3085     * Even if the nodes in the list have parents, the nodes in the result
3086     * will be unparented.
3087     * <p>
3088     * Source range information on the original nodes is automatically copied to the new
3089     * nodes. Client properties (<code>properties</code>) are not carried over.
3090     * </p>
3091     *
3092     * @param target the AST that is to own the nodes in the result
3093     * @param nodes the list of nodes to copy
3094     *    (element type: {@link ASTNode})
3095     * @return the list of copied subtrees
3096     *    (element type: {@link ASTNode})
3097     */
3098    public static List copySubtrees(AST targetList nodes) {
3099        List result = new ArrayList(nodes.size());
3100        for (Iterator it = nodes.iterator(); it.hasNext(); ) {
3101            ASTNode oldNode = (ASTNodeit.next();
3102            ASTNode newNode = oldNode.clone(target);
3103            result.add(newNode);
3104        }
3105        return result;
3106    }
3107
3108    /**
3109     * Returns a deep copy of the subtree of AST nodes rooted at this node.
3110     * The resulting nodes are owned by the given AST, which may be different
3111     * from the AST of this node. Even if this node has a parent, the
3112     * result node will be unparented.
3113     * <p>
3114     * This method reports pre- and post-clone events, and dispatches
3115     * to <code>clone0(AST)</code> which is reimplemented in node subclasses.
3116     * </p>
3117     *
3118     * @param target the AST that is to own the nodes in the result
3119     * @return the root node of the copies subtree
3120     */
3121    final ASTNode clone(AST target) {
3122        this.ast.preCloneNodeEvent(this);
3123        ASTNode c = clone0(target);
3124        this.ast.postCloneNodeEvent(this, c);
3125        return c;
3126    }
3127
3128    /**
3129     * Returns a deep copy of the subtree of AST nodes rooted at this node.
3130     * The resulting nodes are owned by the given AST, which may be different
3131     * from the AST of this node. Even if this node has a parent, the
3132     * result node will be unparented.
3133     * <p>
3134     * This method must be implemented in subclasses.
3135     * </p>
3136     * <p>
3137     * General template for implementation on each concrete ASTNode class:
3138     * <pre>
3139     * <code>
3140     * ConcreteNodeType result = new ConcreteNodeType(target);
3141     * result.setSourceRange(getStartPosition(), getLength());
3142     * result.setChildProperty(
3143     *         (ChildPropertyType) ASTNode.copySubtree(target, getChildProperty()));
3144     * result.setSimpleProperty(isSimpleProperty());
3145     * result.childrenProperty().addAll(
3146     *         ASTNode.copySubtrees(target, childrenProperty()));
3147     * return result;
3148     * </code>
3149     * </pre>
3150     * </p>
3151     * <p>
3152     * This method does not report pre- and post-clone events.
3153     * All callers should instead call <code>clone(AST)</code>
3154     * to ensure that pre- and post-clone events are reported.
3155     * </p>
3156     * <p>
3157     * N.B. This method is package-private, so that the implementations
3158     * of this method in each of the concrete AST node types do not
3159     * clutter up the API doc.
3160     * </p>
3161     *
3162     * @param target the AST that is to own the nodes in the result
3163     * @return the root node of the copies subtree
3164     */
3165    abstract ASTNode clone0(AST target);
3166
3167    /**
3168     * Accepts the given visitor on a visit of the current node.
3169     *
3170     * @param visitor the visitor object
3171     * @exception IllegalArgumentException if the visitor is null
3172     */
3173    public final void accept(ASTVisitor visitor) {
3174        if (visitor == null) {
3175            throw new IllegalArgumentException();
3176        }
3177        // begin with the generic pre-visit
3178        if (visitor.preVisit2(this)) {
3179            // dynamic dispatch to internal method for type-specific visit/endVisit
3180            accept0(visitor);
3181        }
3182        // end with the generic post-visit
3183        visitor.postVisit(this);
3184    }
3185
3186    /**
3187     * Accepts the given visitor on a type-specific visit of the current node.
3188     * This method must be implemented in all concrete AST node types.
3189     * <p>
3190     * General template for implementation on each concrete ASTNode class:
3191     * <pre>
3192     * <code>
3193     * boolean visitChildren = visitor.visit(this);
3194     * if (visitChildren) {
3195     *    // visit children in normal left to right reading order
3196     *    acceptChild(visitor, getProperty1());
3197     *    acceptChildren(visitor, this.rawListProperty);
3198     *    acceptChild(visitor, getProperty2());
3199     * }
3200     * visitor.endVisit(this);
3201     * </code>
3202     * </pre>
3203     * Note that the caller (<code>accept</code>) take cares of invoking
3204     * <code>visitor.preVisit(this)</code> and <code>visitor.postVisit(this)</code>.
3205     * </p>
3206     *
3207     * @param visitor the visitor object
3208     */
3209    abstract void accept0(ASTVisitor visitor);
3210
3211    /**
3212     * Accepts the given visitor on a visit of the current node.
3213     * <p>
3214     * This method should be used by the concrete implementations of
3215     * <code>accept0</code> to traverse optional properties. Equivalent
3216     * to <code>child.accept(visitor)</code> if <code>child</code>
3217     * is not <code>null</code>.
3218     * </p>
3219     *
3220     * @param visitor the visitor object
3221     * @param child the child AST node to dispatch too, or <code>null</code>
3222     *    if none
3223     */
3224    final void acceptChild(ASTVisitor visitorASTNode child) {
3225        if (child == null) {
3226            return;
3227        }
3228        child.accept(visitor);
3229    }
3230
3231    /**
3232     * Accepts the given visitor on a visit of the given live list of
3233     * child nodes.
3234     * <p>
3235     * This method must be used by the concrete implementations of
3236     * <code>accept</code> to traverse list-values properties; it
3237     * encapsulates the proper handling of on-the-fly changes to the list.
3238     * </p>
3239     *
3240     * @param visitor the visitor object
3241     * @param children the child AST node to dispatch too, or <code>null</code>
3242     *    if none
3243     */
3244    final void acceptChildren(ASTVisitor visitorASTNode.NodeList children) {
3245        // use a cursor to keep track of where we are up to
3246        // (the list may be changing under foot)
3247        NodeList.Cursor cursor = children.newCursor();
3248        try {
3249            while (cursor.hasNext()) {
3250                ASTNode child = (ASTNodecursor.next();
3251                child.accept(visitor);
3252            }
3253        } finally {
3254            children.releaseCursor(cursor);
3255        }
3256    }
3257
3258    /**
3259     * Returns the character index into the original source file indicating
3260     * where the source fragment corresponding to this node begins.
3261     * <p>
3262     * The parser supplies useful well-defined source ranges to the nodes it creates.
3263     * See {@link ASTParser#setKind(int)} for details
3264     * on precisely where source ranges begin and end.
3265     * </p>
3266     *
3267     * @return the 0-based character index, or <code>-1</code>
3268     *    if no source position information is recorded for this node
3269     * @see #getLength()
3270     * @see ASTParser
3271     */
3272    public final int getStartPosition() {
3273        return this.startPosition;
3274    }
3275
3276    /**
3277     * Returns the length in characters of the original source file indicating
3278     * where the source fragment corresponding to this node ends.
3279     * <p>
3280     * The parser supplies useful well-defined source ranges to the nodes it creates.
3281     * See {@link ASTParser#setKind(int)} methods for details
3282     * on precisely where source ranges begin and end.
3283     * </p>
3284     *
3285     * @return a (possibly 0) length, or <code>0</code>
3286     *    if no source position information is recorded for this node
3287     * @see #getStartPosition()
3288     * @see ASTParser
3289     */
3290    public final int getLength() {
3291        return this.length;
3292    }
3293
3294    /**
3295     * Sets the source range of the original source file where the source
3296     * fragment corresponding to this node was found.
3297     * <p>
3298     * See {@link ASTParser#setKind(int)} for details
3299     * on precisely where source ranges are supposed to begin and end.
3300     * </p>
3301     *
3302     * @param startPosition a 0-based character index,
3303     *    or <code>-1</code> if no source position information is
3304     *    available for this node
3305     * @param length a (possibly 0) length,
3306     *    or <code>0</code> if no source position information is recorded
3307     *    for this node
3308     * @see #getStartPosition()
3309     * @see #getLength()
3310     * @see ASTParser
3311     */
3312    public final void setSourceRange(int startPositionint length) {
3313        if (startPosition >= 0 && length < 0) {
3314            throw new IllegalArgumentException();
3315        }
3316        if (startPosition < 0 && length != 0) {
3317            throw new IllegalArgumentException();
3318        }
3319        // source positions are not considered a structural property
3320        // but we protect them nevertheless
3321        checkModifiable();
3322        this.startPosition = startPosition;
3323        this.length = length;
3324    }
3325
3326    /**
3327     * Returns a string representation of this node suitable for debugging
3328     * purposes only.
3329     *
3330     * @return a debug string
3331     */
3332    @Override
3333    public final String toString() {
3334        StringBuffer buffer = new StringBuffer();
3335        int p = buffer.length();
3336        try {
3337            appendDebugString(buffer);
3338        } catch (RuntimeException e) {
3339            // since debugger sometimes call toString methods, problems can easily happen when
3340            // toString is called on an instance that is being initialized
3341            buffer.setLength(p);
3342            buffer.append("!"); //$NON-NLS-1$
3343            buffer.append(standardToString());
3344        }
3345        return buffer.toString();
3346    }
3347
3348    /**
3349     * Returns the string representation of this node produced by the standard
3350     * <code>Object.toString</code> method.
3351     *
3352     * @return a debug string
3353     */
3354    final String standardToString() {
3355        return super.toString();
3356    }
3357
3358    /**
3359     * Appends a debug representation of this node to the given string buffer.
3360     * <p>
3361     * The <code>ASTNode</code> implementation of this method prints out the entire
3362     * subtree. Subclasses may override to provide a more succinct representation.
3363     * </p>
3364     *
3365     * @param buffer the string buffer to append to
3366     */
3367    void appendDebugString(StringBuffer buffer) {
3368        // print the subtree by default
3369        appendPrintString(buffer);
3370    }
3371
3372    /**
3373     * Appends a standard Java source code representation of this subtree to the given
3374     * string buffer.
3375     *
3376     * @param buffer the string buffer to append to
3377     */
3378    final void appendPrintString(StringBuffer buffer) {
3379        NaiveASTFlattener printer = new NaiveASTFlattener();
3380        accept(printer);
3381        buffer.append(printer.getResult());
3382    }
3383
3384    /**
3385     * Estimate of size of an object header in bytes.
3386     */
3387    static final int HEADERS = 12;
3388
3389    /**
3390     * Approximate base size of an AST node instance in bytes,
3391     * including object header and instance fields.
3392     * That is, HEADERS + (# instance vars in ASTNode)*4.
3393     */
3394    static final int BASE_NODE_SIZE = HEADERS + 7 * 4;
3395
3396    /**
3397     * Returns an estimate of the memory footprint, in bytes,
3398     * of the given string.
3399     *
3400     * @param string the string to measure, or <code>null</code>
3401     * @return the size of this string object in bytes, or
3402     *   0 if the string is <code>null</code>
3403     * @since 3.0
3404     */
3405    static int stringSize(String string) {
3406        int size = 0;
3407        if (string != null) {
3408            // Strings usually have 4 instance fields, one of which is a char[]
3409            size += HEADERS + 4 * 4;
3410            // char[] has 2 bytes per character
3411            size += HEADERS + 2 * string.length();
3412        }
3413        return size;
3414    }
3415
3416    /**
3417     * Returns an estimate of the memory footprint in bytes of the entire
3418     * subtree rooted at this node.
3419     *
3420     * @return the size of this subtree in bytes
3421     */
3422    public final int subtreeBytes() {
3423        return treeSize();
3424    }
3425
3426    /**
3427     * Returns an estimate of the memory footprint in bytes of the entire
3428     * subtree rooted at this node.
3429     * <p>
3430     * N.B. This method is package-private, so that the implementations
3431     * of this method in each of the concrete AST node types do not
3432     * clutter up the API doc.
3433     * </p>
3434     *
3435     * @return the size of this subtree in bytes
3436     */
3437    abstract int treeSize();
3438
3439    /**
3440     * Returns an estimate of the memory footprint of this node in bytes.
3441     * The estimate does not include the space occupied by child nodes.
3442     *
3443     * @return the size of this node in bytes
3444     */
3445    abstract int memSize();
3446}
3447
MembersX
ASTNode:NodeList:Cursor:next
ASTNode:ARRAY_INITIALIZER
ASTNode:TAG_PROPERTY
ASTNode:length
ASTNode:IF_STATEMENT
ASTNode:copySubtree
ASTNode:getParent
ASTNode:subtreeBytes
ASTNode:NodeList:remove:Block:oldChild
ASTNode:NodeList:remove:Block:result
ASTNode:ASTNode
ASTNode:nodeClassForType
ASTNode:postLazyInit
ASTNode:getNodeType
ASTNode:METHOD_INVOCATION
ASTNode:NodeList:listSize:Block:Block:child
ASTNode:QUALIFIED_TYPE
ASTNode:NodeList:Cursor:remove
ASTNode:acceptChild
ASTNode:CREATION_REFERENCE
ASTNode:addProperty:Block:nodeClass
ASTNode:setProperty
ASTNode:TYPE_METHOD_REFERENCE
ASTNode:getLocationInParent
ASTNode:setStructuralProperty
ASTNode:delete:Block:Block:l
ASTNode:location
ASTNode:NodeList:newCursor:Block:Block:result
ASTNode:PARAMETERIZED_TYPE
ASTNode:unsupportedBelow15
ASTNode:supportedOnlyIn16
ASTNode:unsupportedBelow16
ASTNode:supportedOnlyIn17
ASTNode:LAMBDA_EXPRESSION
ASTNode:unsupportedBelow17
ASTNode:supportedOnlyIn18
ASTNode:unsupportedBelow18
ASTNode:property1
ASTNode:unsupportedBelow11
ASTNode:THIS_EXPRESSION
ASTNode:property2
ASTNode:NodeList:remove
ASTNode:unsupportedBelow12
ASTNode:PROVIDES_DIRECTIVE
ASTNode:unsupportedBelow14
ASTNode:NULL_LITERAL
ASTNode:unsupportedBelow10
ASTNode:supportedOnlyIn12
ASTNode:supportedOnlyIn13
ASTNode:ENUM_DECLARATION
ASTNode:supportedOnlyIn14
ASTNode:supportedOnlyIn15
ASTNode:accept0
ASTNode:TYPE_DECLARATION
ASTNode:ASSIGNMENT
ASTNode:NodeList:updateCursors:Block:Block:c
ASTNode:CYCLE_RISK
ASTNode:reapPropertyList
ASTNode:appendPrintString
ASTNode:TYPE_LITERAL
ASTNode:addProperty
ASTNode:appendDebugString
ASTNode:PROTECT
ASTNode:setProperty:Block:Block:m
ASTNode:METHOD_REF
ASTNode:unsupportedIn2
ASTNode:WILDCARD_TYPE
ASTNode:UNION_TYPE
ASTNode:TRY_STATEMENT
ASTNode:TYPE_DECLARATION_STATEMENT
ASTNode:setNodeType
ASTNode:INITIALIZER
ASTNode:NodeList:propertyDescriptor
ASTNode:IMPORT_DECLARATION
ASTNode:SIMPLE_NAME
ASTNode:standardToString
ASTNode:properties
ASTNode:FOR_STATEMENT
ASTNode:checkNewChild:Block:childClass
ASTNode:setStructuralProperty:Block:Block:child
ASTNode:MODIFIER
ASTNode:equals
ASTNode:NodeList:add
ASTNode:NodeList:listSize:Block:result
ASTNode:internalGetSetChildProperty
ASTNode:toString:Block:buffer
ASTNode:memSize
ASTNode:clone0
ASTNode:copySubtrees:Block:result
ASTNode:ast
ASTNode:unsupportedBelow9
ASTNode:BASE_NODE_SIZE
ASTNode:VARIABLE_DECLARATION_STATEMENT
ASTNode:SWITCH_STATEMENT
ASTNode:SWITCH_EXPRESSION
ASTNode:getProperty
ASTNode:SUPER_FIELD_ACCESS
ASTNode:NodeList:listSize
ASTNode:NodeList:set:Block:newChild
ASTNode:getProperty:Block:m
ASTNode:METHOD_REF_PARAMETER
ASTNode:TYPE_PATTERN
ASTNode:NodeList:add:Block:newChild
ASTNode:EXPRESSION_METHOD_REFERENCE
ASTNode:NodeList:Cursor:update
ASTNode:CAST_EXPRESSION
ASTNode:ANNOTATION_TYPE_MEMBER_DECLARATION
ASTNode:STRING_LITERAL
ASTNode:EXPRESSION_STATEMENT
ASTNode:TYPE_PARAMETER
ASTNode:POSTFIX_EXPRESSION
ASTNode:NodeList:set
ASTNode:VARIABLE_DECLARATION_FRAGMENT
ASTNode:USES_DIRECTIVE
ASTNode:getStructuralProperty:Block:Block:Block:result
ASTNode:setNodeType:Block:old
ASTNode:MEMBER_VALUE_PAIR
ASTNode:SYNCHRONIZED_STATEMENT
ASTNode:internalGetSetBooleanProperty
ASTNode:MARKER_ANNOTATION
ASTNode:PATTERN_INSTANCEOF_EXPRESSION
ASTNode:getFlags
ASTNode:NodeList:memSize:Block:result
ASTNode:checkModifiable
ASTNode:NodeList:releaseCursor
ASTNode:COMPILATION_UNIT
ASTNode:OPTIONAL
ASTNode:REQUIRES_DIRECTIVE
ASTNode:NodeList:updateCursors
ASTNode:getStructuralProperty:Block:Block:p
ASTNode:copySubtrees:Block:Block:newNode
ASTNode:startPosition
ASTNode:copySubtree:Block:newNode
ASTNode:clone
ASTNode:SUPER_METHOD_REFERENCE
ASTNode:CATCH_CLAUSE
ASTNode:preReplaceChild
ASTNode:treeSize
ASTNode:clone:Block:c
ASTNode:setProperty:Block:Block:Block:entries
ASTNode:TAG_ELEMENT
ASTNode:ENUM_CONSTANT_DECLARATION
ASTNode:CONTINUE_STATEMENT
ASTNode:NodeList:NodeList
ASTNode:getStructuralProperty
ASTNode:internalGetChildListProperty
ASTNode:delete:Block:p
ASTNode:WHILE_STATEMENT
ASTNode:INTERSECTION_TYPE
ASTNode:getStartPosition
ASTNode:TEXT_BLOCK
ASTNode:NULL_PATTERN
ASTNode:ARRAY_ACCESS
ASTNode:BREAK_STATEMENT
ASTNode:VARIABLE_DECLARATION_EXPRESSION
ASTNode:SIMPLE_TYPE
ASTNode:acceptChildren:Block:cursor
ASTNode:MODULE_MODIFIER
ASTNode:accept
ASTNode:BOOLEAN_LITERAL
ASTNode:copySubtrees
ASTNode:CONDITIONAL_EXPRESSION
ASTNode:NAME_QUALIFIED_TYPE
ASTNode:parent
ASTNode:unsupportedIn2_3_4
ASTNode:FIELD_ACCESS
ASTNode:getLength
ASTNode:METHOD_DECLARATION
ASTNode:MANDATORY
ASTNode:copySubtrees:Block:Block:oldNode
ASTNode:EXPORTS_DIRECTIVE
ASTNode:EMPTY_STATEMENT
ASTNode:unsupportedIn2_3
ASTNode:getAST
ASTNode:LINE_COMMENT
ASTNode:subtreeMatch0
ASTNode:LABELED_STATEMENT
ASTNode:NUMBER_LITERAL
ASTNode:getRoot:Block:Block:p
ASTNode:INFIX_EXPRESSION
ASTNode:PRIMITIVE_TYPE
ASTNode:JAVADOC
ASTNode:hashCode
ASTNode:NodeList:size
ASTNode:ASSERT_STATEMENT
ASTNode:SWITCH_CASE
ASTNode:getRoot:Block:candidate
ASTNode:postValueChange
ASTNode:QUALIFIED_NAME
ASTNode:subtreeMatch
ASTNode:PACKAGE_DECLARATION
ASTNode:RETURN_STATEMENT
ASTNode:getRoot
ASTNode:setStructuralProperty:Block:Block:Block:arg
ASTNode:NodeList:cursors
ASTNode:CASE_DEFAULT_EXPRESSION
ASTNode:supportedOnlyIn2
ASTNode:MALFORMED
ASTNode:setParent
ASTNode:NodeList:memSize
ASTNode:CLASS_INSTANCE_CREATION
ASTNode:NodeList:set:Block:oldChild
ASTNode:reapPropertyList:Block:a
ASTNode:UNMODIFIABLE_EMPTY_MAP
ASTNode:NodeList:Cursor:position
ASTNode:FIELD_DECLARATION
ASTNode:stringSize
ASTNode:ARRAY_TYPE
ASTNode:GUARDED_PATTERN
ASTNode:NodeList:set:Block:result
ASTNode:MODULE_QUALIFIED_NAME
ASTNode:preLazyInit
ASTNode:TEXT_ELEMENT
ASTNode:acceptChildren
ASTNode:SINGLE_MEMBER_ANNOTATION
ASTNode:ANNOTATION_TYPE_DECLARATION
ASTNode:ENHANCED_FOR_STATEMENT
ASTNode:NO_CYCLE_RISK
ASTNode:JAVADOC_REGION
ASTNode:DIMENSION
ASTNode:RECORD_DECLARATION
ASTNode:HEADERS
ASTNode:setProperty:Block:m
ASTNode:supportedOnlyIn2_3_4
ASTNode:typeAndFlags
ASTNode:getNodeType0
ASTNode:BLOCK
ASTNode:toString:Block:p
ASTNode:ORIGINAL
ASTNode:NodeList:get
ASTNode:postReplaceChild
ASTNode:SUPER_METHOD_INVOCATION
ASTNode:MODULE_DECLARATION
ASTNode:CHARACTER_LITERAL
ASTNode:ARRAY_CREATION
ASTNode:NodeList:Cursor:next:Block:result
ASTNode:internalGetSetIntProperty
ASTNode:internalStructuralPropertiesForType
ASTNode:setSourceRange
ASTNode:YIELD_STATEMENT
ASTNode:internalGetSetObjectProperty
ASTNode:RECOVERED
ASTNode:unsupportedWithoutPreviewError
ASTNode:createPropertyList
ASTNode:NORMAL_ANNOTATION
ASTNode:setStructuralProperty:Block:Block:p
ASTNode:checkNewChild
ASTNode:acceptChildren:Block:Block:Block:child
ASTNode:CONSTRUCTOR_INVOCATION
ASTNode:structuralPropertiesForType
ASTNode:ANONYMOUS_CLASS_DECLARATION
ASTNode:SINGLE_VARIABLE_DECLARATION
ASTNode:setFlags
ASTNode:toString
ASTNode:SUPER_CONSTRUCTOR_INVOCATION
ASTNode:BLOCK_COMMENT
ASTNode:MEMBER_REF
ASTNode:preValueChange
ASTNode:INSTANCEOF_EXPRESSION
ASTNode:NodeList:newCursor
ASTNode:NodeList:store
ASTNode:OPENS_DIRECTIVE
ASTNode:THROW_STATEMENT
ASTNode:stringSize:Block:size
ASTNode:setFlags:Block:old
ASTNode:DO_STATEMENT
ASTNode:PARENTHESIZED_EXPRESSION
ASTNode:NodeList:Cursor:hasNext
ASTNode:PREFIX_EXPRESSION
ASTNode:delete
ASTNode:appendPrintString:Block:printer
Members
X