KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > AST


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 org.eclipse.jdt.core.dom;
13
14 import java.lang.reflect.Constructor JavaDoc;
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22
23 import org.eclipse.jdt.core.IClassFile;
24 import org.eclipse.jdt.core.ICompilationUnit;
25 import org.eclipse.jdt.core.IJavaProject;
26 import org.eclipse.jdt.core.JavaCore;
27 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
28 import org.eclipse.jdt.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  */

95 public final class AST {
96     /**
97      * Constant for indicating the AST API that handles JLS2.
98      * This API is capable of handling all constructs
99      * in the Java language as described in the Java Language
100      * Specification, Second Edition (JLS2).
101      * JLS2 is a superset of all earlier versions of the
102      * Java language, and the JLS2 API can be used to manipulate
103      * programs written in all versions of the Java language
104      * up to and including J2SE 1.4.
105      *
106      * @since 3.0
107      * @deprecated Clients should use the {@link #JLS3} AST API instead.
108      */

109     public static final int JLS2 = 2;
110     
111     /**
112      * Internal synonym for {@link #JLS2}. Use to alleviate
113      * deprecation warnings.
114      * @since 3.1
115      */

116     /*package*/ static final int JLS2_INTERNAL = JLS2;
117
118     /**
119      * Constant for indicating the AST API that handles JLS3.
120      * This API is capable of handling all constructs in the
121      * Java language as described in the Java Language
122      * Specification, Third Edition (JLS3).
123      * JLS3 is a superset of all earlier versions of the
124      * Java language, and the JLS3 API can be used to manipulate
125      * programs written in all versions of the Java language
126      * up to and including J2SE 5 (aka JDK 1.5).
127      *
128      * @since 3.1
129      */

130     public static final int JLS3 = 3;
131     
132     /**
133      * The binding resolver for this AST. Initially a binding resolver that
134      * does not resolve names at all.
135      */

136     private BindingResolver resolver = new BindingResolver();
137     
138     /**
139      * The event handler for this AST.
140      * Initially an event handler that does not nothing.
141      * @since 3.0
142      */

143     private NodeEventHandler eventHandler = new NodeEventHandler();
144     
145     /**
146      * Level of AST API supported by this AST.
147      * @since 3.0
148      */

149     int apiLevel;
150     
151     /**
152      * Internal modification count; initially 0; increases monotonically
153      * <b>by one or more</b> as the AST is successively modified.
154      */

155     private long modificationCount = 0;
156     
157     /**
158      * Internal original modification count; value is equals to <code>
159      * modificationCount</code> at the end of the parse (<code>ASTParser
160      * </code>). If this ast is not created with a parser then value is 0.
161      * @since 3.0
162      */

163     private long originalModificationCount = 0;
164
165     /**
166      * When disableEvents > 0, events are not reported and
167      * the modification count stays fixed.
168      * <p>
169      * This mechanism is used in lazy initialization of a node
170      * to prevent events from being reported for the modification
171      * of the node as well as for the creation of the missing child.
172      * </p>
173      * @since 3.0
174      */

175     private int disableEvents = 0;
176
177     /**
178      * Internal object unique to the AST instance. Readers must synchronize on
179      * this object when the modifying instance fields.
180      * @since 3.0
181      */

182     private final Object JavaDoc internalASTLock = new Object JavaDoc();
183
184     /**
185      * Java Scanner used to validate preconditions for the creation of specific nodes
186      * like CharacterLiteral, NumberLiteral, StringLiteral or SimpleName.
187      */

188     Scanner scanner;
189
190     /**
191      * Internal ast rewriter used to record ast modification when record mode is enabled.
192      */

193     InternalASTRewrite rewriter;
194
195     /**
196      * Default value of <code>flag<code> when a new node is created.
197      */

198     private int defaultNodeFlag = 0;
199
200     /**
201      * Creates a new Java abstract syntax tree
202      * (AST) following the specified set of API rules.
203      *
204      * @param level the API level; one of the LEVEL constants
205      * @since 3.0
206      */

207     private AST(int level) {
208         if ((level != AST.JLS2)
209             && (level != AST.JLS3)) {
210             throw new IllegalArgumentException JavaDoc();
211         }
212         this.apiLevel = level;
213         // initialize a scanner
214
this.scanner = new Scanner(
215                 true /*comment*/,
216                 true /*whitespace*/,
217                 false /*nls*/,
218                 ClassFileConstants.JDK1_3 /*sourceLevel*/,
219                 ClassFileConstants.JDK1_5 /*complianceLevel*/,
220                 null/*taskTag*/,
221                 null/*taskPriorities*/,
222                 true/*taskCaseSensitive*/);
223     }
224
225     /**
226      * Creates a new, empty abstract syntax tree using default options.
227      *
228      * @see JavaCore#getDefaultOptions()
229      * @deprecated Clients should port their code to use the new JLS3 AST API and call
230      * {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
231      */

232     public AST() {
233         this(JavaCore.getDefaultOptions());
234     }
235
236     /**
237      * Internal method.
238      * <p>
239      * This method converts the given internal compiler AST for the given source string
240      * into a compilation unit. This method is not intended to be called by clients.
241      * </p>
242      *
243      * @param level the API level; one of the LEVEL constants
244      * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
245      * @param source the string of the Java compilation unit
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 cancelation,
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      */

253     public static CompilationUnit convertCompilationUnit(
254         int level,
255         org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
256         char[] source,
257         Map JavaDoc options,
258         boolean isResolved,
259         org.eclipse.jdt.internal.core.CompilationUnit workingCopy,
260         int reconcileFlags,
261         IProgressMonitor monitor) {
262
263         ASTConverter converter = new ASTConverter(options, isResolved, monitor);
264         AST ast = AST.newAST(level);
265         int savedDefaultNodeFlag = ast.getDefaultNodeFlag();
266         ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
267         BindingResolver resolver = null;
268         if (isResolved) {
269             resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false);
270             ast.setFlag(AST.RESOLVED_BINDINGS);
271         } else {
272             resolver = new BindingResolver();
273         }
274         ast.setFlag(reconcileFlags);
275         ast.setBindingResolver(resolver);
276         converter.setAST(ast);
277
278         CompilationUnit unit = converter.convert(compilationUnitDeclaration, source);
279         unit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions());
280         unit.setTypeRoot(workingCopy);
281         ast.setDefaultNodeFlag(savedDefaultNodeFlag);
282         return unit;
283     }
284
285     /**
286      * Creates a new, empty abstract syntax tree using the given options.
287      * <p>
288      * Following option keys are significant:
289      * <ul>
290      * <li><code>"org.eclipse.jdt.core.compiler.source"</code> -
291      * indicates source compatibility mode (as per <code>JavaCore</code>);
292      * <code>"1.3"</code> means the source code is as per JDK 1.3;
293      * <code>"1.4"</code> means the source code is as per JDK 1.4
294      * (<code>"assert"</code> is now a keyword);
295      * <code>"1.5"</code> means the source code is as per JDK 1.5
296      * (<code>"enum"</code> is now a keyword);
297      * additional legal values may be added later. </li>
298      * </ul>
299      * Options other than the above are ignored.
300      * </p>
301      *
302      * @param options the table of options (key type: <code>String</code>;
303      * value type: <code>String</code>)
304      * @see JavaCore#getDefaultOptions()
305      * @deprecated Clients should port their code to use the new JLS3 AST API and call
306      * {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
307      */

308     public AST(Map JavaDoc options) {
309         this(JLS2);
310         Object JavaDoc sourceLevelOption = options.get(JavaCore.COMPILER_SOURCE);
311         long sourceLevel = ClassFileConstants.JDK1_3;
312         if (JavaCore.VERSION_1_4.equals(sourceLevelOption)) {
313             sourceLevel = ClassFileConstants.JDK1_4;
314         } else if (JavaCore.VERSION_1_5.equals(sourceLevelOption)) {
315             sourceLevel = ClassFileConstants.JDK1_5;
316         }
317         Object JavaDoc complianceLevelOption = options.get(JavaCore.COMPILER_COMPLIANCE);
318         long complianceLevel = ClassFileConstants.JDK1_3;
319         if (JavaCore.VERSION_1_4.equals(complianceLevelOption)) {
320             complianceLevel = ClassFileConstants.JDK1_4;
321         } else if (JavaCore.VERSION_1_5.equals(complianceLevelOption)) {
322             complianceLevel = ClassFileConstants.JDK1_5;
323         }
324         // override scanner if 1.4 or 1.5 asked for
325
this.scanner = new Scanner(
326             true /*comment*/,
327             true /*whitespace*/,
328             false /*nls*/,
329             sourceLevel /*sourceLevel*/,
330             complianceLevel /*complianceLevel*/,
331             null/*taskTag*/,
332             null/*taskPriorities*/,
333             true/*taskCaseSensitive*/);
334     }
335
336     /**
337      * Creates a new Java abstract syntax tree
338      * (AST) following the specified set of API rules.
339      * <p>
340      * Clients should use this method specifing {@link #JLS3} as the
341      * AST level in all cases, even when dealing with JDK 1.3 or 1.4..
342      * </p>
343      *
344      * @param level the API level; one of the LEVEL constants
345      * @return new AST instance following the specified set of API rules.
346      * @exception IllegalArgumentException if:
347      * <ul>
348      * <li>the API level is not one of the LEVEL constants</li>
349      * </ul>
350      * @since 3.0
351      */

352     public static AST newAST(int level) {
353         if ((level != AST.JLS2)
354             && (level != AST.JLS3)) {
355             throw new IllegalArgumentException JavaDoc();
356         }
357         return new AST(level);
358     }
359
360     /**
361      * Returns the modification count for this AST. The modification count
362      * is a non-negative value that increases (by 1 or perhaps by more) as
363      * this AST or its nodes are changed. The initial value is unspecified.
364      * <p>
365      * The following things count as modifying an AST:
366      * <ul>
367      * <li>creating a new node owned by this AST,</li>
368      * <li>adding a child to a node owned by this AST,</li>
369      * <li>removing a child from a node owned by this AST,</li>
370      * <li>setting a non-node attribute of a node owned by this AST.</li>
371      * </ul>
372      * </p>
373      * Operations which do not entail creating or modifying existing nodes
374      * do not increase the modification count.
375      * <p>
376      * N.B. This method may be called several times in the course
377      * of a single client operation. The only promise is that the modification
378      * count increases monotonically as the AST or its nodes change; there is
379      * no promise that a modifying operation increases the count by exactly 1.
380      * </p>
381      *
382      * @return the current value (non-negative) of the modification counter of
383      * this AST
384      */

385     public long modificationCount() {
386         return this.modificationCount;
387     }
388
389     /**
390      * Return the API level supported by this AST.
391      *
392      * @return level the API level; one of the <code>JLS*</code>LEVEL
393      * declared on <code>AST</code>; assume this set is open-ended
394      * @since 3.0
395      */

396     public int apiLevel() {
397         return this.apiLevel;
398     }
399
400     /**
401      * Indicates that this AST is about to be modified.
402      * <p>
403      * The following things count as modifying an AST:
404      * <ul>
405      * <li>creating a new node owned by this AST</li>
406      * <li>adding a child to a node owned by this AST</li>
407      * <li>removing a child from a node owned by this AST</li>
408      * <li>setting a non-node attribute of a node owned by this AST</li>.
409      * </ul>
410      * </p>
411      * <p>
412      * N.B. This method may be called several times in the course
413      * of a single client operation.
414      * </p>
415      */

416     void modifying() {
417         // when this method is called during lazy init, events are disabled
418
// and the modification count will not be increased
419
if (this.disableEvents > 0) {
420             return;
421         }
422         // increase the modification count
423
this.modificationCount++;
424     }
425
426     /**
427      * Disable events.
428      * This method is thread-safe for AST readers.
429      *
430      * @see #reenableEvents()
431      * @since 3.0
432      */

433     final void disableEvents() {
434         synchronized (this.internalASTLock) {
435             // guard against concurrent access by another reader
436
this.disableEvents++;
437         }
438         // while disableEvents > 0 no events will be reported, and mod count will stay fixed
439
}
440
441     /**
442      * Reenable events.
443      * This method is thread-safe for AST readers.
444      *
445      * @see #disableEvents()
446      * @since 3.0
447      */

