4e0187378778136253613beb372e88289cd75405
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / AST.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.core.dom;
13
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.InvocationTargetException;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.StringTokenizer;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22
23 import net.sourceforge.phpdt.core.IClassFile;
24 import net.sourceforge.phpdt.core.ICompilationUnit;
25 import net.sourceforge.phpdt.core.IJavaProject;
26 import net.sourceforge.phpdt.core.JavaCore;
27 import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
28 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
29 import org.eclipse.jface.text.IDocument;
30 import org.eclipse.text.edits.TextEdit;
31
32 /**
33  * Umbrella owner and abstract syntax tree node factory.
34  * An <code>AST</code> instance serves as the common owner of any number of
35  * AST nodes, and as the factory for creating new AST nodes owned by that 
36  * instance.
37  * <p>
38  * Abstract syntax trees may be hand constructed by clients, using the
39  * <code>new<i>TYPE</i></code> factory methods to create new nodes, and the
40  * various <code>set<i>CHILD</i></code> methods 
41  * (see {@link org.eclipse.jdt.core.dom.ASTNode ASTNode} and its subclasses)
42  * to connect them together.
43  * </p>
44  * <p>
45  * Each AST node belongs to a unique AST instance, called the owning AST.
46  * The children of an AST node always have the same owner as their parent node.
47  * If a node from one AST is to be added to a different AST, the subtree must
48  * be cloned first to ensures that the added nodes have the correct owning AST.
49  * </p>
50  * <p>
51  * There can be any number of AST nodes owned by a single AST instance that are
52  * unparented. Each of these nodes is the root of a separate little tree of nodes.
53  * The method <code>ASTNode.getRoot()</code> navigates from any node to the root
54  * of the tree that it is contained in. Ordinarily, an AST instance has one main
55  * tree (rooted at a <code>CompilationUnit</code>), with newly-created nodes appearing
56  * as additional roots until they are parented somewhere under the main tree.
57  * One can navigate from any node to its AST instance, but not conversely.
58  * </p>
59  * <p>
60  * The class {@link ASTParser} parses a string
61  * containing a Java source code and returns an abstract syntax tree
62  * for it. The resulting nodes carry source ranges relating the node back to
63  * the original source characters.
64  * </p>
65  * <p>
66  * Compilation units created by <code>ASTParser</code> from a
67  * source document can be serialized after arbitrary modifications
68  * with minimal loss of original formatting. Here is an example:
69  * <pre>
70  * Document doc = new Document("import java.util.List;\nclass X {}\n");
71  * ASTParser parser = ASTParser.newParser(AST.JLS3);
72  * parser.setSource(doc.get().toCharArray());
73  * CompilationUnit cu = (CompilationUnit) parser.createAST(null);
74  * cu.recordModifications();
75  * AST ast = cu.getAST();
76  * ImportDeclaration id = ast.newImportDeclaration();
77  * id.setName(ast.newName(new String[] {"java", "util", "Set"});
78  * cu.imports().add(id); // add import declaration at end
79  * TextEdit edits = cu.rewrite(document, null);
80  * UndoEdit undo = edits.apply(document);
81  * </pre>
82  * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
83  * an alternative way to describe and serialize changes to a
84  * read-only AST.
85  * </p>
86  * <p>
87  * Clients may create instances of this class using {@link #newAST(int)}, 
88  * but this class is not intended to be subclassed.
89  * </p>
90  * 
91  * @see ASTParser
92  * @see ASTNode
93  * @since 2.0
94  * @noinstantiate This class is not intended to be instantiated by clients.
95  */
96 public final class AST {
97         /**
98          * Constant for indicating the AST API that handles JLS2.
99          * This API is capable of handling all constructs
100          * in the Java language as described in the Java Language
101      * Specification, Second Edition (JLS2).
102      * JLS2 is a superset of all earlier versions of the
103      * Java language, and the JLS2 API can be used to manipulate
104      * programs written in all versions of the Java language
105      * up to and including J2SE 1.4.
106      *
107          * @since 3.0
108          * @deprecated Clients should use the {@link #JLS3} AST API instead.
109          */
110         public static final int JLS2 = 2;
111         
112         /**
113          * Internal synonym for {@link #JLS2}. Use to alleviate
114          * deprecation warnings.
115          * @since 3.1
116          */
117         /*package*/ static final int JLS2_INTERNAL = JLS2;
118
119         /**
120          * Constant for indicating the AST API that handles JLS3.
121          * This API is capable of handling all constructs in the
122          * Java language as described in the Java Language
123          * Specification, Third Edition (JLS3).
124      * JLS3 is a superset of all earlier versions of the
125      * Java language, and the JLS3 API can be used to manipulate
126      * programs written in all versions of the Java language
127      * up to and including J2SE 5 (aka JDK 1.5). 
128      *
129          * @since 3.1
130          */
131         public static final int JLS3 = 3;
132         
133         /**
134          * The binding resolver for this AST. Initially a binding resolver that
135          * does not resolve names at all.
136          */
137         private BindingResolver resolver = new BindingResolver();
138         
139         /**
140          * The event handler for this AST. 
141          * Initially an event handler that does not nothing.
142          * @since 3.0
143          */
144         private NodeEventHandler eventHandler = new NodeEventHandler();
145         
146         /**
147          * Level of AST API supported by this AST.
148          * @since 3.0
149          */
150         int apiLevel;
151         
152         /**
153          * Internal modification count; initially 0; increases monotonically
154          * <b>by one or more</b> as the AST is successively modified.
155          */
156         private long modificationCount = 0;
157         
158         /**
159          * Internal original modification count; value is equals to <code>
160          * modificationCount</code> at the end of the parse (<code>ASTParser
161          * </code>). If this ast is not created with a parser then value is 0.
162          * @since 3.0
163          */
164         private long originalModificationCount = 0;
165
166         /**
167          * When disableEvents > 0, events are not reported and
168          * the modification count stays fixed.
169          * <p>
170          * This mechanism is used in lazy initialization of a node
171          * to prevent events from being reported for the modification
172          * of the node as well as for the creation of the missing child.
173          * </p>
174          * @since 3.0
175          */
176         private int disableEvents = 0;
177
178         /**
179          * Internal object unique to the AST instance. Readers must synchronize on
180          * this object when the modifying instance fields.
181          * @since 3.0
182          */
183         private final Object internalASTLock = new Object();
184
185         /**
186          * Java Scanner used to validate preconditions for the creation of specific nodes
187          * like CharacterLiteral, NumberLiteral, StringLiteral or SimpleName.
188          */
189         Scanner scanner;
190
191         /**
192          * Internal ast rewriter used to record ast modification when record mode is enabled.
193          */
194         InternalASTRewrite rewriter;
195
196         /**
197          * Default value of <code>flag<code> when a new node is created.
198          */
199         private int defaultNodeFlag = 0;
200
201         /**
202          * Creates a new Java abstract syntax tree
203      * (AST) following the specified set of API rules.
204      *
205          * @param level the API level; one of the LEVEL constants
206      * @since 3.0
207          */
208         private AST(int level) {
209                 if ((level != AST.JLS2)
210                         && (level != AST.JLS3)) {
211                         throw new IllegalArgumentException();
212                 }
213                 this.apiLevel = level;
214                 // initialize a scanner
215                 this.scanner = new Scanner(
216                                 true /*comment*/,
217                                 true /*whitespace*/,
218                                 false /*nls*/,
219                                 ClassFileConstants.JDK1_3 /*sourceLevel*/,
220                                 ClassFileConstants.JDK1_5 /*complianceLevel*/,
221                                 null/*taskTag*/,
222                                 null/*taskPriorities*/,
223                                 true/*taskCaseSensitive*/);
224         }
225
226         /**
227          * Creates a new, empty abstract syntax tree using default options.
228          *
229          * @see JavaCore#getDefaultOptions()
230          * @deprecated Clients should port their code to use the new JLS3 AST API and call
231          *    {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
232          */
233         public AST() {
234                 this(JavaCore.getDefaultOptions());
235         }
236
237         /**
238          * Internal method.
239          * <p>
240          * This method converts the given internal compiler AST for the given source string
241          * into a compilation unit. This method is not intended to be called by clients.
242          * </p>
243          *
244          * @param level the API level; one of the LEVEL constants
245          * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
246          * @param options compiler options
247          * @param workingCopy the working copy that the AST is created from
248          * @param monitor the progress monitor used to report progress and request cancellation,
249          *     or <code>null</code> if none
250          * @param isResolved whether the given compilation unit declaration is resolved
251          * @return the compilation unit node
252          * @since 3.4
253          * @noreference This method is not intended to be referenced by clients.
254          */
255         public static CompilationUnit convertCompilationUnit(
256                 int level,
257                 net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
258                 Map options,
259                 boolean isResolved,
260                 net.sourceforge.phpdt.internal.core.CompilationUnit workingCopy,
261                 int reconcileFlags,
262                 IProgressMonitor monitor) {
263
264                 ASTConverter converter = new ASTConverter(options, isResolved, monitor);
265                 AST ast = AST.newAST(level);
266                 int savedDefaultNodeFlag = ast.getDefaultNodeFlag();
267                 ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
268                 BindingResolver resolver = null;
269                 if (isResolved) {
270                         resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false);
271                         ((DefaultBindingResolver) resolver).isRecoveringBindings = (reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
272                         ast.setFlag(AST.RESOLVED_BINDINGS);
273                 } else {
274                         resolver = new BindingResolver();
275                 }
276                 ast.setFlag(reconcileFlags);
277                 ast.setBindingResolver(resolver);
278                 converter.setAST(ast);
279
280                 CompilationUnit unit = converter.convert(compilationUnitDeclaration, workingCopy.getContents());
281                 unit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions());
282                 unit.setTypeRoot(workingCopy.originalFromClone());
283                 ast.setDefaultNodeFlag(savedDefaultNodeFlag);
284                 return unit;
285         }
286
287         /**
288          * Internal method.
289          * <p>
290          * This method converts the given internal compiler AST for the given source string
291          * into a compilation unit. This method is not intended to be called by clients.
292          * </p>
293          *
294          * @param level the API level; one of the LEVEL constants
295          * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
296          * @param source the string of the Java compilation unit
297          * @param options compiler options
298          * @param workingCopy the working copy that the AST is created from
299          * @param monitor the progress monitor used to report progress and request cancellation,
300          *     or <code>null</code> if none
301          * @param isResolved whether the given compilation unit declaration is resolved
302          * @return the compilation unit node
303          * @deprecated Use org.eclipse.jdt.core.dom.AST.convertCompilationUnit(int, CompilationUnitDeclaration, Map, boolean, CompilationUnit, int, IProgressMonitor) instead
304          * @noreference This method is not intended to be referenced by clients.
305          */
306         public static CompilationUnit convertCompilationUnit(
307                         int level,
308                         net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
309                         char[] source,
310                         Map options,
311                         boolean isResolved,
312                         net.sourceforge.phpdt.internal.core.CompilationUnit workingCopy,
313                         int reconcileFlags,
314                         IProgressMonitor monitor) {
315                 return null;
316         }
317         
318         /**
319          * Creates a new, empty abstract syntax tree using the given options.
320          * <p>
321          * Following option keys are significant:
322          * <ul>
323          * <li><code>"org.eclipse.jdt.core.compiler.source"</code> -
324          *    indicates source compatibility mode (as per <code>JavaCore</code>);
325          *    <code>"1.3"</code> means the source code is as per JDK 1.3;
326          *    <code>"1.4"</code> means the source code is as per JDK 1.4
327          *    (<code>"assert"</code> is now a keyword);
328          *    <code>"1.5"</code> means the source code is as per JDK 1.5
329          *    (<code>"enum"</code> is now a keyword);
330          *    additional legal values may be added later. </li>
331          * </ul>
332          * Options other than the above are ignored.
333          * </p>
334          *
335          * @param options the table of options (key type: <code>String</code>;
336          *    value type: <code>String</code>)
337          * @see JavaCore#getDefaultOptions()
338          * @deprecated Clients should port their code to use the new JLS3 AST API and call
339          *    {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
340          */
341         public AST(Map options) {
342                 this(JLS2);
343                 Object sourceLevelOption = options.get(JavaCore.COMPILER_SOURCE);
344                 long sourceLevel = ClassFileConstants.JDK1_3;
345                 if (JavaCore.VERSION_1_4.equals(sourceLevelOption)) {
346                         sourceLevel = ClassFileConstants.JDK1_4;
347                 } else if (JavaCore.VERSION_1_5.equals(sourceLevelOption)) {
348                         sourceLevel = ClassFileConstants.JDK1_5;
349                 }
350                 Object complianceLevelOption = options.get(JavaCore.COMPILER_COMPLIANCE);
351                 long complianceLevel = ClassFileConstants.JDK1_3;
352                 if (JavaCore.VERSION_1_4.equals(complianceLevelOption)) {
353                         complianceLevel = ClassFileConstants.JDK1_4;
354                 } else if (JavaCore.VERSION_1_5.equals(complianceLevelOption)) {
355                         complianceLevel = ClassFileConstants.JDK1_5;
356                 }
357                 // override scanner if 1.4 or 1.5 asked for
358                 this.scanner = new Scanner(
359                         true /*comment*/,
360                         true /*whitespace*/,
361                         false /*nls*/,
362                         sourceLevel /*sourceLevel*/,
363                         complianceLevel /*complianceLevel*/,
364                         null/*taskTag*/,
365                         null/*taskPriorities*/,
366                         true/*taskCaseSensitive*/);
367         }
368
369         /**
370          * Creates a new Java abstract syntax tree
371      * (AST) following the specified set of API rules.
372      * <p>
373      * Clients should use this method specifing {@link #JLS3} as the
374      * AST level in all cases, even when dealing with JDK 1.3 or 1.4..
375      * </p>
376      *
377          * @param level the API level; one of the LEVEL constants
378          * @return new AST instance following the specified set of API rules.
379          * @exception IllegalArgumentException if:
380          * <ul>
381          * <li>the API level is not one of the LEVEL constants</li>
382          * </ul>
383      * @since 3.0
384          */
385         public static AST newAST(int level) {
386                 if ((level != AST.JLS2)
387                         && (level != AST.JLS3)) {
388                         throw new IllegalArgumentException();
389                 }
390                 return new AST(level);
391         }
392
393         /**
394          * Returns the modification count for this AST. The modification count
395          * is a non-negative value that increases (by 1 or perhaps by more) as
396          * this AST or its nodes are changed. The initial value is unspecified.
397          * <p>
398          * The following things count as modifying an AST:
399          * <ul>
400          * <li>creating a new node owned by this AST,</li>
401          * <li>adding a child to a node owned by this AST,</li>
402          * <li>removing a child from a node owned by this AST,</li>
403          * <li>setting a non-node attribute of a node owned by this AST.</li>
404          * </ul>
405          * </p>
406          * Operations which do not entail creating or modifying existing nodes
407          * do not increase the modification count.
408          * <p>
409          * N.B. This method may be called several times in the course
410          * of a single client operation. The only promise is that the modification
411          * count increases monotonically as the AST or its nodes change; there is
412          * no promise that a modifying operation increases the count by exactly 1.
413          * </p>
414          *
415          * @return the current value (non-negative) of the modification counter of
416          *    this AST
417          */
418         public long modificationCount() {
419                 return this.modificationCount;
420         }
421
422         /**
423          * Return the API level supported by this AST.
424          *
425          * @return level the API level; one of the <code>JLS*</code>LEVEL
426      * declared on <code>AST</code>; assume this set is open-ended
427      * @since 3.0
428          */
429         public int apiLevel() {
430                 return this.apiLevel;
431         }
432
433         /**
434          * Indicates that this AST is about to be modified.
435          * <p>
436          * The following things count as modifying an AST:
437          * <ul>
438          * <li>creating a new node owned by this AST</li>
439          * <li>adding a child to a node owned by this AST</li>
440          * <li>removing a child from a node owned by this AST</li>
441          * <li>setting a non-node attribute of a node owned by this AST</li>.
442          * </ul>
443          * </p>
444          * <p>
445          * N.B. This method may be called several times in the course
446          * of a single client operation.
447          * </p>
448          */
449         void modifying() {
450                 // when this method is called during lazy init, events are disabled
451                 // and the modification count will not be increased
452                 if (this.disableEvents > 0) {
453                         return;
454                 }
455                 // increase the modification count
456                 this.modificationCount++;
457         }
458
459         /**
460      * Disable events.
461          * This method is thread-safe for AST readers.
462          *
463          * @see #reenableEvents()
464      * @since 3.0
465      */
466         final void disableEvents() {
467                 synchronized (this.internalASTLock) {
468                         // guard against concurrent access by another reader
469                         this.disableEvents++;
470                 }
471                 // while disableEvents > 0 no events will be reported, and mod count will stay fixed
472         }
473
474         /**
475      * Reenable events.
476          * This method is thread-safe for AST readers.
477          *
478          * @see #disableEvents()
479      * @since 3.0
480      */
481         final void reenableEvents() {
482                 synchronized (this.internalASTLock) {
483                         // guard against concurrent access by another reader
484                         this.disableEvents--;
485                 }
486         }
487
488         /**
489          * Reports that the given node is about to lose a child.
490          *
491          * @param node the node about to be modified
492          * @param child the node about to be removed
493          * @param property the child or child list property descriptor
494          * @since 3.0
495          */
496         void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
497                 // IMPORTANT: this method is called by readers during lazy init
498                 synchronized (this.internalASTLock) {
499                         // guard against concurrent access by a reader doing lazy init
500                         if (this.disableEvents > 0) {
501                                 // doing lazy init OR already processing an event
502                                 // System.out.println("[BOUNCE DEL]");
503                                 return;
504                         } else {
505                                 disableEvents();
506                         }
507                 }
508                 try {
509                         this.eventHandler.preRemoveChildEvent(node, child, property);
510                         // N.B. even if event handler blows up, the AST is not
511                         // corrupted since node has not been changed yet
512                 } finally {
513                         reenableEvents();
514                 }
515         }
516
517         /**
518          * Reports that the given node jsut lost a child.
519          *
520          * @param node the node that was modified
521          * @param child the child node that was removed
522          * @param property the child or child list property descriptor
523          * @since 3.0
524          */
525         void postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
526                 // IMPORTANT: this method is called by readers during lazy init
527                 synchronized (this.internalASTLock) {
528                         // guard against concurrent access by a reader doing lazy init
529                         if (this.disableEvents > 0) {
530                                 // doing lazy init OR already processing an event
531                                 // System.out.println("[BOUNCE DEL]");
532                                 return;
533                         } else {
534                                 disableEvents();
535                         }
536                 }
537                 try {
538                         this.eventHandler.postRemoveChildEvent(node, child, property);
539                         // N.B. even if event handler blows up, the AST is not
540                         // corrupted since node has not been changed yet
541                 } finally {
542                         reenableEvents();
543                 }
544         }
545
546         /**
547          * Reports that the given node is about have a child replaced.
548          *
549          * @param node the node about to be modified
550          * @param child the child node about to be removed
551          * @param newChild the replacement child
552          * @param property the child or child list property descriptor
553          * @since 3.0
554          */
555         void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
556                 // IMPORTANT: this method is called by readers during lazy init
557                 synchronized (this.internalASTLock) {
558                         // guard against concurrent access by a reader doing lazy init
559                         if (this.disableEvents > 0) {
560                                 // doing lazy init OR already processing an event
561                                 // System.out.println("[BOUNCE REP]");
562                                 return;
563                         } else {
564                                 disableEvents();
565                         }
566                 }
567                 try {
568                         this.eventHandler.preReplaceChildEvent(node, child, newChild, property);
569                         // N.B. even if event handler blows up, the AST is not
570                         // corrupted since node has not been changed yet
571                 } finally {
572                         reenableEvents();
573                 }
574         }
575
576         /**
577          * Reports that the given node has just had a child replaced.
578          *
579          * @param node the node modified
580          * @param child the child removed
581          * @param newChild the replacement child
582          * @param property the child or child list property descriptor
583          * @since 3.0
584          */
585         void postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
586                 // IMPORTANT: this method is called by readers during lazy init
587                 synchronized (this.internalASTLock) {
588                         // guard against concurrent access by a reader doing lazy init
589                         if (this.disableEvents > 0) {
590                                 // doing lazy init OR already processing an event
591                                 // System.out.println("[BOUNCE REP]");
592                                 return;
593                         } else {
594                                 disableEvents();
595                         }
596                 }
597                 try {
598                         this.eventHandler.postReplaceChildEvent(node, child, newChild, property);
599                         // N.B. even if event handler blows up, the AST is not
600                         // corrupted since node has not been changed yet
601                 } finally {
602                         reenableEvents();
603                 }
604         }
605
606         /**
607          * Reports that the given node is about to gain a child.
608          *
609          * @param node the node that to be modified
610          * @param child the node that to be added as a child
611          * @param property the child or child list property descriptor
612          * @since 3.0
613          */
614         void preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
615                 // IMPORTANT: this method is called by readers during lazy init
616                 synchronized (this.internalASTLock) {
617                         // guard against concurrent access by a reader doing lazy init
618                         if (this.disableEvents > 0) {
619                                 // doing lazy init OR already processing an event
620                                 // System.out.println("[BOUNCE ADD]");
621                                 return;
622                         } else {
623                                 disableEvents();
624                         }
625                 }
626                 try {
627                         this.eventHandler.preAddChildEvent(node, child, property);
628                         // N.B. even if event handler blows up, the AST is not
629                         // corrupted since node has already been changed
630                 } finally {
631                         reenableEvents();
632                 }
633         }
634
635         /**
636          * Reports that the given node has just gained a child.
637          *
638          * @param node the node that was modified
639          * @param child the node that was added as a child
640          * @param property the child or child list property descriptor
641          * @since 3.0
642          */
643         void postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
644                 // IMPORTANT: this method is called by readers during lazy init
645                 synchronized (this.internalASTLock) {
646                         // guard against concurrent access by a reader doing lazy init
647                         if (this.disableEvents > 0) {
648                                 // doing lazy init OR already processing an event
649                                 // System.out.println("[BOUNCE ADD]");
650                                 return;
651                         } else {
652                                 disableEvents();
653                         }
654                 }
655                 try {
656                         this.eventHandler.postAddChildEvent(node, child, property);
657                         // N.B. even if event handler blows up, the AST is not
658                         // corrupted since node has already been changed
659                 } finally {
660                         reenableEvents();
661                 }
662         }
663
664         /**
665          * Reports that the given node is about to change the value of a
666          * non-child property.
667          *
668          * @param node the node to be modified
669          * @param property the property descriptor
670          * @since 3.0
671          */
672         void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
673                 // IMPORTANT: this method is called by readers during lazy init
674                 synchronized (this.internalASTLock) {
675                         // guard against concurrent access by a reader doing lazy init
676                         if (this.disableEvents > 0) {
677                                 // doing lazy init OR already processing an event
678                                 // System.out.println("[BOUNCE CHANGE]");
679                                 return;
680                         } else {
681                                 disableEvents();
682                         }
683                 }
684                 try {
685                         this.eventHandler.preValueChangeEvent(node, property);
686                         // N.B. even if event handler blows up, the AST is not
687                         // corrupted since node has already been changed
688                 } finally {
689                         reenableEvents();
690                 }
691         }
692
693         /**
694          * Reports that the given node has just changed the value of a
695          * non-child property.
696          *
697          * @param node the node that was modified
698          * @param property the property descriptor
699          * @since 3.0
700          */
701         void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
702                 // IMPORTANT: this method is called by readers during lazy init
703                 synchronized (this.internalASTLock) {
704                         // guard against concurrent access by a reader doing lazy init
705                         if (this.disableEvents > 0) {
706                                 // doing lazy init OR already processing an event
707                                 // System.out.println("[BOUNCE CHANGE]");
708                                 return;
709                         } else {
710                                 disableEvents();
711                         }
712                 }
713                 try {
714                         this.eventHandler.postValueChangeEvent(node, property);
715                         // N.B. even if event handler blows up, the AST is not
716                         // corrupted since node has already been changed
717                 } finally {
718                         reenableEvents();
719                 }
720         }
721
722         /**
723          * Reports that the given node is about to be cloned.
724          *
725          * @param node the node to be cloned
726          * @since 3.0
727          */
728         void preCloneNodeEvent(ASTNode node) {
729                 synchronized (this.internalASTLock) {
730                         // guard against concurrent access by a reader doing lazy init
731                         if (this.disableEvents > 0) {
732                                 // doing lazy init OR already processing an event
733                                 // System.out.println("[BOUNCE CLONE]");
734                                 return;
735                         } else {
736                                 disableEvents();
737                         }
738                 }
739                 try {
740                         this.eventHandler.preCloneNodeEvent(node);
741                         // N.B. even if event handler blows up, the AST is not
742                         // corrupted since node has already been changed
743                 } finally {
744                         reenableEvents();
745                 }
746         }
747
748         /**
749          * Reports that the given node has just been cloned.
750          *
751          * @param node the node that was cloned
752          * @param clone the clone of <code>node</code>
753          * @since 3.0
754          */
755         void postCloneNodeEvent(ASTNode node, ASTNode clone) {
756                 synchronized (this.internalASTLock) {
757                         // guard against concurrent access by a reader doing lazy init
758                         if (this.disableEvents > 0) {
759                                 // doing lazy init OR already processing an event
760                                 // System.out.println("[BOUNCE CLONE]");
761                                 return;
762                         } else {
763                                 disableEvents();
764                         }
765                 }
766                 try {
767                         this.eventHandler.postCloneNodeEvent(node, clone);
768                         // N.B. even if event handler blows up, the AST is not
769                         // corrupted since node has already been changed
770                 } finally {
771                         reenableEvents();
772                 }
773         }
774
775         /**
776          * Parses the source string of the given Java model compilation unit element
777          * and creates and returns a corresponding abstract syntax tree. The source
778          * string is obtained from the Java model element using
779          * <code>ICompilationUnit.getSource()</code>.
780          * <p>
781          * The returned compilation unit node is the root node of a new AST.
782          * Each node in the subtree carries source range(s) information relating back
783          * to positions in the source string (the source string is not remembered
784          * with the AST).
785          * The source range usually begins at the first character of the first token
786          * corresponding to the node; leading whitespace and comments are <b>not</b>
787          * included. The source range usually extends through the last character of
788          * the last token corresponding to the node; trailing whitespace and
789          * comments are <b>not</b> included. There are a handful of exceptions
790          * (including compilation units and the various body declarations); the
791          * specification for these node type spells out the details.
792          * Source ranges nest properly: the source range for a child is always
793          * within the source range of its parent, and the source ranges of sibling
794          * nodes never overlap.
795          * If a syntax error is detected while parsing, the relevant node(s) of the
796          * tree will be flagged as <code>MALFORMED</code>.
797          * </p>
798          * <p>
799          * If <code>resolveBindings</code> is <code>true</code>, the various names
800          * and types appearing in the compilation unit can be resolved to "bindings"
801          * by calling the <code>resolveBinding</code> methods. These bindings
802          * draw connections between the different parts of a program, and
803          * generally afford a more powerful vantage point for clients who wish to
804          * analyze a program's structure more deeply. These bindings come at a
805          * considerable cost in both time and space, however, and should not be
806          * requested frivolously. The additional space is not reclaimed until the
807          * AST, all its nodes, and all its bindings become garbage. So it is very
808          * important to not retain any of these objects longer than absolutely
809          * necessary. Bindings are resolved at the time the AST is created. Subsequent
810          * modifications to the AST do not affect the bindings returned by
811          * <code>resolveBinding</code> methods in any way; these methods return the
812          * same binding as before the AST was modified (including modifications
813          * that rearrange subtrees by reparenting nodes).
814          * If <code>resolveBindings</code> is <code>false</code>, the analysis
815          * does not go beyond parsing and building the tree, and all
816          * <code>resolveBinding</code> methods return <code>null</code> from the
817          * outset.
818          * </p>
819          *
820          * @param unit the Java model compilation unit whose source code is to be parsed
821          * @param resolveBindings <code>true</code> if bindings are wanted,
822          *   and <code>false</code> if bindings are not of interest
823          * @return the compilation unit node
824          * @exception IllegalArgumentException if the given Java element does not
825          * exist or if its source string cannot be obtained
826          * @see ASTNode#getFlags()
827          * @see ASTNode#MALFORMED
828          * @see ASTNode#getStartPosition()
829          * @see ASTNode#getLength()
830          * @since 2.0
831          * @deprecated Use {@link ASTParser} instead.
832          */
833         public static CompilationUnit parseCompilationUnit(
834                 ICompilationUnit unit,
835                 boolean resolveBindings) {
836
837                 try {
838                         ASTParser c = ASTParser.newParser(AST.JLS2);
839                         c.setSource(unit);
840                         c.setResolveBindings(resolveBindings);
841                         ASTNode result = c.createAST(null);
842                         return (CompilationUnit) result;
843                 } catch (IllegalStateException e) {
844                         // convert ASTParser's complaints into old form
845                         throw new IllegalArgumentException();
846                 }
847         }
848
849         /**
850          * Parses the source string corresponding to the given Java class file
851          * element and creates and returns a corresponding abstract syntax tree.
852          * The source string is obtained from the Java model element using
853          * <code>IClassFile.getSource()</code>, and is only available for a class
854          * files with attached source.
855          * <p>
856          * The returned compilation unit node is the root node of a new AST.
857          * Each node in the subtree carries source range(s) information relating back
858          * to positions in the source string (the source string is not remembered
859          * with the AST).
860          * The source range usually begins at the first character of the first token
861          * corresponding to the node; leading whitespace and comments are <b>not</b>
862          * included. The source range usually extends through the last character of
863          * the last token corresponding to the node; trailing whitespace and
864          * comments are <b>not</b> included. There are a handful of exceptions
865          * (including compilation units and the various body declarations); the
866          * specification for these node type spells out the details.
867          * Source ranges nest properly: the source range for a child is always
868          * within the source range of its parent, and the source ranges of sibling
869          * nodes never overlap.
870          * If a syntax error is detected while parsing, the relevant node(s) of the
871          * tree will be flagged as <code>MALFORMED</code>.
872          * </p>
873          * <p>
874          * If <code>resolveBindings</code> is <code>true</code>, the various names
875          * and types appearing in the compilation unit can be resolved to "bindings"
876          * by calling the <code>resolveBinding</code> methods. These bindings
877          * draw connections between the different parts of a program, and
878          * generally afford a more powerful vantage point for clients who wish to
879          * analyze a program's structure more deeply. These bindings come at a
880          * considerable cost in both time and space, however, and should not be
881          * requested frivolously. The additional space is not reclaimed until the
882          * AST, all its nodes, and all its bindings become garbage. So it is very
883          * important to not retain any of these objects longer than absolutely
884          * necessary. Bindings are resolved at the time the AST is created. Subsequent
885          * modifications to the AST do not affect the bindings returned by
886          * <code>resolveBinding</code> methods in any way; these methods return the
887          * same binding as before the AST was modified (including modifications
888          * that rearrange subtrees by reparenting nodes).
889          * If <code>resolveBindings</code> is <code>false</code>, the analysis
890          * does not go beyond parsing and building the tree, and all
891          * <code>resolveBinding</code> methods return <code>null</code> from the
892          * outset.
893          * </p>
894          *
895          * @param classFile the Java model class file whose corresponding source code is to be parsed
896          * @param resolveBindings <code>true</code> if bindings are wanted,
897          *   and <code>false</code> if bindings are not of interest
898          * @return the compilation unit node
899          * @exception IllegalArgumentException if the given Java element does not
900          * exist or if its source string cannot be obtained
901          * @see ASTNode#getFlags()
902          * @see ASTNode#MALFORMED
903          * @see ASTNode#getStartPosition()
904          * @see ASTNode#getLength()
905          * @since 2.1
906          * @deprecated Use {@link ASTParser} instead.
907          */
908         public static CompilationUnit parseCompilationUnit(
909                 IClassFile classFile,
910                 boolean resolveBindings) {
911
912                 if (classFile == null) {
913                         throw new IllegalArgumentException();
914                 }
915                 try {
916                         ASTParser c = ASTParser.newParser(AST.JLS2);
917                         c.setSource(classFile);
918                         c.setResolveBindings(resolveBindings);
919                         ASTNode result = c.createAST(null);
920                         return (CompilationUnit) result;
921                 } catch (IllegalStateException e) {
922                         // convert ASTParser's complaints into old form
923                         throw new IllegalArgumentException();
924                 }
925         }
926
927         /**
928          * Parses the given string as the hypothetical contents of the named
929          * compilation unit and creates and returns a corresponding abstract syntax tree.
930          * <p>
931          * The returned compilation unit node is the root node of a new AST.
932          * Each node in the subtree carries source range(s) information relating back
933          * to positions in the given source string (the given source string itself
934          * is not remembered with the AST).
935          * The source range usually begins at the first character of the first token
936          * corresponding to the node; leading whitespace and comments are <b>not</b>
937          * included. The source range usually extends through the last character of
938          * the last token corresponding to the node; trailing whitespace and
939          * comments are <b>not</b> included. There are a handful of exceptions
940          * (including compilation units and the various body declarations); the
941          * specification for these node type spells out the details.
942          * Source ranges nest properly: the source range for a child is always
943          * within the source range of its parent, and the source ranges of sibling
944          * nodes never overlap.
945          * If a syntax error is detected while parsing, the relevant node(s) of the
946          * tree will be flagged as <code>MALFORMED</code>.
947          * </p>
948          * <p>
949          * If the given project is not <code>null</code>, the various names
950          * and types appearing in the compilation unit can be resolved to "bindings"
951          * by calling the <code>resolveBinding</code> methods. These bindings
952          * draw connections between the different parts of a program, and
953          * generally afford a more powerful vantage point for clients who wish to
954          * analyze a program's structure more deeply. These bindings come at a
955          * considerable cost in both time and space, however, and should not be
956          * requested frivolously. The additional space is not reclaimed until the
957          * AST, all its nodes, and all its bindings become garbage. So it is very
958          * important to not retain any of these objects longer than absolutely
959          * necessary. Bindings are resolved at the time the AST is created. Subsequent
960          * modifications to the AST do not affect the bindings returned by
961          * <code>resolveBinding</code> methods in any way; these methods return the
962          * same binding as before the AST was modified (including modifications
963          * that rearrange subtrees by reparenting nodes).
964          * If the given project is <code>null</code>, the analysis
965          * does not go beyond parsing and building the tree, and all
966          * <code>resolveBinding</code> methods return <code>null</code> from the
967          * outset.
968          * </p>
969          * <p>
970          * The name of the compilation unit must be supplied for resolving bindings.
971          * This name should be suffixed by a dot ('.') followed by one of the
972          * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
973          * and match the name of the main
974          * (public) class or interface declared in the source. For example, if the source
975          * declares a public class named "Foo", the name of the compilation can be
976          * "Foo.java". For the purposes of resolving bindings, types declared in the
977          * source string hide types by the same name available through the classpath
978          * of the given project.
979          * </p>
980          *
981          * @param source the string to be parsed as a Java compilation unit
982          * @param unitName the name of the compilation unit that would contain the source
983          *    string, or <code>null</code> if <code>javaProject</code> is also <code>null</code>
984          * @param project the Java project used to resolve names, or
985          *    <code>null</code> if bindings are not resolved
986          * @return the compilation unit node
987          * @see ASTNode#getFlags()
988          * @see ASTNode#MALFORMED
989          * @see ASTNode#getStartPosition()
990          * @see ASTNode#getLength()
991          * @since 2.0
992          * @deprecated Use {@link ASTParser} instead.
993          */
994         public static CompilationUnit parseCompilationUnit(
995                 char[] source,
996                 String unitName,
997                 IJavaProject project) {
998
999                 if (source == null) {
1000                         throw new IllegalArgumentException();
1001                 }
1002                 ASTParser astParser = ASTParser.newParser(AST.JLS2);
1003                 astParser.setSource(source);
1004                 astParser.setUnitName(unitName);
1005                 astParser.setProject(project);
1006                 astParser.setResolveBindings(project != null);
1007                 ASTNode result = astParser.createAST(null);
1008                 return (CompilationUnit) result;
1009         }
1010
1011         /**
1012          * Parses the given string as a Java compilation unit and creates and
1013          * returns a corresponding abstract syntax tree.
1014          * <p>
1015          * The returned compilation unit node is the root node of a new AST.
1016          * Each node in the subtree carries source range(s) information relating back
1017          * to positions in the given source string (the given source string itself
1018          * is not remembered with the AST).
1019          * The source range usually begins at the first character of the first token
1020          * corresponding to the node; leading whitespace and comments are <b>not</b>
1021          * included. The source range usually extends through the last character of
1022          * the last token corresponding to the node; trailing whitespace and
1023          * comments are <b>not</b> included. There are a handful of exceptions
1024          * (including compilation units and the various body declarations); the
1025          * specification for these node type spells out the details.
1026          * Source ranges nest properly: the source range for a child is always
1027          * within the source range of its parent, and the source ranges of sibling
1028          * nodes never overlap.
1029          * If a syntax error is detected while parsing, the relevant node(s) of the
1030          * tree will be flagged as <code>MALFORMED</code>.
1031          * </p>
1032          * <p>
1033          * This method does not compute binding information; all <code>resolveBinding</code>
1034          * methods applied to nodes of the resulting AST return <code>null</code>.
1035          * </p>
1036          *
1037          * @param source the string to be parsed as a Java compilation unit
1038          * @return the compilation unit node
1039          * @see ASTNode#getFlags()
1040          * @see ASTNode#MALFORMED
1041          * @see ASTNode#getStartPosition()
1042          * @see ASTNode#getLength()
1043          * @since 2.0
1044          * @deprecated Use {@link ASTParser} instead.
1045          */
1046         public static CompilationUnit parseCompilationUnit(char[] source) {
1047                 if (source == null) {
1048                         throw new IllegalArgumentException();
1049                 }
1050                 ASTParser c = ASTParser.newParser(AST.JLS2);
1051                 c.setSource(source);
1052                 ASTNode result = c.createAST(null);
1053                 return (CompilationUnit) result;
1054         }
1055
1056         /**
1057          * Returns the binding resolver for this AST.
1058          *
1059          * @return the binding resolver for this AST
1060          */
1061         BindingResolver getBindingResolver() {
1062                 return this.resolver;
1063         }
1064
1065         /**
1066          * Returns the event handler for this AST.
1067          *
1068          * @return the event handler for this AST
1069          * @since 3.0
1070          */
1071         NodeEventHandler getEventHandler() {
1072                 return this.eventHandler;
1073         }
1074
1075         /**
1076          * Sets the event handler for this AST.
1077          *
1078          * @param eventHandler the event handler for this AST
1079          * @since 3.0
1080          */
1081         void setEventHandler(NodeEventHandler eventHandler) {
1082                 if (this.eventHandler == null) {
1083                         throw new IllegalArgumentException();
1084                 }
1085                 this.eventHandler = eventHandler;
1086         }
1087
1088         /**
1089          * Returns default node flags of new nodes of this AST.
1090          *
1091          * @return the default node flags of new nodes of this AST
1092          * @since 3.0
1093          */
1094         int getDefaultNodeFlag() {
1095                 return this.defaultNodeFlag;
1096         }
1097
1098         /**
1099          * Sets default node flags of new nodes of this AST.
1100          *
1101          * @param flag node flags of new nodes of this AST
1102          * @since 3.0
1103          */
1104         void setDefaultNodeFlag(int flag) {
1105                 this.defaultNodeFlag = flag;
1106         }
1107
1108         /**
1109          * Set <code>originalModificationCount</code> to the current modification count
1110          *
1111          * @since 3.0
1112          */
1113         void setOriginalModificationCount(long count) {
1114                 this.originalModificationCount = count;
1115         }
1116
1117         /**
1118          * Returns the type binding for a "well known" type.
1119          * <p>
1120          * Note that bindings are generally unavailable unless requested when the
1121          * AST is being built.
1122          * </p>
1123          * <p>
1124          * The following type names are supported:
1125          * <ul>
1126          * <li><code>"boolean"</code></li>
1127          * <li><code>"byte"</code></li>
1128          * <li><code>"char"</code></li>
1129          * <li><code>"double"</code></li>
1130          * <li><code>"float"</code></li>
1131          * <li><code>"int"</code></li>
1132          * <li><code>"long"</code></li>
1133          * <li><code>"short"</code></li>
1134          * <li><code>"void"</code></li>
1135          * <li><code>"java.lang.Boolean"</code> (since 3.1)</li>
1136          * <li><code>"java.lang.Byte"</code> (since 3.1)</li>
1137          * <li><code>"java.lang.Character"</code> (since 3.1)</li>
1138          * <li><code>"java.lang.Class"</code></li>
1139          * <li><code>"java.lang.Cloneable"</code></li>
1140          * <li><code>"java.lang.Double"</code> (since 3.1)</li>
1141          * <li><code>"java.lang.Error"</code></li>
1142          * <li><code>"java.lang.Exception"</code></li>
1143          * <li><code>"java.lang.Float"</code> (since 3.1)</li>
1144          * <li><code>"java.lang.Integer"</code> (since 3.1)</li>
1145          * <li><code>"java.lang.Long"</code> (since 3.1)</li>
1146          * <li><code>"java.lang.Object"</code></li>
1147          * <li><code>"java.lang.RuntimeException"</code></li>
1148          * <li><code>"java.lang.Short"</code> (since 3.1)</li>
1149          * <li><code>"java.lang.String"</code></li>
1150          * <li><code>"java.lang.StringBuffer"</code></li>
1151          * <li><code>"java.lang.Throwable"</code></li>
1152          * <li><code>"java.lang.Void"</code> (since 3.1)</li>
1153          * <li><code>"java.io.Serializable"</code></li>
1154          * </ul>
1155          * </p>
1156          *
1157          * @param name the name of a well known type
1158          * @return the corresponding type binding, or <code>null</code> if the
1159          *   named type is not considered well known or if no binding can be found
1160          *   for it
1161          */
1162         public ITypeBinding resolveWellKnownType(String name) {
1163                 if (name == null) {
1164                         return null;
1165                 }
1166                 return getBindingResolver().resolveWellKnownType(name);
1167         }
1168
1169         /**
1170          * Sets the binding resolver for this AST.
1171          *
1172          * @param resolver the new binding resolver for this AST
1173          */
1174         void setBindingResolver(BindingResolver resolver) {
1175                 if (resolver == null) {
1176                         throw new IllegalArgumentException();
1177                 }
1178                 this.resolver = resolver;
1179         }
1180
1181         /**
1182      * Checks that this AST operation is not used when
1183      * building level JLS2 ASTs.
1184
1185      * @exception UnsupportedOperationException
1186          * @since 3.0
1187      */
1188         void unsupportedIn2() {
1189           if (this.apiLevel == AST.JLS2) {
1190                 throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
1191           }
1192         }
1193
1194         /**
1195      * Checks that this AST operation is only used when
1196      * building level JLS2 ASTs.
1197
1198      * @exception UnsupportedOperationException
1199          * @since 3.0
1200      */
1201         void supportedOnlyIn2() {
1202           if (this.apiLevel != AST.JLS2) {
1203                 throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
1204           }
1205         }
1206
1207         /**
1208          * new Class[] {AST.class}
1209          * @since 3.0
1210          */
1211         private static final Class[] AST_CLASS = new Class[] {AST.class};
1212
1213         /**
1214          * new Object[] {this}
1215          * @since 3.0
1216          */
1217         private final Object[] THIS_AST= new Object[] {this};
1218
1219         /*
1220          * Must not collide with a value for ICompilationUnit constants
1221          */
1222         static final int RESOLVED_BINDINGS = 0x80000000;
1223
1224         /**
1225          * Tag bit value. This represents internal state of the tree.
1226          */
1227         private int bits;
1228
1229         /**
1230          * Creates an unparented node of the given node class
1231          * (non-abstract subclass of {@link ASTNode}). 
1232          * 
1233          * @param nodeClass AST node class
1234          * @return a new unparented node owned by this AST
1235          * @exception IllegalArgumentException if <code>nodeClass</code> is
1236          * <code>null</code> or is not a concrete node type class
1237          * @since 3.0
1238          */
1239         public ASTNode createInstance(Class nodeClass) {
1240                 if (nodeClass == null) {
1241                         throw new IllegalArgumentException();
1242                 }
1243                 try {
1244                         // invoke constructor with signature Foo(AST)
1245                         Constructor c = nodeClass.getDeclaredConstructor(AST_CLASS);
1246                         Object result = c.newInstance(this.THIS_AST);
1247                         return (ASTNode) result;
1248                 } catch (NoSuchMethodException e) {
1249                         // all AST node classes have a Foo(AST) constructor
1250                         // therefore nodeClass is not legit
1251                         throw new IllegalArgumentException();
1252                 } catch (InstantiationException e) {
1253                         // all concrete AST node classes can be instantiated
1254                         // therefore nodeClass is not legit
1255                         throw new IllegalArgumentException();
1256                 } catch (IllegalAccessException e) {
1257                         // all AST node classes have an accessible Foo(AST) constructor
1258                         // therefore nodeClass is not legit
1259                         throw new IllegalArgumentException();
1260                 } catch (InvocationTargetException e) {
1261                         // concrete AST node classes do not die in the constructor
1262                         // therefore nodeClass is not legit
1263                         throw new IllegalArgumentException();
1264                 }
1265         }
1266
1267         /**
1268          * Creates an unparented node of the given node type.
1269          * This convenience method is equivalent to:
1270          * <pre>
1271          * createInstance(ASTNode.nodeClassForType(nodeType))
1272          * </pre>
1273          *
1274          * @param nodeType AST node type, one of the node type
1275          * constants declared on {@link ASTNode}
1276          * @return a new unparented node owned by this AST
1277          * @exception IllegalArgumentException if <code>nodeType</code> is
1278          * not a legal AST node type
1279          * @since 3.0
1280          */
1281         public ASTNode createInstance(int nodeType) {
1282                 // nodeClassForType throws IllegalArgumentException if nodeType is bogus
1283                 Class nodeClass = ASTNode.nodeClassForType(nodeType);
1284                 return createInstance(nodeClass);
1285         }
1286
1287         //=============================== NAMES ===========================
1288         /**
1289          * Creates and returns a new unparented simple name node for the given
1290          * identifier. The identifier should be a legal Java identifier, but not
1291          * a keyword, boolean literal ("true", "false") or null literal ("null").
1292          *
1293          * @param identifier the identifier
1294          * @return a new unparented simple name node
1295          * @exception IllegalArgumentException if the identifier is invalid
1296          */
1297         public SimpleName newSimpleName(String identifier) {
1298                 if (identifier == null) {
1299                         throw new IllegalArgumentException();
1300                 }
1301                 SimpleName result = new SimpleName(this);
1302                 result.setIdentifier(identifier);
1303                 return result;
1304         }
1305
1306         /**
1307          * Creates and returns a new unparented qualified name node for the given
1308          * qualifier and simple name child node.
1309          *
1310          * @param qualifier the qualifier name node
1311          * @param name the simple name being qualified
1312          * @return a new unparented qualified name node
1313          * @exception IllegalArgumentException if:
1314          * <ul>
1315          * <li>the node belongs to a different AST</li>
1316          * <li>the node already has a parent</li>
1317          * </ul>
1318          */
1319         public QualifiedName newQualifiedName(
1320                 Name qualifier,
1321                 SimpleName name) {
1322                 QualifiedName result = new QualifiedName(this);
1323                 result.setQualifier(qualifier);
1324                 result.setName(name);
1325                 return result;
1326
1327         }
1328
1329         /**
1330          * Creates and returns a new unparented name node for the given name
1331          * segments. Returns a simple name if there is only one name segment, and
1332          * a qualified name if there are multiple name segments. Each of the name
1333          * segments should be legal Java identifiers (this constraint may or may
1334          * not be enforced), and there must be at least one name segment.
1335          *
1336          * @param identifiers a list of 1 or more name segments, each of which
1337          *    is a legal Java identifier
1338          * @return a new unparented name node
1339          * @exception IllegalArgumentException if:
1340          * <ul>
1341          * <li>the identifier is invalid</li>
1342          * <li>the list of identifiers is empty</li>
1343          * </ul>
1344          */
1345         public Name newName(String[] identifiers) {
1346                 // update internalSetName(String[] if changed
1347                 int count = identifiers.length;
1348                 if (count == 0) {
1349                         throw new IllegalArgumentException();
1350                 }
1351                 Name result = newSimpleName(identifiers[0]);
1352                 for (int i = 1; i < count; i++) {
1353                         SimpleName name = newSimpleName(identifiers[i]);
1354                         result = newQualifiedName(result, name);
1355                 }
1356                 return result;
1357         }
1358
1359         /* (omit javadoc for this method)
1360          * This method is a copy of setName(String[]) that doesn't do any validation.
1361          */
1362         Name internalNewName(String[] identifiers) {
1363                 int count = identifiers.length;
1364                 if (count == 0) {
1365                         throw new IllegalArgumentException();
1366                 }
1367                 final SimpleName simpleName = new SimpleName(this);
1368                 simpleName.internalSetIdentifier(identifiers[0]);
1369                 Name result = simpleName;
1370                 for (int i = 1; i < count; i++) {
1371                         SimpleName name = new SimpleName(this);
1372                         name.internalSetIdentifier(identifiers[i]);
1373                         result = newQualifiedName(result, name);
1374                 }
1375                 return result;
1376         }
1377
1378         /**
1379          * Creates and returns a new unparented name node for the given name.
1380          * The name string must consist of 1 or more name segments separated
1381          * by single dots '.'. Returns a {@link QualifiedName} if the name has
1382          * dots, and a {@link SimpleName} otherwise. Each of the name
1383          * segments should be legal Java identifiers (this constraint may or may
1384          * not be enforced), and there must be at least one name segment.
1385          * The string must not contains white space, '&lt;', '&gt;',
1386          * '[', ']', or other any other characters that are not
1387          * part of the Java identifiers or separating '.'s.
1388          *
1389          * @param qualifiedName string consisting of 1 or more name segments,
1390          * each of which is a legal Java identifier, separated  by single dots '.'
1391          * @return a new unparented name node
1392          * @exception IllegalArgumentException if:
1393          * <ul>
1394          * <li>the string is empty</li>
1395          * <li>the string begins or ends in a '.'</li>
1396          * <li>the string has adjacent '.'s</li>
1397          * <li>the segments between the '.'s are not valid Java identifiers</li>
1398          * </ul>
1399          * @since 3.1
1400          */
1401         public Name newName(String qualifiedName) {
1402                 StringTokenizer t = new StringTokenizer(qualifiedName, ".", true); //$NON-NLS-1$
1403                 Name result = null;
1404                 // balance is # of name tokens - # of period tokens seen so far
1405                 // initially 0; finally 1; should never drop < 0 or > 1
1406                 int balance = 0;
1407                 while(t.hasMoreTokens()) {
1408                         String s = t.nextToken();
1409                         if (s.indexOf('.') >= 0) {
1410                                 // this is a delimiter
1411                                 if (s.length() > 1) {
1412                                         // too many dots in a row
1413                                         throw new IllegalArgumentException();
1414                                 }
1415                                 balance--;
1416                                 if (balance < 0) {
1417                                         throw new IllegalArgumentException();
1418                                 }
1419                         } else {
1420                                 // this is an identifier segment
1421                                 balance++;
1422                                 SimpleName name = newSimpleName(s);
1423                                 if (result == null) {
1424                                         result = name;
1425                                 } else {
1426                                         result = newQualifiedName(result, name);
1427                                 }
1428                         }
1429                 }
1430                 if (balance != 1) {
1431                         throw new IllegalArgumentException();
1432                 }
1433                 return result;
1434         }
1435
1436         //=============================== TYPES ===========================
1437         /**
1438          * Creates and returns a new unparented simple type node with the given
1439          * type name.
1440          * <p>
1441          * This method can be used to convert a name (<code>Name</code>) into a
1442          * type (<code>Type</code>) by wrapping it.
1443          * </p>
1444          *
1445          * @param typeName the name of the class or interface
1446          * @return a new unparented simple type node
1447          * @exception IllegalArgumentException if:
1448          * <ul>
1449          * <li>the node belongs to a different AST</li>
1450          * <li>the node already has a parent</li>
1451          * </ul>
1452          */
1453         public SimpleType newSimpleType(Name typeName) {
1454                 SimpleType result = new SimpleType(this);
1455                 result.setName(typeName);
1456                 return result;
1457         }
1458
1459         /**
1460          * Creates and returns a new unparented array type node with the given
1461          * component type, which may be another array type.
1462          *
1463          * @param componentType the component type (possibly another array type)
1464          * @return a new unparented array type node
1465          * @exception IllegalArgumentException if:
1466          * <ul>
1467          * <li>the node belongs to a different AST</li>
1468          * <li>the node already has a parent</li>
1469          * <li>a cycle in would be created</li>
1470          * </ul>
1471          */
1472         public ArrayType newArrayType(Type componentType) {
1473                 ArrayType result = new ArrayType(this);
1474                 result.setComponentType(componentType);
1475                 return result;
1476         }
1477
1478         /**
1479          * Creates and returns a new unparented array type node with the given
1480          * element type and number of dimensions.
1481          * <p>
1482          * Note that if the element type passed in is an array type, the
1483          * element type of the result will not be the same as what was passed in.
1484          * </p>
1485          *
1486          * @param elementType the element type (never an array type)
1487          * @param dimensions the number of dimensions, a positive number
1488          * @return a new unparented array type node
1489          * @exception IllegalArgumentException if:
1490          * <ul>
1491          * <li>the node belongs to a different AST</li>
1492          * <li>the node already has a parent</li>
1493          * <li>a cycle in would be created</li>
1494          * <li>the element type is null</li>
1495          * <li>the element type is an array type</li>
1496          * <li>the number of dimensions is lower than 1</li>
1497          * <li>the number of dimensions is greater than 1000</li>
1498          * </ul>
1499          */
1500         public ArrayType newArrayType(Type elementType, int dimensions) {
1501                 if (elementType == null || elementType.isArrayType()) {
1502                         throw new IllegalArgumentException();
1503                 }
1504                 if (dimensions < 1 || dimensions > 1000) {
1505                         // we would blow our stacks anyway with a 1000-D array
1506                         throw new IllegalArgumentException();
1507                 }
1508                 ArrayType result = new ArrayType(this);
1509                 result.setComponentType(elementType);
1510                 for (int i = 2; i <= dimensions; i++) {
1511                         result = newArrayType(result);
1512                 }
1513                 return result;
1514
1515         }
1516
1517         /**
1518          * Creates and returns a new unparented primitive type node with the given
1519          * type code.
1520          *
1521          * @param typeCode one of the primitive type code constants declared in
1522          *    <code>PrimitiveType</code>
1523          * @return a new unparented primitive type node
1524          * @exception IllegalArgumentException if the primitive type code is invalid
1525          */
1526         public PrimitiveType newPrimitiveType(PrimitiveType.Code typeCode) {
1527                 PrimitiveType result = new PrimitiveType(this);
1528                 result.setPrimitiveTypeCode(typeCode);
1529                 return result;
1530         }
1531
1532         /**
1533          * Creates and returns a new unparented parameterized type node with the
1534          * given type and an empty list of type arguments.
1535          *
1536          * @param type the type that is parameterized
1537          * @return a new unparented parameterized type node
1538          * @exception IllegalArgumentException if:
1539          * <ul>
1540          * <li>the node belongs to a different AST</li>
1541          * <li>the node already has a parent</li>
1542          * </ul>
1543          * @exception UnsupportedOperationException if this operation is used in
1544          * a JLS2 AST
1545          * @since 3.1
1546          */
1547         public ParameterizedType newParameterizedType(Type type) {
1548                 ParameterizedType result = new ParameterizedType(this);
1549                 result.setType(type);
1550                 return result;
1551         }
1552
1553         /**
1554          * Creates and returns a new unparented qualified type node with
1555          * the given qualifier type and name.
1556          *
1557          * @param qualifier the qualifier type node
1558          * @param name the simple name being qualified
1559          * @return a new unparented qualified type node
1560          * @exception IllegalArgumentException if:
1561          * <ul>
1562          * <li>the node belongs to a different AST</li>
1563          * <li>the node already has a parent</li>
1564          * </ul>
1565          * @exception UnsupportedOperationException if this operation is used in
1566          * a JLS2 AST
1567          * @since 3.1
1568          */
1569         public QualifiedType newQualifiedType(Type qualifier, SimpleName name) {
1570                 QualifiedType result = new QualifiedType(this);
1571                 result.setQualifier(qualifier);
1572                 result.setName(name);
1573                 return result;
1574         }
1575
1576         /**
1577          * Creates and returns a new unparented wildcard type node with no
1578          * type bound.
1579          *
1580          * @return a new unparented wildcard type node
1581          * @exception UnsupportedOperationException if this operation is used in
1582          * a JLS2 AST
1583          * @since 3.1
1584          */
1585         public WildcardType newWildcardType() {
1586                 WildcardType result = new WildcardType(this);
1587                 return result;
1588         }
1589
1590         //=============================== DECLARATIONS ===========================
1591         /**
1592          * Creates an unparented compilation unit node owned by this AST.
1593          * The compilation unit initially has no package declaration, no
1594          * import declarations, and no type declarations.
1595          *
1596          * @return the new unparented compilation unit node
1597          */
1598         public CompilationUnit newCompilationUnit() {
1599                 return new CompilationUnit(this);
1600         }
1601
1602         /**
1603          * Creates an unparented package declaration node owned by this AST.
1604          * The package declaration initially declares a package with an
1605          * unspecified name.
1606          *
1607          * @return the new unparented package declaration node
1608          */
1609         public PackageDeclaration newPackageDeclaration() {
1610                 PackageDeclaration result = new PackageDeclaration(this);
1611                 return result;
1612         }
1613
1614         /**
1615          * Creates an unparented import declaration node owned by this AST.
1616          * The import declaration initially contains a single-type import
1617          * of a type with an unspecified name.
1618          *
1619          * @return the new unparented import declaration node
1620          */
1621         public ImportDeclaration newImportDeclaration() {
1622                 ImportDeclaration result = new ImportDeclaration(this);
1623                 return result;
1624         }
1625
1626         /**
1627          * Creates an unparented class declaration node owned by this AST.
1628          * The name of the class is an unspecified, but legal, name;
1629          * no modifiers; no doc comment; no superclass or superinterfaces;
1630          * and an empty class body.
1631          * <p>
1632          * To create an interface, use this method and then call
1633          * <code>TypeDeclaration.setInterface(true)</code>.
1634          * </p>
1635          *
1636          * @return a new unparented type declaration node
1637          */
1638         public TypeDeclaration newTypeDeclaration() {
1639                 TypeDeclaration result = new TypeDeclaration(this);
1640                 result.setInterface(false);
1641                 return result;
1642         }
1643
1644         /**
1645          * Creates an unparented method declaration node owned by this AST.
1646          * By default, the declaration is for a method of an unspecified, but
1647          * legal, name; no modifiers; no doc comment; no parameters; return
1648          * type void; no extra array dimensions; no thrown exceptions; and no
1649          * body (as opposed to an empty body).
1650          * <p>
1651          * To create a constructor, use this method and then call
1652          * <code>MethodDeclaration.setConstructor(true)</code> and
1653          * <code>MethodDeclaration.setName(className)</code>.
1654          * </p>
1655          *
1656          * @return a new unparented method declaration node
1657          */
1658         public MethodDeclaration newMethodDeclaration() {
1659                 MethodDeclaration result = new MethodDeclaration(this);
1660                 result.setConstructor(false);
1661                 return result;
1662         }
1663
1664         /**
1665          * Creates an unparented single variable declaration node owned by this AST.
1666          * By default, the declaration is for a variable with an unspecified, but
1667          * legal, name and type; no modifiers; no array dimensions after the
1668          * variable; no initializer; not variable arity.
1669          *
1670          * @return a new unparented single variable declaration node
1671          */
1672         public SingleVariableDeclaration newSingleVariableDeclaration() {
1673                 SingleVariableDeclaration result = new SingleVariableDeclaration(this);
1674                 return result;
1675         }
1676
1677         /**
1678          * Creates an unparented variable declaration fragment node owned by this
1679          * AST. By default, the fragment is for a variable with an unspecified, but
1680          * legal, name; no extra array dimensions; and no initializer.
1681          *
1682          * @return a new unparented variable declaration fragment node
1683          */
1684         public VariableDeclarationFragment newVariableDeclarationFragment() {
1685                 VariableDeclarationFragment result = new VariableDeclarationFragment(this);
1686                 return result;
1687         }
1688
1689         /**
1690          * Creates an unparented initializer node owned by this AST, with an
1691          * empty block. By default, the initializer has no modifiers and
1692          * an empty block.
1693          *
1694          * @return a new unparented initializer node
1695          */
1696         public Initializer newInitializer() {
1697                 Initializer result = new Initializer(this);
1698                 return result;
1699         }
1700
1701         /**
1702          * Creates an unparented enum constant declaration node owned by this AST.
1703          * The name of the constant is an unspecified, but legal, name;
1704          * no doc comment; no modifiers or annotations; no arguments;
1705          * and does not declare an anonymous class.
1706          *
1707          * @return a new unparented enum constant declaration node
1708          * @exception UnsupportedOperationException if this operation is used in
1709          * a JLS2 AST
1710          * @since 3.1
1711          */
1712         public EnumConstantDeclaration newEnumConstantDeclaration() {
1713                 EnumConstantDeclaration result = new EnumConstantDeclaration(this);
1714                 return result;
1715         }
1716
1717         /**
1718          * Creates an unparented enum declaration node owned by this AST.
1719          * The name of the enum is an unspecified, but legal, name;
1720          * no doc comment; no modifiers or annotations;
1721          * no superinterfaces; and empty lists of enum constants
1722          * and body declarations.
1723          *
1724          * @return a new unparented enum declaration node
1725          * @exception UnsupportedOperationException if this operation is used in
1726          * a JLS2 AST
1727          * @since 3.1
1728          */
1729         public EnumDeclaration newEnumDeclaration() {
1730                 EnumDeclaration result = new EnumDeclaration(this);
1731                 return result;
1732         }
1733
1734         /**
1735          * Creates and returns a new unparented type parameter type node with an
1736          * unspecified type variable name and an empty list of type bounds.
1737          *
1738          * @return a new unparented type parameter node
1739          * @exception UnsupportedOperationException if this operation is used in
1740          * a JLS2 AST
1741          * @since 3.1
1742          */
1743         public TypeParameter newTypeParameter() {
1744                 TypeParameter result = new TypeParameter(this);
1745                 return result;
1746         }
1747
1748         /**
1749          * Creates and returns a new unparented annotation type declaration
1750          * node for an unspecified, but legal, name; no modifiers; no javadoc;
1751          * and an empty list of member declarations.
1752          *
1753          * @return a new unparented annotation type declaration node
1754          * @exception UnsupportedOperationException if this operation is used in
1755          * a JLS2 AST
1756          * @since 3.1
1757          */
1758         public AnnotationTypeDeclaration newAnnotationTypeDeclaration() {
1759                 AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(this);
1760                 return result;
1761         }
1762
1763         /**
1764          * Creates and returns a new unparented annotation type
1765          * member declaration node for an unspecified, but legal,
1766          * member name and type; no modifiers; no javadoc;
1767          * and no default value.
1768          *
1769          * @return a new unparented annotation type member declaration node
1770          * @exception UnsupportedOperationException if this operation is used in
1771          * a JLS2 AST
1772          * @since 3.1
1773          */
1774         public AnnotationTypeMemberDeclaration newAnnotationTypeMemberDeclaration() {
1775                 AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(this);
1776                 return result;
1777         }
1778
1779         /**
1780          * Creates and returns a new unparented modifier node for the given
1781          * modifier.
1782          *
1783          * @param keyword one of the modifier keyword constants
1784          * @return a new unparented modifier node
1785          * @exception IllegalArgumentException if the primitive type code is invalid
1786          * @exception UnsupportedOperationException if this operation is used in
1787          * a JLS2 AST
1788          * @since 3.1
1789          */
1790         public Modifier newModifier(Modifier.ModifierKeyword keyword) {
1791                 Modifier result = new Modifier(this);
1792                 result.setKeyword(keyword);
1793                 return result;
1794         }
1795
1796         /**
1797          * Creates and returns a list of new unparented modifier nodes
1798          * for the given modifier flags. When multiple modifiers are
1799          * requested the modifiers nodes will appear in the following order:
1800          * public, protected, private, abstract, static, final, synchronized,
1801          * native, strictfp, transient, volatile. This order is consistent
1802          * with the recommendations in JLS2 8.1.1, 8.3.1, and 8.4.3.
1803          *
1804          * @param flags bitwise or of modifier flags declared on {@link Modifier}
1805          * @return a possibly empty list of new unparented modifier nodes
1806          *   (element type <code>Modifier</code>)
1807          * @exception UnsupportedOperationException if this operation is used in
1808          * a JLS2 AST
1809          * @since 3.1
1810          */
1811         public List newModifiers(int flags) {
1812                 if (this.apiLevel == AST.JLS2) {
1813                         unsupportedIn2();
1814                 }
1815                 List result = new ArrayList(3); // 3 modifiers is more than average
1816                 if (Modifier.isPublic(flags)) {
1817                         result.add(newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
1818                 }
1819                 if (Modifier.isProtected(flags)) {
1820                         result.add(newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD));
1821                 }
1822                 if (Modifier.isPrivate(flags)) {
1823                         result.add(newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD));
1824                 }
1825                 if (Modifier.isAbstract(flags)) {
1826                         result.add(newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD));
1827                 }
1828                 if (Modifier.isStatic(flags)) {
1829                         result.add(newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
1830                 }
1831                 if (Modifier.isFinal(flags)) {
1832                         result.add(newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
1833                 }
1834                 if (Modifier.isSynchronized(flags)) {
1835                         result.add(newModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD));
1836                 }
1837                 if (Modifier.isNative(flags)) {
1838                         result.add(newModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD));
1839                 }
1840                 if (Modifier.isStrictfp(flags)) {
1841                         result.add(newModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD));
1842                 }
1843                 if (Modifier.isTransient(flags)) {
1844                         result.add(newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD));
1845                 }
1846                 if (Modifier.isVolatile(flags)) {
1847                         result.add(newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD));
1848                 }
1849                 return result;
1850         }
1851
1852         //=============================== COMMENTS ===========================
1853
1854         /**
1855          * Creates and returns a new block comment placeholder node.
1856          * <p>
1857          * Note that this node type is used to recording the source
1858          * range where a comment was found in the source string.
1859          * These comment nodes are normally found (only) in
1860          * {@linkplain CompilationUnit#getCommentList()
1861          * the comment table} for parsed compilation units.
1862          * </p>
1863          *
1864          * @return a new unparented block comment node
1865          * @since 3.0
1866          */
1867         public BlockComment newBlockComment() {
1868                 BlockComment result = new BlockComment(this);
1869                 return result;
1870         }
1871
1872         /**
1873          * Creates and returns a new line comment placeholder node.
1874          * <p>
1875          * Note that this node type is used to recording the source
1876          * range where a comment was found in the source string.
1877          * These comment nodes are normally found (only) in
1878          * {@linkplain CompilationUnit#getCommentList()
1879          * the comment table} for parsed compilation units.
1880          * </p>
1881          *
1882          * @return a new unparented line comment node
1883          * @since 3.0
1884          */
1885         public LineComment newLineComment() {
1886                 LineComment result = new LineComment(this);
1887                 return result;
1888         }
1889
1890         /**
1891          * Creates and returns a new doc comment node.
1892          * Initially the new node has an empty list of tag elements
1893          * (and, for backwards compatability, an unspecified, but legal,
1894          * doc comment string)
1895          *
1896          * @return a new unparented doc comment node
1897          */
1898         public Javadoc newJavadoc() {
1899                 Javadoc result = new Javadoc(this);
1900                 return result;
1901         }
1902
1903         /**
1904          * Creates and returns a new tag element node.
1905          * Initially the new node has no tag name and an empty list of fragments.
1906          * <p>
1907          * Note that this node type is used only inside doc comments
1908          * ({@link Javadoc}).
1909          * </p>
1910          *
1911          * @return a new unparented tag element node
1912          * @since 3.0
1913          */
1914         public TagElement newTagElement() {
1915                 TagElement result = new TagElement(this);
1916                 return result;
1917         }
1918
1919         /**
1920          * Creates and returns a new text element node.
1921          * Initially the new node has an empty text string.
1922          * <p>
1923          * Note that this node type is used only inside doc comments
1924          * ({@link Javadoc Javadoc}).
1925          * </p>
1926          *
1927          * @return a new unparented text element node
1928          * @since 3.0
1929          */
1930         public TextElement newTextElement() {
1931                 TextElement result = new TextElement(this);
1932                 return result;
1933         }
1934
1935         /**
1936          * Creates and returns a new member reference node.
1937          * Initially the new node has no qualifier name and
1938          * an unspecified, but legal, member name.
1939          * <p>
1940          * Note that this node type is used only inside doc comments
1941          * ({@link Javadoc}).
1942          * </p>
1943          *
1944          * @return a new unparented member reference node
1945          * @since 3.0
1946          */
1947         public MemberRef newMemberRef() {
1948                 MemberRef result = new MemberRef(this);
1949                 return result;
1950         }
1951
1952         /**
1953          * Creates and returns a new method reference node.
1954          * Initially the new node has no qualifier name,
1955          * an unspecified, but legal, method name, and an
1956          * empty parameter list.
1957          * <p>
1958          * Note that this node type is used only inside doc comments
1959          * ({@link Javadoc Javadoc}).
1960          * </p>
1961          *
1962          * @return a new unparented method reference node
1963          * @since 3.0
1964          */
1965         public MethodRef newMethodRef() {
1966                 MethodRef result = new MethodRef(this);
1967                 return result;
1968         }
1969
1970         /**
1971          * Creates and returns a new method reference node.
1972          * Initially the new node has an unspecified, but legal,
1973          * type, not variable arity, and no parameter name.
1974          * <p>
1975          * Note that this node type is used only inside doc comments
1976          * ({@link Javadoc}).
1977          * </p>
1978          *
1979          * @return a new unparented method reference parameter node
1980          * @since 3.0
1981          */
1982         public MethodRefParameter newMethodRefParameter() {
1983                 MethodRefParameter result = new MethodRefParameter(this);
1984                 return result;
1985         }
1986
1987         //=============================== STATEMENTS ===========================
1988         /**
1989          * Creates a new unparented local variable declaration statement node
1990          * owned by this AST, for the given variable declaration fragment.
1991          * By default, there are no modifiers and the base type is unspecified
1992          * (but legal).
1993          * <p>
1994          * This method can be used to convert a variable declaration fragment
1995          * (<code>VariableDeclarationFragment</code>) into a statement
1996          * (<code>Statement</code>) by wrapping it. Additional variable
1997          * declaration fragments can be added afterwards.
1998          * </p>
1999          *
2000          * @param fragment the variable declaration fragment
2001          * @return a new unparented variable declaration statement node
2002          * @exception IllegalArgumentException if:
2003          * <ul>
2004          * <li>the node belongs to a different AST</li>
2005          * <li>the node already has a parent</li>
2006          * <li>a cycle in would be created</li>
2007          * <li>the variable declaration fragment is null</li>
2008          * </ul>
2009          */
2010         public VariableDeclarationStatement
2011                         newVariableDeclarationStatement(VariableDeclarationFragment fragment) {
2012                 if (fragment == null) {
2013                         throw new IllegalArgumentException();
2014                 }
2015                 VariableDeclarationStatement result =
2016                         new VariableDeclarationStatement(this);
2017                 result.fragments().add(fragment);
2018                 return result;
2019         }
2020
2021         /**
2022          * Creates a new unparented local type declaration statement node
2023          * owned by this AST, for the given type declaration.
2024          * <p>
2025          * This method can be used to convert a type declaration
2026          * (<code>TypeDeclaration</code>) into a statement
2027          * (<code>Statement</code>) by wrapping it.
2028          * </p>
2029          *
2030          * @param decl the type declaration
2031          * @return a new unparented local type declaration statement node
2032          * @exception IllegalArgumentException if:
2033          * <ul>
2034          * <li>the node belongs to a different AST</li>
2035          * <li>the node already has a parent</li>
2036          * <li>a cycle in would be created</li>
2037          * </ul>
2038          */
2039         public TypeDeclarationStatement
2040                         newTypeDeclarationStatement(TypeDeclaration decl) {
2041                 TypeDeclarationStatement result = new TypeDeclarationStatement(this);
2042                 result.setDeclaration(decl);
2043                 return result;
2044         }
2045
2046         /**
2047          * Creates a new unparented local type declaration statement node
2048          * owned by this AST, for the given type declaration.
2049          * <p>
2050          * This method can be used to convert any kind of type declaration
2051          * (<code>AbstractTypeDeclaration</code>) into a statement
2052          * (<code>Statement</code>) by wrapping it.
2053          * </p>
2054          *
2055          * @param decl the type declaration
2056          * @return a new unparented local type declaration statement node
2057          * @exception IllegalArgumentException if:
2058          * <ul>
2059          * <li>the node belongs to a different AST</li>
2060          * <li>the node already has a parent</li>
2061          * <li>a cycle in would be created</li>
2062          * </ul>
2063          * @since 3.0
2064          */
2065         public TypeDeclarationStatement
2066                         newTypeDeclarationStatement(AbstractTypeDeclaration decl) {
2067                 TypeDeclarationStatement result = new TypeDeclarationStatement(this);
2068                 if (this.apiLevel == AST.JLS2) {
2069                         result.internalSetTypeDeclaration((TypeDeclaration) decl);
2070                 }
2071                 if (this.apiLevel >= AST.JLS3) {
2072                         result.setDeclaration(decl);
2073                 }
2074                 return result;
2075         }
2076
2077         /**
2078          * Creates an unparented block node owned by this AST, for an empty list
2079          * of statements.
2080          *
2081          * @return a new unparented, empty block node
2082          */
2083         public Block newBlock() {
2084                 return new Block(this);
2085         }
2086
2087         /**
2088          * Creates an unparented continue statement node owned by this AST.
2089          * The continue statement has no label.
2090          *
2091          * @return a new unparented continue statement node
2092          */
2093         public ContinueStatement newContinueStatement() {
2094                 return new ContinueStatement(this);
2095         }
2096
2097         /**
2098          * Creates an unparented break statement node owned by this AST.
2099          * The break statement has no label.
2100          *
2101          * @return a new unparented break statement node
2102          */
2103         public BreakStatement newBreakStatement() {
2104                 return new BreakStatement(this);
2105         }
2106
2107         /**
2108          * Creates a new unparented expression statement node owned by this AST,
2109          * for the given expression.
2110          * <p>
2111          * This method can be used to convert an expression
2112          * (<code>Expression</code>) into a statement (<code>Type</code>)
2113          * by wrapping it. Note, however, that the result is only legal for
2114          * limited expression types, including method invocations, assignments,
2115          * and increment/decrement operations.
2116          * </p>
2117          *
2118          * @param expression the expression
2119          * @return a new unparented statement node
2120          * @exception IllegalArgumentException if:
2121          * <ul>
2122          * <li>the node belongs to a different AST</li>
2123          * <li>the node already has a parent</li>
2124          * <li>a cycle in would be created</li>
2125          * </ul>
2126          */
2127         public ExpressionStatement newExpressionStatement(Expression expression) {
2128                 ExpressionStatement result = new ExpressionStatement(this);
2129                 result.setExpression(expression);
2130                 return result;
2131         }
2132
2133         /**
2134          * Creates a new unparented if statement node owned by this AST.
2135          * By default, the expression is unspecified (but legal),
2136          * the then statement is an empty block, and there is no else statement.
2137          *
2138          * @return a new unparented if statement node
2139          */
2140         public IfStatement newIfStatement() {
2141                 return new IfStatement(this);
2142         }
2143
2144         /**
2145          * Creates a new unparented while statement node owned by this AST.
2146          * By default, the expression is unspecified (but legal), and
2147          * the body statement is an empty block.
2148          *
2149          * @return a new unparented while statement node
2150          */
2151         public WhileStatement newWhileStatement() {
2152                 return new WhileStatement(this);
2153         }
2154
2155         /**
2156          * Creates a new unparented do statement node owned by this AST.
2157          * By default, the expression is unspecified (but legal), and
2158          * the body statement is an empty block.
2159          *
2160          * @return a new unparented do statement node
2161          */
2162         public DoStatement newDoStatement() {
2163                 return new DoStatement(this);
2164         }
2165
2166         /**
2167          * Creates a new unparented try statement node owned by this AST.
2168          * By default, the try statement has an empty block, no catch
2169          * clauses, and no finally block.
2170          *
2171          * @return a new unparented try statement node
2172          */
2173         public TryStatement newTryStatement() {
2174                 return new TryStatement(this);
2175         }
2176
2177         /**
2178          * Creates a new unparented catch clause node owned by this AST.
2179          * By default, the catch clause declares an unspecified, but legal,
2180          * exception declaration and has an empty block.
2181          *
2182          * @return a new unparented catch clause node
2183          */
2184         public CatchClause newCatchClause() {
2185                 return new CatchClause(this);
2186         }
2187
2188         /**
2189          * Creates a new unparented return statement node owned by this AST.
2190          * By default, the return statement has no expression.
2191          *
2192          * @return a new unparented return statement node
2193          */
2194         public ReturnStatement newReturnStatement() {
2195                 return new ReturnStatement(this);
2196         }
2197
2198         /**
2199          * Creates a new unparented throw statement node owned by this AST.
2200          * By default, the expression is unspecified, but legal.
2201          *
2202          * @return a new unparented throw statement node
2203          */
2204         public ThrowStatement newThrowStatement() {
2205                 return new ThrowStatement(this);
2206         }
2207
2208         /**
2209          * Creates a new unparented assert statement node owned by this AST.
2210          * By default, the first expression is unspecified, but legal, and has no
2211          * message expression.
2212          *
2213          * @return a new unparented assert statement node
2214          */
2215         public AssertStatement newAssertStatement() {
2216                 return new AssertStatement(this);
2217         }
2218
2219         /**
2220          * Creates a new unparented empty statement node owned by this AST.
2221          *
2222          * @return a new unparented empty statement node
2223          */
2224         public EmptyStatement newEmptyStatement() {
2225                 return new EmptyStatement(this);
2226         }
2227
2228         /**
2229          * Creates a new unparented labeled statement node owned by this AST.
2230          * By default, the label and statement are both unspecified, but legal.
2231          *
2232          * @return a new unparented labeled statement node
2233          */
2234         public LabeledStatement newLabeledStatement() {
2235                 return new LabeledStatement(this);
2236         }
2237
2238         /**
2239          * Creates a new unparented switch statement node owned by this AST.
2240          * By default, the expression is unspecified, but legal, and there are
2241          * no statements or switch cases.
2242          *
2243          * @return a new unparented labeled statement node
2244          */
2245         public SwitchStatement newSwitchStatement() {
2246                 return new SwitchStatement(this);
2247         }
2248
2249         /**
2250          * Creates a new unparented switch case statement node owned by
2251          * this AST. By default, the expression is unspecified, but legal.
2252          *
2253          * @return a new unparented switch case node
2254          */
2255         public SwitchCase newSwitchCase() {
2256                 return new SwitchCase(this);
2257         }
2258
2259         /**
2260          * Creates a new unparented synchronized statement node owned by this AST.
2261          * By default, the expression is unspecified, but legal, and the body is
2262          * an empty block.
2263          *
2264          * @return a new unparented synchronized statement node
2265          */
2266         public SynchronizedStatement newSynchronizedStatement() {
2267                 return new SynchronizedStatement(this);
2268         }
2269
2270         /**
2271          * Creates a new unparented for statement node owned by this AST.
2272          * By default, there are no initializers, no condition expression,
2273          * no updaters, and the body is an empty block.
2274          *
2275          * @return a new unparented for statement node
2276          */
2277         public ForStatement newForStatement() {
2278                 return new ForStatement(this);
2279         }
2280
2281         /**
2282          * Creates a new unparented enhanced for statement node owned by this AST.
2283          * By default, the paramter and expression are unspecified
2284          * but legal subtrees, and the body is an empty block.
2285          *
2286          * @return a new unparented throw statement node
2287          * @exception UnsupportedOperationException if this operation is used in
2288          * a JLS2 AST
2289          * @since 3.1
2290          */
2291         public EnhancedForStatement newEnhancedForStatement() {
2292                 return new EnhancedForStatement(this);
2293         }
2294
2295         //=============================== EXPRESSIONS ===========================
2296         /**
2297          * Creates and returns a new unparented string literal node for
2298          * the empty string literal.
2299          *
2300          * @return a new unparented string literal node
2301          */
2302         public StringLiteral newStringLiteral() {
2303                 return new StringLiteral(this);
2304         }
2305
2306
2307         /**
2308          * Creates and returns a new unparented character literal node.
2309          * Initially the node has an unspecified character literal.
2310          *
2311          * @return a new unparented character literal node
2312          */
2313         public CharacterLiteral newCharacterLiteral() {
2314                 return new CharacterLiteral(this);
2315         }
2316
2317         /**
2318          * Creates and returns a new unparented number literal node.
2319          *
2320          * @param literal the token for the numeric literal as it would
2321          *    appear in Java source code
2322          * @return a new unparented number literal node
2323          * @exception IllegalArgumentException if the literal is null
2324          */
2325         public NumberLiteral newNumberLiteral(String literal) {
2326                 if (literal == null) {
2327                         throw new IllegalArgumentException();
2328                 }
2329                 NumberLiteral result = new NumberLiteral(this);
2330                 result.setToken(literal);
2331                 return result;
2332         }
2333
2334         /**
2335          * Creates and returns a new unparented number literal node.
2336          * Initially the number literal token is <code>"0"</code>.
2337          *
2338          * @return a new unparented number literal node
2339          */
2340         public NumberLiteral newNumberLiteral() {
2341                 NumberLiteral result = new NumberLiteral(this);
2342                 return result;
2343         }
2344
2345         /**
2346          * Creates and returns a new unparented null literal node.
2347          *
2348          * @return a new unparented null literal node
2349          */
2350         public NullLiteral newNullLiteral() {
2351                 return new NullLiteral(this);
2352         }
2353
2354         /**
2355          * Creates and returns a new unparented boolean literal node.
2356          * <p>
2357          * For example, the assignment expression <code>foo = true</code>
2358          * is generated by the following snippet:
2359          * <code>
2360          * <pre>
2361          * Assignment e= ast.newAssignment();
2362          * e.setLeftHandSide(ast.newSimpleName("foo"));
2363          * e.setRightHandSide(ast.newBooleanLiteral(true));
2364          * </pre>
2365          * </code>
2366          * </p>
2367          *
2368          * @param value the boolean value
2369          * @return a new unparented boolean literal node
2370          */
2371         public BooleanLiteral newBooleanLiteral(boolean value) {
2372                 BooleanLiteral result = new BooleanLiteral(this);
2373                 result.setBooleanValue(value);
2374                 return result;
2375         }
2376
2377         /**
2378          * Creates and returns a new unparented assignment expression node
2379          * owned by this AST. By default, the assignment operator is "=" and
2380          * the left and right hand side expressions are unspecified, but
2381          * legal, names.
2382          *
2383          * @return a new unparented assignment expression node
2384          */
2385         public Assignment newAssignment() {
2386                 Assignment result = new Assignment(this);
2387                 return result;
2388         }
2389
2390         /**
2391          * Creates an unparented method invocation expression node owned by this
2392          * AST. By default, the name of the method is unspecified (but legal)
2393          * there is no receiver expression, no type arguments, and the list of
2394          * arguments is empty.
2395          *
2396          * @return a new unparented method invocation expression node
2397          */
2398         public MethodInvocation newMethodInvocation() {
2399                 MethodInvocation result = new MethodInvocation(this);
2400                 return result;
2401         }
2402
2403         /**
2404          * Creates an unparented "super" method invocation expression node owned by
2405          * this AST. By default, the name of the method is unspecified (but legal)
2406          * there is no qualifier, no type arguments, and the list of arguments is empty.
2407          *
2408          * @return a new unparented  "super" method invocation
2409          *    expression node
2410          */
2411         public SuperMethodInvocation newSuperMethodInvocation() {
2412                 SuperMethodInvocation result = new SuperMethodInvocation(this);
2413                 return result;
2414         }
2415
2416         /**
2417          * Creates an unparented alternate constructor ("this(...);") invocation
2418          * statement node owned by this AST. By default, the lists of arguments
2419          * and type arguments are both empty.
2420          * <p>
2421          * Note that this type of node is a Statement, whereas a regular
2422          * method invocation is an Expression. The only valid use of these
2423          * statements are as the first statement of a constructor body.
2424          * </p>
2425          *
2426          * @return a new unparented alternate constructor invocation statement node
2427          */
2428         public ConstructorInvocation newConstructorInvocation() {
2429                 ConstructorInvocation result = new ConstructorInvocation(this);
2430                 return result;
2431         }
2432
2433         /**
2434          * Creates an unparented alternate super constructor ("super(...);")
2435          * invocation statement node owned by this AST. By default, there is no
2436          * qualifier, no type arguments, and the list of arguments is empty.
2437          * <p>
2438          * Note that this type of node is a Statement, whereas a regular
2439          * super method invocation is an Expression. The only valid use of these
2440          * statements are as the first statement of a constructor body.
2441          * </p>
2442          *
2443          * @return a new unparented super constructor invocation statement node
2444          */
2445         public SuperConstructorInvocation newSuperConstructorInvocation() {
2446                 SuperConstructorInvocation result =
2447                         new SuperConstructorInvocation(this);
2448                 return result;
2449         }
2450
2451         /**
2452          * Creates a new unparented local variable declaration expression node
2453          * owned by this AST, for the given variable declaration fragment. By
2454          * default, there are no modifiers and the base type is unspecified
2455          * (but legal).
2456          * <p>
2457          * This method can be used to convert a variable declaration fragment
2458          * (<code>VariableDeclarationFragment</code>) into an expression
2459          * (<code>Expression</code>) by wrapping it. Additional variable
2460          * declaration fragments can be added afterwards.
2461          * </p>
2462          *
2463          * @param fragment the first variable declaration fragment
2464          * @return a new unparented variable declaration expression node
2465          * @exception IllegalArgumentException if:
2466          * <ul>
2467          * <li>the node belongs to a different AST</li>
2468          * <li>the node already has a parent</li>
2469          * <li>a cycle in would be created</li>
2470          * <li>the given fragment is null</li>
2471          * <li>a cycle in would be created</li>
2472          * </ul>
2473          */
2474         public VariableDeclarationExpression
2475                         newVariableDeclarationExpression(VariableDeclarationFragment fragment) {
2476                 if (fragment == null) {
2477                         throw new IllegalArgumentException();
2478                 }
2479                 VariableDeclarationExpression result =
2480                         new VariableDeclarationExpression(this);
2481                 result.fragments().add(fragment);
2482                 return result;
2483         }
2484
2485         /**
2486          * Creates a new unparented field declaration node owned by this AST,
2487          * for the given variable declaration fragment. By default, there are no
2488          * modifiers, no doc comment, and the base type is unspecified
2489          * (but legal).
2490          * <p>
2491          * This method can be used to wrap a variable declaration fragment
2492          * (<code>VariableDeclarationFragment</code>) into a field declaration
2493          * suitable for inclusion in the body of a type declaration
2494          * (<code>FieldDeclaration</code> implements <code>BodyDeclaration</code>).
2495          * Additional variable declaration fragments can be added afterwards.
2496          * </p>
2497          *
2498          * @param fragment the variable declaration fragment
2499          * @return a new unparented field declaration node
2500          * @exception IllegalArgumentException if:
2501          * <ul>
2502          * <li>the node belongs to a different AST</li>
2503          * <li>the node already has a parent</li>
2504          * <li>a cycle in would be created</li>
2505          * <li>the given fragment is null</li>
2506          * </ul>
2507          */
2508         public FieldDeclaration newFieldDeclaration(VariableDeclarationFragment fragment) {
2509                 if (fragment == null) {
2510                         throw new IllegalArgumentException();
2511                 }
2512                 FieldDeclaration result = new FieldDeclaration(this);
2513                 result.fragments().add(fragment);
2514                 return result;
2515         }
2516
2517         /**
2518          * Creates and returns a new unparented "this" expression node
2519          * owned by this AST. By default, there is no qualifier.
2520          *
2521          * @return a new unparented "this" expression node
2522          */
2523         public ThisExpression newThisExpression() {
2524                 ThisExpression result = new ThisExpression(this);
2525                 return result;
2526         }
2527
2528         /**
2529          * Creates and returns a new unparented field access expression node
2530          * owned by this AST. By default, the expression and field are both
2531          * unspecified, but legal, names.
2532          *
2533          * @return a new unparented field access expression node
2534          */
2535         public FieldAccess newFieldAccess() {
2536                 FieldAccess result = new FieldAccess(this);
2537                 return result;
2538         }
2539
2540         /**
2541          * Creates and returns a new unparented super field access expression node
2542          * owned by this AST. By default, the expression and field are both
2543          * unspecified, but legal, names.
2544          *
2545          * @return a new unparented super field access expression node
2546          */
2547         public SuperFieldAccess newSuperFieldAccess() {
2548                 SuperFieldAccess result = new SuperFieldAccess(this);
2549                 return result;
2550         }
2551
2552         /**
2553          * Creates and returns a new unparented type literal expression node
2554          * owned by this AST. By default, the type is unspecified (but legal).
2555          *
2556          * @return a new unparented type literal node
2557          */
2558         public TypeLiteral newTypeLiteral() {
2559                 TypeLiteral result = new TypeLiteral(this);
2560                 return result;
2561         }
2562
2563         /**
2564          * Creates and returns a new unparented cast expression node
2565          * owned by this AST. By default, the type and expression are unspecified
2566          * (but legal).
2567          *
2568          * @return a new unparented cast expression node
2569          */
2570         public CastExpression newCastExpression() {
2571                 CastExpression result = new CastExpression(this);
2572                 return result;
2573         }
2574
2575         /**
2576          * Creates and returns a new unparented parenthesized expression node
2577          * owned by this AST. By default, the expression is unspecified (but legal).
2578          *
2579          * @return a new unparented parenthesized expression node
2580          */
2581         public ParenthesizedExpression newParenthesizedExpression() {
2582                 ParenthesizedExpression result = new ParenthesizedExpression(this);
2583                 return result;
2584         }
2585
2586         /**
2587          * Creates and returns a new unparented infix expression node
2588          * owned by this AST. By default, the operator and left and right
2589          * operand are unspecified (but legal), and there are no extended
2590          * operands.
2591          *
2592          * @return a new unparented infix expression node
2593          */
2594         public InfixExpression newInfixExpression() {
2595                 InfixExpression result = new InfixExpression(this);
2596                 return result;
2597         }
2598
2599         /**
2600          * Creates and returns a new unparented instanceof expression node
2601          * owned by this AST. By default, the operator and left and right
2602          * operand are unspecified (but legal).
2603          *
2604          * @return a new unparented instanceof expression node
2605          */
2606         public InstanceofExpression newInstanceofExpression() {
2607                 InstanceofExpression result = new InstanceofExpression(this);
2608                 return result;
2609         }
2610
2611         /**
2612          * Creates and returns a new unparented postfix expression node
2613          * owned by this AST. By default, the operator and operand are
2614          * unspecified (but legal).
2615          *
2616          * @return a new unparented postfix expression node
2617          */
2618         public PostfixExpression newPostfixExpression() {
2619                 PostfixExpression result = new PostfixExpression(this);
2620                 return result;
2621         }
2622
2623         /**
2624          * Creates and returns a new unparented prefix expression node
2625          * owned by this AST. By default, the operator and operand are
2626          * unspecified (but legal).
2627          *
2628          * @return a new unparented prefix expression node
2629          */
2630         public PrefixExpression newPrefixExpression() {
2631                 PrefixExpression result = new PrefixExpression(this);
2632                 return result;
2633         }
2634
2635         /**
2636          * Creates and returns a new unparented array access expression node
2637          * owned by this AST. By default, the array and index expression are
2638          * both unspecified (but legal).
2639          *
2640          * @return a new unparented array access expression node
2641          */
2642         public ArrayAccess newArrayAccess() {
2643                 ArrayAccess result = new ArrayAccess(this);
2644                 return result;
2645         }
2646
2647         /**
2648          * Creates and returns a new unparented array creation expression node
2649          * owned by this AST. By default, the array type is an unspecified
2650          * 1-dimensional array, the list of dimensions is empty, and there is no
2651          * array initializer.
2652          * <p>
2653          * Examples:
2654          * <code>
2655          * <pre>
2656          * // new String[len]
2657          * ArrayCreation ac1 = ast.newArrayCreation();
2658          * ac1.setType(
2659          *    ast.newArrayType(
2660          *       ast.newSimpleType(ast.newSimpleName("String"))));
2661          * ac1.dimensions().add(ast.newSimpleName("len"));
2662      *
2663          * // new double[7][24][]
2664          * ArrayCreation ac2 = ast.newArrayCreation();
2665          * ac2.setType(
2666          *    ast.newArrayType(
2667          *       ast.newPrimitiveType(PrimitiveType.DOUBLE), 3));
2668          * ac2.dimensions().add(ast.newNumberLiteral("7"));
2669          * ac2.dimensions().add(ast.newNumberLiteral("24"));
2670          *
2671          * // new int[] {1, 2}
2672          * ArrayCreation ac3 = ast.newArrayCreation();
2673          * ac3.setType(
2674          *    ast.newArrayType(
2675          *       ast.newPrimitiveType(PrimitiveType.INT)));
2676          * ArrayInitializer ai = ast.newArrayInitializer();
2677          * ac3.setInitializer(ai);
2678          * ai.expressions().add(ast.newNumberLiteral("1"));
2679          * ai.expressions().add(ast.newNumberLiteral("2"));
2680          * </pre>
2681          * </code>
2682          * </p>
2683          *
2684          * @return a new unparented array creation expression node
2685          */
2686         public ArrayCreation newArrayCreation() {
2687                 ArrayCreation result = new ArrayCreation(this);
2688                 return result;
2689         }
2690
2691         /**
2692          * Creates and returns a new unparented class instance creation
2693          * ("new") expression node owned by this AST. By default,
2694          * there is no qualifying expression, no type parameters,
2695          * an unspecified (but legal) type name, an empty list of
2696          * arguments, and does not declare an anonymous class declaration.
2697          *
2698          * @return a new unparented class instance creation expression node
2699          */
2700         public ClassInstanceCreation newClassInstanceCreation() {
2701                 ClassInstanceCreation result = new ClassInstanceCreation(this);
2702                 return result;
2703         }
2704
2705         /**
2706          * Creates and returns a new unparented anonymous class declaration
2707          * node owned by this AST. By default, the body declaration list is empty.
2708          *
2709          * @return a new unparented anonymous class declaration node
2710          */
2711         public AnonymousClassDeclaration newAnonymousClassDeclaration() {
2712                 AnonymousClassDeclaration result = new AnonymousClassDeclaration(this);
2713                 return result;
2714         }
2715
2716         /**
2717          * Creates and returns a new unparented array initializer node
2718          * owned by this AST. By default, the initializer has no expressions.
2719          *
2720          * @return a new unparented array initializer node
2721          */
2722         public ArrayInitializer newArrayInitializer() {
2723                 ArrayInitializer result = new ArrayInitializer(this);
2724                 return result;
2725         }
2726
2727         /**
2728          * Creates and returns a new unparented conditional expression node
2729          * owned by this AST. By default, the condition and both expressions
2730          * are unspecified (but legal).
2731          *
2732          * @return a new unparented array conditional expression node
2733          */
2734         public ConditionalExpression newConditionalExpression() {
2735                 ConditionalExpression result = new ConditionalExpression(this);
2736                 return result;
2737         }
2738
2739         //=============================== ANNOTATIONS ====================
2740
2741         /**
2742          * Creates and returns a new unparented normal annotation node with
2743          * an unspecified type name and an empty list of member value
2744          * pairs.
2745          *
2746          * @return a new unparented normal annotation node
2747          * @exception UnsupportedOperationException if this operation is used in
2748          * a JLS2 AST
2749          * @since 3.1
2750          */
2751         public NormalAnnotation newNormalAnnotation() {
2752                 NormalAnnotation result = new NormalAnnotation(this);
2753                 return result;
2754         }
2755
2756         /**
2757          * Creates and returns a new unparented marker annotation node with
2758          * an unspecified type name.
2759          *
2760          * @return a new unparented marker annotation node
2761          * @exception UnsupportedOperationException if this operation is used in
2762          * a JLS2 AST
2763          * @since 3.1
2764          */
2765         public MarkerAnnotation newMarkerAnnotation() {
2766                 MarkerAnnotation result = new MarkerAnnotation(this);
2767                 return result;
2768         }
2769
2770         /**
2771          * Creates and returns a new unparented single member annotation node with
2772          * an unspecified type name and value.
2773          *
2774          * @return a new unparented single member annotation node
2775          * @exception UnsupportedOperationException if this operation is used in
2776          * a JLS2 AST
2777          * @since 3.1
2778          */
2779         public SingleMemberAnnotation newSingleMemberAnnotation() {
2780                 SingleMemberAnnotation result = new SingleMemberAnnotation(this);
2781                 return result;
2782         }
2783
2784         /**
2785          * Creates and returns a new unparented member value pair node with
2786          * an unspecified member name and value.
2787          *
2788          * @return a new unparented member value pair node
2789          * @exception UnsupportedOperationException if this operation is used in
2790          * a JLS2 AST
2791          * @since 3.1
2792          */
2793         public MemberValuePair newMemberValuePair() {
2794                 MemberValuePair result = new MemberValuePair(this);
2795                 return result;
2796         }
2797
2798         /**
2799          * Enables the recording of changes to the given compilation
2800          * unit and its descendents. The compilation unit must have
2801          * been created by <code>ASTParser</code> and still be in
2802          * its original state. Once recording is on,
2803          * arbitrary changes to the subtree rooted at the compilation
2804          * unit are recorded internally. Once the modification has
2805          * been completed, call <code>rewrite</code> to get an object
2806          * representing the corresponding edits to the original
2807          * source code string.
2808          *
2809          * @exception IllegalArgumentException if this compilation unit is
2810          * marked as unmodifiable, or if this compilation unit has already
2811          * been tampered with, or if recording has already been enabled,
2812          * or if <code>root</code> is not owned by this AST
2813          * @see CompilationUnit#recordModifications()
2814          * @since 3.0
2815          */
2816         void recordModifications(CompilationUnit root) {
2817                 if(this.modificationCount != this.originalModificationCount) {
2818                         throw new IllegalArgumentException("AST is already modified"); //$NON-NLS-1$
2819                 } else if(this.rewriter  != null) {
2820                         throw new IllegalArgumentException("AST modifications are already recorded"); //$NON-NLS-1$
2821                 } else if((root.getFlags() & ASTNode.PROTECT) != 0) {
2822                         throw new IllegalArgumentException("Root node is unmodifiable"); //$NON-NLS-1$
2823                 } else if(root.getAST() != this) {
2824                         throw new IllegalArgumentException("Root node is not owned by this ast"); //$NON-NLS-1$
2825                 }
2826
2827                 this.rewriter = new InternalASTRewrite(root);
2828                 this.setEventHandler(this.rewriter);
2829         }
2830
2831         /**
2832          * Converts all modifications recorded into an object
2833          * representing the corresponding text edits to the
2834          * given document containing the original source
2835          * code for the compilation unit that gave rise to
2836          * this AST.
2837          *
2838          * @param document original document containing source code
2839          * for the compilation unit
2840          * @param options the table of formatter options
2841          * (key type: <code>String</code>; value type: <code>String</code>);
2842          * or <code>null</code> to use the standard global options
2843          * {@link JavaCore#getOptions() JavaCore.getOptions()}.
2844          * @return text edit object describing the changes to the
2845          * document corresponding to the recorded AST modifications
2846          * @exception IllegalArgumentException if the document passed is
2847          * <code>null</code> or does not correspond to this AST
2848          * @exception IllegalStateException if <code>recordModifications</code>
2849          * was not called to enable recording
2850          * @see CompilationUnit#rewrite(IDocument, Map)
2851          * @since 3.0
2852          */
2853         TextEdit rewrite(IDocument document, Map options) {
2854                 if (document == null) {
2855                         throw new IllegalArgumentException();
2856                 }
2857                 if (this.rewriter  == null) {
2858                         throw new IllegalStateException("Modifications record is not enabled"); //$NON-NLS-1$
2859                 }
2860                 return this.rewriter.rewriteAST(document, options);
2861         }
2862
2863         /**
2864          * Returns true if the ast tree was created with bindings, false otherwise
2865          *
2866          * @return true if the ast tree was created with bindings, false otherwise
2867          * @since 3.3
2868          */
2869         public boolean hasResolvedBindings() {
2870                 return (this.bits & RESOLVED_BINDINGS) != 0;
2871         }
2872
2873         /**
2874          * Returns true if the ast tree was created with statements recovery, false otherwise
2875          *
2876          * @return true if the ast tree was created with statements recovery, false otherwise
2877          * @since 3.3
2878          */
2879         public boolean hasStatementsRecovery() {
2880                 return (this.bits & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0;
2881         }
2882
2883         /**
2884          * Returns true if the ast tree was created with bindings recovery, false otherwise
2885          *
2886          * @return true if the ast tree was created with bindings recovery, false otherwise
2887          * @since 3.3
2888          */
2889         public boolean hasBindingsRecovery() {
2890                 return (this.bits & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
2891         }
2892
2893         void setFlag(int newValue) {
2894                 this.bits |= newValue;
2895         }
2896 }
2897