1 /*******************************************************************************
2  * Copyright (c) 2000, 2020 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 
15 package org.eclipse.jdt.core.dom;
16 
17 import java.util.AbstractList;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 
25 import 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" })
128 public 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 	/**
991 	 * Returns the node class for the corresponding node type.
992 	 *
993 	 * @param nodeType AST node type
994 	 * @return the corresponding <code>ASTNode</code> subclass
995 	 * @exception IllegalArgumentException if <code>nodeType</code> is
996 	 * not a legal AST node type
997 	 * @see #getNodeType()
998 	 * @since 3.0
999 	 */
nodeClassForType(int nodeType)1000 	public static Class nodeClassForType(int nodeType) {
1001 		switch (nodeType) {
1002 			case ANNOTATION_TYPE_DECLARATION :
1003 				return AnnotationTypeDeclaration.class;
1004 			case ANNOTATION_TYPE_MEMBER_DECLARATION :
1005 				return AnnotationTypeMemberDeclaration.class;
1006 			case ANONYMOUS_CLASS_DECLARATION :
1007 				return AnonymousClassDeclaration.class;
1008 			case ARRAY_ACCESS :
1009 				return ArrayAccess.class;
1010 			case ARRAY_CREATION :
1011 				return ArrayCreation.class;
1012 			case ARRAY_INITIALIZER :
1013 				return ArrayInitializer.class;
1014 			case ARRAY_TYPE :
1015 				return ArrayType.class;
1016 			case ASSERT_STATEMENT :
1017 				return AssertStatement.class;
1018 			case ASSIGNMENT :
1019 				return Assignment.class;
1020 			case BLOCK :
1021 				return Block.class;
1022 			case BLOCK_COMMENT :
1023 				return BlockComment.class;
1024 			case BOOLEAN_LITERAL :
1025 				return BooleanLiteral.class;
1026 			case BREAK_STATEMENT :
1027 				return BreakStatement.class;
1028 			case CAST_EXPRESSION :
1029 				return CastExpression.class;
1030 			case CATCH_CLAUSE :
1031 				return CatchClause.class;
1032 			case CHARACTER_LITERAL :
1033 				return CharacterLiteral.class;
1034 			case CLASS_INSTANCE_CREATION :
1035 				return ClassInstanceCreation.class;
1036 			case COMPILATION_UNIT :
1037 				return CompilationUnit.class;
1038 			case CONDITIONAL_EXPRESSION :
1039 				return ConditionalExpression.class;
1040 			case CONSTRUCTOR_INVOCATION :
1041 				return ConstructorInvocation.class;
1042 			case CONTINUE_STATEMENT :
1043 				return ContinueStatement.class;
1044 			case CREATION_REFERENCE :
1045 				return CreationReference.class;
1046 			case DIMENSION:
1047 				return Dimension.class;
1048 			case DO_STATEMENT :
1049 				return DoStatement.class;
1050 			case EMPTY_STATEMENT :
1051 				return EmptyStatement.class;
1052 			case ENHANCED_FOR_STATEMENT :
1053 				return EnhancedForStatement.class;
1054 			case ENUM_CONSTANT_DECLARATION :
1055 				return EnumConstantDeclaration.class;
1056 			case ENUM_DECLARATION :
1057 				return EnumDeclaration.class;
1058 			case EXPORTS_DIRECTIVE :
1059 				return ExportsDirective.class;
1060 			case EXPRESSION_METHOD_REFERENCE :
1061 				return ExpressionMethodReference.class;
1062 			case EXPRESSION_STATEMENT :
1063 				return ExpressionStatement.class;
1064 			case FIELD_ACCESS :
1065 				return FieldAccess.class;
1066 			case FIELD_DECLARATION :
1067 				return FieldDeclaration.class;
1068 			case FOR_STATEMENT :
1069 				return ForStatement.class;
1070 			case IF_STATEMENT :
1071 				return IfStatement.class;
1072 			case IMPORT_DECLARATION :
1073 				return ImportDeclaration.class;
1074 			case INFIX_EXPRESSION :
1075 				return InfixExpression.class;
1076 			case INITIALIZER :
1077 				return Initializer.class;
1078 			case INSTANCEOF_EXPRESSION :
1079 				return InstanceofExpression.class;
1080 			case INTERSECTION_TYPE:
1081 				return IntersectionType.class;
1082 			case JAVADOC :
1083 				return Javadoc.class;
1084 			case LABELED_STATEMENT :
1085 				return LabeledStatement.class;
1086 			case LAMBDA_EXPRESSION :
1087 				return LambdaExpression.class;
1088 			case LINE_COMMENT :
1089 				return LineComment.class;
1090 			case MARKER_ANNOTATION :
1091 				return MarkerAnnotation.class;
1092 			case MEMBER_REF :
1093 				return MemberRef.class;
1094 			case MEMBER_VALUE_PAIR :
1095 				return MemberValuePair.class;
1096 			case METHOD_DECLARATION :
1097 				return MethodDeclaration.class;
1098 			case METHOD_INVOCATION :
1099 				return MethodInvocation.class;
1100 			case METHOD_REF :
1101 				return MethodRef.class;
1102 			case METHOD_REF_PARAMETER :
1103 				return MethodRefParameter.class;
1104 			case MODIFIER :
1105 				return Modifier.class;
1106 			case MODULE_DECLARATION :
1107 				return ModuleDeclaration.class;
1108 			case MODULE_MODIFIER :
1109 				return ModuleModifier.class;
1110 			case NAME_QUALIFIED_TYPE :
1111 				return NameQualifiedType.class;
1112 			case NORMAL_ANNOTATION :
1113 				return NormalAnnotation.class;
1114 			case NULL_LITERAL :
1115 				return NullLiteral.class;
1116 			case NUMBER_LITERAL :
1117 				return NumberLiteral.class;
1118 			case OPENS_DIRECTIVE :
1119 				return OpensDirective.class;
1120 			case PACKAGE_DECLARATION :
1121 				return PackageDeclaration.class;
1122 			case PARAMETERIZED_TYPE :
1123 				return ParameterizedType.class;
1124 			case PARENTHESIZED_EXPRESSION :
1125 				return ParenthesizedExpression.class;
1126 			case POSTFIX_EXPRESSION :
1127 				return PostfixExpression.class;
1128 			case PREFIX_EXPRESSION :
1129 				return PrefixExpression.class;
1130 			case PRIMITIVE_TYPE :
1131 				return PrimitiveType.class;
1132 			case PROVIDES_DIRECTIVE :
1133 				return ProvidesDirective.class;
1134 			case QUALIFIED_NAME :
1135 				return QualifiedName.class;
1136 			case QUALIFIED_TYPE :
1137 				return QualifiedType.class;
1138 			case RECORD_DECLARATION :
1139 				return RecordDeclaration.class;
1140 			case REQUIRES_DIRECTIVE :
1141 				return RequiresDirective.class;
1142 			case RETURN_STATEMENT :
1143 				return ReturnStatement.class;
1144 			case SIMPLE_NAME :
1145 				return SimpleName.class;
1146 			case SIMPLE_TYPE :
1147 				return SimpleType.class;
1148 			case SINGLE_MEMBER_ANNOTATION :
1149 				return SingleMemberAnnotation.class;
1150 			case SINGLE_VARIABLE_DECLARATION :
1151 				return SingleVariableDeclaration.class;
1152 			case STRING_LITERAL :
1153 				return StringLiteral.class;
1154 			case SUPER_CONSTRUCTOR_INVOCATION :
1155 				return SuperConstructorInvocation.class;
1156 			case SUPER_FIELD_ACCESS :
1157 				return SuperFieldAccess.class;
1158 			case SUPER_METHOD_INVOCATION :
1159 				return SuperMethodInvocation.class;
1160 			case SUPER_METHOD_REFERENCE :
1161 				return SuperMethodReference.class;
1162 			case SWITCH_CASE:
1163 				return SwitchCase.class;
1164 			case SWITCH_STATEMENT :
1165 				return SwitchStatement.class;
1166 			case SWITCH_EXPRESSION :
1167 				return SwitchExpression.class;
1168 			case SYNCHRONIZED_STATEMENT :
1169 				return SynchronizedStatement.class;
1170 			case TAG_ELEMENT :
1171 				return TagElement.class;
1172 			case TEXT_BLOCK :
1173 				return TextBlock.class;
1174 			case TEXT_ELEMENT :
1175 				return TextElement.class;
1176 			case THIS_EXPRESSION :
1177 				return ThisExpression.class;
1178 			case THROW_STATEMENT :
1179 				return ThrowStatement.class;
1180 			case TRY_STATEMENT :
1181 				return TryStatement.class;
1182 			case TYPE_DECLARATION :
1183 				return TypeDeclaration.class;
1184 			case TYPE_DECLARATION_STATEMENT :
1185 				return TypeDeclarationStatement.class;
1186 			case TYPE_METHOD_REFERENCE :
1187 				return TypeMethodReference.class;
1188 			case TYPE_LITERAL :
1189 				return TypeLiteral.class;
1190 			case TYPE_PARAMETER :
1191 				return TypeParameter.class;
1192 			case UNION_TYPE :
1193 				return UnionType.class;
1194 			case USES_DIRECTIVE :
1195 				return UsesDirective.class;
1196 			case VARIABLE_DECLARATION_EXPRESSION :
1197 				return VariableDeclarationExpression.class;
1198 			case VARIABLE_DECLARATION_FRAGMENT :
1199 				return VariableDeclarationFragment.class;
1200 			case VARIABLE_DECLARATION_STATEMENT :
1201 				return VariableDeclarationStatement.class;
1202 			case WHILE_STATEMENT :
1203 				return WhileStatement.class;
1204 			case WILDCARD_TYPE :
1205 				return WildcardType.class;
1206 			case YIELD_STATEMENT :
1207 				return YieldStatement.class;
1208 		}
1209 		throw new IllegalArgumentException();
1210 	}
1211 
1212 	/**
1213 	 * Owning AST.
1214      * <p>
1215      * N.B. This is a private field, but declared as package-visible
1216      * for more efficient access from inner classes.
1217      * </p>
1218 	 */
1219 	final AST ast;
1220 
1221 	/**
1222 	 * Parent AST node, or <code>null</code> if this node is a root.
1223 	 * Initially <code>null</code>.
1224 	 */
1225 	private ASTNode parent = null;
1226 
1227 	/**
1228 	 * An unmodifiable empty map (used to implement <code>properties()</code>).
1229 	 */
1230 	private static final Map UNMODIFIABLE_EMPTY_MAP
1231 		= Collections.unmodifiableMap(new HashMap(1));
1232 
1233 	/**
1234 	 * Primary field used in representing node properties efficiently.
1235 	 * If <code>null</code>, this node has no properties.
1236 	 * If a {@link String}, this is the name of this node's sole property,
1237 	 * and <code>property2</code> contains its value.
1238 	 * If a {@link Map}, this is the table of property name-value
1239 	 * mappings; <code>property2</code>, if non-null is its unmodifiable
1240 	 * equivalent.
1241 	 * Initially <code>null</code>.
1242 	 *
1243 	 * @see #property2
1244 	 */
1245 	private Object property1 = null;
1246 
1247 	/**
1248 	 * Auxiliary field used in representing node properties efficiently.
1249 	 *
1250 	 * @see #property1
1251 	 */
1252 	private Object property2 = null;
1253 
1254 	/**
1255 	 * A character index into the original source string,
1256 	 * or <code>-1</code> if no source position information is available
1257 	 * for this node; <code>-1</code> by default.
1258 	 */
1259 	private int startPosition = -1;
1260 
1261 	/**
1262 	 * A character length, or <code>0</code> if no source position
1263 	 * information is recorded for this node; <code>0</code> by default.
1264 	 */
1265 	private int length = 0;
1266 
1267 	/**
1268 	 * Flag constant (bit mask, value 1) indicating that there is something
1269 	 * not quite right with this AST node.
1270 	 * <p>
1271 	 * The standard parser (<code>ASTParser</code>) sets this
1272 	 * flag on a node to indicate a syntax error detected in the vicinity.
1273 	 * </p>
1274 	 */
1275 	public static final int MALFORMED = 1;
1276 
1277 	/**
1278 	 * Flag constant (bit mask, value 2) indicating that this is a node
1279 	 * that was created by the parser (as opposed to one created by another
1280 	 * party).
1281 	 * <p>
1282 	 * The standard parser (<code>ASTParser</code>) sets this
1283 	 * flag on the nodes it creates.
1284 	 * </p>
1285 	 * @since 3.0
1286 	 */
1287 	public static final int ORIGINAL = 2;
1288 
1289 	/**
1290 	 * Flag constant (bit mask, value 4) indicating that this node
1291 	 * is unmodifiable. When a node is marked unmodifiable, the
1292 	 * following operations result in a runtime exception:
1293 	 * <ul>
1294 	 * <li>Change a simple property of this node.</li>
1295 	 * <li>Add or remove a child node from this node.</li>
1296 	 * <li>Parent (or reparent) this node.</li>
1297 	 * </ul>
1298 	 * <p>
1299 	 * The standard parser (<code>ASTParser</code>) does not set
1300 	 * this flag on the nodes it creates. However, clients may set
1301 	 * this flag on a node to prevent further modification of the
1302 	 * its structural properties.
1303 	 * </p>
1304 	 * @since 3.0
1305 	 */
1306 	public static final int PROTECT = 4;
1307 
1308 	/**
1309 	 * Flag constant (bit mask, value 8) indicating that this node
1310 	 * or a part of this node is recovered from source that contains
1311 	 * a syntax error detected in the vicinity.
1312 	 * <p>
1313 	 * The standard parser (<code>ASTParser</code>) sets this
1314 	 * flag on a node to indicate a recovered node.
1315 	 * </p>
1316 	 * @since 3.2
1317 	 */
1318 	public static final int RECOVERED = 8;
1319 
1320 	/**
1321 	 * int containing the node type in the top 16 bits and
1322 	 * flags in the bottom 16 bits; none set by default.
1323      * <p>
1324      * N.B. This is a private field, but declared as package-visible
1325      * for more efficient access from inner classes.
1326      * </p>
1327 	 *
1328 	 * @see #MALFORMED
1329 	 */
1330 	int typeAndFlags = 0;
1331 
1332 	/**
1333 	 * Property of parent in which this node is a child, or <code>null</code>
1334 	 * if this node is a root. Initially <code>null</code>.
1335 	 *
1336 	 * @see #getLocationInParent
1337 	 * @since 3.0
1338 	 */
1339 	private StructuralPropertyDescriptor location = null;
1340 
1341 	/** Internal convenience constant indicating that there is definite risk of cycles.
1342 	 * @see ChildPropertyDescriptor#cycleRisk()
1343 	 * @see ChildListPropertyDescriptor#cycleRisk()
1344 	 * @since 3.0
1345 	 */
1346 	static final boolean CYCLE_RISK = true;
1347 
1348 	/** Internal convenience constant indicating that there is no risk of cycles.
1349 	 * @see ChildPropertyDescriptor#cycleRisk()
1350 	 * @see ChildListPropertyDescriptor#cycleRisk()
1351 	 * @since 3.0
1352 	 */
1353 	static final boolean NO_CYCLE_RISK = false;
1354 
1355 	/** Internal convenience constant indicating that a structural property is mandatory.
1356 	 * @since 3.0
1357 	 */
1358 	static final boolean MANDATORY = true;
1359 
1360 	/** Internal convenience constant indicating that a structural property is optional.
1361 	 * @since 3.0
1362 	 */
1363 	static final boolean OPTIONAL = false;
1364 
1365 	/**
1366 	 * A specialized implementation of a list of ASTNodes. The
1367 	 * implementation is based on an ArrayList.
1368 	 */
1369 	class NodeList extends AbstractList {
1370 
1371 		/**
1372 		 * The underlying list in which the nodes of this list are
1373 		 * stored (element type: {@link ASTNode}).
1374 		 * <p>
1375 		 * Be stingy on storage - assume that list will be empty.
1376 		 * </p>
1377 		 * <p>
1378 		 * This field declared default visibility (rather than private)
1379 		 * so that accesses from <code>NodeList.Cursor</code> do not require
1380 		 * a synthetic accessor method.
1381 		 * </p>
1382 		 */
1383 		ArrayList store = new ArrayList(0);
1384 
1385 		/**
1386 		 * The property descriptor for this list.
1387 		 */
1388 		ChildListPropertyDescriptor propertyDescriptor;
1389 
1390 		/**
1391 		 * A cursor for iterating over the elements of the list.
1392 		 * Does not lose its position if the list is changed during
1393 		 * the iteration.
1394 		 */
1395 		class Cursor implements Iterator {
1396 			/**
1397 			 * The position of the cursor between elements. If the value
1398 			 * is N, then the cursor sits between the element at positions
1399 			 * N-1 and N. Initially just before the first element of the
1400 			 * list.
1401 			 */
1402 			private int position = 0;
1403 
1404 			@Override
hasNext()1405 			public boolean hasNext() {
1406 				return this.position < NodeList.this.store.size();
1407 			}
1408 
1409 			@Override
next()1410 			public Object next() {
1411 				Object result = NodeList.this.store.get(this.position);
1412 				this.position++;
1413 				return result;
1414 		    }
1415 
1416 			@Override
remove()1417 			public void remove() {
1418 				throw new UnsupportedOperationException();
1419 			}
1420 
1421 			/**
1422 			 * Adjusts this cursor to accommodate an add/remove at the given
1423 			 * index.
1424 			 *
1425 			 * @param index the position at which the element was added
1426 			 *    or removed
1427 			 * @param delta +1 for add, and -1 for remove
1428 			 */
update(int index, int delta)1429 			void update(int index, int delta) {
1430 				if (this.position > index) {
1431 					// the cursor has passed the added or removed element
1432 					this.position += delta;
1433 				}
1434 			}
1435 		}
1436 
1437 		/**
1438 		 * A list of currently active cursors (element type:
1439 		 * {@link Cursor}), or <code>null</code> if there are no
1440 		 * active cursors.
1441 		 * <p>
1442 		 * It is important for storage considerations to maintain the
1443 		 * null-means-empty invariant; otherwise, every NodeList instance
1444 		 * will waste a lot of space. A cursor is needed only for the duration
1445 		 * of a visit to the child nodes. Under normal circumstances, only a
1446 		 * single cursor is needed; multiple cursors are only required if there
1447 		 * are multiple visits going on at the same time.
1448 		 * </p>
1449 		 */
1450 		private List cursors = null;
1451 
1452 		/**
1453 		 * Creates a new empty list of nodes owned by this node.
1454 		 * This node will be the common parent of all nodes added to
1455 		 * this list.
1456 		 *
1457 		 * @param property the property descriptor
1458 		 * @since 3.0
1459 		 */
NodeList(ChildListPropertyDescriptor property)1460 		NodeList(ChildListPropertyDescriptor property) {
1461 			super();
1462 			this.propertyDescriptor = property;
1463 		}
1464 
1465 		@Override
size()1466 		public int size() {
1467 			return this.store.size();
1468 		}
1469 
1470 		@Override
get(int index)1471 		public Object get(int index) {
1472 			return this.store.get(index);
1473 		}
1474 
1475 		@Override
set(int index, Object element)1476 		public Object set(int index, Object element) {
1477 		    if (element == null) {
1478 		        throw new IllegalArgumentException();
1479 		    }
1480 			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
1481 				// this node is protected => cannot gain or lose children
1482 				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1483 			}
1484 			// delink old child from parent, and link new child to parent
1485 			ASTNode newChild = (ASTNode) element;
1486 			ASTNode oldChild = (ASTNode) this.store.get(index);
1487 			if (oldChild == newChild) {
1488 				return oldChild;
1489 			}
1490 			if ((oldChild.typeAndFlags & PROTECT) != 0) {
1491 				// old child is protected => cannot be unparented
1492 				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1493 			}
1494 			ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
1495 			ASTNode.this.ast.preReplaceChildEvent(ASTNode.this, oldChild, newChild, this.propertyDescriptor);
1496 
1497 			Object result = this.store.set(index, newChild);
1498 			// n.b. setParent will call ast.modifying()
1499 			oldChild.setParent(null, null);
1500 			newChild.setParent(ASTNode.this, this.propertyDescriptor);
1501 			ASTNode.this.ast.postReplaceChildEvent(ASTNode.this, oldChild, newChild, this.propertyDescriptor);
1502 			return result;
1503 		}
1504 
1505 		@Override
add(int index, Object element)1506 		public void add(int index, Object element) {
1507 		    if (element == null) {
1508 		        throw new IllegalArgumentException();
1509 		    }
1510 			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
1511 				// this node is protected => cannot gain or lose children
1512 				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1513 			}
1514 			// link new child to parent
1515 			ASTNode newChild = (ASTNode) element;
1516 			ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
1517 			ASTNode.this.ast.preAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
1518 
1519 
1520 			this.store.add(index, element);
1521 			updateCursors(index, +1);
1522 			// n.b. setParent will call ast.modifying()
1523 			newChild.setParent(ASTNode.this, this.propertyDescriptor);
1524 			ASTNode.this.ast.postAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
1525 		}
1526 
1527 		@Override
remove(int index)1528 		public Object remove(int index) {
1529 			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
1530 				// this node is protected => cannot gain or lose children
1531 				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1532 			}
1533 			// delink old child from parent
1534 			ASTNode oldChild = (ASTNode) this.store.get(index);
1535 			if ((oldChild.typeAndFlags & PROTECT) != 0) {
1536 				// old child is protected => cannot be unparented
1537 				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
1538 			}
1539 
1540 			ASTNode.this.ast.preRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
1541 			// n.b. setParent will call ast.modifying()
1542 			oldChild.setParent(null, null);
1543 			Object result = this.store.remove(index);
1544 			updateCursors(index, -1);
1545 			ASTNode.this.ast.postRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
1546 			return result;
1547 
1548 		}
1549 
1550 		/**
1551 		 * Allocate a cursor to use for a visit. The client must call
1552 		 * <code>releaseCursor</code> when done.
1553 		 * <p>
1554 		 * This method is internally synchronized on this NodeList.
1555 		 * It is thread-safe to create a cursor.
1556 		 * </p>
1557 		 *
1558 		 * @return a new cursor positioned before the first element
1559 		 *    of the list
1560 		 */
newCursor()1561 		Cursor newCursor() {
1562 			synchronized (this) {
1563 				// serialize cursor management on this NodeList
1564 				if (this.cursors == null) {
1565 					// convert null to empty list
1566 					this.cursors = new ArrayList(1);
1567 				}
1568 				Cursor result = new Cursor();
1569 				this.cursors.add(result);
1570 				return result;
1571 			}
1572 		}
1573 
1574 		/**
1575 		 * Releases the given cursor at the end of a visit.
1576 		 * <p>
1577 		 * This method is internally synchronized on this NodeList.
1578 		 * It is thread-safe to release a cursor.
1579 		 * </p>
1580 		 *
1581 		 * @param cursor the cursor
1582 		 */
releaseCursor(Cursor cursor)1583 		void releaseCursor(Cursor cursor) {
1584 			synchronized (this) {
1585 				// serialize cursor management on this NodeList
1586 				this.cursors.remove(cursor);
1587 				if (this.cursors.isEmpty()) {
1588 					// important: convert empty list back to null
1589 					// otherwise the node will hang on to needless junk
1590 					this.cursors = null;
1591 				}
1592 			}
1593 		}
1594 
1595 		/**
1596 		 * Adjusts all cursors to accommodate an add/remove at the given
1597 		 * index.
1598 		 * <p>
1599 		 * This method is only used when the list is being modified.
1600 		 * The AST is not thread-safe if any of the clients are modifying it.
1601 		 * </p>
1602 		 *
1603 		 * @param index the position at which the element was added
1604 		 *    or removed
1605 		 * @param delta +1 for add, and -1 for remove
1606 		 */
updateCursors(int index, int delta)1607 		private synchronized void updateCursors(int index, int delta) {
1608 			if (this.cursors == null) {
1609 				// there are no cursors to worry about
1610 				return;
1611 			}
1612 			for (Iterator it = this.cursors.iterator(); it.hasNext(); ) {
1613 				Cursor c = (Cursor) it.next();
1614 				c.update(index, delta);
1615 			}
1616 		}
1617 
1618 		/**
1619 		 * Returns an estimate of the memory footprint of this node list
1620 		 * instance in bytes.
1621 	     * <ul>
1622 	     * <li>1 object header for the NodeList instance</li>
1623 	     * <li>5 4-byte fields of the NodeList instance</li>
1624 	     * <li>0 for cursors since null unless walk in progress</li>
1625 	     * <li>1 object header for the ArrayList instance</li>
1626 	     * <li>2 4-byte fields of the ArrayList instance</li>
1627 	     * <li>1 object header for an Object[] instance</li>
1628 	     * <li>4 bytes in array for each element</li>
1629 	     * </ul>
1630 	 	 *
1631 		 * @return the size of this node list in bytes
1632 		 */
memSize()1633 		int memSize() {
1634 			int result = HEADERS + 5 * 4;
1635 			result += HEADERS + 2 * 4;
1636 			result += HEADERS + 4 * size();
1637 			return result;
1638 		}
1639 
1640 		/**
1641 		 * Returns an estimate of the memory footprint in bytes of this node
1642 		 * list and all its subtrees.
1643 		 *
1644 		 * @return the size of this list of subtrees in bytes
1645 		 */
listSize()1646 		int listSize() {
1647 			int result = memSize();
1648 			for (Iterator it = iterator(); it.hasNext(); ) {
1649 				ASTNode child = (ASTNode) it.next();
1650 				result += child.treeSize();
1651 			}
1652 			return result;
1653 		}
1654 	}
1655 
1656 	/**
1657 	 * Creates a new AST node owned by the given AST. Once established,
1658 	 * the relationship between an AST node and its owning AST does not change
1659 	 * over the lifetime of the node. The new node has no parent node,
1660 	 * and no properties.
1661 	 * <p>
1662 	 * N.B. This constructor is package-private; all subclasses my be
1663 	 * declared in the same package; clients are unable to declare
1664 	 * additional subclasses.
1665 	 * </p>
1666 	 *
1667 	 * @param ast the AST that is to own this node
1668 	 */
ASTNode(AST ast)1669 	ASTNode(AST ast) {
1670 		if (ast == null) {
1671 			throw new IllegalArgumentException();
1672 		}
1673 
1674 		this.ast = ast;
1675 		setNodeType(getNodeType0());
1676 		setFlags(ast.getDefaultNodeFlag());
1677 		// setFlags calls modifying();
1678 	}
1679 
1680 	/**
1681 	 * Returns this node's AST.
1682 	 * <p>
1683 	 * Note that the relationship between an AST node and its owing AST does
1684 	 * not change over the lifetime of a node.
1685 	 * </p>
1686 	 *
1687 	 * @return the AST that owns this node
1688 	 */
getAST()1689 	public final AST getAST() {
1690 		return this.ast;
1691 	}
1692 
1693 	/**
1694 	 * Returns this node's parent node, or <code>null</code> if this is the
1695 	 * root node.
1696 	 * <p>
1697 	 * Note that the relationship between an AST node and its parent node
1698 	 * may change over the lifetime of a node.
1699 	 * </p>
1700 	 *
1701 	 * @return the parent of this node, or <code>null</code> if none
1702 	 */
getParent()1703 	public final ASTNode getParent() {
1704 		return this.parent;
1705 	}
1706 
1707 	/**
1708 	 * Returns the location of this node within its parent,
1709 	 * or <code>null</code> if this is a root node.
1710 	 * <pre>
1711 	 * ASTNode node = ...;
1712 	 * ASTNode parent = node.getParent();
1713 	 * StructuralPropertyDescriptor location = node.getLocationInParent();
1714 	 * assert (parent != null) == (location != null);
1715 	 * if ((location != null) && location.isChildProperty())
1716 	 *    assert parent.getStructuralProperty(location) == node;
1717 	 * if ((location != null) && location.isChildListProperty())
1718 	 *    assert ((List) parent.getStructuralProperty(location)).contains(node);
1719 	 * </pre>
1720 	 * <p>
1721 	 * Note that the relationship between an AST node and its parent node
1722 	 * may change over the lifetime of a node.
1723 	 * </p>
1724 	 *
1725 	 * @return the location of this node in its parent,
1726 	 * or <code>null</code> if this node has no parent
1727 	 * @since 3.0
1728 	 */
getLocationInParent()1729 	public final StructuralPropertyDescriptor getLocationInParent() {
1730 		return this.location;
1731 	}
1732 
1733 	/**
1734 	 * Returns the root node at or above this node; returns this node if
1735 	 * it is a root.
1736 	 *
1737 	 * @return the root node at or above this node
1738 	 */
getRoot()1739 	public final ASTNode getRoot() {
1740 		ASTNode candidate = this;
1741 		while (true) {
1742 			ASTNode p = candidate.getParent();
1743 			if (p == null) {
1744 				// candidate has no parent - that's the guy
1745 				return candidate;
1746 			}
1747 			candidate = p;
1748 		}
1749 	}
1750 
1751 	/**
1752 	 * Returns the value of the given structural property for this node. The value
1753 	 * returned depends on the kind of property:
1754 	 * <ul>
1755 	 * <li>{@link SimplePropertyDescriptor} - the value of the given simple property,
1756 	 * or <code>null</code> if none; primitive values are "boxed"</li>
1757 	 * <li>{@link ChildPropertyDescriptor} - the child node (type <code>ASTNode</code>),
1758 	 * or <code>null</code> if none</li>
1759 	 * <li>{@link ChildListPropertyDescriptor} - the list (element type: {@link ASTNode})</li>
1760 	 * </ul>
1761 	 *
1762 	 * @param property the property
1763 	 * @return the value, or <code>null</code> if none
1764 	 * @exception RuntimeException if this node does not have the given property
1765 	 * @since 3.0
1766 	 */
getStructuralProperty(StructuralPropertyDescriptor property)1767 	public final Object getStructuralProperty(StructuralPropertyDescriptor property) {
1768 		if (property instanceof SimplePropertyDescriptor) {
1769 			SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
1770 			if (p.getValueType() == int.class) {
1771 				int result = internalGetSetIntProperty(p, true, 0);
1772 				return Integer.valueOf(result);
1773 			} else if (p.getValueType() == boolean.class) {
1774 				boolean result = internalGetSetBooleanProperty(p, true, false);
1775 				return Boolean.valueOf(result);
1776 			} else {
1777 				return internalGetSetObjectProperty(p, true, null);
1778 			}
1779 		}
1780 		if (property instanceof ChildPropertyDescriptor) {
1781 			return internalGetSetChildProperty((ChildPropertyDescriptor) property, true, null);
1782 		}
1783 		if (property instanceof ChildListPropertyDescriptor) {
1784 			return internalGetChildListProperty((ChildListPropertyDescriptor) property);
1785 		}
1786 		throw new IllegalArgumentException();
1787 	}
1788 
1789 	/**
1790 	 * Sets the value of the given structural property for this node. The value
1791 	 * passed depends on the kind of property:
1792 	 * <ul>
1793 	 * <li>{@link SimplePropertyDescriptor} - the new value of the given simple property,
1794 	 * or <code>null</code> if none; primitive values are "boxed"</li>
1795 	 * <li>{@link ChildPropertyDescriptor} - the new child node (type <code>ASTNode</code>),
1796 	 * or <code>null</code> if none</li>
1797 	 * <li>{@link ChildListPropertyDescriptor} - not allowed</li>
1798 	 * </ul>
1799 	 *
1800 	 * @param property the property
1801 	 * @param value the property value
1802 	 * @exception RuntimeException if this node does not have the
1803 	 * given property, or if the given property cannot be set
1804 	 * @since 3.0
1805 	 */
setStructuralProperty(StructuralPropertyDescriptor property, Object value)1806 	public final void setStructuralProperty(StructuralPropertyDescriptor property, Object value) {
1807 		if (property instanceof SimplePropertyDescriptor) {
1808 			SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
1809 			if (p.getValueType() == int.class) {
1810 				int arg = ((Integer) value).intValue();
1811 				internalGetSetIntProperty(p, false, arg);
1812 				return;
1813 			} else if (p.getValueType() == boolean.class) {
1814 				boolean arg = ((Boolean) value).booleanValue();
1815 				internalGetSetBooleanProperty(p, false, arg);
1816 				return;
1817 			} else {
1818 				if (value == null && p.isMandatory()) {
1819 					throw new IllegalArgumentException();
1820 				}
1821 				internalGetSetObjectProperty(p, false, value);
1822 				return;
1823 			}
1824 		}
1825 		if (property instanceof ChildPropertyDescriptor) {
1826 			ChildPropertyDescriptor p = (ChildPropertyDescriptor) property;
1827 			ASTNode child = (ASTNode) value;
1828 			if (child == null && p.isMandatory()) {
1829 				throw new IllegalArgumentException();
1830 			}
1831 			internalGetSetChildProperty(p, false, child);
1832 			return;
1833 		}
1834 		if (property instanceof ChildListPropertyDescriptor) {
1835 			throw new IllegalArgumentException("Cannot set the list of child list property");  //$NON-NLS-1$
1836 		}
1837 	}
1838 
1839 	/**
1840 	 * Sets the value of the given int-valued property for this node.
1841 	 * The default implementation of this method throws an exception explaining
1842 	 * that this node does not have such a property. This method should be
1843 	 * extended in subclasses that have at least one simple property whose value
1844 	 * type is int.
1845 	 *
1846 	 * @param property the property
1847 	 * @param get <code>true</code> for a get operation, and
1848 	 * <code>false</code> for a set operation
1849 	 * @param value the new property value; ignored for get operations
1850 	 * @return the value; always returns
1851 	 * <code>0</code> for set operations
1852 	 * @exception RuntimeException if this node does not have the
1853 	 * given property, or if the given value cannot be set as specified
1854 	 * @since 3.0
1855 	 */
internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value)1856 	int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
1857 		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1858 	}
1859 
1860 	/**
1861 	 * Sets the value of the given boolean-valued property for this node.
1862 	 * The default implementation of this method throws an exception explaining
1863 	 * that this node does not have such a property. This method should be
1864 	 * extended in subclasses that have at least one simple property whose value
1865 	 * type is boolean.
1866 	 *
1867 	 * @param property the property
1868 	 * @param get <code>true</code> for a get operation, and
1869 	 * <code>false</code> for a set operation
1870 	 * @param value the new property value; ignored for get operations
1871 	 * @return the value; always returns
1872 	 * <code>false</code> for set operations
1873 	 * @exception RuntimeException if this node does not have the
1874 	 * given property, or if the given value cannot be set as specified
1875 	 * @since 3.0
1876 	 */
internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value)1877 	boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
1878 		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1879 	}
1880 
1881 	/**
1882 	 * Sets the value of the given property for this node.
1883 	 * The default implementation of this method throws an exception explaining
1884 	 * that this node does not have such a property. This method should be
1885 	 * extended in subclasses that have at least one simple property whose value
1886 	 * type is a reference type.
1887 	 *
1888 	 * @param property the property
1889 	 * @param get <code>true</code> for a get operation, and
1890 	 * <code>false</code> for a set operation
1891 	 * @param value the new property value, or <code>null</code> if none;
1892 	 * ignored for get operations
1893 	 * @return the value, or <code>null</code> if none; always returns
1894 	 * <code>null</code> for set operations
1895 	 * @exception RuntimeException if this node does not have the
1896 	 * given property, or if the given value cannot be set as specified
1897 	 * @since 3.0
1898 	 */
internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value)1899 	Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
1900 		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1901 	}
1902 
1903 	/**
1904 	 * Sets the child value of the given property for this node.
1905 	 * The default implementation of this method throws an exception explaining
1906 	 * that this node does not have such a property. This method should be
1907 	 * extended in subclasses that have at least one child property.
1908 	 *
1909 	 * @param property the property
1910 	 * @param get <code>true</code> for a get operation, and
1911 	 * <code>false</code> for a set operation
1912 	 * @param child the new child value, or <code>null</code> if none;
1913 	 * always <code>null</code> for get operations
1914 	 * @return the child, or <code>null</code> if none; always returns
1915 	 * <code>null</code> for set operations
1916 	 * @exception RuntimeException if this node does not have the
1917 	 * given property, or if the given child cannot be set as specified
1918 	 * @since 3.0
1919 	 */
internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child)1920 	ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
1921 		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1922 	}
1923 
1924 	/**
1925 	 * Returns the list value of the given property for this node.
1926 	 * The default implementation of this method throws an exception explaining
1927 	 * that this node does not have such a property. This method should be
1928 	 * extended in subclasses that have at least one child list property.
1929 	 *
1930 	 * @param property the property
1931 	 * @return the list (element type: {@link ASTNode})
1932 	 * @exception RuntimeException if the given node does not have the
1933 	 * given property
1934 	 * @since 3.0
1935 	 */
internalGetChildListProperty(ChildListPropertyDescriptor property)1936 	List internalGetChildListProperty(ChildListPropertyDescriptor property) {
1937 		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
1938 	}
1939 
1940 	/**
1941 	 * Returns a list of structural property descriptors for nodes of the
1942 	 * same type as this node. Clients must not modify the result.
1943 	 * <p>
1944 	 * Note that property descriptors are a meta-level mechanism
1945 	 * for manipulating ASTNodes in a generic way. They are
1946 	 * unrelated to <code>get/setProperty</code>.
1947 	 * </p>
1948 	 *
1949 	 * @return a list of property descriptors (element type:
1950 	 * {@link StructuralPropertyDescriptor})
1951 	 * @since 3.0
1952 	 */
structuralPropertiesForType()1953 	public final List structuralPropertiesForType() {
1954 		return internalStructuralPropertiesForType(this.ast.apiLevel, this.ast.isPreviewEnabled());
1955 	}
1956 
1957 	/**
1958 	 * Returns a list of property descriptors for this node type.
1959 	 * Clients must not modify the result. This abstract method
1960 	 * must be implemented in each concrete AST node type.
1961 	 * <p>
1962 	 * N.B. This method is package-private, so that the implementations
1963 	 * of this method in each of the concrete AST node types do not
1964 	 * clutter up the API doc.
1965 	 * </p>
1966 	 *
1967 	 * @param apiLevel the API level; one of the <code>AST.JLS*</code> constants
1968 	 * @return a list of property descriptors (element type:
1969 	 * {@link StructuralPropertyDescriptor})
1970 	 * @since 3.0
1971 	 */
internalStructuralPropertiesForType(int apiLevel)1972 	abstract List internalStructuralPropertiesForType(int apiLevel);
1973 
1974 
1975 	/**
1976 	 * Returns a list of property descriptors for this node type.
1977 	 * Clients must not modify the result. This abstract method
1978 	 * must be implemented in each concrete AST node type.
1979 	 * <p>
1980 	 * N.B. This method is package-private, so that the implementations
1981 	 * of this method in each of the concrete AST node types do not
1982 	 * clutter up the API doc.
1983 	 * </p>
1984 	 *
1985 	 * @param apiLevel the API level; one of the <code>AST.JLS*</code> constants
1986 	 * @param previewEnabled the previewEnabled flag
1987 	 * @return a list of property descriptors (element type:
1988 	 * {@link StructuralPropertyDescriptor})
1989 	 * @since 3.19
1990 	 */
internalStructuralPropertiesForType(int apiLevel, boolean previewEnabled)1991 	List internalStructuralPropertiesForType(int apiLevel, boolean previewEnabled) {
1992 		return internalStructuralPropertiesForType(apiLevel);
1993 	}
1994 
1995 	/**
1996 	 * Internal helper method that starts the building a list of
1997 	 * property descriptors for the given node type.
1998 	 *
1999 	 * @param nodeClass the class for a concrete node type with n properties
2000 	 * @param propertyList empty list, with capacity for n+1 elements
2001 	 */
createPropertyList(Class nodeClass, List propertyList)2002 	static void createPropertyList(Class nodeClass, List propertyList) {
2003 		// stuff nodeClass at head of list for future ref
2004 		propertyList.add(nodeClass);
2005 	}
2006 
2007 	/**
2008 	 * Internal helper method that adding a property descriptor.
2009 	 *
2010 	 * @param property the structural property descriptor
2011 	 * @param propertyList list beginning with the AST node class
2012 	 * followed by accumulated structural property descriptors
2013 	 */
addProperty(StructuralPropertyDescriptor property, List propertyList)2014 	static void addProperty(StructuralPropertyDescriptor property, List propertyList) {
2015 		Class nodeClass = (Class) propertyList.get(0);
2016 		if (property.getNodeClass() != nodeClass) {
2017 			// easily made cut-and-paste mistake
2018 			throw new RuntimeException("Structural property descriptor has wrong node class!");  //$NON-NLS-1$
2019 		}
2020 		propertyList.add(property);
2021 	}
2022 
2023 	/**
2024 	 * Internal helper method that completes the building of
2025 	 * a node type's structural property descriptor list.
2026 	 *
2027 	 * @param propertyList list beginning with the AST node class
2028 	 * followed by accumulated structural property descriptors
2029 	 * @return unmodifiable list of structural property descriptors
2030 	 * (element type: {@link StructuralPropertyDescriptor})
2031 	 */
reapPropertyList(List propertyList)2032 	static List reapPropertyList(List propertyList) {
2033 		propertyList.remove(0); // remove nodeClass
2034 		// compact
2035 		ArrayList a = new ArrayList(propertyList.size());
2036 		a.addAll(propertyList);
2037 		return Collections.unmodifiableList(a);
2038 	}
2039 
2040 	/**
2041      * Checks that this AST operation is not used when
2042      * building JLS2 level ASTs.
2043      * <p>
2044      * Use this method to prevent access to new properties that have been added in JLS3.
2045      * </p>
2046      *
2047 	 * @exception UnsupportedOperationException if this operation is used in a JLS2 AST
2048 	 * @since 3.0
2049      */
unsupportedIn2()2050 	final void unsupportedIn2() {
2051 	  if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
2052 	  	throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
2053 	  }
2054 	}
2055 
2056 	/**
2057      * Checks that this AST operation is not used when
2058      * building JLS2 or JLS3 level ASTs.
2059      * <p>
2060      * Use this method to prevent access to new properties that have been added in JLS4.
2061      * </p>
2062      *
2063 	 * @exception UnsupportedOperationException if this operation is used in a JLS2 or JLS3 AST
2064 	 * @since 3.7
2065 	 */
unsupportedIn2_3()2066 	final void unsupportedIn2_3() {
2067 		if (this.ast.apiLevel <= AST.JLS3_INTERNAL) {
2068 			throw new UnsupportedOperationException("Operation only supported in JLS4 and later AST"); //$NON-NLS-1$
2069 		}
2070 	}
2071 
2072 	/**
2073      * Checks that this AST operation is not used when
2074      * building JLS2 or JLS3 or JLS4 level ASTs.
2075      * <p>
2076      * Use this method to prevent access to new properties that have been added in JLS8.
2077      * </p>
2078      *
2079 	 * @exception UnsupportedOperationException if this operation is used below JLS8
2080 	 * @since 3.10
2081 	 */
unsupportedIn2_3_4()2082 	final void unsupportedIn2_3_4() {
2083 		if (this.ast.apiLevel < AST.JLS8_INTERNAL) {
2084 			throw new UnsupportedOperationException("Operation only supported in JLS8 and later AST"); //$NON-NLS-1$
2085 		}
2086 	}
2087 
2088 	/**
2089      * Checks that this AST operation is not used when
2090      * building JLS2, JLS3, JLS4 or JLS8 level ASTs.
2091      * <p>
2092      * Use this method to prevent access to new properties that have been added in JLS9.
2093      * </p>
2094      *
2095 	 * @exception UnsupportedOperationException if this operation is used below JLS9
2096 	 * @since 3.14
2097 	 */
unsupportedBelow9()2098 	final void unsupportedBelow9() {
2099 		if (this.ast.apiLevel < AST.JLS9_INTERNAL) {
2100 			throw new UnsupportedOperationException("Operation only supported in JLS9 and later AST"); //$NON-NLS-1$
2101 		}
2102 	}
2103 	/**
2104      * Checks that this AST operation is not used when
2105      * building JLS2, JLS3, JLS4, JLS8 or JLS9 level ASTs.
2106      * <p>
2107      * Use this method to prevent access to new properties that have been added in JLS10
2108      * </p>
2109      *
2110 	 * @exception UnsupportedOperationException if this operation is used below JLS10
2111 	 * @since 3.14
2112 	 */
unsupportedBelow10()2113 	final void unsupportedBelow10() {
2114 		if (this.ast.apiLevel < AST.JLS10_INTERNAL) {
2115 			throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS10 and above"); //$NON-NLS-1$
2116 		}
2117 	}
2118 	/**
2119      * Checks that this AST operation is not used when
2120      * building JLS2, JLS3, JLS4, JLS8, JLS9 or JLS10 level ASTs.
2121      * <p>
2122      * Use this method to prevent access to new properties that have been added in JLS11
2123      * </p>
2124      *
2125 	 * @exception UnsupportedOperationException if this operation is used below JLS11
2126 	 * @since 3.14
2127 	 */
unsupportedBelow11()2128 	final void unsupportedBelow11() {
2129 		if (this.ast.apiLevel < AST.JLS11_INTERNAL) {
2130 			throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS11 and above"); //$NON-NLS-1$
2131 		}
2132 	}
2133 
2134 	/**
2135      * Checks that this AST operation is not used when
2136      * building JLS2, JLS3, JLS4, JLS8, JLS9,JLS10 or JLS11 level ASTs.
2137      * <p>
2138      * Use this method to prevent access to new properties that have been added in JLS12
2139      * </p>
2140      *
2141 	 * @exception UnsupportedOperationException if this operation is used below JLS12
2142 	 * @deprecated
2143 	 * @since 3.16
2144 	 */
unsupportedBelow12()2145 	final void unsupportedBelow12() {
2146 		if (this.ast.apiLevel < AST.JLS12_INTERNAL) {
2147 			throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS12 and above"); //$NON-NLS-1$
2148 		}
2149 	}
2150 
2151 	/**
2152      * Checks that this AST operation is not used when
2153      * building JLS2, JLS3, JLS4, JLS8, JLS9, JLS10, JLS11, JLS12 or JSL13 level ASTs.
2154      * <p>
2155      * Use this method to prevent access to new properties that have been added in JLS14
2156      * </p>
2157      *
2158 	 * @exception UnsupportedOperationException if this operation is used below JLS14
2159 	 * @since 3.22
2160 	 */
unsupportedBelow14()2161 	final void unsupportedBelow14() {
2162 		if (this.ast.apiLevel < AST.JLS14_INTERNAL) {
2163 			throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS14 and above"); //$NON-NLS-1$
2164 		}
2165 	}
2166 
2167 
2168 	/**
2169      * Checks that this AST operation is not used when
2170      * building ASTs without previewEnabled flag.
2171      * <p>
2172      * Use this method to prevent access to new properties that have been added with preview feature
2173      * </p>
2174      *
2175 	 * @exception UnsupportedOperationException if this operation is used with previewEnabled flag as false
2176 	 * @since 3.19
2177 	 */
unsupportedWithoutPreviewError()2178 	final void unsupportedWithoutPreviewError() {
2179 		if (!this.ast.isPreviewEnabled()) {
2180 			throw new UnsupportedOperationException("Operation only supported in ASTs with previewEnabled flag as true"); //$NON-NLS-1$
2181 		}
2182 	}
2183 
2184 	/**
2185      * Checks that this AST operation is only used when
2186      * building JLS2 level ASTs.
2187      * <p>
2188      * Use this method to prevent access to deprecated properties (deprecated in JLS3).
2189      * </p>
2190      *
2191 	 * @exception UnsupportedOperationException if this operation is used in an AST later than JLS2
2192 	 * @since 3.0
2193      */
2194 	// In API Javadocs, add: * @deprecated In the JLS3 API, this method is replaced by {@link #replacement()}.
supportedOnlyIn2()2195 	final void supportedOnlyIn2() {
2196 	  if (this.ast.apiLevel != AST.JLS2_INTERNAL) {
2197 	  	throw new UnsupportedOperationException("Operation only supported in JLS2 AST"); //$NON-NLS-1$
2198 	  }
2199 	}
2200 
2201 	/**
2202      * Checks that this AST operation is only used when
2203      * building JLS2, JLS3 or JLS4 level ASTs.
2204      * <p>
2205      * Use this method to prevent access to deprecated properties (deprecated in JLS8).
2206      * </p>
2207      *
2208 	 * @exception UnsupportedOperationException if this operation is used in an AST later than JLS4
2209      * @since 3.10
2210      */
2211 	// In API Javadocs, add: * @deprecated In the JLS8 API, this method is replaced by {@link #replacement()}.
supportedOnlyIn2_3_4()2212 	final void supportedOnlyIn2_3_4() {
2213 	  if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
2214 	  	throw new UnsupportedOperationException("Operation only supported in JLS2, JLS3 and JLS4 ASTs"); //$NON-NLS-1$
2215 	  }
2216 	}
2217 
2218 	/**
2219      * Checks that this AST operation is only used when
2220      * building JLS12 level ASTs.
2221      * <p>
2222      * Use this method to prevent access to properties available only in JLS12.
2223      * </p>
2224      *
2225 	 * @exception UnsupportedOperationException if this operation is is not used in JLS12
2226 	 * @since 3.20
2227      */
2228 	// In API Javadocs, add: * @deprecated In the JLS13 API, this method is replaced by {@link #replacement()}.
supportedOnlyIn12()2229 	final void supportedOnlyIn12() {
2230 	  if (this.ast.apiLevel != AST.JLS12_INTERNAL) {
2231 	  	throw new UnsupportedOperationException("Operation only supported in JLS12 AST"); //$NON-NLS-1$
2232 	  }
2233 	}
2234 
2235 	/**
2236  	 * Checks that this AST operation is only used when
2237      * building JLS13 level ASTs.
2238      * <p>
2239      * Use this method to prevent access to new properties available only in JLS13.
2240      * </p>
2241      *
2242 	 * @exception UnsupportedOperationException if this operation is not used in JLS13
2243 	 * @since 3.20
2244 	 */
supportedOnlyIn13()2245 	final void supportedOnlyIn13() {
2246 		if (this.ast.apiLevel != AST.JLS13_INTERNAL) {
2247 			throw new UnsupportedOperationException("Operation only supported in JLS13 AST"); //$NON-NLS-1$
2248 		}
2249 	}
2250 
2251 	/**
2252  	 * Checks that this AST operation is only used when
2253      * building JLS13 level ASTs.
2254      * <p>
2255      * Use this method to prevent access to new properties available only in JLS14.
2256      * </p>
2257      *
2258 	 * @exception UnsupportedOperationException if this operation is not used in JLS14
2259 	 * @since 3.20
2260 	 */
supportedOnlyIn14()2261 	final void supportedOnlyIn14() {
2262 		if (this.ast.apiLevel != AST.JLS14_INTERNAL) {
2263 			throw new UnsupportedOperationException("Operation only supported in JLS14 AST"); //$NON-NLS-1$
2264 		}
2265 	}
2266 	/**
2267 	 * Sets or clears this node's parent node and location.
2268 	 * <p>
2269 	 * Note that this method is package-private. The pointer from a node
2270 	 * to its parent is set implicitly as a side effect of inserting or
2271 	 * removing the node as a child of another node. This method calls
2272 	 * <code>ast.modifying()</code>.
2273 	 * </p>
2274 	 *
2275 	 * @param parent the new parent of this node, or <code>null</code> if none
2276 	 * @param property the location of this node in its parent,
2277 	 * or <code>null</code> if <code>parent</code> is <code>null</code>
2278 	 * @see #getLocationInParent
2279 	 * @see #getParent
2280 	 * @since 3.0
2281 	 */
setParent(ASTNode parent, StructuralPropertyDescriptor property)2282 	final void setParent(ASTNode parent, StructuralPropertyDescriptor property) {
2283 		this.ast.modifying();
2284 		this.parent = parent;
2285 		this.location = property;
2286 	}
2287 
2288 	/**
2289 	 * Removes this node from its parent. Has no effect if this node
2290 	 * is unparented. If this node appears as an element of a child list
2291 	 * property of its parent, then this node is removed from the
2292 	 * list using <code>List.remove</code>.
2293 	 * If this node appears as the value of a child property of its
2294 	 * parent, then this node is detached from its parent
2295 	 * by passing <code>null</code> to the appropriate setter method;
2296 	 * this operation fails if this node is in a mandatory property.
2297 	 *
2298 	 * @since 3.0
2299 	 */
delete()2300 	public final void delete() {
2301 		StructuralPropertyDescriptor p = getLocationInParent();
2302 		if (p == null) {
2303 			// node is unparented
2304 			return;
2305 		}
2306 		if (p.isChildProperty()) {
2307 			getParent().setStructuralProperty(this.location, null);
2308 			return;
2309 		}
2310 		if (p.isChildListProperty()) {
2311 			List l = (List) getParent().getStructuralProperty(this.location);
2312 			l.remove(this);
2313 		}
2314 	}
2315 
2316 	/**
2317 	 * Checks whether the given new child node is a node
2318 	 * in a different AST from its parent-to-be, whether it is
2319 	 * already has a parent, whether adding it to its
2320 	 * parent-to-be would create a cycle, and whether the child is of
2321 	 * the right type. The parent-to-be is the enclosing instance.
2322 	 *
2323 	 * @param node the parent-to-be node
2324 	 * @param newChild the new child of the parent
2325 	 * @param cycleCheck <code>true</code> if cycles are possible and need
2326 	 *   to be checked, <code>false</code> if cycles are impossible and do
2327 	 *   not need to be checked
2328 	 * @param nodeType a type constraint on child nodes, or <code>null</code>
2329 	 *   if no special check is required
2330 	 * @exception IllegalArgumentException if:
2331 	 * <ul>
2332 	 * <li>the child is null</li>
2333 	 * <li>the node belongs to a different AST</li>
2334 	 * <li>the child has the incorrect node type</li>
2335 	 * <li>the node already has a parent</li>
2336 	 * <li>a cycle in would be created</li>
2337 	 * </ul>
2338 	 */
checkNewChild(ASTNode node, ASTNode newChild, boolean cycleCheck, Class nodeType)2339 	static void checkNewChild(ASTNode node, ASTNode newChild,
2340 			boolean cycleCheck, Class nodeType) {
2341 		if (newChild.ast != node.ast) {
2342 			// new child is from a different AST
2343 			throw new IllegalArgumentException();
2344 		}
2345 		if (newChild.getParent() != null) {
2346 			// new child currently has a different parent
2347 			throw new IllegalArgumentException();
2348 		}
2349 		if (cycleCheck && newChild == node.getRoot()) {
2350 			// inserting new child would create a cycle
2351 			throw new IllegalArgumentException();
2352 		}
2353 		Class childClass = newChild.getClass();
2354 		if (nodeType != null && !nodeType.isAssignableFrom(childClass)) {
2355 			// new child is not of the right type
2356 			throw new ClassCastException(childClass + " is not an instance of " + nodeType); //$NON-NLS-1$
2357 		}
2358 		if ((newChild.typeAndFlags & PROTECT) != 0) {
2359 			// new child node is protected => cannot be parented
2360 			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2361 		}
2362 	}
2363 
2364 	/**
2365      * Prelude portion of the "3 step program" for replacing the
2366 	 * old child of this node with another node.
2367      * Here is the code pattern found in all AST node subclasses:
2368      * <pre>
2369      * ASTNode oldChild = this.foo;
2370      * preReplaceChild(oldChild, newFoo, FOO_PROPERTY);
2371      * this.foo = newFoo;
2372      * postReplaceChild(oldChild, newFoo, FOO_PROPERTY);
2373      * </pre>
2374      * The first part (preReplaceChild) does all the precondition checks,
2375      * reports pre-delete events, and changes parent links.
2376 	 * The old child is delinked from its parent (making it a root node),
2377 	 * and the new child node is linked to its parent. The new child node
2378 	 * must be a root node in the same AST as its new parent, and must not
2379 	 * be an ancestor of this node. All three nodes must be
2380      * modifiable (not PROTECTED). The replace operation must fail
2381      * atomically; so it is crucial that all precondition checks
2382      * be done before any linking and delinking happens.
2383      * The final part (postReplaceChild )reports post-add events.
2384 	 * <p>
2385 	 * This method calls <code>ast.modifying()</code> for the nodes affected.
2386 	 * </p>
2387 	 *
2388 	 * @param oldChild the old child of this node, or <code>null</code> if
2389 	 *   there was no old child to replace
2390 	 * @param newChild the new child of this node, or <code>null</code> if
2391 	 *   there is no replacement child
2392 	 * @param property the property descriptor of this node describing
2393      * the relationship between node and child
2394 	 * @exception RuntimeException if:
2395 	 * <ul>
2396 	 * <li>the node belongs to a different AST</li>
2397 	 * <li>the node already has a parent</li>
2398 	 * <li>a cycle in would be created</li>
2399 	 * <li>any of the nodes involved are unmodifiable</li>
2400 	 * </ul>
2401 	 * @since 3.0
2402 	 */
preReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property)2403 	final void preReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property) {
2404 		if ((this.typeAndFlags & PROTECT) != 0) {
2405 			// this node is protected => cannot gain or lose children
2406 			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2407 		}
2408 		if (newChild != null) {
2409 			checkNewChild(this, newChild, property.cycleRisk, null);
2410 		}
2411 		// delink old child from parent
2412 		if (oldChild != null) {
2413 			if ((oldChild.typeAndFlags & PROTECT) != 0) {
2414 				// old child node is protected => cannot be unparented
2415 				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2416 			}
2417 			if (newChild != null) {
2418 				this.ast.preReplaceChildEvent(this, oldChild, newChild, property);
2419 			} else {
2420 				this.ast.preRemoveChildEvent(this, oldChild, property);
2421 			}
2422 			oldChild.setParent(null, null);
2423 		} else {
2424 			if(newChild != null) {
2425 				this.ast.preAddChildEvent(this, newChild, property);
2426 			}
2427 		}
2428 		// link new child to parent
2429 		if (newChild != null) {
2430 			newChild.setParent(this, property);
2431 			// cannot notify postAddChildEvent until parent is linked to child too
2432 		}
2433 	}
2434 
2435 	/**
2436      * Postlude portion of the "3 step program" for replacing the
2437 	 * old child of this node with another node.
2438      * See {@link #preReplaceChild(ASTNode, ASTNode, ChildPropertyDescriptor)}
2439      * for details.
2440 	 * @since 3.0
2441 	 */
postReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property)2442 	final void postReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property) {
2443 		// link new child to parent
2444 		if (newChild != null) {
2445 			if (oldChild != null) {
2446 				this.ast.postReplaceChildEvent(this, oldChild, newChild, property);
2447 			} else {
2448 				this.ast.postAddChildEvent(this, newChild, property);
2449 			}
2450 		} else {
2451 			this.ast.postRemoveChildEvent(this, oldChild, property);
2452 		}
2453 	}
2454 
2455 	/**
2456      * Prelude portion of the "3 step program" for changing the
2457 	 * value of a simple property of this node.
2458      * Here is the code pattern found in all AST node subclasses:
2459      * <pre>
2460      * preValueChange(FOO_PROPERTY);
2461      * this.foo = newFoo;
2462      * postValueChange(FOO_PROPERTY);
2463      * </pre>
2464      * The first part (preValueChange) does the precondition check
2465      * to make sure the node is modifiable (not PROTECTED).
2466      * The change operation must fail atomically; so it is crucial
2467      * that the precondition checks are done before the field is
2468      * hammered. The final part (postValueChange)reports post-change
2469      * events.
2470 	 * <p>
2471 	 * This method calls <code>ast.modifying()</code> for the node affected.
2472 	 * </p>
2473 	 *
2474 	 * @param property the property descriptor of this node
2475 	 * @exception RuntimeException if:
2476 	 * <ul>
2477 	 * <li>this node is unmodifiable</li>
2478 	 * </ul>
2479 	 * @since 3.0
2480 	 */
preValueChange(SimplePropertyDescriptor property)2481 	final void preValueChange(SimplePropertyDescriptor property) {
2482 		if ((this.typeAndFlags & PROTECT) != 0) {
2483 			// this node is protected => cannot change value of properties
2484 			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2485 		}
2486 		this.ast.preValueChangeEvent(this, property);
2487 		this.ast.modifying();
2488 	}
2489 
2490 	/**
2491      * Postlude portion of the "3 step program" for replacing the
2492 	 * old child of this node with another node.
2493      * See {@link #preValueChange(SimplePropertyDescriptor)} for details.
2494 	 * @since 3.0
2495 	 */
postValueChange(SimplePropertyDescriptor property)2496 	final void postValueChange(SimplePropertyDescriptor property) {
2497 		this.ast.postValueChangeEvent(this, property);
2498 	}
2499 
2500 	/**
2501      * Ensures that this node is modifiable (that is, not marked PROTECTED).
2502      * If successful, calls ast.modifying().
2503      * @exception RuntimeException is not modifiable
2504      */
checkModifiable()2505 	final void checkModifiable() {
2506 		if ((this.typeAndFlags & PROTECT) != 0) {
2507 			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
2508 		}
2509 		this.ast.modifying();
2510 	}
2511 
2512 	/**
2513      * Begin lazy initialization of this node.
2514      * Here is the code pattern found in all AST
2515      * node subclasses:
2516      * <pre>
2517      * if (this.foo == null) {
2518 	 *    // lazy init must be thread-safe for readers
2519      *    synchronized (this) {
2520      *       if (this.foo == null) {
2521      *          preLazyInit();
2522      *          this.foo = ...; // code to create new node
2523      *          postLazyInit(this.foo, FOO_PROPERTY);
2524      *       }
2525      *    }
2526      * }
2527      * </pre>
2528      * @since 3.0
2529      */
preLazyInit()2530 	final void preLazyInit() {
2531 		// IMPORTANT: this method is called by readers
2532 		// ASTNode.this is locked at this point
2533 		this.ast.disableEvents();
2534 		// will turn events back on in postLasyInit
2535 	}
2536 
2537 	/**
2538      * End lazy initialization of this node.
2539      *
2540 	 * @param newChild the new child of this node, or <code>null</code> if
2541 	 *   there is no replacement child
2542 	 * @param property the property descriptor of this node describing
2543      * the relationship between node and child
2544      * @since 3.0
2545      */
postLazyInit(ASTNode newChild, ChildPropertyDescriptor property)2546 	final void postLazyInit(ASTNode newChild, ChildPropertyDescriptor property) {
2547 		// IMPORTANT: this method is called by readers
2548 		// ASTNode.this is locked at this point
2549 		// newChild is brand new (so no chance of concurrent access)
2550 		newChild.setParent(this, property);
2551 		// turn events back on (they were turned off in corresponding preLazyInit)
2552 		this.ast.reenableEvents();
2553 	}
2554 
2555 	/**
2556 	 * Returns the value of the named property of this node, or <code>null</code> if none.
2557 	 *
2558 	 * @param propertyName the property name
2559 	 * @return the property value, or <code>null</code> if none
2560 	 * @see #setProperty(String,Object)
2561 	 */
getProperty(String propertyName)2562 	public final Object getProperty(String propertyName) {
2563 		if (propertyName == null) {
2564 			throw new IllegalArgumentException();
2565 		}
2566 		if (this.property1 == null) {
2567 			// node has no properties at all
2568 			return null;
2569 		}
2570 		if (this.property1 instanceof String) {
2571 			// node has only a single property
2572 			if (propertyName.equals(this.property1)) {
2573 				return this.property2;
2574 			} else {
2575 				return null;
2576 			}
2577 		}
2578 		// otherwise node has table of properties
2579 		Map m = (Map) this.property1;
2580 		return m.get(propertyName);
2581 	}
2582 
2583 	/**
2584 	 * Sets the named property of this node to the given value,
2585 	 * or to <code>null</code> to clear it.
2586 	 * <p>
2587 	 * Clients should employ property names that are sufficiently unique
2588 	 * to avoid inadvertent conflicts with other clients that might also be
2589 	 * setting properties on the same node.
2590 	 * </p>
2591 	 * <p>
2592 	 * Note that modifying a property is not considered a modification to the
2593 	 * AST itself. This is to allow clients to decorate existing nodes with
2594 	 * their own properties without jeopardizing certain things (like the
2595 	 * validity of bindings), which rely on the underlying tree remaining static.
2596 	 * </p>
2597 	 *
2598 	 * @param propertyName the property name
2599 	 * @param data the new property value, or <code>null</code> if none
2600 	 * @see #getProperty(String)
2601 	 * @throws IllegalArgumentException if the given property name is <code>null</code>
2602 	 */
setProperty(String propertyName, Object data)2603 	public final void setProperty(String propertyName, Object data) {
2604 		if (propertyName == null) {
2605 			throw new IllegalArgumentException();
2606 		}
2607 		// N.B. DO NOT CALL ast.modifying();
2608 
2609 		if (this.property1 == null) {
2610 			// node has no properties at all
2611 			if (data == null) {
2612 				// we already know this
2613 				return;
2614 			}
2615 			// node gets its fist property
2616 			this.property1 = propertyName;
2617 			this.property2 = data;
2618 			return;
2619 		}
2620 
2621 		if (this.property1 instanceof String) {
2622 			// node has only a single property
2623 			if (propertyName.equals(this.property1)) {
2624 				// we're in luck
2625 				if (data == null) {
2626 					// just deleted last property
2627 					this.property1 = null;
2628 					this.property2 = null;
2629 				} else {
2630 					this.property2 = data;
2631 				}
2632 				return;
2633 			}
2634 			if (data == null) {
2635 				// we already know this
2636 				return;
2637 			}
2638 			// node already has one property - getting its second
2639 			// convert to more flexible representation
2640 			Map m = new HashMap(3);
2641 			m.put(this.property1, this.property2);
2642 			m.put(propertyName, data);
2643 			this.property1 = m;
2644 			this.property2 = null;
2645 			return;
2646 		}
2647 
2648 		// node has two or more properties
2649 		Map m = (Map) this.property1;
2650 		if (data == null) {
2651 			m.remove(propertyName);
2652 			// check for just one property left
2653 			if (m.size() == 1) {
2654 				// convert to more efficient representation
2655 				Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]);
2656 				this.property1 = entries[0].getKey();
2657 				this.property2 = entries[0].getValue();
2658 			}
2659 			return;
2660 		} else {
2661 			m.put(propertyName, data);
2662 			// still has two or more properties
2663 			return;
2664 		}
2665 	}
2666 
2667 	/**
2668 	 * Returns an unmodifiable table of the properties of this node with
2669 	 * non-<code>null</code> values.
2670 	 *
2671 	 * @return the table of property values keyed by property name
2672 	 *   (key type: <code>String</code>; value type: <code>Object</code>)
2673 	 */
properties()2674 	public final Map properties() {
2675 		if (this.property1 == null) {
2676 			// node has no properties at all
2677 			return UNMODIFIABLE_EMPTY_MAP;
2678 		}
2679 		if (this.property1 instanceof String) {
2680 			// node has a single property
2681 			return Collections.singletonMap(this.property1, this.property2);
2682 		}
2683 
2684 		// node has two or more properties
2685 		if (this.property2 == null) {
2686 			this.property2 = Collections.unmodifiableMap((Map) this.property1);
2687 		}
2688 		// property2 is unmodifiable wrapper for map in property1
2689 		return (Map) this.property2;
2690 	}
2691 
2692 	/**
2693 	 * Returns the flags associated with this node.
2694 	 * <p>
2695 	 * No flags are associated with newly created nodes.
2696 	 * </p>
2697 	 * <p>
2698 	 * The flags are the bitwise-or of individual flags.
2699 	 * The following flags are currently defined:
2700 	 * <ul>
2701 	 * <li>{@link #MALFORMED} - indicates node is syntactically
2702 	 *   malformed</li>
2703 	 * <li>{@link #ORIGINAL} - indicates original node
2704 	 * created by ASTParser</li>
2705 	 * <li>{@link #PROTECT} - indicates node is protected
2706 	 * from further modification</li>
2707 	 * <li>{@link #RECOVERED} - indicates node or a part of this node
2708 	 *  is recovered from source that contains a syntax error</li>
2709 	 * </ul>
2710 	 * Other bit positions are reserved for future use.
2711 	 *
2712 	 * @return the bitwise-or of individual flags
2713 	 * @see #setFlags(int)
2714 	 */
getFlags()2715 	public final int getFlags() {
2716 		return this.typeAndFlags & 0xFFFF;
2717 	}
2718 
2719 	/**
2720 	 * Sets the flags associated with this node to the given value.
2721 	 * <p>
2722 	 * The flags are the bitwise-or of individual flags.
2723 	 * The following flags are currently defined:
2724 	 * <ul>
2725 	 * <li>{@link #MALFORMED} - indicates node is syntactically
2726 	 *   malformed</li>
2727 	 * <li>{@link #ORIGINAL} - indicates original node
2728 	 * created by ASTParser</li>
2729 	 * <li>{@link #PROTECT} - indicates node is protected
2730 	 * from further modification</li>
2731 	 * <li>{@link #RECOVERED} - indicates node or a part of this node
2732 	 *  is recovered from source that contains a syntax error</li>
2733 	 * </ul>
2734 	 * Other bit positions are reserved for future use.
2735 	 * <p>
2736 	 * Note that the flags are <em>not</em> considered a structural
2737 	 * property of the node, and can be changed even if the
2738 	 * node is marked as protected.
2739 	 * </p>
2740 	 *
2741 	 * @param flags the bitwise-or of individual flags
2742 	 * @see #getFlags()
2743 	 */
setFlags(int flags)2744 	public final void setFlags(int flags) {
2745 		this.ast.modifying();
2746 		int old = this.typeAndFlags & 0xFFFF0000;
2747 		this.typeAndFlags = old | (flags & 0xFFFF);
2748 	}
2749 
2750 	/**
2751 	 * Returns an integer value identifying the type of this concrete AST node.
2752 	 * The values are small positive integers, suitable for use in switch statements.
2753 	 * <p>
2754 	 * For each concrete node type there is a unique node type constant (name
2755 	 * and value). The unique node type constant for a concrete node type such as
2756 	 * <code>CastExpression</code> is <code>ASTNode.CAST_EXPRESSION</code>.
2757 	 * </p>
2758 	 *
2759 	 * @return one of the node type constants
2760 	 */
getNodeType()2761 	public final int getNodeType() {
2762 		return this.typeAndFlags >>> 16;
2763 	}
2764 
2765 	/**
2766 	 * Sets the integer value identifying the type of this concrete AST node.
2767 	 * The values are small positive integers, suitable for use in switch statements.
2768 	 *
2769 	 * @param nodeType one of the node type constants
2770 	 */
setNodeType(int nodeType)2771 	private void setNodeType(int nodeType) {
2772 		int old = this.typeAndFlags & 0xFFFF0000;
2773 		this.typeAndFlags = old | (nodeType << 16);
2774 	}
2775 
2776 	/**
2777 	 * Returns an integer value identifying the type of this concrete AST node.
2778 	 * <p>
2779 	 * This internal method is implemented in each of the
2780 	 * concrete node subclasses.
2781 	 * </p>
2782 	 *
2783 	 * @return one of the node type constants
2784 	 */
getNodeType0()2785 	abstract int getNodeType0();
2786 
2787 	/**
2788 	 * The <code>ASTNode</code> implementation of this <code>Object</code>
2789 	 * method uses object identity (==). Use <code>subtreeMatch</code> to
2790 	 * compare two subtrees for equality.
2791 	 *
2792 	 * @param obj {@inheritDoc}
2793 	 * @return {@inheritDoc}
2794 	 * @see #subtreeMatch(ASTMatcher matcher, Object other)
2795 	 */
2796 	@Override
equals(Object obj)2797 	public final boolean equals(Object obj) {
2798 		return this == obj; // equivalent to Object.equals
2799 	}
2800 
2801 	/*
2802 	 * (non-Javadoc)
2803 	 * This makes it consistent with the fact that a equals methods has been provided.
2804 	 * @see java.lang.Object#hashCode()
2805 	 */
2806 	@Override
hashCode()2807 	public final int hashCode() {
2808 		return super.hashCode();
2809 	}
2810 
2811 	/**
2812 	 * Returns whether the subtree rooted at the given node matches the
2813 	 * given other object as decided by the given matcher.
2814 	 *
2815 	 * @param matcher the matcher
2816 	 * @param other the other object, or <code>null</code>
2817 	 * @return <code>true</code> if the subtree matches, or
2818 	 * <code>false</code> if they do not match
2819 	 */
subtreeMatch(ASTMatcher matcher, Object other)2820 	public final boolean subtreeMatch(ASTMatcher matcher, Object other) {
2821 		return subtreeMatch0(matcher, other);
2822 	}
2823 
2824 	/**
2825 	 * Returns whether the subtree rooted at the given node matches the
2826 	 * given other object as decided by the given matcher.
2827 	 * <p>
2828 	 * This internal method is implemented in each of the
2829 	 * concrete node subclasses.
2830 	 * </p>
2831 	 *
2832 	 * @param matcher the matcher
2833 	 * @param other the other object, or <code>null</code>
2834 	 * @return <code>true</code> if the subtree matches, or
2835 	 * <code>false</code> if they do not match
2836 	 */
subtreeMatch0(ASTMatcher matcher, Object other)2837 	abstract boolean subtreeMatch0(ASTMatcher matcher, Object other);
2838 
2839 	/**
2840 	 * Returns a deep copy of the subtree of AST nodes rooted at the
2841 	 * given node. The resulting nodes are owned by the given AST,
2842 	 * which may be different from the ASTs of the given node.
2843 	 * Even if the given node has a parent, the result node will be unparented.
2844 	 * <p>
2845 	 * Source range information on the original nodes is automatically copied to the new
2846 	 * nodes. Client properties (<code>properties</code>) are not carried over.
2847 	 * </p>
2848 	 * <p>
2849 	 * The node's <code>AST</code> and the target <code>AST</code> must support
2850      * the same API level.
2851 	 * </p>
2852 	 *
2853 	 * @param target the AST that is to own the nodes in the result
2854 	 * @param node the node to copy, or <code>null</code> if none
2855 	 * @return the copied node, or <code>null</code> if <code>node</code>
2856 	 *    is <code>null</code>
2857 	 */
copySubtree(AST target, ASTNode node)2858 	public static ASTNode copySubtree(AST target, ASTNode node) {
2859 		if (node == null) {
2860 			return null;
2861 		}
2862 		if (target == null) {
2863 			throw new IllegalArgumentException();
2864 		}
2865 		if (target.apiLevel() != node.getAST().apiLevel()) {
2866 			throw new UnsupportedOperationException();
2867 		}
2868 		ASTNode newNode = node.clone(target);
2869 		return newNode;
2870 	}
2871 
2872 	/**
2873 	 * Returns a deep copy of the subtrees of AST nodes rooted at the
2874 	 * given list of nodes. The resulting nodes are owned by the given AST,
2875 	 * which may be different from the ASTs of the nodes in the list.
2876 	 * Even if the nodes in the list have parents, the nodes in the result
2877 	 * will be unparented.
2878 	 * <p>
2879 	 * Source range information on the original nodes is automatically copied to the new
2880 	 * nodes. Client properties (<code>properties</code>) are not carried over.
2881 	 * </p>
2882 	 *
2883 	 * @param target the AST that is to own the nodes in the result
2884 	 * @param nodes the list of nodes to copy
2885 	 *    (element type: {@link ASTNode})
2886 	 * @return the list of copied subtrees
2887 	 *    (element type: {@link ASTNode})
2888 	 */
copySubtrees(AST target, List nodes)2889 	public static List copySubtrees(AST target, List nodes) {
2890 		List result = new ArrayList(nodes.size());
2891 		for (Iterator it = nodes.iterator(); it.hasNext(); ) {
2892 			ASTNode oldNode = (ASTNode) it.next();
2893 			ASTNode newNode = oldNode.clone(target);
2894 			result.add(newNode);
2895 		}
2896 		return result;
2897 	}
2898 
2899 	/**
2900 	 * Returns a deep copy of the subtree of AST nodes rooted at this node.
2901 	 * The resulting nodes are owned by the given AST, which may be different
2902 	 * from the AST of this node. Even if this node has a parent, the
2903 	 * result node will be unparented.
2904 	 * <p>
2905 	 * This method reports pre- and post-clone events, and dispatches
2906 	 * to <code>clone0(AST)</code> which is reimplemented in node subclasses.
2907 	 * </p>
2908 	 *
2909 	 * @param target the AST that is to own the nodes in the result
2910 	 * @return the root node of the copies subtree
2911 	 */
clone(AST target)2912 	final ASTNode clone(AST target) {
2913 		this.ast.preCloneNodeEvent(this);
2914 		ASTNode c = clone0(target);
2915 		this.ast.postCloneNodeEvent(this, c);
2916 		return c;
2917 	}
2918 
2919 	/**
2920 	 * Returns a deep copy of the subtree of AST nodes rooted at this node.
2921 	 * The resulting nodes are owned by the given AST, which may be different
2922 	 * from the AST of this node. Even if this node has a parent, the
2923 	 * result node will be unparented.
2924 	 * <p>
2925 	 * This method must be implemented in subclasses.
2926 	 * </p>
2927 	 * <p>
2928 	 * General template for implementation on each concrete ASTNode class:
2929 	 * <pre>
2930 	 * <code>
2931 	 * ConcreteNodeType result = new ConcreteNodeType(target);
2932 	 * result.setSourceRange(getStartPosition(), getLength());
2933 	 * result.setChildProperty(
2934 	 *         (ChildPropertyType) ASTNode.copySubtree(target, getChildProperty()));
2935 	 * result.setSimpleProperty(isSimpleProperty());
2936 	 * result.childrenProperty().addAll(
2937 	 *         ASTNode.copySubtrees(target, childrenProperty()));
2938 	 * return result;
2939 	 * </code>
2940 	 * </pre>
2941 	 * </p>
2942 	 * <p>
2943 	 * This method does not report pre- and post-clone events.
2944 	 * All callers should instead call <code>clone(AST)</code>
2945 	 * to ensure that pre- and post-clone events are reported.
2946 	 * </p>
2947 	 * <p>
2948 	 * N.B. This method is package-private, so that the implementations
2949 	 * of this method in each of the concrete AST node types do not
2950 	 * clutter up the API doc.
2951 	 * </p>
2952 	 *
2953 	 * @param target the AST that is to own the nodes in the result
2954 	 * @return the root node of the copies subtree
2955 	 */
clone0(AST target)2956 	abstract ASTNode clone0(AST target);
2957 
2958 	/**
2959 	 * Accepts the given visitor on a visit of the current node.
2960 	 *
2961 	 * @param visitor the visitor object
2962 	 * @exception IllegalArgumentException if the visitor is null
2963 	 */
accept(ASTVisitor visitor)2964 	public final void accept(ASTVisitor visitor) {
2965 		if (visitor == null) {
2966 			throw new IllegalArgumentException();
2967 		}
2968 		// begin with the generic pre-visit
2969 		if (visitor.preVisit2(this)) {
2970 			// dynamic dispatch to internal method for type-specific visit/endVisit
2971 			accept0(visitor);
2972 		}
2973 		// end with the generic post-visit
2974 		visitor.postVisit(this);
2975 	}
2976 
2977 	/**
2978 	 * Accepts the given visitor on a type-specific visit of the current node.
2979 	 * This method must be implemented in all concrete AST node types.
2980 	 * <p>
2981 	 * General template for implementation on each concrete ASTNode class:
2982 	 * <pre>
2983 	 * <code>
2984 	 * boolean visitChildren = visitor.visit(this);
2985 	 * if (visitChildren) {
2986 	 *    // visit children in normal left to right reading order
2987 	 *    acceptChild(visitor, getProperty1());
2988 	 *    acceptChildren(visitor, this.rawListProperty);
2989 	 *    acceptChild(visitor, getProperty2());
2990 	 * }
2991 	 * visitor.endVisit(this);
2992 	 * </code>
2993 	 * </pre>
2994 	 * Note that the caller (<code>accept</code>) take cares of invoking
2995 	 * <code>visitor.preVisit(this)</code> and <code>visitor.postVisit(this)</code>.
2996 	 * </p>
2997 	 *
2998 	 * @param visitor the visitor object
2999 	 */
accept0(ASTVisitor visitor)3000 	abstract void accept0(ASTVisitor visitor);
3001 
3002 	/**
3003 	 * Accepts the given visitor on a visit of the current node.
3004 	 * <p>
3005 	 * This method should be used by the concrete implementations of
3006 	 * <code>accept0</code> to traverse optional properties. Equivalent
3007 	 * to <code>child.accept(visitor)</code> if <code>child</code>
3008 	 * is not <code>null</code>.
3009 	 * </p>
3010 	 *
3011 	 * @param visitor the visitor object
3012 	 * @param child the child AST node to dispatch too, or <code>null</code>
3013 	 *    if none
3014 	 */
acceptChild(ASTVisitor visitor, ASTNode child)3015 	final void acceptChild(ASTVisitor visitor, ASTNode child) {
3016 		if (child == null) {
3017 			return;
3018 		}
3019 		child.accept(visitor);
3020 	}
3021 
3022 	/**
3023 	 * Accepts the given visitor on a visit of the given live list of
3024 	 * child nodes.
3025 	 * <p>
3026 	 * This method must be used by the concrete implementations of
3027 	 * <code>accept</code> to traverse list-values properties; it
3028 	 * encapsulates the proper handling of on-the-fly changes to the list.
3029 	 * </p>
3030 	 *
3031 	 * @param visitor the visitor object
3032 	 * @param children the child AST node to dispatch too, or <code>null</code>
3033 	 *    if none
3034 	 */
acceptChildren(ASTVisitor visitor, ASTNode.NodeList children)3035 	final void acceptChildren(ASTVisitor visitor, ASTNode.NodeList children) {
3036 		// use a cursor to keep track of where we are up to
3037 		// (the list may be changing under foot)
3038 		NodeList.Cursor cursor = children.newCursor();
3039 		try {
3040 			while (cursor.hasNext()) {
3041 				ASTNode child = (ASTNode) cursor.next();
3042 				child.accept(visitor);
3043 			}
3044 		} finally {
3045 			children.releaseCursor(cursor);
3046 		}
3047 	}
3048 
3049 	/**
3050 	 * Returns the character index into the original source file indicating
3051 	 * where the source fragment corresponding to this node begins.
3052 	 * <p>
3053 	 * The parser supplies useful well-defined source ranges to the nodes it creates.
3054 	 * See {@link ASTParser#setKind(int)} for details
3055 	 * on precisely where source ranges begin and end.
3056 	 * </p>
3057 	 *
3058 	 * @return the 0-based character index, or <code>-1</code>
3059 	 *    if no source position information is recorded for this node
3060 	 * @see #getLength()
3061 	 * @see ASTParser
3062 	 */
getStartPosition()3063 	public final int getStartPosition() {
3064 		return this.startPosition;
3065 	}
3066 
3067 	/**
3068 	 * Returns the length in characters of the original source file indicating
3069 	 * where the source fragment corresponding to this node ends.
3070 	 * <p>
3071 	 * The parser supplies useful well-defined source ranges to the nodes it creates.
3072 	 * See {@link ASTParser#setKind(int)} methods for details
3073 	 * on precisely where source ranges begin and end.
3074 	 * </p>
3075 	 *
3076 	 * @return a (possibly 0) length, or <code>0</code>
3077 	 *    if no source position information is recorded for this node
3078 	 * @see #getStartPosition()
3079 	 * @see ASTParser
3080 	 */
getLength()3081 	public final int getLength() {
3082 		return this.length;
3083 	}
3084 
3085 	/**
3086 	 * Sets the source range of the original source file where the source
3087 	 * fragment corresponding to this node was found.
3088 	 * <p>
3089 	 * See {@link ASTParser#setKind(int)} for details
3090 	 * on precisely where source ranges are supposed to begin and end.
3091 	 * </p>
3092 	 *
3093 	 * @param startPosition a 0-based character index,
3094 	 *    or <code>-1</code> if no source position information is
3095 	 *    available for this node
3096 	 * @param length a (possibly 0) length,
3097 	 *    or <code>0</code> if no source position information is recorded
3098 	 *    for this node
3099 	 * @see #getStartPosition()
3100 	 * @see #getLength()
3101 	 * @see ASTParser
3102 	 */
setSourceRange(int startPosition, int length)3103 	public final void setSourceRange(int startPosition, int length) {
3104 		if (startPosition >= 0 && length < 0) {
3105 			throw new IllegalArgumentException();
3106 		}
3107 		if (startPosition < 0 && length != 0) {
3108 			throw new IllegalArgumentException();
3109 		}
3110 		// source positions are not considered a structural property
3111 		// but we protect them nevertheless
3112 		checkModifiable();
3113 		this.startPosition = startPosition;
3114 		this.length = length;
3115 	}
3116 
3117 	/**
3118 	 * Returns a string representation of this node suitable for debugging
3119 	 * purposes only.
3120 	 *
3121 	 * @return a debug string
3122 	 */
3123 	@Override
toString()3124 	public final String toString() {
3125 		StringBuffer buffer = new StringBuffer();
3126 		int p = buffer.length();
3127 		try {
3128 			appendDebugString(buffer);
3129 		} catch (RuntimeException e) {
3130 			// since debugger sometimes call toString methods, problems can easily happen when
3131 			// toString is called on an instance that is being initialized
3132 			buffer.setLength(p);
3133 			buffer.append("!"); //$NON-NLS-1$
3134 			buffer.append(standardToString());
3135 		}
3136 		return buffer.toString();
3137 	}
3138 
3139 	/**
3140 	 * Returns the string representation of this node produced by the standard
3141 	 * <code>Object.toString</code> method.
3142 	 *
3143 	 * @return a debug string
3144 	 */
standardToString()3145 	final String standardToString() {
3146 		return super.toString();
3147 	}
3148 
3149 	/**
3150 	 * Appends a debug representation of this node to the given string buffer.
3151 	 * <p>
3152 	 * The <code>ASTNode</code> implementation of this method prints out the entire
3153 	 * subtree. Subclasses may override to provide a more succinct representation.
3154 	 * </p>
3155 	 *
3156 	 * @param buffer the string buffer to append to
3157 	 */
appendDebugString(StringBuffer buffer)3158 	void appendDebugString(StringBuffer buffer) {
3159 		// print the subtree by default
3160 		appendPrintString(buffer);
3161 	}
3162 
3163 	/**
3164 	 * Appends a standard Java source code representation of this subtree to the given
3165 	 * string buffer.
3166 	 *
3167 	 * @param buffer the string buffer to append to
3168 	 */
appendPrintString(StringBuffer buffer)3169 	final void appendPrintString(StringBuffer buffer) {
3170 		NaiveASTFlattener printer = new NaiveASTFlattener();
3171 		accept(printer);
3172 		buffer.append(printer.getResult());
3173 	}
3174 
3175 	/**
3176 	 * Estimate of size of an object header in bytes.
3177 	 */
3178 	static final int HEADERS = 12;
3179 
3180 	/**
3181 	 * Approximate base size of an AST node instance in bytes,
3182 	 * including object header and instance fields.
3183 	 * That is, HEADERS + (# instance vars in ASTNode)*4.
3184 	 */
3185 	static final int BASE_NODE_SIZE = HEADERS + 7 * 4;
3186 
3187 	/**
3188 	 * Returns an estimate of the memory footprint, in bytes,
3189 	 * of the given string.
3190 	 *
3191 	 * @param string the string to measure, or <code>null</code>
3192 	 * @return the size of this string object in bytes, or
3193 	 *   0 if the string is <code>null</code>
3194      * @since 3.0
3195 	 */
stringSize(String string)3196 	static int stringSize(String string) {
3197 		int size = 0;
3198 		if (string != null) {
3199 			// Strings usually have 4 instance fields, one of which is a char[]
3200 			size += HEADERS + 4 * 4;
3201 			// char[] has 2 bytes per character
3202 			size += HEADERS + 2 * string.length();
3203 		}
3204 		return size;
3205 	}
3206 
3207 	/**
3208 	 * Returns an estimate of the memory footprint in bytes of the entire
3209 	 * subtree rooted at this node.
3210 	 *
3211 	 * @return the size of this subtree in bytes
3212 	 */
subtreeBytes()3213 	public final int subtreeBytes() {
3214 		return treeSize();
3215 	}
3216 
3217 	/**
3218 	 * Returns an estimate of the memory footprint in bytes of the entire
3219 	 * subtree rooted at this node.
3220 	 * <p>
3221 	 * N.B. This method is package-private, so that the implementations
3222 	 * of this method in each of the concrete AST node types do not
3223 	 * clutter up the API doc.
3224 	 * </p>
3225 	 *
3226 	 * @return the size of this subtree in bytes
3227 	 */
treeSize()3228 	abstract int treeSize();
3229 
3230 	/**
3231 	 * Returns an estimate of the memory footprint of this node in bytes.
3232 	 * The estimate does not include the space occupied by child nodes.
3233 	 *
3234 	 * @return the size of this node in bytes
3235 	 */
memSize()3236 	abstract int memSize();
3237 }
3238