448     final void reenableEvents() {
449         synchronized (this.internalASTLock) {
450             // guard against concurrent access by another reader
451
this.disableEvents--;
452         }
453     }
454
455     /**
456      * Reports that the given node is about to lose a child.
457      *
458      * @param node the node about to be modified
459      * @param child the node about to be removed
460      * @param property the child or child list property descriptor
461      * @since 3.0
462      */

463     void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
464         // IMPORTANT: this method is called by readers during lazy init
465
synchronized (this.internalASTLock) {
466             // guard against concurrent access by a reader doing lazy init
467
if (this.disableEvents > 0) {
468                 // doing lazy init OR already processing an event
469
// System.out.println("[BOUNCE DEL]");
470
return;
471             } else {
472                 disableEvents();
473             }
474         }
475         try {
476             this.eventHandler.preRemoveChildEvent(node, child, property);
477             // N.B. even if event handler blows up, the AST is not
478
// corrupted since node has not been changed yet
479
} finally {
480             reenableEvents();
481         }
482     }
483
484     /**
485      * Reports that the given node jsut lost a child.
486      *
487      * @param node the node that was modified
488      * @param child the child node that was removed
489      * @param property the child or child list property descriptor
490      * @since 3.0
491      */

492     void postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
493         // IMPORTANT: this method is called by readers during lazy init
494
synchronized (this.internalASTLock) {
495             // guard against concurrent access by a reader doing lazy init
496
if (this.disableEvents > 0) {
497                 // doing lazy init OR already processing an event
498
// System.out.println("[BOUNCE DEL]");
499
return;
500             } else {
501                 disableEvents();
502             }
503         }
504         try {
505             this.eventHandler.postRemoveChildEvent(node, child, property);
506             // N.B. even if event handler blows up, the AST is not
507
// corrupted since node has not been changed yet
508
} finally {
509             reenableEvents();
510         }
511     }
512
513     /**
514      * Reports that the given node is about have a child replaced.
515      *
516      * @param node the node about to be modified
517      * @param child the child node about to be removed
518      * @param newChild the replacement child
519      * @param property the child or child list property descriptor
520      * @since 3.0
521      */

522     void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
523         // IMPORTANT: this method is called by readers during lazy init
524
synchronized (this.internalASTLock) {
525             // guard against concurrent access by a reader doing lazy init
526
if (this.disableEvents > 0) {
527                 // doing lazy init OR already processing an event
528
// System.out.println("[BOUNCE REP]");
529
return;
530             } else {
531                 disableEvents();
532             }
533         }
534         try {
535             this.eventHandler.preReplaceChildEvent(node, child, newChild, property);
536             // N.B. even if event handler blows up, the AST is not
537
// corrupted since node has not been changed yet
538
} finally {
539             reenableEvents();
540         }
541     }
542
543     /**
544      * Reports that the given node has just had a child replaced.
545      *
546      * @param node the node modified
547      * @param child the child removed
548      * @param newChild the replacement child
549      * @param property the child or child list property descriptor
550      * @since 3.0
551      */

552     void postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
553         // IMPORTANT: this method is called by readers during lazy init
554
synchronized (this.internalASTLock) {
555             // guard against concurrent access by a reader doing lazy init
556
if (this.disableEvents > 0) {
557                 // doing lazy init OR already processing an event
558
// System.out.println("[BOUNCE REP]");
559
return;
560             } else {
561                 disableEvents();
562             }
563         }
564         try {
565             this.eventHandler.postReplaceChildEvent(node, child, newChild, property);
566             // N.B. even if event handler blows up, the AST is not
567
// corrupted since node has not been changed yet
568
} finally {
569             reenableEvents();
570         }
571     }
572
573     /**
574      * Reports that the given node is about to gain a child.
575      *
576      * @param node the node that to be modified
577      * @param child the node that to be added as a child
578      * @param property the child or child list property descriptor
579      * @since 3.0
580      */

581     void preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
582         // IMPORTANT: this method is called by readers during lazy init
583
synchronized (this.internalASTLock) {
584             // guard against concurrent access by a reader doing lazy init
585
if (this.disableEvents > 0) {
586                 // doing lazy init OR already processing an event
587
// System.out.println("[BOUNCE ADD]");
588
return;
589             } else {
590                 disableEvents();
591             }
592         }
593         try {
594             this.eventHandler.preAddChildEvent(node, child, property);
595             // N.B. even if event handler blows up, the AST is not
596
// corrupted since node has already been changed
597
} finally {
598             reenableEvents();
599         }
600     }
601
602     /**
603      * Reports that the given node has just gained a child.
604      *
605      * @param node the node that was modified
606      * @param child the node that was added as a child
607      * @param property the child or child list property descriptor
608      * @since 3.0
609      */

610     void postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
611         // IMPORTANT: this method is called by readers during lazy init
612
synchronized (this.internalASTLock) {
613             // guard against concurrent access by a reader doing lazy init
614
if (this.disableEvents > 0) {
615                 // doing lazy init OR already processing an event
616
// System.out.println("[BOUNCE ADD]");
617
return;
618             } else {
619                 disableEvents();
620             }
621         }
622         try {
623             this.eventHandler.postAddChildEvent(node, child, property);
624             // N.B. even if event handler blows up, the AST is not
625
// corrupted since node has already been changed
626
} finally {
627             reenableEvents();
628         }
629     }
630
631     /**
632      * Reports that the given node is about to change the value of a
633      * non-child property.
634      *
635      * @param node the node to be modified
636      * @param property the property descriptor
637      * @since 3.0
638      */

639     void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
640         // IMPORTANT: this method is called by readers during lazy init
641
synchronized (this.internalASTLock) {
642             // guard against concurrent access by a reader doing lazy init
643
if (this.disableEvents > 0) {
644                 // doing lazy init OR already processing an event
645
// System.out.println("[BOUNCE CHANGE]");
646
return;
647             } else {
648                 disableEvents();
649             }
650         }
651         try {
652             this.eventHandler.preValueChangeEvent(node, property);
653             // N.B. even if event handler blows up, the AST is not
654
// corrupted since node has already been changed
655
} finally {
656             reenableEvents();
657         }
658     }
659
660     /**
661      * Reports that the given node has just changed the value of a
662      * non-child property.
663      *
664      * @param node the node that was modified
665      * @param property the property descriptor
666      * @since 3.0
667      */

668     void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
669         // IMPORTANT: this method is called by readers during lazy init
670
synchronized (this.internalASTLock) {
671             // guard against concurrent access by a reader doing lazy init
672
if (this.disableEvents > 0) {
673                 // doing lazy init OR already processing an event
674
// System.out.println("[BOUNCE CHANGE]");
675
return;
676             } else {
677                 disableEvents();
678             }
679         }
680         try {
681             this.eventHandler.postValueChangeEvent(node, property);
682             // N.B. even if event handler blows up, the AST is not
683
// corrupted since node has already been changed
684
} finally {
685             reenableEvents();
686         }
687     }
688
689     /**
690      * Reports that the given node is about to be cloned.
691      *
692      * @param node the node to be cloned
693      * @since 3.0
694      */

695     void preCloneNodeEvent(ASTNode node) {
696         synchronized (this.internalASTLock) {
697             // guard against concurrent access by a reader doing lazy init
698
if (this.disableEvents > 0) {
699                 // doing lazy init OR already processing an event
700
// System.out.println("[BOUNCE CLONE]");
701
return;
702             } else {
703                 disableEvents();
704             }
705         }
706         try {
707             this.eventHandler.preCloneNodeEvent(node);
708             // N.B. even if event handler blows up, the AST is not
709
// corrupted since node has already been changed
710
} finally {
711             reenableEvents();
712         }
713     }
714
715     /**
716      * Reports that the given node has just been cloned.
717      *
718      * @param node the node that was cloned
719      * @param clone the clone of <code>node</code>
720      * @since 3.0
721      */

722     void postCloneNodeEvent(ASTNode node, ASTNode clone) {
723         synchronized (this.internalASTLock) {
724             // guard against concurrent access by a reader doing lazy init
725
if (this.disableEvents > 0) {
726                 // doing lazy init OR already processing an event
727
// System.out.println("[BOUNCE CLONE]");
728
return;
729             } else {
730                 disableEvents();
731             }
732         }
733         try {
734             this.eventHandler.postCloneNodeEvent(node, clone);
735             // N.B. even if event handler blows up, the AST is not
736
// corrupted since node has already been changed
737
} finally {
738             reenableEvents();
739         }
740     }
741
742     /**
743      * Parses the source string of the given Java model compilation unit element
744      * and creates and returns a corresponding abstract syntax tree. The source
745      * string is obtained from the Java model element using
746      * <code>ICompilationUnit.getSource()</code>.
747      * <p>
748      * The returned compilation unit node is the root node of a new AST.
749      * Each node in the subtree carries source range(s) information relating back
750      * to positions in the source string (the source string is not remembered
751      * with the AST).
752      * The source range usually begins at the first character of the first token
753      * corresponding to the node; leading whitespace and comments are <b>not</b>
754      * included. The source range usually extends through the last character of
755      * the last token corresponding to the node; trailing whitespace and
756      * comments are <b>not</b> included. There are a handful of exceptions
757      * (including compilation units and the various body declarations); the
758      * specification for these node type spells out the details.
759      * Source ranges nest properly: the source range for a child is always
760      * within the source range of its parent, and the source ranges of sibling
761      * nodes never overlap.
762      * If a syntax error is detected while parsing, the relevant node(s) of the
763      * tree will be flagged as <code>MALFORMED</code>.
764      * </p>
765      * <p>
766      * If <code>resolveBindings</code> is <code>true</code>, the various names
767      * and types appearing in the compilation unit can be resolved to "bindings"
768      * by calling the <code>resolveBinding</code> methods. These bindings
769      * draw connections between the different parts of a program, and
770      * generally afford a more powerful vantage point for clients who wish to
771      * analyze a program's structure more deeply. These bindings come at a
772      * considerable cost in both time and space, however, and should not be
773      * requested frivolously. The additional space is not reclaimed until the
774      * AST, all its nodes, and all its bindings become garbage. So it is very
775      * important to not retain any of these objects longer than absolutely
776      * necessary. Bindings are resolved at the time the AST is created. Subsequent
777      * modifications to the AST do not affect the bindings returned by
778      * <code>resolveBinding</code> methods in any way; these methods return the
779      * same binding as before the AST was modified (including modifications
780      * that rearrange subtrees by reparenting nodes).
781      * If <code>resolveBindings</code> is <code>false</code>, the analysis
782      * does not go beyond parsing and building the tree, and all
783      * <code>resolveBinding</code> methods return <code>null</code> from the
784      * outset.
785      * </p>
786      *
787      * @param unit the Java model compilation unit whose source code is to be parsed
788      * @param resolveBindings <code>true</code> if bindings are wanted,
789      * and <code>false</code> if bindings are not of interest
790      * @return the compilation unit node
791      * @exception IllegalArgumentException if the given Java element does not
792      * exist or if its source string cannot be obtained
793      * @see ASTNode#getFlags()
794      * @see ASTNode#MALFORMED
795      * @see ASTNode#getStartPosition()
796      * @see ASTNode#getLength()
797      * @since 2.0
798      * @deprecated Use {@link ASTParser} instead.
799      */

