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      * ou