800     public static CompilationUnit parseCompilationUnit(
801         ICompilationUnit unit,
802         boolean resolveBindings) {
803
804         try {
805             ASTParser c = ASTParser.newParser(AST.JLS2);
806             c.setSource(unit);
807             c.setResolveBindings(resolveBindings);
808             ASTNode result = c.createAST(null);
809             return (CompilationUnit) result;
810         } catch (IllegalStateException JavaDoc e) {
811             // convert ASTParser's complaints into old form
812
throw new IllegalArgumentException JavaDoc();
813         }
814     }
815
816     /**
817      * Parses the source string corresponding to the given Java class file
818      * element and creates and returns a corresponding abstract syntax tree.
819      * The source string is obtained from the Java model element using
820      * <code>IClassFile.getSource()</code>, and is only available for a class
821      * files with attached source.
822      * <p>
823      * The returned compilation unit node is the root node of a new AST.
824      * Each node in the subtree carries source range(s) information relating back
825      * to positions in the source string (the source string is not remembered
826      * with the AST).
827      * The source range usually begins at the first character of the first token
828      * corresponding to the node; leading whitespace and comments are <b>not</b>
829      * included. The source range usually extends through the last character of
830      * the last token corresponding to the node; trailing whitespace and
831      * comments are <b>not</b> included. There are a handful of exceptions
832      * (including compilation units and the various body declarations); the
833      * specification for these node type spells out the details.
834      * Source ranges nest properly: the source range for a child is always
835      * within the source range of its parent, and the source ranges of sibling
836      * nodes never overlap.
837      * If a syntax error is detected while parsing, the relevant node(s) of the
838      * tree will be flagged as <code>MALFORMED</code>.
839      * </p>
840      * <p>
841      * If <code>resolveBindings</code> is <code>true</code>, the various names
842      * and types appearing in the compilation unit can be resolved to "bindings"
843      * by calling the <code>resolveBinding</code> methods. These bindings
844      * draw connections between the different parts of a program, and
845      * generally afford a more powerful vantage point for clients who wish to
846      * analyze a program's structure more deeply. These bindings come at a
847      * considerable cost in both time and space, however, and should not be
848      * requested frivolously. The additional space is not reclaimed until the
849      * AST, all its nodes, and all its bindings become garbage. So it is very
850      * important to not retain any of these objects longer than absolutely
851      * necessary. Bindings are resolved at the time the AST is created. Subsequent
852      * modifications to the AST do not affect the bindings returned by
853      * <code>resolveBinding</code> methods in any way; these methods return the
854      * same binding as before the AST was modified (including modifications
855      * that rearrange subtrees by reparenting nodes).
856      * If <code>resolveBindings</code> is <code>false</code>, the analysis
857      * does not go beyond parsing and building the tree, and all
858      * <code>resolveBinding</code> methods return <code>null</code> from the
859      * outset.
860      * </p>
861      *
862      * @param classFile the Java model class file whose corresponding source code is to be parsed
863      * @param resolveBindings <code>true</code> if bindings are wanted,
864      * and <code>false</code> if bindings are not of interest
865      * @return the compilation unit node
866      * @exception IllegalArgumentException if the given Java element does not
867      * exist or if its source string cannot be obtained
868      * @see ASTNode#getFlags()
869      * @see ASTNode#MALFORMED
870      * @see ASTNode#getStartPosition()
871      * @see ASTNode#getLength()
872      * @since 2.1
873      * @deprecated Use {@link ASTParser} instead.
874      */

875     public static CompilationUnit parseCompilationUnit(
876         IClassFile classFile,
877         boolean resolveBindings) {
878
879         if (classFile == null) {
880             throw new IllegalArgumentException JavaDoc();
881         }
882         try {
883             ASTParser c = ASTParser.newParser(AST.JLS2);
884             c.setSource(classFile);
885             c.setResolveBindings(resolveBindings);
886             ASTNode result = c.createAST(null);
887             return (CompilationUnit) result;
888         } catch (IllegalStateException JavaDoc e) {
889             // convert ASTParser's complaints into old form
890
throw new IllegalArgumentException JavaDoc();
891         }
892     }
893
894     /**
895      * Parses the given string as the hypothetical contents of the named
896      * compilation unit and creates and returns a corresponding abstract syntax tree.
897      * <p>
898      * The returned compilation unit node is the root node of a new AST.
899      * Each node in the subtree carries source range(s) information relating back
900      * to positions in the given source string (the given source string itself
901      * is not remembered with the AST).
902      * The source range usually begins at the first character of the first token
903      * corresponding to the node; leading whitespace and comments are <b>not</b>
904      * included. The source range usually extends through the last character of
905      * the last token corresponding to the node; trailing whitespace and
906      * comments are <b>not</b> included. There are a handful of exceptions
907      * (including compilation units and the various body declarations); the
908      * specification for these node type spells out the details.
909      * Source ranges nest properly: the source range for a child is always
910      * within the source range of its parent, and the source ranges of sibling
911      * nodes never overlap.
912      * If a syntax error is detected while parsing, the relevant node(s) of the
913      * tree will be flagged as <code>MALFORMED</code>.
914      * </p>
915      * <p>
916      * If the given project is not <code>null</code>, the various names
917      * and types appearing in the compilation unit can be resolved to "bindings"
918      * by calling the <code>resolveBinding</code> methods. These bindings
919      * draw connections between the different parts of a program, and
920      * generally afford a more powerful vantage point for clients who wish to
921      * analyze a program's structure more deeply. These bindings come at a
922      * considerable cost in both time and space, however, and should not be
923      * requested frivolously. The additional space is not reclaimed until the
924      * AST, all its nodes, and all its bindings become garbage. So it is very
925      * important to not retain any of these objects longer than absolutely
926      * necessary. Bindings are resolved at the time the AST is created. Subsequent
927      * modifications to the AST do not affect the bindings returned by
928      * <code>resolveBinding</code> methods in any way; these methods return the
929      * same binding as before the AST was modified (including modifications
930      * that rearrange subtrees by reparenting nodes).
931      * If the given project is <code>null</code>, the analysis
932      * does not go beyond parsing and building the tree, and all
933      * <code>resolveBinding</code> methods return <code>null</code> from the
934      * outset.
935      * </p>
936      * <p>
937      * The name of the compilation unit must be supplied for resolving bindings.
938      * This name should be suffixed by a dot ('.') followed by one of the
939      * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
940      * and match the name of the main
941      * (public) class or interface declared in the source. For example, if the source
942      * declares a public class named "Foo", the name of the compilation can be
943      * "Foo.java". For the purposes of resolving bindings, types declared in the
944      * source string hide types by the same name available through the classpath
945      * of the given project.
946      * </p>
947      *
948      * @param source the string to be parsed as a Java compilation unit
949      * @param unitName the name of the compilation unit that would contain the source
950      * string, or <code>null</code> if <code>javaProject</code> is also <code>null</code>
951      * @param project the Java project used to resolve names, or
952      * <code>null</code> if bindings are not resolved
953      * @return the compilation unit node
954      * @see ASTNode#getFlags()
955      * @see ASTNode#MALFORMED
956      * @see ASTNode#getStartPosition()
957      * @see ASTNode#getLength()
958      * @since 2.0
959      * @deprecated Use {@link ASTParser} instead.
960      */

961     public static CompilationUnit parseCompilationUnit(
962         char[] source,
963         String JavaDoc unitName,
964         IJavaProject project) {
965
966         if (source == null) {
967             throw new IllegalArgumentException JavaDoc();
968         }
969         ASTParser astParser = ASTParser.newParser(AST.JLS2);
970         astParser.setSource(source);
971         astParser.setUnitName(unitName);
972         astParser.setProject(project);
973         astParser.setResolveBindings(project != null);
974         ASTNode result = astParser.createAST(null);
975         return (CompilationUnit) result;
976     }
977
978     /**
979      * Parses the given string as a Java compilation unit and creates and
980      * returns a corresponding abstract syntax tree.
981      * <p>
982      * The returned compilation unit node is the root node of a new AST.
983      * Each node in the subtree carries source range(s) information relating back
984      * to positions in the given source string (the given source string itself
985      * is not remembered with the AST).
986      * The source range usually begins at the first character of the first token
987      * corresponding to the node; leading whitespace and comments are <b>not</b>
988      * included. The source range usually extends through the last character of
989      * the last token corresponding to the node; trailing whitespace and
990      * comments are <b>not</b> included. There are a handful of exceptions
991      * (including compilation units and the various body declarations); the
992      * specification for these node type spells out the details.
993      * Source ranges nest properly: the source range for a child is always
994      * within the source range of its parent, and the source ranges of sibling
995      * nodes never overlap.
996      * If a syntax error is detected while parsing, the relevant node(s) of the
997      * tree will be flagged as <code>MALFORMED</code>.
998      * </p>
999      * <p>
1000     * This method does not compute binding information; all <code>resolveBinding</code>
1001     * methods applied to nodes of the resulting AST return <code>null</code>.
1002     * </p>
1003     *
1004     * @param source the string to be parsed as a Java compilation unit
1005     * @return the compilation unit node
1006     * @see ASTNode#getFlags()
1007     * @see ASTNode#MALFORMED
1008     * @see ASTNode#getStartPosition()
1009     * @see ASTNode#getLength()
1010     * @since 2.0
1011     * @deprecated Use {@link ASTParser} instead.
1012     */

1013    public static CompilationUnit parseCompilationUnit(char[] source) {
1014        if (source == null) {
1015            throw new IllegalArgumentException JavaDoc();
1016        }
1017        ASTParser c = ASTParser.newParser(AST.JLS2);
1018        c.setSource(source);
1019        ASTNode result = c.createAST(null);
1020        return (CompilationUnit) result;
1021    }
1022
1023    /**
1024     * Returns the binding resolver for this AST.
1025     *
1026     * @return the binding resolver for this AST
1027     */

1028    BindingResolver getBindingResolver() {
1029        return this.resolver;
1030    }
1031
1032    /**
1033     * Returns the event handler for this AST.
1034     *
1035     * @return the event handler for this AST
1036     * @since 3.0
1037     */

1038    NodeEventHandler getEventHandler() {
1039        return this.eventHandler;
1040    }
1041
1042    /**
1043     * Sets the event handler for this AST.
1044     *
1045     * @param eventHandler the event handler for this AST
1046     * @since 3.0
1047     */

1048    void setEventHandler(NodeEventHandler eventHandler) {
1049        if (this.eventHandler == null) {
1050            throw new IllegalArgumentException JavaDoc();
1051        }
1052        this.eventHandler = eventHandler;
1053    }
1054
1055    /**
1056     * Returns default node flags of new nodes of this AST.
1057     *
1058     * @return the default node flags of new nodes of this AST
1059     * @since 3.0
1060     */

1061    int getDefaultNodeFlag() {
1062        return this.defaultNodeFlag;
1063    }
1064
1065    /**
1066     * Sets default node flags of new nodes of this AST.
1067     *
1068     * @param flag node flags of new nodes of this AST
1069     * @since 3.0
1070     */

1071    void setDefaultNodeFlag(int flag) {
1072        this.defaultNodeFlag = flag;
1073    }
1074
1075    /**
1076     * Set <code>originalModificationCount</code> to the current modification count
1077     *
1078     * @since 3.0
1079     */

1080    void setOriginalModificationCount(long count) {
1081        this.originalModificationCount = count;
1082    }
1083
1084    /**
1085     * Returns the type binding for a "well known" type.
1086     * <p>
1087     * Note that bindings are generally unavailable unless requested when the
1088     * AST is being built.
1089     * </p>
1090     * <p>
1091     * The following type names are supported:
1092     * <ul>
1093     * <li><code>"boolean"</code></li>
1094     * <li><code>"byte"</code></li>
1095     * <li><code>"char"</code></li>
1096     * <li><code>"double"</code></li>
1097     * <li><code>"float"</code></li>
1098     * <li><code>"int"</code></li>
1099     * <li><code>"long"</code></li>
1100     * <li><code>"short"</code></li>
1101     * <li><code>"void"</code></li>
1102     * <li><code>"java.lang.Boolean"</code> (since 3.1)</li>
1103     * <li><code>"java.lang.Byte"</code> (since 3.1)</li>
1104     * <li><code>"java.lang.Character"</code> (since 3.1)</li>
1105     * <li><code>"java.lang.Class"</code></li>
1106     * <li><code>"java.lang.Cloneable"</code></li>
1107     * <li><code>"java.lang.Double"</code> (since 3.1)</li>
1108     * <li><code>"java.lang.Error"</code></li>
1109     * <li><code>"java.lang.Exception"</code></li>
1110     * <li><code>"java.lang.Float"</code> (since 3.1)</li>
1111     * <li><code>"java.lang.Integer"</code> (since 3.1)</li>
1112     * <li><code>"java.lang.Long"</code> (since 3.1)</li>
1113     * <li><code>"java.lang.Object"</code></li>
1114     * <li><code>"java.lang.RuntimeException"</code></li>
1115     * <li><code>"java.lang.Short"</code> (since 3.1)</li>
1116     * <li><code>"java.lang.String"</code></li>
1117     * <li><code>"java.lang.StringBuffer"</code></li>
1118     * <li><code>"java.lang.Throwable"</code></li>
1119     * <li><code>"java.lang.Void"</code> (since 3.1)</li>
1120     * <li><code>"java.io.Serializable"</code></li>
1121     * </ul>
1122     * </p>
1123     *
1124     * @param name the name of a well known type
1125     * @return the corresponding type binding, or <code>null</code> if the
1126     * named type is not considered well known or if no binding can be found
1127     * for it
1128     */

1129    public ITypeBinding resolveWellKnownType(String JavaDoc name) {
1130        if (name == null) {
1131            return null;
1132        }
1133        return getBindingResolver().resolveWellKnownType(name);
1134    }
1135
1136    /**
1137     * Sets the binding resolver for this AST.
1138     *
1139     * @param resolver the new binding resolver for this AST
1140     */

1141    void setBindingResolver(BindingResolver resolver) {
1142        if (resolver == null) {
1143            throw new IllegalArgumentException JavaDoc();
1144        }
1145        this.resolver = resolver;
1146    }
1147
1148    /**
1149     * Checks that this AST operation is not used when
1150     * building level JLS2 ASTs.
1151
1152     * @exception UnsupportedOperationException
1153     * @since 3.0
1154     */

1155    void unsupportedIn2() {
1156      if (this.apiLevel == AST.JLS2) {
1157        throw new UnsupportedOperationException JavaDoc("Operation not supported in JLS2 AST"); //$NON-NLS-1$
1158
}
1159    }
1160
1161    /**
1162     * Checks that this AST operation is only used when
1163     * building level JLS2 ASTs.
1164
1165     * @exception UnsupportedOperationException
1166     * @since 3.0
1167     */

1168    void supportedOnlyIn2() {
1169      if (this.apiLevel != AST.JLS2) {
1170        throw new UnsupportedOperationException JavaDoc("Operation not supported in JLS2 AST"); //$NON-NLS-1$
1171
}
1172    }
1173
1174    /**
1175     * new Class[] {AST.class}
1176     * @since 3.0
1177     */

1178    private static final Class JavaDoc[] AST_CLASS = new Class JavaDoc[] {AST.class};
1179
1180    /**
1181     * new Object[] {this}
1182     * @since 3.0
1183     */

1184    private final Object JavaDoc[] THIS_AST= new Object JavaDoc[] {this};
1185
1186    /*
1187     * Must not collide with a value for ICompilationUnit constants
1188     */

1189    static final int RESOLVED_BINDINGS = 0x80000000;
1190
1191    /**
1192     * Tag bit value. This represents internal state of the tree.
1193     */

1194    private int bits;
1195
1196    /**
1197     * Creates an unparented node of the given node class
1198     * (non-abstract subclass of {@link ASTNode}).
1199     *
1200     * @param nodeClass AST node class
1201     * @return a new unparented node owned by this AST
1202     * @exception IllegalArgumentException if <code>nodeClass</code> is
1203     * <code>null</code> or is not a concrete node type class
1204     * @since 3.0
1205     */

1206    public ASTNode createInstance(Class JavaDoc nodeClass) {
1207        if (nodeClass == null) {
1208            throw new IllegalArgumentException JavaDoc();
1209        }
1210        try {
1211            // invoke constructor with signature Foo(AST)
1212
Constructor JavaDoc c = nodeClass.getDeclaredConstructor(AST_CLASS);
1213            Object JavaDoc result = c.newInstance(this.THIS_AST);
1214            return (ASTNode) result;
1215        } catch (NoSuchMethodException JavaDoc e) {
1216            // all AST node classes have a Foo(AST) constructor
1217
// therefore nodeClass is not legit
1218
throw new IllegalArgumentException JavaDoc();
1219        } catch (InstantiationException JavaDoc e) {
1220            // all concrete AST node classes can be instantiated
1221
// therefore nodeClass is not legit
1222
throw new IllegalArgumentException JavaDoc();
1223        } catch (IllegalAccessException JavaDoc e) {
1224            // all AST node classes have an accessible Foo(AST) constructor
1225
// therefore nodeClass is not legit
1226
throw new IllegalArgumentException JavaDoc();
1227        } catch (InvocationTargetException JavaDoc e) {
1228            // concrete AST node classes do not die in the constructor
1229
// therefore nodeClass is not legit
1230
throw new IllegalArgumentException JavaDoc();
1231        }
1232    }
1233
1234    /**
1235     * Creates an unparented node of the given node type.
1236     * This convenience method is equivalent to:
1237     * <pre>
1238     * createInstance(ASTNode.nodeClassForType(nodeType))
1239     * </pre>
1240     *
1241     * @param nodeType AST node type, one of the node type
1242     * constants declared on {@link ASTNode}
1243     * @return a new unparented node owned by this AST
1244     * @exception IllegalArgumentException if <code>nodeType</code> is
1245     * not a legal AST node type
1246     * @since 3.0
1247     */

1248    public ASTNode createInstance(int nodeType) {
1249        // nodeClassForType throws IllegalArgumentException if nodeType is bogus
1250
Class JavaDoc nodeClass = ASTNode.nodeClassForType(nodeType);
1251        return createInstance(nodeClass);
1252    }
1253
1254    //=============================== NAMES ===========================
1255
/**
1256     * Creates and returns a new unparented simple name node for the given
1257     * identifier. The identifier should be a legal Java identifier, but not
1258     * a keyword, boolean literal ("true", "false") or null literal ("null").
1259     *
1260     * @param identifier the identifier
1261     * @return a new unparented simple name node
1262     * @exception IllegalArgumentException if the identifier is invalid
1263     */

1264    public SimpleName newSimpleName(String JavaDoc identifier) {
1265        if (identifier == null) {
1266            throw new IllegalArgumentException JavaDoc();
1267        }
1268        SimpleName result = new SimpleName(this);
1269        result.setIdentifier(identifier);
1270        return result;
1271    }
1272
1273    /**
1274     * Creates and returns a new unparented qualified name node for the given
1275     * qualifier and simple name child node.
1276     *
1277     * @param qualifier the qualifier name node
1278     * @param name the simple name being qualified
1279     * @return a new unparented qualified name node
1280     * @exception IllegalArgumentException if:
1281     * <ul>
1282     * <li>the node belongs to a different AST</li>
1283     * <li>the node already has a parent</li>
1284     * </ul>
1285     */

1286    public QualifiedName newQualifiedName(
1287        Name qualifier,
1288        SimpleName name) {
1289        QualifiedName result = new QualifiedName(this);
1290        result.setQualifier(qualifier);
1291        result.setName(name);
1292        return result;
1293
1294    }
1295
1296    /**
1297     * Creates and returns a new unparented name node for the given name
1298     * segments. Returns a simple name if there is only one name segment, and
1299     * a qualified name if there are multiple name segments. Each of the name
1300     * segments should be legal Java identifiers (this constraint may or may
1301     * not be enforced), and there must be at least one name segment.
1302     *
1303     * @param identifiers a list of 1 or more name segments, each of which
1304     * is a legal Java identifier
1305     * @return a new unparented name node
1306     * @exception IllegalArgumentException if:
1307     * <ul>
1308     * <li>the identifier is invalid</li>
1309     * <li>the list of identifiers is empty</li>
1310     * </ul>
1311     */

1312    public Name newName(String JavaDoc[] identifiers) {
1313        // update internalSetName(String[] if changed
1314
int count = identifiers.length;
1315        if (count == 0) {
1316            throw new IllegalArgumentException JavaDoc();
1317        }
1318        Name result = newSimpleName(identifiers[0]);
1319        for (int i = 1; i < count; i++) {
1320            SimpleName name = newSimpleName(identifiers[i]);
1321            result = newQualifiedName(result, name);
1322        }
1323        return result;
1324    }
1325
1326    /* (omit javadoc for this method)
1327     * This method is a copy of setName(String[]) that doesn't do any validation.
1328     */

1329    Name internalNewName(String JavaDoc[] identifiers) {
1330        int count = identifiers.length;
1331        if (count == 0) {
1332            throw new IllegalArgumentException JavaDoc();
1333        }
1334        final SimpleName simpleName = new SimpleName(this);
1335        simpleName.internalSetIdentifier(identifiers[0]);
1336        Name result = simpleName;
1337        for (int i = 1; i < count; i++) {
1338            SimpleName name = new SimpleName(this);
1339            name.internalSetIdentifier(identifiers[i]);
1340            result = newQualifiedName(result, name);
1341        }
1342        return result;
1343    }
1344
1345    /**
1346     * Creates and returns a new unparented name node for the given name.
1347     * The name string must consist of 1 or more name segments separated
1348     * by single dots '.'. Returns a {@link QualifiedName} if the name has
1349     * dots, and a {@link SimpleName} otherwise. Each of the name
1350     * segments should be legal Java identifiers (this constraint may or may
1351     * not be enforced), and there must be at least one name segment.
1352     * The string must not contains white space, '&lt;', '&gt;',
1353     * '[', ']', or other any other characters that are not
1354     * part of the Java identifiers or separating '.'s.
1355     *
1356     * @param qualifiedName string consisting of 1 or more name segments,
1357     * each of which is a legal Java identifier, separated by single dots '.'
1358     * @return a new unparented name node
1359     * @exception IllegalArgumentException if:
1360     * <ul>
1361     * <li>the string is empty</li>
1362     * <li>the string begins or ends in a '.'</li>
1363     * <li>the string has adjacent '.'s</li>
1364     * <li>the segments between the '.'s are not valid Java identifiers</li>
1365     * </ul>
1366     * @since 3.1
1367     */

1368    public Name newName(String JavaDoc qualifiedName) {
1369        StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(qualifiedName, ".", true); //$NON-NLS-1$
1370
Name result = null;
1371        // balance is # of name tokens - # of period tokens seen so far
1372
// initially 0; finally 1; should never drop < 0 or > 1
1373
int balance = 0;
1374        while(t.hasMoreTokens()) {
1375            String JavaDoc s = t.nextToken();
1376            if (s.indexOf('.') >= 0) {
1377                // this is a delimiter
1378
if (s.length() > 1) {
1379                    // too many dots in a row
1380
throw new IllegalArgumentException JavaDoc();
1381                }
1382                balance--;
1383                if (balance < 0) {
1384                    throw new IllegalArgumentException JavaDoc();
1385                }
1386            } else {
1387                // this is an identifier segment
1388
balance++;
1389                SimpleName name = newSimpleName(s);
1390                if (result == null) {
1391                    result = name;
1392                } else {
1393                    result = newQualifiedName(result, name);
1394                }
1395            }
1396        }
1397        if (balance != 1) {
1398            throw new IllegalArgumentException JavaDoc();
1399        }
1400        return result;
1401    }
1402
1403    //=============================== TYPES ===========================
1404
/**
1405     * Creates and returns a new unparented simple type node with the given
1406     * type name.
1407     * <p>
1408     * This method can be used to convert a name (<code>Name</code>) into a
1409     * type (<code>Type</code>) by wrapping it.
1410     * </p>
1411     *
1412     * @param typeName the name of the class or interface
1413     * @return a new unparented simple type node
1414     * @exception IllegalArgumentException if:
1415     * <ul>
1416     * <li>the node belongs to a different AST</li>
1417     * <li>the node already has a parent</li>
1418     * </ul>
1419     */

1420    public SimpleType newSimpleType(Name typeName) {
1421        SimpleType result = new SimpleType(this);
1422        result.setName(typeName);
1423        return result;
1424    }
1425
1426    /**
1427     * Creates and returns a new unparented array type node with the given
1428     * component type, which may be another array type.
1429     *
1430     * @param componentType the component type (possibly another array type)
1431     * @return a new unparented array type node
1432     * @exception IllegalArgumentException if:
1433     * <ul>
1434     * <li>the node belongs to a different AST</li>
1435     * <li>the node already has a parent</li>
1436     * <li>a cycle in would be created</li>
1437     * </ul>
1438     */

1439    public ArrayType newArrayType(Type componentType) {
1440        ArrayType result = new ArrayType(this);
1441        result.setComponentType(componentType);
1442        return result;
1443    }
1444
1445    /**
1446     * Creates and returns a new unparented array type node with the given
1447     * element type and number of dimensions.
1448     * <p>
1449     * Note that if the element type passed in is an array type, the
1450     * element type of the result will not be the same as what was passed in.
1451     * </p>
1452     *
1453     * @param elementType the element type (never an array type)
1454     * @param dimensions the number of dimensions, a positive number
1455     * @return a new unparented array type node
1456     * @exception IllegalArgumentException if:
1457     * <ul>
1458     * <li>the node belongs to a different AST</li>
1459     * <li>the node already has a parent</li>
1460     * <li>a cycle in would be created</li>
1461     * <li>the element type is null</li>
1462     * <li>the element type is an array type</li>
1463     * <li>the number of dimensions is lower than 1</li>
1464     * <li>the number of dimensions is greater than 1000</li>
1465     * </ul>
1466     */

1467    public ArrayType newArrayType(Type elementType, int dimensions) {
1468        if (elementType == null || elementType.isArrayType()) {
1469            throw new IllegalArgumentException JavaDoc();
1470        }
1471        if (dimensions < 1 || dimensions > 1000) {
1472            // we would blow our stacks anyway with a 1000-D array
1473
throw new IllegalArgumentException JavaDoc();
1474        }
1475        ArrayType result = new ArrayType(this);
1476        result.setComponentType(elementType);
1477        for (int i = 2; i <= dimensions; i++) {
1478            result = newArrayType(result);
1479        }
1480        return result;
1481
1482    }
1483
1484    /**
1485     * Creates and returns a new unparented primitive type node with the given
1486     * type code.
1487     *
1488     * @param typeCode one of the primitive type code constants declared in
1489     * <code>PrimitiveType</code>
1490     * @return a new unparented primitive type node
1491     * @exception IllegalArgumentException if the primitive type code is invalid
1492     */

1493    public PrimitiveType newPrimitiveType(PrimitiveType.Code typeCode) {
1494        PrimitiveType result = new PrimitiveType(this);
1495        result.setPrimitiveTypeCode(typeCode);
1496        return result;
1497    }
1498
1499    /**
1500     * Creates and returns a new unparented parameterized type node with the
1501     * given type and an empty list of type arguments.
1502     *
1503     * @param type the type that is parameterized
1504     * @return a new unparented parameterized type node
1505     * @exception IllegalArgumentException if:
1506     * <ul>
1507     * <li>the node belongs to a different AST</li>
1508     * <li>the node already has a parent</li>
1509     * </ul>
1510     * @exception UnsupportedOperationException if this operation is used in
1511     * a JLS2 AST
1512     * @since 3.1
1513     */

1514    public ParameterizedType newParameterizedType(Type type) {
1515        ParameterizedType result = new ParameterizedType(this);
1516        result.setType(type);
1517        return result;
1518    }
1519
1520    /**
1521     * Creates and returns a new unparented qualified type node with
1522     * the given qualifier type and name.
1523     *
1524     * @param qualifier the qualifier type node
1525     * @param name the simple name being qualified
1526     * @return a new unparented qualified type node
1527     * @exception IllegalArgumentException if:
1528     * <ul>
1529     * <li>the node belongs to a different AST</li>
1530     * <li>the node already has a parent</li>
1531     * </ul>
1532     * @exception UnsupportedOperationException if this operation is used in
1533     * a JLS2 AST
1534     * @since 3.1
1535     */

1536    public QualifiedType newQualifiedType(Type qualifier, SimpleName name) {
1537        QualifiedType result = new QualifiedType(this);
1538        result.setQualifier(qualifier);
1539        result.setName(name);
1540        return result;
1541    }
1542
1543    /**
1544     * Creates and returns a new unparented wildcard type node with no
1545     * type bound.
1546     *
1547     * @return a new unparented wildcard type node
1548     * @exception UnsupportedOperationException if this operation is used in
1549     * a JLS2 AST
1550     * @since 3.1
1551     */

1552    public WildcardType newWildcardType() {
1553        WildcardType result = new WildcardType(this);
1554        return result;
1555    }
1556
1557    //=============================== DECLARATIONS ===========================
1558
/**
1559     * Creates an unparented compilation unit node owned by this AST.
1560     * The compilation unit initially has no package declaration, no
1561     * import declarations, and no type declarations.
1562     *
1563     * @return the new unparented compilation unit node
1564     */

1565    public CompilationUnit newCompilationUnit() {
1566        return new CompilationUnit(this);
1567    }
1568
1569    /**
1570     * Creates an unparented package declaration node owned by this AST.
1571     * The package declaration initially declares a package with an
1572     * unspecified name.
1573     *
1574     * @return the new unparented package declaration node
1575     */

1576    public PackageDeclaration newPackageDeclaration() {
1577        PackageDeclaration result = new PackageDeclaration(this);
1578        return result;
1579    }
1580
1581    /**
1582     * Creates an unparented import declaration node owned by this AST.
1583     * The import declaration initially contains a single-type import
1584     * of a type with an unspecified name.
1585     *
1586     * @return the new unparented import declaration node
1587     */

1588    public ImportDeclaration newImportDeclaration() {
1589        ImportDeclaration result = new ImportDeclaration(this);
1590        return result;
1591    }
1592
1593    /**
1594     * Creates an unparented class declaration node owned by this AST.
1595     * The name of the class is an unspecified, but legal, name;
1596     * no modifiers; no doc comment; no superclass or superinterfaces;
1597     * and an empty class body.
1598     * <p>
1599     * To create an interface, use this method and then call
1600     * <code>TypeDeclaration.setInterface(true)</code>.
1601     * </p>
1602     * <p>
1603     * To create an enum declaration, use this method and then call
1604     * <code>TypeDeclaration.setEnumeration(true)</code>.
1605     * </p>
1606     *
1607     * @return a new unparented type declaration node
1608     */

1609    public TypeDeclaration newTypeDeclaration() {
1610        TypeDeclaration result = new TypeDeclaration(this);
1611        result.setInterface(false);
1612        return result;
1613    }
1614
1615    /**
1616     * Creates an unparented method declaration node owned by this AST.
1617     * By default, the declaration is for a method of an unspecified, but
1618     * legal, name; no modifiers; no doc comment; no parameters; return
1619     * type void; no extra array dimensions; no thrown exceptions; and no
1620     * body (as opposed to an empty body).
1621     * <p>
1622     * To create a constructor, use this method and then call
1623     * <code>MethodDeclaration.setConstructor(true)</code> and
1624     * <code>MethodDeclaration.setName(className)</code>.
1625     * </p>
1626     *
1627     * @return a new unparented method declaration node
1628     */

1629    public MethodDeclaration newMethodDeclaration() {
1630        MethodDeclaration result = new MethodDeclaration(this);
1631        result.setConstructor(false);
1632        return result;
1633    }
1634
1635    /**
1636     * Creates an unparented single variable declaration node owned by this AST.
1637     * By default, the declaration is for a variable with an unspecified, but
1638     * legal, name and type; no modifiers; no array dimensions after the
1639     * variable; no initializer; not variable arity.
1640     *
1641     * @return a new unparented single variable declaration node
1642     */

1643    public SingleVariableDeclaration newSingleVariableDeclaration() {
1644        SingleVariableDeclaration result = new SingleVariableDeclaration(this);
1645        return result;
1646    }
1647
1648    /**
1649     * Creates an unparented variable declaration fragment node owned by this
1650     * AST. By default, the fragment is for a variable with an unspecified, but
1651     * legal, name; no extra array dimensions; and no initializer.
1652     *
1653     * @return a new unparented variable declaration fragment node
1654     */

1655    public VariableDeclarationFragment newVariableDeclarationFragment() {
1656        VariableDeclarationFragment result = new VariableDeclarationFragment(this);
1657        return result;
1658    }
1659
1660    /**
1661     * Creates an unparented initializer node owned by this AST, with an
1662     * empty block. By default, the initializer has no modifiers and
1663     * an empty block.
1664     *
1665     * @return a new unparented initializer node
1666     */

1667    public Initializer newInitializer() {
1668        Initializer result = new Initializer(this);
1669        return result;
1670    }
1671
1672    /**
1673     * Creates an unparented enum constant declaration node owned by this AST.
1674     * The name of the constant is an unspecified, but legal, name;
1675     * no doc comment; no modifiers or annotations; no arguments;
1676     * and does not declare an anonymous class.
1677     *
1678     * @return a new unparented enum constant declaration node
1679     * @exception UnsupportedOperationException if this operation is used in
1680     * a JLS2 AST
1681     * @since 3.1
1682     */

1683    public EnumConstantDeclaration newEnumConstantDeclaration() {
1684        EnumConstantDeclaration result = new EnumConstantDeclaration(this);
1685        return result;
1686    }
1687
1688    /**
1689     * Creates an unparented enum declaration node owned by this AST.
1690     * The name of the enum is an unspecified, but legal, name;
1691     * no doc comment; no modifiers or annotations;
1692     * no superinterfaces; and empty lists of enum constants
1693     * and body declarations.
1694     *
1695     * @return a new unparented enum declaration node
1696     * @exception UnsupportedOperationException if this operation is used in
1697     * a JLS2 AST
1698     * @since 3.1
1699     */

1700    public EnumDeclaration newEnumDeclaration() {
1701        EnumDeclaration result = new EnumDeclaration(this);
1702        return result;
1703    }
1704
1705    /**
1706     * Creates and returns a new unparented type parameter type node with an
1707     * unspecified type variable name and an empty list of type bounds.
1708     *
1709     * @return a new unparented type parameter node
1710     * @exception UnsupportedOperationException if this operation is used in
1711     * a JLS2 AST
1712     * @since 3.1
1713     */

1714    public TypeParameter newTypeParameter() {
1715        TypeParameter result = new TypeParameter(this);
1716        return result;
1717    }
1718
1719    /**
1720     * Creates and returns a new unparented annotation type declaration
1721     * node for an unspecified, but legal, name; no modifiers; no javadoc;
1722     * and an empty list of member declarations.
1723     *
1724     * @return a new unparented annotation type declaration node
1725     * @exception UnsupportedOperationException if this operation is used in
1726     * a JLS2 AST
1727     * @since 3.1
1728     */

1729    public AnnotationTypeDeclaration newAnnotationTypeDeclaration() {
1730        AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(this);
1731        return result;
1732    }
1733
1734    /**
1735     * Creates and returns a new unparented annotation type
1736     * member declaration node for an unspecified, but legal,
1737     * member name and type; no modifiers; no javadoc;
1738     * and no default value.
1739     *
1740     * @return a new unparented annotation type member declaration node
1741     * @exception UnsupportedOperationException if this operation is used in
1742     * a JLS2 AST
1743     * @since 3.1
1744     */

1745    public AnnotationTypeMemberDeclaration newAnnotationTypeMemberDeclaration() {
1746        AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(this);
1747        return result;
1748    }
1749
1750    /**
1751     * Creates and returns a new unparented modifier node for the given
1752     * modifier.
1753     *
1754     * @param keyword one of the modifier keyword constants
1755     * @return a new unparented modifier node
1756     * @exception IllegalArgumentException if the primitive type code is invalid
1757     * @exception UnsupportedOperationException if this operation is used in
1758     * a JLS2 AST
1759     * @since 3.1
1760     */

1761    public Modifier newModifier(Modifier.ModifierKeyword keyword) {
1762        Modifier result = new Modifier(this);
1763        result.setKeyword(keyword);
1764        return result;
1765    }
1766
1767    /**
1768     * Creates and returns a list of new unparented modifier nodes
1769     * for the given modifier flags. When multiple modifiers are
1770     * requested the modifiers nodes will appear in the following order:
1771     * public, protected, private, abstract, static, final, synchronized,
1772     * native, strictfp, transient, volatile. This order is consistent
1773     * with the recommendations in JLS2 8.1.1, 8.3.1, and 8.4.3.
1774     *
1775     * @param flags bitwise or of modifier flags declared on {@link Modifier}
1776     * @return a possibly empty list of new unparented modifier nodes
1777     * (element type <code>Modifier</code>)
1778     * @exception UnsupportedOperationException if this operation is used in
1779     * a JLS2 AST
1780     * @since 3.1
1781     */

1782    public List JavaDoc newModifiers(int flags) {
1783        if (this.apiLevel == AST.JLS2) {
1784            unsupportedIn2();
1785        }
1786        List JavaDoc result = new ArrayList JavaDoc(3); // 3 modifiers is more than average
1787
if (Modifier.isPublic(flags)) {
1788            result.add(newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
1789        }
1790        if (Modifier.isProtected(flags)) {
1791            result.add(newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD));
1792        }
1793        if (Modifier.isPrivate(flags)) {
1794            result.add(newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD));
1795        }
1796        if (Modifier.isAbstract(flags)) {
1797            result.add(newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD));
1798        }
1799        if (Modifier.isStatic(flags)) {
1800            result.add(newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
1801        }
1802        if (Modifier.isFinal(flags)) {
1803            result.add(newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
1804        }
1805        if (Modifier.isSynchronized(flags)) {
1806            result.add(newModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD));
1807        }
1808        if (Modifier.isNative(flags)) {
1809            result.add(newModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD));
1810        }
1811        if (Modifier.isStrictfp(flags)) {
1812            result.add(newModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD));
1813        }
1814        if (Modifier.isTransient(flags)) {
1815            result.add(newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD));
1816        }
1817        if (Modifier.isVolatile(flags)) {
1818            result.add(newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD));
1819        }
1820        return result;
1821    }
1822
1823    //=============================== COMMENTS ===========================
1824

1825    /**
1826     * Creates and returns a new block comment placeholder node.
1827     * <p>
1828     * Note that this node type is used to recording the source
1829     * range where a comment was found in the source string.
1830     * These comment nodes are normally found (only) in
1831     * {@linkplain CompilationUnit#getCommentList()
1832     * the comment table} for parsed compilation units.
1833     * </p>
1834     *
1835     * @return a new unparented block comment node
1836     * @since 3.0
1837     */

1838    public BlockComment newBlockComment() {
1839        BlockComment result = new BlockComment(this);
1840        return result;
1841    }
1842
1843    /**
1844     * Creates and returns a new line comment placeholder node.
1845     * <p>
1846     * Note that this node type is used to recording the source
1847     * range where a comment was found in the source string.
1848     * These comment nodes are normally found (only) in
1849     * {@linkplain CompilationUnit#getCommentList()
1850     * the comment table} for parsed compilation units.
1851     * </p>
1852     *
1853     * @return a new unparented line comment node
1854     * @since 3.0
1855     */

1856    public LineComment newLineComment() {
1857        LineComment result = new LineComment(this);
1858        return result;
1859    }
1860
1861    /**
1862     * Creates and returns a new doc comment node.
1863     * Initially the new node has an empty list of tag elements
1864     * (and, for backwards compatability, an unspecified, but legal,
1865     * doc comment string)
1866     *
1867     * @return a new unparented doc comment node
1868     */

1869    public Javadoc newJavadoc() {
1870        Javadoc result = new Javadoc(this);
1871        return result;
1872    }
1873
1874    /**
1875     * Creates and returns a new tag element node.
1876     * Initially the new node has no tag name and an empty list of fragments.
1877     * <p>
1878     * Note that this node type is used only inside doc comments
1879     * ({@link Javadoc}).
1880     * </p>
1881     *
1882     * @return a new unparented tag element node
1883     * @since 3.0
1884     */

1885    public TagElement newTagElement() {
1886        TagElement result = new TagElement(this);
1887        return result;
1888    }
1889
1890    /**
1891     * Creates and returns a new text element node.
1892     * Initially the new node has an empty text string.
1893     * <p>
1894     * Note that this node type is used only inside doc comments
1895     * ({@link Javadoc Javadoc}).
1896     * </p>
1897     *
1898     * @return a new unparented text element node
1899     * @since 3.0
1900     */

1901    public TextElement newTextElement() {
1902        TextElement result = new TextElement(this);
1903        return result;
1904    }
1905
1906    /**
1907     * Creates and returns a new member reference node.
1908     * Initially the new node has no qualifier name and
1909     * an unspecified, but legal, member name.
1910     * <p>
1911     * Note that this node type is used only inside doc comments
1912     * ({@link Javadoc}).
1913     * </p>
1914     *
1915     * @return a new unparented member reference node
1916     * @since 3.0
1917     */

1918    public MemberRef newMemberRef() {
1919        MemberRef result = new MemberRef(this);
1920        return result;
1921    }
1922
1923    /**
1924     * Creates and returns a new method reference node.
1925     * Initially the new node has no qualifier name,
1926     * an unspecified, but legal, method name, and an
1927     * empty parameter list.
1928     * <p>
1929     * Note that this node type is used only inside doc comments
1930     * ({@link Javadoc Javadoc}).
1931     * </p>
1932     *
1933     * @return a new unparented method reference node
1934     * @since 3.0
1935     */

1936    public MethodRef newMethodRef() {
1937        MethodRef result = new MethodRef(this);
1938        return result;
1939    }
1940
1941    /**
1942     * Creates and returns a new method reference node.
1943     * Initially the new node has an unspecified, but legal,
1944     * type, not variable arity, and no parameter name.
1945     * <p>
1946     * Note that this node type is used only inside doc comments
1947     * ({@link Javadoc}).
1948     * </p>
1949     *
1950     * @return a new unparented method reference parameter node
1951     * @since 3.0
1952     */

1953    public MethodRefParameter newMethodRefParameter() {
1954        MethodRefParameter result = new MethodRefParameter(this);
1955        return result;
1956    }
1957
1958    //=============================== STATEMENTS ===========================
1959
/**
1960     * Creates a new unparented local variable declaration statement node
1961     * owned by this AST, for the given variable declaration fragment.
1962     * By default, there are no modifiers and the base type is unspecified
1963     * (but legal).
1964     * <p>
1965     * This method can be used to convert a variable declaration fragment
1966     * (<code>VariableDeclarationFragment</code>) into a statement
1967     * (<code>Statement</code>) by wrapping it. Additional variable
1968     * declaration fragments can be added afterwards.
1969     * </p>
1970     *
1971     * @param fragment the variable declaration fragment
1972     * @return a new unparented variable declaration statement node
1973     * @exception IllegalArgumentException if:
1974     * <ul>
1975     * <li>the node belongs to a different AST</li>
1976     * <li>the node already has a parent</li>
1977     * <li>a cycle in would be created</li>
1978     * <li>the variable declaration fragment is null</li>
1979     * </ul>
1980     */

1981    public VariableDeclarationStatement
1982            newVariableDeclarationStatement(VariableDeclarationFragment fragment) {
1983        if (fragment == null) {
1984            throw new IllegalArgumentException JavaDoc();
1985        }
1986        VariableDeclarationStatement result =
1987            new VariableDeclarationStatement(this);
1988        result.fragments().add(fragment);
1989        return result;
1990    }
1991
1992    /**
1993     * Creates a new unparented local type declaration statement node
1994     * owned by this AST, for the given type declaration.
1995     * <p>
1996     * This method can be used to convert a type declaration
1997     * (<code>TypeDeclaration</code>) into a statement
1998     * (<code>Statement</code>) by wrapping it.
1999     * </p>
2000     *
2001     * @param decl the type declaration
2002     * @return a new unparented local type declaration statement node
2003     * @exception IllegalArgumentException if:
2004     * <ul>
2005     * <li>the node belongs to a different AST</li>
2006     * <li>the node already has a parent</li>
2007     * <li>a cycle in would be created</li>
2008     * </ul>
2009     */

2010    public TypeDeclarationStatement
2011            newTypeDeclarationStatement(TypeDeclaration decl) {
2012        TypeDeclarationStatement result = new TypeDeclarationStatement(this);
2013        result.setDeclaration(decl);
2014        return result;
2015    }
2016
2017    /**
2018     * Creates a new unparented local type declaration statement node
2019     * owned by this AST, for the given type declaration.
2020     * <p>
2021     * This method can be used to convert any kind of type declaration
2022     * (<code>AbstractTypeDeclaration</code>) into a statement
2023     * (<code>Statement</code>) by wrapping it.
2024     * </p>
2025     *
2026     * @param decl the type declaration
2027     * @return a new unparented local type declaration statement node
2028     * @exception IllegalArgumentException if:
2029     * <ul>
2030     * <li>the node belongs to a different AST</li>
2031     * <li>the node already has a parent</li>
2032     * <li>a cycle in would be created</li>
2033     * </ul>
2034     * @since 3.0
2035     */

2036    public TypeDeclarationStatement
2037            newTypeDeclarationStatement(AbstractTypeDeclaration decl) {
2038        TypeDeclarationStatement result = new TypeDeclarationStatement(this);
2039        if (this.apiLevel == AST.JLS2) {
2040            result.internalSetTypeDeclaration((TypeDeclaration) decl);
2041        }
2042        if (this.apiLevel >= AST.JLS3) {
2043            result.setDeclaration(decl);
2044        }
2045        return result;
2046    }
2047
2048    /**
2049     * Creates an unparented block node owned by this AST, for an empty list
2050     * of statements.
2051     *
2052     * @return a new unparented, empty block node
2053     */

2054    public Block newBlock() {
2055        return new Block(this);
2056    }
2057
2058    /**
2059     * Creates an unparented continue statement node owned by this AST.
2060     * The continue statement has no label.
2061     *
2062     * @return a new unparented continue statement node
2063     */

2064    public ContinueStatement newContinueStatement() {
2065        return new ContinueStatement(this);
2066    }
2067
2068    /**
2069     * Creates an unparented break statement node owned by this AST.
2070     * The break statement has no label.
2071     *
2072     * @return a new unparented break statement node
2073     */

2074    public BreakStatement newBreakStatement() {
2075        return new BreakStatement(this);
2076    }
2077
2078    /**
2079     * Creates a new unparented expression statement node owned by this AST,
2080     * for the given expression.
2081     * <p>
2082     * This method can be used to convert an expression
2083     * (<code>Expression</code>) into a statement (<code>Type</code>)
2084     * by wrapping it. Note, however, that the result is only legal for
2085     * limited expression types, including method invocations, assignments,
2086     * and increment/decrement operations.
2087     * </p>
2088     *
2089     * @param expression the expression
2090     * @return a new unparented statement node
2091     * @exception IllegalArgumentException if:
2092     * <ul>
2093     * <li>the node belongs to a different AST</li>
2094     * <li>the node already has a parent</li>
2095     * <li>a cycle in would be created</li>
2096     * </ul>
2097     */

2098    public ExpressionStatement newExpressionStatement(Expression expression) {
2099        ExpressionStatement result = new ExpressionStatement(this);
2100        result.setExpression(expression);
2101        return result;
2102    }
2103
2104    /**
2105     * Creates a new unparented if statement node owned by this AST.
2106     * By default, the expression is unspecified (but legal),
2107     * the then statement is an empty block, and there is no else statement.
2108     *
2109     * @return a new unparented if statement node
2110     */

2111    public IfStatement newIfStatement() {
2112        return new IfStatement(this);
2113    }
2114
2115    /**
2116     * Creates a new unparented while statement node owned by this AST.
2117     * By default, the expression is unspecified (but legal), and
2118     * the body statement is an empty block.
2119     *
2120     * @return a new unparented while statement node
2121     */

2122    public WhileStatement newWhileStatement() {
2123        return new WhileStatement(this);
2124    }
2125
2126    /**
2127     * Creates a new unparented do statement node owned by this AST.
2128     * By default, the expression is unspecified (but legal), and
2129     * the body statement is an empty block.
2130     *
2131     * @return a new unparented do statement node
2132     */

2133    public DoStatement newDoStatement() {
2134        return new DoStatement(this);
2135    }
2136
2137    /**
2138     * Creates a new unparented try statement node owned by this AST.
2139     * By default, the try statement has an empty block, no catch
2140     * clauses, and no finally block.
2141     *
2142     * @return a new unparented try statement node
2143     */

2144    public TryStatement newTryStatement() {
2145        return new TryStatement(this);
2146    }
2147
2148    /**
2149     * Creates a new unparented catch clause node owned by this AST.
2150     * By default, the catch clause declares an unspecified, but legal,
2151     * exception declaration and has an empty block.
2152     *
2153     * @return a new unparented catch clause node
2154     */

2155    public CatchClause newCatchClause() {
2156        return new CatchClause(this);
2157    }
2158
2159    /**
2160     * Creates a new unparented return statement node owned by this AST.
2161     * By default, the return statement has no expression.
2162     *
2163     * @return a new unparented return statement node
2164     */

2165    public ReturnStatement newReturnStatement() {
2166        return new ReturnStatement(this);
2167    }
2168
2169    /**
2170     * Creates a new unparented throw statement node owned by this AST.
2171     * By default, the expression is unspecified, but legal.
2172     *
2173     * @return a new unparented throw statement node
2174     */

2175    public ThrowStatement newThrowStatement() {
2176        return new ThrowStatement(this);
2177    }
2178
2179    /**
2180     * Creates a new unparented assert statement node owned by this AST.
2181     * By default, the first expression is unspecified, but legal, and has no
2182     * message expression.
2183     *
2184     * @return a new unparented assert statement node
2185     */

2186    public AssertStatement newAssertStatement() {
2187        return new AssertStatement(this);
2188    }
2189
2190    /**
2191     * Creates a new unparented empty statement node owned by this AST.
2192     *
2193     * @return a new unparented empty statement node
2194     */

2195    public EmptyStatement newEmptyStatement() {
2196        return new EmptyStatement(this);
2197    }
2198
2199    /**
2200     * Creates a new unparented labeled statement node owned by this AST.
2201     * By default, the label and statement are both unspecified, but legal.
2202     *
2203     * @return a new unparented labeled statement node
2204     */

2205    public LabeledStatement newLabeledStatement() {
2206        return new LabeledStatement(this);
2207    }
2208
2209    /**
2210     * Creates a new unparented switch statement node owned by this AST.
2211     * By default, the expression is unspecified, but legal, and there are
2212     * no statements or switch cases.
2213     *
2214     * @return a new unparented labeled statement node
2215     */

2216    public SwitchStatement newSwitchStatement() {
2217        return new SwitchStatement(this);
2218    }
2219
2220    /**
2221     * Creates a new unparented switch case statement node owned by
2222     * this AST. By default, the expression is unspecified, but legal.
2223     *
2224     * @return a new unparented switch case node
2225     */

2226    public SwitchCase newSwitchCase() {
2227        return new SwitchCase(this);
2228    }
2229
2230    /**
2231     * Creates a new unparented synchronized statement node owned by this AST.
2232     * By default, the expression is unspecified, but legal, and the body is
2233     * an empty block.
2234     *
2235     * @return a new unparented synchronized statement node
2236     */

2237    public SynchronizedStatement newSynchronizedStatement() {
2238        return new SynchronizedStatement(this);
2239    }
2240
2241    /**
2242     * Creates a new unparented for statement node owned by this AST.
2243     * By default, there are no initializers, no condition expression,
2244     * no updaters, and the body is an empty block.
2245     *
2246     * @return a new unparented for statement node
2247     */

2248    public ForStatement newForStatement() {
2249        return new ForStatement(this);
2250    }
2251
2252    /**
2253     * Creates a new unparented enhanced for statement node owned by this AST.
2254     * By default, the paramter and expression are unspecified
2255     * but legal subtrees, and the body is an empty block.
2256     *
2257     * @return a new unparented throw statement node
2258     * @exception UnsupportedOperationException if this operation is used in
2259     * a JLS2 AST
2260     * @since 3.1
2261     */

2262    public EnhancedForStatement newEnhancedForStatement() {
2263        return new EnhancedForStatement(this);
2264    }
2265
2266    //=============================== EXPRESSIONS ===========================
2267
/**
2268     * Creates and returns a new unparented string literal node for
2269     * the empty string literal.
2270     *
2271     * @return a new unparented string literal node
2272     */

2273    public StringLiteral newStringLiteral() {
2274        return new StringLiteral(this);
2275    }
2276
2277
2278    /**
2279     * Creates and returns a new unparented character literal node.
2280     * Initially the node has an unspecified character literal.
2281     *
2282     * @return a new unparented character literal node
2283     */

2284    public CharacterLiteral newCharacterLiteral() {
2285        return new CharacterLiteral(this);
2286    }
2287
2288    /**
2289     * Creates and returns a new unparented number literal node.
2290     *
2291     * @param literal the token for the numeric literal as it would
2292     * appear in Java source code
2293     * @return a new unparented number literal node
2294     * @exception IllegalArgumentException if the literal is null
2295     */

2296    public NumberLiteral newNumberLiteral(String JavaDoc literal) {
2297        if (literal == null) {
2298            throw new IllegalArgumentException JavaDoc();
2299        }
2300        NumberLiteral result = new NumberLiteral(this);
2301        result.setToken(literal);
2302        return result;
2303    }
2304
2305    /**
2306     * Creates and returns a new unparented number literal node.
2307     * Initially the number literal token is <code>"0"</code>.
2308     *
2309     * @return a new unparented number literal node
2310     */

2311    public NumberLiteral newNumberLiteral() {
2312        NumberLiteral result = new NumberLiteral(this);
2313        return result;
2314    }
2315
2316    /**
2317     * Creates and returns a new unparented null literal node.
2318     *
2319     * @return a new unparented null literal node
2320     */

2321    public NullLiteral newNullLiteral() {
2322        return new NullLiteral(this);
2323    }
2324
2325    /**
2326     * Creates and returns a new unparented boolean literal node.
2327     * <p>
2328     * For example, the assignment expression <code>foo = true</code>
2329     * is generated by the following snippet:
2330     * <code>
2331     * <pre>
2332     * Assignment e= ast.newAssignment();
2333     * e.setLeftHandSide(ast.newSimpleName("foo"));
2334     * e.setRightHandSide(ast.newBooleanLiteral(true));
2335     * </pre>
2336     * </code>
2337     * </p>
2338     *
2339     * @param value the boolean value
2340     * @return a new unparented boolean literal node
2341     */

2342    public BooleanLiteral newBooleanLiteral(boolean value) {
2343        BooleanLiteral result = new BooleanLiteral(this);
2344        result.setBooleanValue(value);
2345        return result;
2346    }
2347
2348    /**
2349     * Creates and returns a new unparented assignment expression node
2350     * owned by this AST. By default, the assignment operator is "=" and
2351     * the left and right hand side expressions are unspecified, but
2352     * legal, names.
2353     *
2354     * @return a new unparented assignment expression node
2355     */

2356    public Assignment newAssignment() {
2357        Assignment result = new Assignment(this);
2358        return result;
2359    }
2360
2361    /**
2362     * Creates an unparented method invocation expression node owned by this
2363     * AST. By default, the name of the method is unspecified (but legal)
2364     * there is no receiver expression, no type arguments, and the list of
2365     * arguments is empty.
2366     *
2367     * @return a new unparented method invocation expression node
2368     */

2369    public MethodInvocation newMethodInvocation() {
2370        MethodInvocation result = new MethodInvocation(this);
2371        return result;
2372    }
2373
2374    /**
2375     * Creates an unparented "super" method invocation expression node owned by
2376     * this AST. By default, the name of the method is unspecified (but legal)
2377     * there is no qualifier, no type arguments, and the list of arguments is empty.
2378     *
2379     * @return a new unparented "super" method invocation
2380     * expression node
2381     */

2382    public SuperMethodInvocation newSuperMethodInvocation() {
2383        SuperMethodInvocation result = new SuperMethodInvocation(this);
2384        return result;
2385    }
2386
2387    /**
2388     * Creates an unparented alternate constructor ("this(...);") invocation
2389     * statement node owned by this AST. By default, the lists of arguments
2390     * and type arguments are both empty.
2391     * <p>
2392     * Note that this type of node is a Statement, whereas a regular
2393     * method invocation is an Expression. The only valid use of these
2394     * statements are as the first statement of a constructor body.
2395     * </p>
2396     *
2397     * @return a new unparented alternate constructor invocation statement node
2398     */

2399    public ConstructorInvocation newConstructorInvocation() {
2400        ConstructorInvocation result = new ConstructorInvocation(this);
2401        return result;
2402    }
2403
2404    /**
2405     * Creates an unparented alternate super constructor ("super(...);")
2406     * invocation statement node owned by this AST. By default, there is no
2407     * qualifier, no type arguments, and the list of arguments is empty.
2408     * <p>
2409     * Note that this type of node is a Statement, whereas a regular
2410     * super method invocation is an Expression. The only valid use of these
2411     * statements are as the first statement of a constructor body.
2412     * </p>
2413     *
2414     * @return a new unparented super constructor invocation statement node
2415     */

2416    public SuperConstructorInvocation newSuperConstructorInvocation() {
2417        SuperConstructorInvocation result =
2418            new SuperConstructorInvocation(this);
2419        return result;
2420    }
2421
2422    /**
2423     * Creates a new unparented local variable declaration expression node
2424     * owned by this AST, for the given variable declaration fragment. By
2425     * default, there are no modifiers and the base type is unspecified
2426     * (but legal).
2427     * <p>
2428     * This method can be used to convert a variable declaration fragment
2429     * (<code>VariableDeclarationFragment</code>) into an expression
2430     * (<code>Expression</code>) by wrapping it. Additional variable
2431     * declaration fragments can be added afterwards.
2432     * </p>
2433     *
2434     * @param fragment the first variable declaration fragment
2435     * @return a new unparented variable declaration expression node
2436     * @exception IllegalArgumentException if:
2437     * <ul>
2438     * <li>the node belongs to a different AST</li>
2439     * <li>the node already has a parent</li>
2440     * <li>a cycle in would be created</li>
2441     * <li>the given fragment is null</li>
2442     * <li>a cycle in would be created</li>
2443     * </ul>
2444     */

2445    public VariableDeclarationExpression
2446            newVariableDeclarationExpression(VariableDeclarationFragment fragment) {
2447        if (fragment == null) {
2448            throw new IllegalArgumentException JavaDoc();
2449        }
2450        VariableDeclarationExpression result =
2451            new VariableDeclarationExpression(this);
2452        result.fragments().add(fragment);
2453        return result;
2454    }
2455
2456    /**
2457     * Creates a new unparented field declaration node owned by this AST,
2458     * for the given variable declaration fragment. By default, there are no
2459     * modifiers, no doc comment, and the base type is unspecified
2460     * (but legal).
2461     * <p>
2462     * This method can be used to wrap a variable declaration fragment
2463     * (<code>VariableDeclarationFragment</code>) into a field declaration
2464     * suitable for inclusion in the body of a type declaration
2465     * (<code>FieldDeclaration</code> implements <code>BodyDeclaration</code>).
2466     * Additional variable declaration fragments can be added afterwards.
2467     * </p>
2468     *
2469     * @param fragment the variable declaration fragment
2470     * @return a new unparented field declaration node
2471     * @exception IllegalArgumentException if:
2472     * <ul>
2473     * <li>the node belongs to a different AST</li>
2474     * <li>the node already has a parent</li>
2475     * <li>a cycle in would be created</li>
2476     * <li>the given fragment is null</li>
2477     * </ul>
2478     */

2479    public FieldDeclaration newFieldDeclaration(VariableDeclarationFragment fragment) {
2480        if (fragment == null) {
2481            throw new IllegalArgumentException JavaDoc();
2482        }
2483        FieldDeclaration result = new FieldDeclaration(this);
2484        result.fragments().add(fragment);
2485        return result;
2486    }
2487
2488    /**
2489     * Creates and returns a new unparented "this" expression node
2490     * owned by this AST. By default, there is no qualifier.
2491     *
2492     * @return a new unparented "this" expression node
2493     */

2494    public ThisExpression newThisExpression() {
2495        ThisExpression result = new ThisExpression(this);
2496        return result;
2497    }
2498
2499    /**
2500     * Creates and returns a new unparented field access expression node
2501     * owned by this AST. By default, the expression and field are both
2502     * unspecified, but legal, names.
2503     *
2504     * @return a new unparented field access expression node
2505     */

2506    public FieldAccess newFieldAccess() {
2507        FieldAccess result = new FieldAccess(this);
2508        return result;
2509    }
2510
2511    /**
2512     * Creates and returns a new unparented super field access expression node
2513     * owned by this AST. By default, the expression and field are both
2514     * unspecified, but legal, names.
2515     *
2516     * @return a new unparented super field access expression node
2517     */

2518    public SuperFieldAccess newSuperFieldAccess() {
2519        SuperFieldAccess result = new SuperFieldAccess(this);
2520        return result;
2521    }
2522
2523    /**
2524     * Creates and returns a new unparented type literal expression node
2525     * owned by this AST. By default, the type is unspecified (but legal).
2526     *
2527     * @return a new unparented type literal node
2528     */

2529    public TypeLiteral newTypeLiteral() {
2530        TypeLiteral result = new TypeLiteral(this);
2531        return result;
2532    }
2533
2534    /**
2535     * Creates and returns a new unparented cast expression node
2536     * owned by this AST. By default, the type and expression are unspecified
2537     * (but legal).
2538     *
2539     * @return a new unparented cast expression node
2540     */

2541    public CastExpression newCastExpression() {
2542        CastExpression result = new CastExpression(this);
2543        return result;
2544    }
2545
2546    /**
2547     * Creates and returns a new unparented parenthesized expression node
2548     * owned by this AST. By default, the expression is unspecified (but legal).
2549     *
2550     * @return a new unparented parenthesized expression node
2551     */

2552    public ParenthesizedExpression newParenthesizedExpression() {
2553        ParenthesizedExpression result = new ParenthesizedExpression(this);
2554        return result;
2555    }
2556
2557    /**
2558     * Creates and returns a new unparented infix expression node
2559     * owned by this AST. By default, the operator and left and right
2560     * operand are unspecified (but legal), and there are no extended
2561     * operands.
2562     *
2563     * @return a new unparented infix expression node
2564     */

2565    public InfixExpression newInfixExpression() {
2566        InfixExpression result = new InfixExpression(this);
2567        return result;
2568    }
2569
2570    /**
2571     * Creates and returns a new unparented instanceof expression node
2572     * owned by this AST. By default, the operator and left and right
2573     * operand are unspecified (but legal).
2574     *
2575     * @return a new unparented instanceof expression node
2576     */

2577    public InstanceofExpression newInstanceofExpression() {
2578        InstanceofExpression result = new InstanceofExpression(this);
2579        return result;
2580    }
2581
2582    /**
2583     * Creates and returns a new unparented postfix expression node
2584     * owned by this AST. By default, the operator and operand are
2585     * unspecified (but legal).
2586     *
2587     * @return a new unparented postfix expression node
2588     */

2589    public PostfixExpression newPostfixExpression() {
2590        PostfixExpression result = new PostfixExpression(this);
2591        return result;
2592    }
2593
2594    /**
2595     * Creates and returns a new unparented prefix expression node
2596     * owned by this AST. By default, the operator and operand are
2597     * unspecified (but legal).
2598     *
2599     * @return a new unparented prefix expression node
2600     */

2601    public PrefixExpression newPrefixExpression() {
2602        PrefixExpression result = new PrefixExpression(this);
2603        return result;
2604    }
2605
2606    /**
2607     * Creates and returns a new unparented array access expression node
2608     * owned by this AST. By default, the array and index expression are
2609     * both unspecified (but legal).
2610     *
2611     * @return a new unparented array access expression node
2612     */

2613    public ArrayAccess newArrayAccess() {
2614        ArrayAccess result = new ArrayAccess(this);
2615        return result;
2616    }
2617
2618    /**
2619     * Creates and returns a new unparented array creation expression node
2620     * owned by this AST. By default, the array type is an unspecified
2621     * 1-dimensional array, the list of dimensions is empty, and there is no
2622     * array initializer.
2623     * <p>
2624     * Examples:
2625     * <code>
2626     * <pre>
2627     * // new String[len]
2628     * ArrayCreation ac1 = ast.newArrayCreation();
2629     * ac1.setType(
2630     * ast.newArrayType(
2631     * ast.newSimpleType(ast.newSimpleName("String"))));
2632     * ac1.dimensions().add(ast.newSimpleName("len"));
2633     *
2634     * // new double[7][24][]
2635     * ArrayCreation ac2 = ast.newArrayCreation();
2636     * ac2.setType(
2637     * ast.newArrayType(
2638     * ast.newPrimitiveType(PrimitiveType.DOUBLE), 3));
2639     * ac2.dimensions().add(ast.newNumberLiteral("7"));
2640     * ac2.dimensions().add(ast.newNumberLiteral("24"));
2641     *
2642     * // new int[] {1, 2}
2643     * ArrayCreation ac3 = ast.newArrayCreation();
2644     * ac3.setType(
2645     * ast.newArrayType(
2646     * ast.newPrimitiveType(PrimitiveType.INT)));
2647     * ArrayInitializer ai = ast.newArrayInitializer();
2648     * ac3.setInitializer(ai);
2649     * ai.expressions().add(ast.newNumberLiteral("1"));
2650     * ai.expressions().add(ast.newNumberLiteral("2"));
2651     * </pre>
2652     * </code>
2653     * </p>
2654     *
2655     * @return a new unparented array creation expression node
2656     */

2657    public ArrayCreation newArrayCreation() {
2658        ArrayCreation result = new ArrayCreation(this);
2659        return result;
2660    }
2661
2662    /**
2663     * Creates and returns a new unparented class instance creation
2664     * ("new") expression node owned by this AST. By default,
2665     * there is no qualifying expression, no type parameters,
2666     * an unspecified (but legal) type name, an empty list of
2667     * arguments, and does not declare an anonymous class declaration.
2668     *
2669     * @return a new unparented class instance creation expression node
2670     */

2671    public ClassInstanceCreation newClassInstanceCreation() {
2672        ClassInstanceCreation result = new ClassInstanceCreation(this);
2673        return result;
2674    }
2675
2676    /**
2677     * Creates and returns a new unparented anonymous class declaration
2678     * node owned by this AST. By default, the body declaration list is empty.
2679     *
2680     * @return a new unparented anonymous class declaration node
2681     */

2682    public AnonymousClassDeclaration newAnonymousClassDeclaration() {
2683        AnonymousClassDeclaration result = new AnonymousClassDeclaration(this);
2684        return result;
2685    }
2686
2687    /**
2688     * Creates and returns a new unparented array initializer node
2689     * owned by this AST. By default, the initializer has no expressions.
2690     *
2691     * @return a new unparented array initializer node
2692     */

2693    public ArrayInitializer newArrayInitializer() {
2694        ArrayInitializer result = new ArrayInitializer(this);
2695        return result;
2696    }
2697
2698    /**
2699     * Creates and returns a new unparented conditional expression node
2700     * owned by this AST. By default, the condition and both expressions
2701     * are unspecified (but legal).
2702     *
2703     * @return a new unparented array conditional expression node
2704     */

2705    public ConditionalExpression newConditionalExpression() {
2706        ConditionalExpression result = new ConditionalExpression(this);
2707        return result;
2708    }
2709
2710    //=============================== ANNOTATIONS ====================
2711

2712    /**
2713     * Creates and returns a new unparented normal annotation node with
2714     * an unspecified type name and an empty list of member value
2715     * pairs.
2716     *
2717     * @return a new unparented normal annotation node
2718     * @exception UnsupportedOperationException if this operation is used in
2719     * a JLS2 AST
2720     * @since 3.1
2721     */

2722    public NormalAnnotation newNormalAnnotation() {
2723        NormalAnnotation result = new NormalAnnotation(this);
2724        return result;
2725    }
2726
2727    /**
2728     * Creates and returns a new unparented marker annotation node with
2729     * an unspecified type name.
2730     *
2731     * @return a new unparented marker annotation node
2732     * @exception UnsupportedOperationException if this operation is used in
2733     * a JLS2 AST
2734     * @since 3.1
2735     */

2736    public MarkerAnnotation newMarkerAnnotation() {
2737        MarkerAnnotation result = new MarkerAnnotation(this);
2738        return result;
2739    }
2740
2741    /**
2742     * Creates and returns a new unparented single member annotation node with
2743     * an unspecified type name and value.
2744     *
2745     * @return a new unparented single member annotation node
2746     * @exception UnsupportedOperationException if this operation is used in
2747     * a JLS2 AST
2748     * @since 3.1
2749     */

2750    public SingleMemberAnnotation newSingleMemberAnnotation() {
2751        SingleMemberAnnotation result = new SingleMemberAnnotation(this);
2752        return result;
2753    }
2754
2755    /**
2756     * Creates and returns a new unparented member value pair node with
2757     * an unspecified member name and value.
2758     *
2759     * @return a new unparented member value pair node
2760     * @exception UnsupportedOperationException if this operation is used in
2761     * a JLS2 AST
2762     * @since 3.1
2763     */

2764    public MemberValuePair newMemberValuePair() {
2765        MemberValuePair result = new MemberValuePair(this);
2766        return result;
2767    }
2768
2769    /**
2770     * Enables the recording of changes to the given compilation
2771     * unit and its descendents. The compilation unit must have
2772     * been created by <code>ASTParser</code> and still be in
2773     * its original state. Once recording is on,
2774     * arbitrary changes to the subtree rooted at the compilation
2775     * unit are recorded internally. Once the modification has
2776     * been completed, call <code>rewrite</code> to get an object
2777     * representing the corresponding edits to the original
2778     * source code string.
2779     *
2780     * @exception IllegalArgumentException if this compilation unit is
2781     * marked as unmodifiable, or if this compilation unit has already
2782     * been tampered with, or if recording has already been enabled,
2783     * or if <code>root</code> is not owned by this AST
2784     * @see CompilationUnit#recordModifications()
2785     * @since 3.0
2786     */

2787    void recordModifications(CompilationUnit root) {
2788        if(this.modificationCount != this.originalModificationCount) {
2789            throw new IllegalArgumentException JavaDoc("AST is already modified"); //$NON-NLS-1$
2790
} else if(this.rewriter != null) {
2791            throw new IllegalArgumentException JavaDoc("AST modifications are already recorded"); //$NON-NLS-1$
2792
} else if((root.getFlags() & ASTNode.PROTECT) != 0) {
2793            throw new IllegalArgumentException JavaDoc("Root node is unmodifiable"); //$NON-NLS-1$
2794
} else if(root.getAST() != this) {
2795            throw new IllegalArgumentException JavaDoc("Root node is not owned by this ast"); //$NON-NLS-1$
2796
}
2797
2798        this.rewriter = new InternalASTRewrite(root);
2799        this.setEventHandler(this.rewriter);
2800    }
2801
2802    /**
2803     * Converts all modifications recorded into an object
2804     * representing the corresponding text edits to the
2805     * given document containing the original source
2806     * code for the compilation unit that gave rise to
2807     * this AST.
2808     *
2809     * @param document original document containing source code
2810     * for the compilation unit
2811     * @param options the table of formatter options
2812     * (key type: <code>String</code>; value type: <code>String</code>);
2813     * or <code>null</code> to use the standard global options
2814     * {@link JavaCore#getOptions() JavaCore.getOptions()}.
2815     * @return text edit object describing the changes to the
2816     * document corresponding to the recorded AST modifications
2817     * @exception IllegalArgumentException if the document passed is
2818     * <code>null</code> or does not correspond to this AST
2819     * @exception IllegalStateException if <code>recordModifications</code>
2820     * was not called to enable recording
2821     * @see CompilationUnit#rewrite(IDocument, Map)
2822     * @since 3.0
2823     */

2824    TextEdit rewrite(IDocument document, Map JavaDoc options) {
2825        if (document == null) {
2826            throw new IllegalArgumentException JavaDoc();
2827        }
2828        if (this.rewriter == null) {
2829            throw new IllegalStateException JavaDoc("Modifications record is not enabled"); //$NON-NLS-1$
2830
}
2831        return this.rewriter.rewriteAST(document, options);
2832    }
2833
2834    /**
2835     * Returns true if the ast tree was created with bindings, false otherwise
2836     *
2837     * @return true if the ast tree was created with bindings, false otherwise
2838     * @since 3.3
2839     */

2840    public boolean hasResolvedBindings() {
2841        return (this.bits & RESOLVED_BINDINGS) != 0;
2842    }
2843
2844    /**
2845     * Returns true if the ast tree was created with statements recovery, false otherwise
2846     *
2847     * @return true if the ast tree was created with statements recovery, false otherwise
2848     * @since 3.3
2849     */

2850    public boolean hasStatementsRecovery() {
2851        return (this.bits & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0;
2852    }
2853
2854    /**
2855     * Returns true if the ast tree was created with bindings recovery, false otherwise
2856     *
2857     * @return true if the ast tree was created with bindings recovery, false otherwise
2858     * @since 3.3
2859     */

2860    public boolean hasBindingsRecovery() {
2861        return (this.bits & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
2862    }
2863
2864    void setFlag(int newValue) {
2865        this.bits |= newValue;
2866    }
2867}
2868
2869
Popular Tags