1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.InvocationTargetException;
16 import java.util.ArrayList;
17 import java.util.List;
19 import java.util.StringTokenizer;
21 import org.eclipse.core.runtime.IProgressMonitor;
23 import net.sourceforge.phpdt.core.IClassFile;
24 import net.sourceforge.phpdt.core.ICompilationUnit;
25 import net.sourceforge.phpdt.core.IJavaProject;
26 import net.sourceforge.phpdt.core.JavaCore;
27 import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
28 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
29 import org.eclipse.jface.text.IDocument;
30 import org.eclipse.text.edits.TextEdit;
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
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.
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.
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.
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.
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:
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);
82 * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
83 * an alternative way to describe and serialize changes to a
87 * Clients may create instances of this class using {@link #newAST(int)},
88 * but this class is not intended to be subclassed.
94 * @noinstantiate This class is not intended to be instantiated by clients.
96 public final class AST {
98 * Constant for indicating the AST API that handles JLS2.
99 * This API is capable of handling all constructs
100 * in the Java language as described in the Java Language
101 * Specification, Second Edition (JLS2).
102 * JLS2 is a superset of all earlier versions of the
103 * Java language, and the JLS2 API can be used to manipulate
104 * programs written in all versions of the Java language
105 * up to and including J2SE 1.4.
108 * @deprecated Clients should use the {@link #JLS3} AST API instead.
110 public static final int JLS2 = 2;
113 * Internal synonym for {@link #JLS2}. Use to alleviate
114 * deprecation warnings.
117 /*package*/ static final int JLS2_INTERNAL = JLS2;
120 * Constant for indicating the AST API that handles JLS3.
121 * This API is capable of handling all constructs in the
122 * Java language as described in the Java Language
123 * Specification, Third Edition (JLS3).
124 * JLS3 is a superset of all earlier versions of the
125 * Java language, and the JLS3 API can be used to manipulate
126 * programs written in all versions of the Java language
127 * up to and including J2SE 5 (aka JDK 1.5).
131 public static final int JLS3 = 3;
134 * The binding resolver for this AST. Initially a binding resolver that
135 * does not resolve names at all.
137 private BindingResolver resolver = new BindingResolver();
140 * The event handler for this AST.
141 * Initially an event handler that does not nothing.
144 private NodeEventHandler eventHandler = new NodeEventHandler();
147 * Level of AST API supported by this AST.
153 * Internal modification count; initially 0; increases monotonically
154 * <b>by one or more</b> as the AST is successively modified.
156 private long modificationCount = 0;
159 * Internal original modification count; value is equals to <code>
160 * modificationCount</code> at the end of the parse (<code>ASTParser
161 * </code>). If this ast is not created with a parser then value is 0.
164 private long originalModificationCount = 0;
167 * When disableEvents > 0, events are not reported and
168 * the modification count stays fixed.
170 * This mechanism is used in lazy initialization of a node
171 * to prevent events from being reported for the modification
172 * of the node as well as for the creation of the missing child.
176 private int disableEvents = 0;
179 * Internal object unique to the AST instance. Readers must synchronize on
180 * this object when the modifying instance fields.
183 private final Object internalASTLock = new Object();
186 * Java Scanner used to validate preconditions for the creation of specific nodes
187 * like CharacterLiteral, NumberLiteral, StringLiteral or SimpleName.
192 * Internal ast rewriter used to record ast modification when record mode is enabled.
194 InternalASTRewrite rewriter;
197 * Default value of <code>flag<code> when a new node is created.
199 private int defaultNodeFlag = 0;
202 * Creates a new Java abstract syntax tree
203 * (AST) following the specified set of API rules.
205 * @param level the API level; one of the LEVEL constants
208 private AST(int level) {
209 if ((level != AST.JLS2)
210 && (level != AST.JLS3)) {
211 throw new IllegalArgumentException();
213 this.apiLevel = level;
214 // initialize a scanner
215 this.scanner = new Scanner(
219 ClassFileConstants.JDK1_3 /*sourceLevel*/,
220 ClassFileConstants.JDK1_5 /*complianceLevel*/,
222 null/*taskPriorities*/,
223 true/*taskCaseSensitive*/);
227 * Creates a new, empty abstract syntax tree using default options.
229 * @see JavaCore#getDefaultOptions()
230 * @deprecated Clients should port their code to use the new JLS3 AST API and call
231 * {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
234 this(JavaCore.getDefaultOptions());
240 * This method converts the given internal compiler AST for the given source string
241 * into a compilation unit. This method is not intended to be called by clients.
244 * @param level the API level; one of the LEVEL constants
245 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
246 * @param options compiler options
247 * @param workingCopy the working copy that the AST is created from
248 * @param monitor the progress monitor used to report progress and request cancellation,
249 * or <code>null</code> if none
250 * @param isResolved whether the given compilation unit declaration is resolved
251 * @return the compilation unit node
253 * @noreference This method is not intended to be referenced by clients.
255 public static CompilationUnit convertCompilationUnit(
257 net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
260 net.sourceforge.phpdt.internal.core.CompilationUnit workingCopy,
262 IProgressMonitor monitor) {
264 ASTConverter converter = new ASTConverter(options, isResolved, monitor);
265 AST ast = AST.newAST(level);
266 int savedDefaultNodeFlag = ast.getDefaultNodeFlag();
267 ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
268 BindingResolver resolver = null;
270 resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false);
271 ((DefaultBindingResolver) resolver).isRecoveringBindings = (reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
272 ast.setFlag(AST.RESOLVED_BINDINGS);
274 resolver = new BindingResolver();
276 ast.setFlag(reconcileFlags);
277 ast.setBindingResolver(resolver);
278 converter.setAST(ast);
280 CompilationUnit unit = converter.convert(compilationUnitDeclaration, workingCopy.getContents());
281 unit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions());
282 unit.setTypeRoot(workingCopy.originalFromClone());
283 ast.setDefaultNodeFlag(savedDefaultNodeFlag);
290 * This method converts the given internal compiler AST for the given source string
291 * into a compilation unit. This method is not intended to be called by clients.
294 * @param level the API level; one of the LEVEL constants
295 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
296 * @param source the string of the Java compilation unit
297 * @param options compiler options
298 * @param workingCopy the working copy that the AST is created from
299 * @param monitor the progress monitor used to report progress and request cancellation,
300 * or <code>null</code> if none
301 * @param isResolved whether the given compilation unit declaration is resolved
302 * @return the compilation unit node
303 * @deprecated Use org.eclipse.jdt.core.dom.AST.convertCompilationUnit(int, CompilationUnitDeclaration, Map, boolean, CompilationUnit, int, IProgressMonitor) instead
304 * @noreference This method is not intended to be referenced by clients.
306 public static CompilationUnit convertCompilationUnit(
308 net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
312 net.sourceforge.phpdt.internal.core.CompilationUnit workingCopy,
314 IProgressMonitor monitor) {
319 * Creates a new, empty abstract syntax tree using the given options.
321 * Following option keys are significant:
323 * <li><code>"org.eclipse.jdt.core.compiler.source"</code> -
324 * indicates source compatibility mode (as per <code>JavaCore</code>);
325 * <code>"1.3"</code> means the source code is as per JDK 1.3;
326 * <code>"1.4"</code> means the source code is as per JDK 1.4
327 * (<code>"assert"</code> is now a keyword);
328 * <code>"1.5"</code> means the source code is as per JDK 1.5
329 * (<code>"enum"</code> is now a keyword);
330 * additional legal values may be added later. </li>
332 * Options other than the above are ignored.
335 * @param options the table of options (key type: <code>String</code>;
336 * value type: <code>String</code>)
337 * @see JavaCore#getDefaultOptions()
338 * @deprecated Clients should port their code to use the new JLS3 AST API and call
339 * {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
341 public AST(Map options) {
343 Object sourceLevelOption = options.get(JavaCore.COMPILER_SOURCE);
344 long sourceLevel = ClassFileConstants.JDK1_3;
345 if (JavaCore.VERSION_1_4.equals(sourceLevelOption)) {
346 sourceLevel = ClassFileConstants.JDK1_4;
347 } else if (JavaCore.VERSION_1_5.equals(sourceLevelOption)) {
348 sourceLevel = ClassFileConstants.JDK1_5;
350 Object complianceLevelOption = options.get(JavaCore.COMPILER_COMPLIANCE);
351 long complianceLevel = ClassFileConstants.JDK1_3;
352 if (JavaCore.VERSION_1_4.equals(complianceLevelOption)) {
353 complianceLevel = ClassFileConstants.JDK1_4;
354 } else if (JavaCore.VERSION_1_5.equals(complianceLevelOption)) {
355 complianceLevel = ClassFileConstants.JDK1_5;
357 // override scanner if 1.4 or 1.5 asked for
358 this.scanner = new Scanner(
362 sourceLevel /*sourceLevel*/,
363 complianceLevel /*complianceLevel*/,
365 null/*taskPriorities*/,
366 true/*taskCaseSensitive*/);
370 * Creates a new Java abstract syntax tree
371 * (AST) following the specified set of API rules.
373 * Clients should use this method specifing {@link #JLS3} as the
374 * AST level in all cases, even when dealing with JDK 1.3 or 1.4..
377 * @param level the API level; one of the LEVEL constants
378 * @return new AST instance following the specified set of API rules.
379 * @exception IllegalArgumentException if:
381 * <li>the API level is not one of the LEVEL constants</li>
385 public static AST newAST(int level) {
386 if ((level != AST.JLS2)
387 && (level != AST.JLS3)) {
388 throw new IllegalArgumentException();
390 return new AST(level);
394 * Returns the modification count for this AST. The modification count
395 * is a non-negative value that increases (by 1 or perhaps by more) as
396 * this AST or its nodes are changed. The initial value is unspecified.
398 * The following things count as modifying an AST:
400 * <li>creating a new node owned by this AST,</li>
401 * <li>adding a child to a node owned by this AST,</li>
402 * <li>removing a child from a node owned by this AST,</li>
403 * <li>setting a non-node attribute of a node owned by this AST.</li>
406 * Operations which do not entail creating or modifying existing nodes
407 * do not increase the modification count.
409 * N.B. This method may be called several times in the course
410 * of a single client operation. The only promise is that the modification
411 * count increases monotonically as the AST or its nodes change; there is
412 * no promise that a modifying operation increases the count by exactly 1.
415 * @return the current value (non-negative) of the modification counter of
418 public long modificationCount() {
419 return this.modificationCount;
423 * Return the API level supported by this AST.
425 * @return level the API level; one of the <code>JLS*</code>LEVEL
426 * declared on <code>AST</code>; assume this set is open-ended
429 public int apiLevel() {
430 return this.apiLevel;
434 * Indicates that this AST is about to be modified.
436 * The following things count as modifying an AST:
438 * <li>creating a new node owned by this AST</li>
439 * <li>adding a child to a node owned by this AST</li>
440 * <li>removing a child from a node owned by this AST</li>
441 * <li>setting a non-node attribute of a node owned by this AST</li>.
445 * N.B. This method may be called several times in the course
446 * of a single client operation.
450 // when this method is called during lazy init, events are disabled
451 // and the modification count will not be increased
452 if (this.disableEvents > 0) {
455 // increase the modification count
456 this.modificationCount++;
461 * This method is thread-safe for AST readers.
463 * @see #reenableEvents()
466 final void disableEvents() {
467 synchronized (this.internalASTLock) {
468 // guard against concurrent access by another reader
469 this.disableEvents++;
471 // while disableEvents > 0 no events will be reported, and mod count will stay fixed
476 * This method is thread-safe for AST readers.
478 * @see #disableEvents()
481 final void reenableEvents() {
482 synchronized (this.internalASTLock) {
483 // guard against concurrent access by another reader
484 this.disableEvents--;
489 * Reports that the given node is about to lose a child.
491 * @param node the node about to be modified
492 * @param child the node about to be removed
493 * @param property the child or child list property descriptor
496 void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
497 // IMPORTANT: this method is called by readers during lazy init
498 synchronized (this.internalASTLock) {
499 // guard against concurrent access by a reader doing lazy init
500 if (this.disableEvents > 0) {
501 // doing lazy init OR already processing an event
502 // System.out.println("[BOUNCE DEL]");
509 this.eventHandler.preRemoveChildEvent(node, child, property);
510 // N.B. even if event handler blows up, the AST is not
511 // corrupted since node has not been changed yet
518 * Reports that the given node jsut lost a child.
520 * @param node the node that was modified
521 * @param child the child node that was removed
522 * @param property the child or child list property descriptor
525 void postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
526 // IMPORTANT: this method is called by readers during lazy init
527 synchronized (this.internalASTLock) {
528 // guard against concurrent access by a reader doing lazy init
529 if (this.disableEvents > 0) {
530 // doing lazy init OR already processing an event
531 // System.out.println("[BOUNCE DEL]");
538 this.eventHandler.postRemoveChildEvent(node, child, property);
539 // N.B. even if event handler blows up, the AST is not
540 // corrupted since node has not been changed yet
547 * Reports that the given node is about have a child replaced.
549 * @param node the node about to be modified
550 * @param child the child node about to be removed
551 * @param newChild the replacement child
552 * @param property the child or child list property descriptor
555 void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
556 // IMPORTANT: this method is called by readers during lazy init
557 synchronized (this.internalASTLock) {
558 // guard against concurrent access by a reader doing lazy init
559 if (this.disableEvents > 0) {
560 // doing lazy init OR already processing an event
561 // System.out.println("[BOUNCE REP]");
568 this.eventHandler.preReplaceChildEvent(node, child, newChild, property);
569 // N.B. even if event handler blows up, the AST is not
570 // corrupted since node has not been changed yet
577 * Reports that the given node has just had a child replaced.
579 * @param node the node modified
580 * @param child the child removed
581 * @param newChild the replacement child
582 * @param property the child or child list property descriptor
585 void postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
586 // IMPORTANT: this method is called by readers during lazy init
587 synchronized (this.internalASTLock) {
588 // guard against concurrent access by a reader doing lazy init
589 if (this.disableEvents > 0) {
590 // doing lazy init OR already processing an event
591 // System.out.println("[BOUNCE REP]");
598 this.eventHandler.postReplaceChildEvent(node, child, newChild, property);
599 // N.B. even if event handler blows up, the AST is not
600 // corrupted since node has not been changed yet
607 * Reports that the given node is about to gain a child.
609 * @param node the node that to be modified
610 * @param child the node that to be added as a child
611 * @param property the child or child list property descriptor
614 void preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
615 // IMPORTANT: this method is called by readers during lazy init
616 synchronized (this.internalASTLock) {
617 // guard against concurrent access by a reader doing lazy init
618 if (this.disableEvents > 0) {
619 // doing lazy init OR already processing an event
620 // System.out.println("[BOUNCE ADD]");
627 this.eventHandler.preAddChildEvent(node, child, property);
628 // N.B. even if event handler blows up, the AST is not
629 // corrupted since node has already been changed
636 * Reports that the given node has just gained a child.
638 * @param node the node that was modified
639 * @param child the node that was added as a child
640 * @param property the child or child list property descriptor
643 void postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
644 // IMPORTANT: this method is called by readers during lazy init
645 synchronized (this.internalASTLock) {
646 // guard against concurrent access by a reader doing lazy init
647 if (this.disableEvents > 0) {
648 // doing lazy init OR already processing an event
649 // System.out.println("[BOUNCE ADD]");
656 this.eventHandler.postAddChildEvent(node, child, property);
657 // N.B. even if event handler blows up, the AST is not
658 // corrupted since node has already been changed
665 * Reports that the given node is about to change the value of a
666 * non-child property.
668 * @param node the node to be modified
669 * @param property the property descriptor
672 void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
673 // IMPORTANT: this method is called by readers during lazy init
674 synchronized (this.internalASTLock) {
675 // guard against concurrent access by a reader doing lazy init
676 if (this.disableEvents > 0) {
677 // doing lazy init OR already processing an event
678 // System.out.println("[BOUNCE CHANGE]");
685 this.eventHandler.preValueChangeEvent(node, property);
686 // N.B. even if event handler blows up, the AST is not
687 // corrupted since node has already been changed
694 * Reports that the given node has just changed the value of a
695 * non-child property.
697 * @param node the node that was modified
698 * @param property the property descriptor
701 void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
702 // IMPORTANT: this method is called by readers during lazy init
703 synchronized (this.internalASTLock) {
704 // guard against concurrent access by a reader doing lazy init
705 if (this.disableEvents > 0) {
706 // doing lazy init OR already processing an event
707 // System.out.println("[BOUNCE CHANGE]");
714 this.eventHandler.postValueChangeEvent(node, property);
715 // N.B. even if event handler blows up, the AST is not
716 // corrupted since node has already been changed
723 * Reports that the given node is about to be cloned.
725 * @param node the node to be cloned
728 void preCloneNodeEvent(ASTNode node) {
729 synchronized (this.internalASTLock) {
730 // guard against concurrent access by a reader doing lazy init
731 if (this.disableEvents > 0) {
732 // doing lazy init OR already processing an event
733 // System.out.println("[BOUNCE CLONE]");
740 this.eventHandler.preCloneNodeEvent(node);
741 // N.B. even if event handler blows up, the AST is not
742 // corrupted since node has already been changed
749 * Reports that the given node has just been cloned.
751 * @param node the node that was cloned
752 * @param clone the clone of <code>node</code>
755 void postCloneNodeEvent(ASTNode node, ASTNode clone) {
756 synchronized (this.internalASTLock) {
757 // guard against concurrent access by a reader doing lazy init
758 if (this.disableEvents > 0) {
759 // doing lazy init OR already processing an event
760 // System.out.println("[BOUNCE CLONE]");
767 this.eventHandler.postCloneNodeEvent(node, clone);
768 // N.B. even if event handler blows up, the AST is not
769 // corrupted since node has already been changed
776 * Parses the source string of the given Java model compilation unit element
777 * and creates and returns a corresponding abstract syntax tree. The source
778 * string is obtained from the Java model element using
779 * <code>ICompilationUnit.getSource()</code>.
781 * The returned compilation unit node is the root node of a new AST.
782 * Each node in the subtree carries source range(s) information relating back
783 * to positions in the source string (the source string is not remembered
785 * The source range usually begins at the first character of the first token
786 * corresponding to the node; leading whitespace and comments are <b>not</b>
787 * included. The source range usually extends through the last character of
788 * the last token corresponding to the node; trailing whitespace and
789 * comments are <b>not</b> included. There are a handful of exceptions
790 * (including compilation units and the various body declarations); the
791 * specification for these node type spells out the details.
792 * Source ranges nest properly: the source range for a child is always
793 * within the source range of its parent, and the source ranges of sibling
794 * nodes never overlap.
795 * If a syntax error is detected while parsing, the relevant node(s) of the
796 * tree will be flagged as <code>MALFORMED</code>.
799 * If <code>resolveBindings</code> is <code>true</code>, the various names
800 * and types appearing in the compilation unit can be resolved to "bindings"
801 * by calling the <code>resolveBinding</code> methods. These bindings
802 * draw connections between the different parts of a program, and
803 * generally afford a more powerful vantage point for clients who wish to
804 * analyze a program's structure more deeply. These bindings come at a
805 * considerable cost in both time and space, however, and should not be
806 * requested frivolously. The additional space is not reclaimed until the
807 * AST, all its nodes, and all its bindings become garbage. So it is very
808 * important to not retain any of these objects longer than absolutely
809 * necessary. Bindings are resolved at the time the AST is created. Subsequent
810 * modifications to the AST do not affect the bindings returned by
811 * <code>resolveBinding</code> methods in any way; these methods return the
812 * same binding as before the AST was modified (including modifications
813 * that rearrange subtrees by reparenting nodes).
814 * If <code>resolveBindings</code> is <code>false</code>, the analysis
815 * does not go beyond parsing and building the tree, and all
816 * <code>resolveBinding</code> methods return <code>null</code> from the
820 * @param unit the Java model compilation unit whose source code is to be parsed
821 * @param resolveBindings <code>true</code> if bindings are wanted,
822 * and <code>false</code> if bindings are not of interest
823 * @return the compilation unit node
824 * @exception IllegalArgumentException if the given Java element does not
825 * exist or if its source string cannot be obtained
826 * @see ASTNode#getFlags()
827 * @see ASTNode#MALFORMED
828 * @see ASTNode#getStartPosition()
829 * @see ASTNode#getLength()
831 * @deprecated Use {@link ASTParser} instead.
833 public static CompilationUnit parseCompilationUnit(
834 ICompilationUnit unit,
835 boolean resolveBindings) {
838 ASTParser c = ASTParser.newParser(AST.JLS2);
840 c.setResolveBindings(resolveBindings);
841 ASTNode result = c.createAST(null);
842 return (CompilationUnit) result;
843 } catch (IllegalStateException e) {
844 // convert ASTParser's complaints into old form
845 throw new IllegalArgumentException();
850 * Parses the source string corresponding to the given Java class file
851 * element and creates and returns a corresponding abstract syntax tree.
852 * The source string is obtained from the Java model element using
853 * <code>IClassFile.getSource()</code>, and is only available for a class
854 * files with attached source.
856 * The returned compilation unit node is the root node of a new AST.
857 * Each node in the subtree carries source range(s) information relating back
858 * to positions in the source string (the source string is not remembered
860 * The source range usually begins at the first character of the first token
861 * corresponding to the node; leading whitespace and comments are <b>not</b>
862 * included. The source range usually extends through the last character of
863 * the last token corresponding to the node; trailing whitespace and
864 * comments are <b>not</b> included. There are a handful of exceptions
865 * (including compilation units and the various body declarations); the
866 * specification for these node type spells out the details.
867 * Source ranges nest properly: the source range for a child is always
868 * within the source range of its parent, and the source ranges of sibling
869 * nodes never overlap.
870 * If a syntax error is detected while parsing, the relevant node(s) of the
871 * tree will be flagged as <code>MALFORMED</code>.
874 * If <code>resolveBindings</code> is <code>true</code>, the various names
875 * and types appearing in the compilation unit can be resolved to "bindings"
876 * by calling the <code>resolveBinding</code> methods. These bindings
877 * draw connections between the different parts of a program, and
878 * generally afford a more powerful vantage point for clients who wish to
879 * analyze a program's structure more deeply. These bindings come at a
880 * considerable cost in both time and space, however, and should not be
881 * requested frivolously. The additional space is not reclaimed until the
882 * AST, all its nodes, and all its bindings become garbage. So it is very
883 * important to not retain any of these objects longer than absolutely
884 * necessary. Bindings are resolved at the time the AST is created. Subsequent
885 * modifications to the AST do not affect the bindings returned by
886 * <code>resolveBinding</code> methods in any way; these methods return the
887 * same binding as before the AST was modified (including modifications
888 * that rearrange subtrees by reparenting nodes).
889 * If <code>resolveBindings</code> is <code>false</code>, the analysis
890 * does not go beyond parsing and building the tree, and all
891 * <code>resolveBinding</code> methods return <code>null</code> from the
895 * @param classFile the Java model class file whose corresponding source code is to be parsed
896 * @param resolveBindings <code>true</code> if bindings are wanted,
897 * and <code>false</code> if bindings are not of interest
898 * @return the compilation unit node
899 * @exception IllegalArgumentException if the given Java element does not
900 * exist or if its source string cannot be obtained
901 * @see ASTNode#getFlags()
902 * @see ASTNode#MALFORMED
903 * @see ASTNode#getStartPosition()
904 * @see ASTNode#getLength()
906 * @deprecated Use {@link ASTParser} instead.
908 public static CompilationUnit parseCompilationUnit(
909 IClassFile classFile,
910 boolean resolveBindings) {
912 if (classFile == null) {
913 throw new IllegalArgumentException();
916 ASTParser c = ASTParser.newParser(AST.JLS2);
917 c.setSource(classFile);
918 c.setResolveBindings(resolveBindings);
919 ASTNode result = c.createAST(null);
920 return (CompilationUnit) result;
921 } catch (IllegalStateException e) {
922 // convert ASTParser's complaints into old form
923 throw new IllegalArgumentException();
928 * Parses the given string as the hypothetical contents of the named
929 * compilation unit and creates and returns a corresponding abstract syntax tree.
931 * The returned compilation unit node is the root node of a new AST.
932 * Each node in the subtree carries source range(s) information relating back
933 * to positions in the given source string (the given source string itself
934 * is not remembered with the AST).
935 * The source range usually begins at the first character of the first token
936 * corresponding to the node; leading whitespace and comments are <b>not</b>
937 * included. The source range usually extends through the last character of
938 * the last token corresponding to the node; trailing whitespace and
939 * comments are <b>not</b> included. There are a handful of exceptions
940 * (including compilation units and the various body declarations); the
941 * specification for these node type spells out the details.
942 * Source ranges nest properly: the source range for a child is always
943 * within the source range of its parent, and the source ranges of sibling
944 * nodes never overlap.
945 * If a syntax error is detected while parsing, the relevant node(s) of the
946 * tree will be flagged as <code>MALFORMED</code>.
949 * If the given project is not <code>null</code>, the various names
950 * and types appearing in the compilation unit can be resolved to "bindings"
951 * by calling the <code>resolveBinding</code> methods. These bindings
952 * draw connections between the different parts of a program, and
953 * generally afford a more powerful vantage point for clients who wish to
954 * analyze a program's structure more deeply. These bindings come at a
955 * considerable cost in both time and space, however, and should not be
956 * requested frivolously. The additional space is not reclaimed until the
957 * AST, all its nodes, and all its bindings become garbage. So it is very
958 * important to not retain any of these objects longer than absolutely
959 * necessary. Bindings are resolved at the time the AST is created. Subsequent
960 * modifications to the AST do not affect the bindings returned by
961 * <code>resolveBinding</code> methods in any way; these methods return the
962 * same binding as before the AST was modified (including modifications
963 * that rearrange subtrees by reparenting nodes).
964 * If the given project is <code>null</code>, the analysis
965 * does not go beyond parsing and building the tree, and all
966 * <code>resolveBinding</code> methods return <code>null</code> from the
970 * The name of the compilation unit must be supplied for resolving bindings.
971 * This name should be suffixed by a dot ('.') followed by one of the
972 * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
973 * and match the name of the main
974 * (public) class or interface declared in the source. For example, if the source
975 * declares a public class named "Foo", the name of the compilation can be
976 * "Foo.java". For the purposes of resolving bindings, types declared in the
977 * source string hide types by the same name available through the classpath
978 * of the given project.
981 * @param source the string to be parsed as a Java compilation unit
982 * @param unitName the name of the compilation unit that would contain the source
983 * string, or <code>null</code> if <code>javaProject</code> is also <code>null</code>
984 * @param project the Java project used to resolve names, or
985 * <code>null</code> if bindings are not resolved
986 * @return the compilation unit node
987 * @see ASTNode#getFlags()
988 * @see ASTNode#MALFORMED
989 * @see ASTNode#getStartPosition()
990 * @see ASTNode#getLength()
992 * @deprecated Use {@link ASTParser} instead.
994 public static CompilationUnit parseCompilationUnit(
997 IJavaProject project) {
999 if (source == null) {
1000 throw new IllegalArgumentException();
1002 ASTParser astParser = ASTParser.newParser(AST.JLS2);
1003 astParser.setSource(source);
1004 astParser.setUnitName(unitName);
1005 astParser.setProject(project);
1006 astParser.setResolveBindings(project != null);
1007 ASTNode result = astParser.createAST(null);
1008 return (CompilationUnit) result;
1012 * Parses the given string as a Java compilation unit and creates and
1013 * returns a corresponding abstract syntax tree.
1015 * The returned compilation unit node is the root node of a new AST.
1016 * Each node in the subtree carries source range(s) information relating back
1017 * to positions in the given source string (the given source string itself
1018 * is not remembered with the AST).
1019 * The source range usually begins at the first character of the first token
1020 * corresponding to the node; leading whitespace and comments are <b>not</b>
1021 * included. The source range usually extends through the last character of
1022 * the last token corresponding to the node; trailing whitespace and
1023 * comments are <b>not</b> included. There are a handful of exceptions
1024 * (including compilation units and the various body declarations); the
1025 * specification for these node type spells out the details.
1026 * Source ranges nest properly: the source range for a child is always
1027 * within the source range of its parent, and the source ranges of sibling
1028 * nodes never overlap.
1029 * If a syntax error is detected while parsing, the relevant node(s) of the
1030 * tree will be flagged as <code>MALFORMED</code>.
1033 * This method does not compute binding information; all <code>resolveBinding</code>
1034 * methods applied to nodes of the resulting AST return <code>null</code>.
1037 * @param source the string to be parsed as a Java compilation unit
1038 * @return the compilation unit node
1039 * @see ASTNode#getFlags()
1040 * @see ASTNode#MALFORMED
1041 * @see ASTNode#getStartPosition()
1042 * @see ASTNode#getLength()
1044 * @deprecated Use {@link ASTParser} instead.
1046 public static CompilationUnit parseCompilationUnit(char[] source) {
1047 if (source == null) {
1048 throw new IllegalArgumentException();
1050 ASTParser c = ASTParser.newParser(AST.JLS2);
1051 c.setSource(source);
1052 ASTNode result = c.createAST(null);
1053 return (CompilationUnit) result;
1057 * Returns the binding resolver for this AST.
1059 * @return the binding resolver for this AST
1061 BindingResolver getBindingResolver() {
1062 return this.resolver;
1066 * Returns the event handler for this AST.
1068 * @return the event handler for this AST
1071 NodeEventHandler getEventHandler() {
1072 return this.eventHandler;
1076 * Sets the event handler for this AST.
1078 * @param eventHandler the event handler for this AST
1081 void setEventHandler(NodeEventHandler eventHandler) {
1082 if (this.eventHandler == null) {
1083 throw new IllegalArgumentException();
1085 this.eventHandler = eventHandler;
1089 * Returns default node flags of new nodes of this AST.
1091 * @return the default node flags of new nodes of this AST
1094 int getDefaultNodeFlag() {
1095 return this.defaultNodeFlag;
1099 * Sets default node flags of new nodes of this AST.
1101 * @param flag node flags of new nodes of this AST
1104 void setDefaultNodeFlag(int flag) {
1105 this.defaultNodeFlag = flag;
1109 * Set <code>originalModificationCount</code> to the current modification count
1113 void setOriginalModificationCount(long count) {
1114 this.originalModificationCount = count;
1118 * Returns the type binding for a "well known" type.
1120 * Note that bindings are generally unavailable unless requested when the
1121 * AST is being built.
1124 * The following type names are supported:
1126 * <li><code>"boolean"</code></li>
1127 * <li><code>"byte"</code></li>
1128 * <li><code>"char"</code></li>
1129 * <li><code>"double"</code></li>
1130 * <li><code>"float"</code></li>
1131 * <li><code>"int"</code></li>
1132 * <li><code>"long"</code></li>
1133 * <li><code>"short"</code></li>
1134 * <li><code>"void"</code></li>
1135 * <li><code>"java.lang.Boolean"</code> (since 3.1)</li>
1136 * <li><code>"java.lang.Byte"</code> (since 3.1)</li>
1137 * <li><code>"java.lang.Character"</code> (since 3.1)</li>
1138 * <li><code>"java.lang.Class"</code></li>
1139 * <li><code>"java.lang.Cloneable"</code></li>
1140 * <li><code>"java.lang.Double"</code> (since 3.1)</li>
1141 * <li><code>"java.lang.Error"</code></li>
1142 * <li><code>"java.lang.Exception"</code></li>
1143 * <li><code>"java.lang.Float"</code> (since 3.1)</li>
1144 * <li><code>"java.lang.Integer"</code> (since 3.1)</li>
1145 * <li><code>"java.lang.Long"</code> (since 3.1)</li>
1146 * <li><code>"java.lang.Object"</code></li>
1147 * <li><code>"java.lang.RuntimeException"</code></li>
1148 * <li><code>"java.lang.Short"</code> (since 3.1)</li>
1149 * <li><code>"java.lang.String"</code></li>
1150 * <li><code>"java.lang.StringBuffer"</code></li>
1151 * <li><code>"java.lang.Throwable"</code></li>
1152 * <li><code>"java.lang.Void"</code> (since 3.1)</li>
1153 * <li><code>"java.io.Serializable"</code></li>
1157 * @param name the name of a well known type
1158 * @return the corresponding type binding, or <code>null</code> if the
1159 * named type is not considered well known or if no binding can be found
1162 public ITypeBinding resolveWellKnownType(String name) {
1166 return getBindingResolver().resolveWellKnownType(name);
1170 * Sets the binding resolver for this AST.
1172 * @param resolver the new binding resolver for this AST
1174 void setBindingResolver(BindingResolver resolver) {
1175 if (resolver == null) {
1176 throw new IllegalArgumentException();
1178 this.resolver = resolver;
1182 * Checks that this AST operation is not used when
1183 * building level JLS2 ASTs.
1185 * @exception UnsupportedOperationException
1188 void unsupportedIn2() {
1189 if (this.apiLevel == AST.JLS2) {
1190 throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
1195 * Checks that this AST operation is only used when
1196 * building level JLS2 ASTs.
1198 * @exception UnsupportedOperationException
1201 void supportedOnlyIn2() {
1202 if (this.apiLevel != AST.JLS2) {
1203 throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
1208 * new Class[] {AST.class}
1211 private static final Class[] AST_CLASS = new Class[] {AST.class};
1214 * new Object[] {this}
1217 private final Object[] THIS_AST= new Object[] {this};
1220 * Must not collide with a value for ICompilationUnit constants
1222 static final int RESOLVED_BINDINGS = 0x80000000;
1225 * Tag bit value. This represents internal state of the tree.
1230 * Creates an unparented node of the given node class
1231 * (non-abstract subclass of {@link ASTNode}).
1233 * @param nodeClass AST node class
1234 * @return a new unparented node owned by this AST
1235 * @exception IllegalArgumentException if <code>nodeClass</code> is
1236 * <code>null</code> or is not a concrete node type class
1239 public ASTNode createInstance(Class nodeClass) {
1240 if (nodeClass == null) {
1241 throw new IllegalArgumentException();
1244 // invoke constructor with signature Foo(AST)
1245 Constructor c = nodeClass.getDeclaredConstructor(AST_CLASS);
1246 Object result = c.newInstance(this.THIS_AST);
1247 return (ASTNode) result;
1248 } catch (NoSuchMethodException e) {
1249 // all AST node classes have a Foo(AST) constructor
1250 // therefore nodeClass is not legit
1251 throw new IllegalArgumentException();
1252 } catch (InstantiationException e) {
1253 // all concrete AST node classes can be instantiated
1254 // therefore nodeClass is not legit
1255 throw new IllegalArgumentException();
1256 } catch (IllegalAccessException e) {
1257 // all AST node classes have an accessible Foo(AST) constructor
1258 // therefore nodeClass is not legit
1259 throw new IllegalArgumentException();
1260 } catch (InvocationTargetException e) {
1261 // concrete AST node classes do not die in the constructor
1262 // therefore nodeClass is not legit
1263 throw new IllegalArgumentException();
1268 * Creates an unparented node of the given node type.
1269 * This convenience method is equivalent to:
1271 * createInstance(ASTNode.nodeClassForType(nodeType))
1274 * @param nodeType AST node type, one of the node type
1275 * constants declared on {@link ASTNode}
1276 * @return a new unparented node owned by this AST
1277 * @exception IllegalArgumentException if <code>nodeType</code> is
1278 * not a legal AST node type
1281 public ASTNode createInstance(int nodeType) {
1282 // nodeClassForType throws IllegalArgumentException if nodeType is bogus
1283 Class nodeClass = ASTNode.nodeClassForType(nodeType);
1284 return createInstance(nodeClass);
1287 //=============================== NAMES ===========================
1289 * Creates and returns a new unparented simple name node for the given
1290 * identifier. The identifier should be a legal Java identifier, but not
1291 * a keyword, boolean literal ("true", "false") or null literal ("null").
1293 * @param identifier the identifier
1294 * @return a new unparented simple name node
1295 * @exception IllegalArgumentException if the identifier is invalid
1297 public SimpleName newSimpleName(String identifier) {
1298 if (identifier == null) {
1299 throw new IllegalArgumentException();
1301 SimpleName result = new SimpleName(this);
1302 result.setIdentifier(identifier);
1307 * Creates and returns a new unparented qualified name node for the given
1308 * qualifier and simple name child node.
1310 * @param qualifier the qualifier name node
1311 * @param name the simple name being qualified
1312 * @return a new unparented qualified name node
1313 * @exception IllegalArgumentException if:
1315 * <li>the node belongs to a different AST</li>
1316 * <li>the node already has a parent</li>
1319 public QualifiedName newQualifiedName(
1322 QualifiedName result = new QualifiedName(this);
1323 result.setQualifier(qualifier);
1324 result.setName(name);
1330 * Creates and returns a new unparented name node for the given name
1331 * segments. Returns a simple name if there is only one name segment, and
1332 * a qualified name if there are multiple name segments. Each of the name
1333 * segments should be legal Java identifiers (this constraint may or may
1334 * not be enforced), and there must be at least one name segment.
1336 * @param identifiers a list of 1 or more name segments, each of which
1337 * is a legal Java identifier
1338 * @return a new unparented name node
1339 * @exception IllegalArgumentException if:
1341 * <li>the identifier is invalid</li>
1342 * <li>the list of identifiers is empty</li>
1345 public Name newName(String[] identifiers) {
1346 // update internalSetName(String[] if changed
1347 int count = identifiers.length;
1349 throw new IllegalArgumentException();
1351 Name result = newSimpleName(identifiers[0]);
1352 for (int i = 1; i < count; i++) {
1353 SimpleName name = newSimpleName(identifiers[i]);
1354 result = newQualifiedName(result, name);
1359 /* (omit javadoc for this method)
1360 * This method is a copy of setName(String[]) that doesn't do any validation.
1362 Name internalNewName(String[] identifiers) {
1363 int count = identifiers.length;
1365 throw new IllegalArgumentException();
1367 final SimpleName simpleName = new SimpleName(this);
1368 simpleName.internalSetIdentifier(identifiers[0]);
1369 Name result = simpleName;
1370 for (int i = 1; i < count; i++) {
1371 SimpleName name = new SimpleName(this);
1372 name.internalSetIdentifier(identifiers[i]);
1373 result = newQualifiedName(result, name);
1379 * Creates and returns a new unparented name node for the given name.
1380 * The name string must consist of 1 or more name segments separated
1381 * by single dots '.'. Returns a {@link QualifiedName} if the name has
1382 * dots, and a {@link SimpleName} otherwise. Each of the name
1383 * segments should be legal Java identifiers (this constraint may or may
1384 * not be enforced), and there must be at least one name segment.
1385 * The string must not contains white space, '<', '>',
1386 * '[', ']', or other any other characters that are not
1387 * part of the Java identifiers or separating '.'s.
1389 * @param qualifiedName string consisting of 1 or more name segments,
1390 * each of which is a legal Java identifier, separated by single dots '.'
1391 * @return a new unparented name node
1392 * @exception IllegalArgumentException if:
1394 * <li>the string is empty</li>
1395 * <li>the string begins or ends in a '.'</li>
1396 * <li>the string has adjacent '.'s</li>
1397 * <li>the segments between the '.'s are not valid Java identifiers</li>
1401 public Name newName(String qualifiedName) {
1402 StringTokenizer t = new StringTokenizer(qualifiedName, ".", true); //$NON-NLS-1$
1404 // balance is # of name tokens - # of period tokens seen so far
1405 // initially 0; finally 1; should never drop < 0 or > 1
1407 while(t.hasMoreTokens()) {
1408 String s = t.nextToken();
1409 if (s.indexOf('.') >= 0) {
1410 // this is a delimiter
1411 if (s.length() > 1) {
1412 // too many dots in a row
1413 throw new IllegalArgumentException();
1417 throw new IllegalArgumentException();
1420 // this is an identifier segment
1422 SimpleName name = newSimpleName(s);
1423 if (result == null) {
1426 result = newQualifiedName(result, name);
1431 throw new IllegalArgumentException();
1436 //=============================== TYPES ===========================
1438 * Creates and returns a new unparented simple type node with the given
1441 * This method can be used to convert a name (<code>Name</code>) into a
1442 * type (<code>Type</code>) by wrapping it.
1445 * @param typeName the name of the class or interface
1446 * @return a new unparented simple type node
1447 * @exception IllegalArgumentException if:
1449 * <li>the node belongs to a different AST</li>
1450 * <li>the node already has a parent</li>
1453 public SimpleType newSimpleType(Name typeName) {
1454 SimpleType result = new SimpleType(this);
1455 result.setName(typeName);
1460 * Creates and returns a new unparented array type node with the given
1461 * component type, which may be another array type.
1463 * @param componentType the component type (possibly another array type)
1464 * @return a new unparented array type node
1465 * @exception IllegalArgumentException if:
1467 * <li>the node belongs to a different AST</li>
1468 * <li>the node already has a parent</li>
1469 * <li>a cycle in would be created</li>
1472 public ArrayType newArrayType(Type componentType) {
1473 ArrayType result = new ArrayType(this);
1474 result.setComponentType(componentType);
1479 * Creates and returns a new unparented array type node with the given
1480 * element type and number of dimensions.
1482 * Note that if the element type passed in is an array type, the
1483 * element type of the result will not be the same as what was passed in.
1486 * @param elementType the element type (never an array type)
1487 * @param dimensions the number of dimensions, a positive number
1488 * @return a new unparented array type node
1489 * @exception IllegalArgumentException if:
1491 * <li>the node belongs to a different AST</li>
1492 * <li>the node already has a parent</li>
1493 * <li>a cycle in would be created</li>
1494 * <li>the element type is null</li>
1495 * <li>the element type is an array type</li>
1496 * <li>the number of dimensions is lower than 1</li>
1497 * <li>the number of dimensions is greater than 1000</li>
1500 public ArrayType newArrayType(Type elementType, int dimensions) {
1501 if (elementType == null || elementType.isArrayType()) {
1502 throw new IllegalArgumentException();
1504 if (dimensions < 1 || dimensions > 1000) {
1505 // we would blow our stacks anyway with a 1000-D array
1506 throw new IllegalArgumentException();
1508 ArrayType result = new ArrayType(this);
1509 result.setComponentType(elementType);
1510 for (int i = 2; i <= dimensions; i++) {
1511 result = newArrayType(result);
1518 * Creates and returns a new unparented primitive type node with the given
1521 * @param typeCode one of the primitive type code constants declared in
1522 * <code>PrimitiveType</code>
1523 * @return a new unparented primitive type node
1524 * @exception IllegalArgumentException if the primitive type code is invalid
1526 public PrimitiveType newPrimitiveType(PrimitiveType.Code typeCode) {
1527 PrimitiveType result = new PrimitiveType(this);
1528 result.setPrimitiveTypeCode(typeCode);
1533 * Creates and returns a new unparented parameterized type node with the
1534 * given type and an empty list of type arguments.
1536 * @param type the type that is parameterized
1537 * @return a new unparented parameterized type node
1538 * @exception IllegalArgumentException if:
1540 * <li>the node belongs to a different AST</li>
1541 * <li>the node already has a parent</li>
1543 * @exception UnsupportedOperationException if this operation is used in
1547 public ParameterizedType newParameterizedType(Type type) {
1548 ParameterizedType result = new ParameterizedType(this);
1549 result.setType(type);
1554 * Creates and returns a new unparented qualified type node with
1555 * the given qualifier type and name.
1557 * @param qualifier the qualifier type node
1558 * @param name the simple name being qualified
1559 * @return a new unparented qualified type node
1560 * @exception IllegalArgumentException if:
1562 * <li>the node belongs to a different AST</li>
1563 * <li>the node already has a parent</li>
1565 * @exception UnsupportedOperationException if this operation is used in
1569 public QualifiedType newQualifiedType(Type qualifier, SimpleName name) {
1570 QualifiedType result = new QualifiedType(this);
1571 result.setQualifier(qualifier);
1572 result.setName(name);
1577 * Creates and returns a new unparented wildcard type node with no
1580 * @return a new unparented wildcard type node
1581 * @exception UnsupportedOperationException if this operation is used in
1585 public WildcardType newWildcardType() {
1586 WildcardType result = new WildcardType(this);
1590 //=============================== DECLARATIONS ===========================
1592 * Creates an unparented compilation unit node owned by this AST.
1593 * The compilation unit initially has no package declaration, no
1594 * import declarations, and no type declarations.
1596 * @return the new unparented compilation unit node
1598 public CompilationUnit newCompilationUnit() {
1599 return new CompilationUnit(this);
1603 * Creates an unparented package declaration node owned by this AST.
1604 * The package declaration initially declares a package with an
1607 * @return the new unparented package declaration node
1609 public PackageDeclaration newPackageDeclaration() {
1610 PackageDeclaration result = new PackageDeclaration(this);
1615 * Creates an unparented import declaration node owned by this AST.
1616 * The import declaration initially contains a single-type import
1617 * of a type with an unspecified name.
1619 * @return the new unparented import declaration node
1621 public ImportDeclaration newImportDeclaration() {
1622 ImportDeclaration result = new ImportDeclaration(this);
1627 * Creates an unparented class declaration node owned by this AST.
1628 * The name of the class is an unspecified, but legal, name;
1629 * no modifiers; no doc comment; no superclass or superinterfaces;
1630 * and an empty class body.
1632 * To create an interface, use this method and then call
1633 * <code>TypeDeclaration.setInterface(true)</code>.
1636 * @return a new unparented type declaration node
1638 public TypeDeclaration newTypeDeclaration() {
1639 TypeDeclaration result = new TypeDeclaration(this);
1640 result.setInterface(false);
1645 * Creates an unparented method declaration node owned by this AST.
1646 * By default, the declaration is for a method of an unspecified, but
1647 * legal, name; no modifiers; no doc comment; no parameters; return
1648 * type void; no extra array dimensions; no thrown exceptions; and no
1649 * body (as opposed to an empty body).
1651 * To create a constructor, use this method and then call
1652 * <code>MethodDeclaration.setConstructor(true)</code> and
1653 * <code>MethodDeclaration.setName(className)</code>.
1656 * @return a new unparented method declaration node
1658 public MethodDeclaration newMethodDeclaration() {
1659 MethodDeclaration result = new MethodDeclaration(this);
1660 result.setConstructor(false);
1665 * Creates an unparented single variable declaration node owned by this AST.
1666 * By default, the declaration is for a variable with an unspecified, but
1667 * legal, name and type; no modifiers; no array dimensions after the
1668 * variable; no initializer; not variable arity.
1670 * @return a new unparented single variable declaration node
1672 public SingleVariableDeclaration newSingleVariableDeclaration() {
1673 SingleVariableDeclaration result = new SingleVariableDeclaration(this);
1678 * Creates an unparented variable declaration fragment node owned by this
1679 * AST. By default, the fragment is for a variable with an unspecified, but
1680 * legal, name; no extra array dimensions; and no initializer.
1682 * @return a new unparented variable declaration fragment node
1684 public VariableDeclarationFragment newVariableDeclarationFragment() {
1685 VariableDeclarationFragment result = new VariableDeclarationFragment(this);
1690 * Creates an unparented initializer node owned by this AST, with an
1691 * empty block. By default, the initializer has no modifiers and
1694 * @return a new unparented initializer node
1696 public Initializer newInitializer() {
1697 Initializer result = new Initializer(this);
1702 * Creates an unparented enum constant declaration node owned by this AST.
1703 * The name of the constant is an unspecified, but legal, name;
1704 * no doc comment; no modifiers or annotations; no arguments;
1705 * and does not declare an anonymous class.
1707 * @return a new unparented enum constant declaration node
1708 * @exception UnsupportedOperationException if this operation is used in
1712 public EnumConstantDeclaration newEnumConstantDeclaration() {
1713 EnumConstantDeclaration result = new EnumConstantDeclaration(this);
1718 * Creates an unparented enum declaration node owned by this AST.
1719 * The name of the enum is an unspecified, but legal, name;
1720 * no doc comment; no modifiers or annotations;
1721 * no superinterfaces; and empty lists of enum constants
1722 * and body declarations.
1724 * @return a new unparented enum declaration node
1725 * @exception UnsupportedOperationException if this operation is used in
1729 public EnumDeclaration newEnumDeclaration() {
1730 EnumDeclaration result = new EnumDeclaration(this);
1735 * Creates and returns a new unparented type parameter type node with an
1736 * unspecified type variable name and an empty list of type bounds.
1738 * @return a new unparented type parameter node
1739 * @exception UnsupportedOperationException if this operation is used in
1743 public TypeParameter newTypeParameter() {
1744 TypeParameter result = new TypeParameter(this);
1749 * Creates and returns a new unparented annotation type declaration
1750 * node for an unspecified, but legal, name; no modifiers; no javadoc;
1751 * and an empty list of member declarations.
1753 * @return a new unparented annotation type declaration node
1754 * @exception UnsupportedOperationException if this operation is used in
1758 public AnnotationTypeDeclaration newAnnotationTypeDeclaration() {
1759 AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(this);
1764 * Creates and returns a new unparented annotation type
1765 * member declaration node for an unspecified, but legal,
1766 * member name and type; no modifiers; no javadoc;
1767 * and no default value.
1769 * @return a new unparented annotation type member declaration node
1770 * @exception UnsupportedOperationException if this operation is used in
1774 public AnnotationTypeMemberDeclaration newAnnotationTypeMemberDeclaration() {
1775 AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(this);
1780 * Creates and returns a new unparented modifier node for the given
1783 * @param keyword one of the modifier keyword constants
1784 * @return a new unparented modifier node
1785 * @exception IllegalArgumentException if the primitive type code is invalid
1786 * @exception UnsupportedOperationException if this operation is used in
1790 public Modifier newModifier(Modifier.ModifierKeyword keyword) {
1791 Modifier result = new Modifier(this);
1792 result.setKeyword(keyword);
1797 * Creates and returns a list of new unparented modifier nodes
1798 * for the given modifier flags. When multiple modifiers are
1799 * requested the modifiers nodes will appear in the following order:
1800 * public, protected, private, abstract, static, final, synchronized,
1801 * native, strictfp, transient, volatile. This order is consistent
1802 * with the recommendations in JLS2 8.1.1, 8.3.1, and 8.4.3.
1804 * @param flags bitwise or of modifier flags declared on {@link Modifier}
1805 * @return a possibly empty list of new unparented modifier nodes
1806 * (element type <code>Modifier</code>)
1807 * @exception UnsupportedOperationException if this operation is used in
1811 public List newModifiers(int flags) {
1812 if (this.apiLevel == AST.JLS2) {
1815 List result = new ArrayList(3); // 3 modifiers is more than average
1816 if (Modifier.isPublic(flags)) {
1817 result.add(newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
1819 if (Modifier.isProtected(flags)) {
1820 result.add(newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD));
1822 if (Modifier.isPrivate(flags)) {
1823 result.add(newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD));
1825 if (Modifier.isAbstract(flags)) {
1826 result.add(newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD));
1828 if (Modifier.isStatic(flags)) {
1829 result.add(newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
1831 if (Modifier.isFinal(flags)) {
1832 result.add(newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
1834 if (Modifier.isSynchronized(flags)) {
1835 result.add(newModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD));
1837 if (Modifier.isNative(flags)) {
1838 result.add(newModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD));
1840 if (Modifier.isStrictfp(flags)) {
1841 result.add(newModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD));
1843 if (Modifier.isTransient(flags)) {
1844 result.add(newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD));
1846 if (Modifier.isVolatile(flags)) {
1847 result.add(newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD));
1852 //=============================== COMMENTS ===========================
1855 * Creates and returns a new block comment placeholder node.
1857 * Note that this node type is used to recording the source
1858 * range where a comment was found in the source string.
1859 * These comment nodes are normally found (only) in
1860 * {@linkplain CompilationUnit#getCommentList()
1861 * the comment table} for parsed compilation units.
1864 * @return a new unparented block comment node
1867 public BlockComment newBlockComment() {
1868 BlockComment result = new BlockComment(this);
1873 * Creates and returns a new line comment placeholder node.
1875 * Note that this node type is used to recording the source
1876 * range where a comment was found in the source string.
1877 * These comment nodes are normally found (only) in
1878 * {@linkplain CompilationUnit#getCommentList()
1879 * the comment table} for parsed compilation units.
1882 * @return a new unparented line comment node
1885 public LineComment newLineComment() {
1886 LineComment result = new LineComment(this);
1891 * Creates and returns a new doc comment node.
1892 * Initially the new node has an empty list of tag elements
1893 * (and, for backwards compatability, an unspecified, but legal,
1894 * doc comment string)
1896 * @return a new unparented doc comment node
1898 public Javadoc newJavadoc() {
1899 Javadoc result = new Javadoc(this);
1904 * Creates and returns a new tag element node.
1905 * Initially the new node has no tag name and an empty list of fragments.
1907 * Note that this node type is used only inside doc comments
1908 * ({@link Javadoc}).
1911 * @return a new unparented tag element node
1914 public TagElement newTagElement() {
1915 TagElement result = new TagElement(this);
1920 * Creates and returns a new text element node.
1921 * Initially the new node has an empty text string.
1923 * Note that this node type is used only inside doc comments
1924 * ({@link Javadoc Javadoc}).
1927 * @return a new unparented text element node
1930 public TextElement newTextElement() {
1931 TextElement result = new TextElement(this);
1936 * Creates and returns a new member reference node.
1937 * Initially the new node has no qualifier name and
1938 * an unspecified, but legal, member name.
1940 * Note that this node type is used only inside doc comments
1941 * ({@link Javadoc}).
1944 * @return a new unparented member reference node
1947 public MemberRef newMemberRef() {
1948 MemberRef result = new MemberRef(this);
1953 * Creates and returns a new method reference node.
1954 * Initially the new node has no qualifier name,
1955 * an unspecified, but legal, method name, and an
1956 * empty parameter list.
1958 * Note that this node type is used only inside doc comments
1959 * ({@link Javadoc Javadoc}).
1962 * @return a new unparented method reference node
1965 public MethodRef newMethodRef() {
1966 MethodRef result = new MethodRef(this);
1971 * Creates and returns a new method reference node.
1972 * Initially the new node has an unspecified, but legal,
1973 * type, not variable arity, and no parameter name.
1975 * Note that this node type is used only inside doc comments
1976 * ({@link Javadoc}).
1979 * @return a new unparented method reference parameter node
1982 public MethodRefParameter newMethodRefParameter() {
1983 MethodRefParameter result = new MethodRefParameter(this);
1987 //=============================== STATEMENTS ===========================
1989 * Creates a new unparented local variable declaration statement node
1990 * owned by this AST, for the given variable declaration fragment.
1991 * By default, there are no modifiers and the base type is unspecified
1994 * This method can be used to convert a variable declaration fragment
1995 * (<code>VariableDeclarationFragment</code>) into a statement
1996 * (<code>Statement</code>) by wrapping it. Additional variable
1997 * declaration fragments can be added afterwards.
2000 * @param fragment the variable declaration fragment
2001 * @return a new unparented variable declaration statement node
2002 * @exception IllegalArgumentException if:
2004 * <li>the node belongs to a different AST</li>
2005 * <li>the node already has a parent</li>
2006 * <li>a cycle in would be created</li>
2007 * <li>the variable declaration fragment is null</li>
2010 public VariableDeclarationStatement
2011 newVariableDeclarationStatement(VariableDeclarationFragment fragment) {
2012 if (fragment == null) {
2013 throw new IllegalArgumentException();
2015 VariableDeclarationStatement result =
2016 new VariableDeclarationStatement(this);
2017 result.fragments().add(fragment);
2022 * Creates a new unparented local type declaration statement node
2023 * owned by this AST, for the given type declaration.
2025 * This method can be used to convert a type declaration
2026 * (<code>TypeDeclaration</code>) into a statement
2027 * (<code>Statement</code>) by wrapping it.
2030 * @param decl the type declaration
2031 * @return a new unparented local type declaration statement node
2032 * @exception IllegalArgumentException if:
2034 * <li>the node belongs to a different AST</li>
2035 * <li>the node already has a parent</li>
2036 * <li>a cycle in would be created</li>
2039 public TypeDeclarationStatement
2040 newTypeDeclarationStatement(TypeDeclaration decl) {
2041 TypeDeclarationStatement result = new TypeDeclarationStatement(this);
2042 result.setDeclaration(decl);
2047 * Creates a new unparented local type declaration statement node
2048 * owned by this AST, for the given type declaration.
2050 * This method can be used to convert any kind of type declaration
2051 * (<code>AbstractTypeDeclaration</code>) into a statement
2052 * (<code>Statement</code>) by wrapping it.
2055 * @param decl the type declaration
2056 * @return a new unparented local type declaration statement node
2057 * @exception IllegalArgumentException if:
2059 * <li>the node belongs to a different AST</li>
2060 * <li>the node already has a parent</li>
2061 * <li>a cycle in would be created</li>
2065 public TypeDeclarationStatement
2066 newTypeDeclarationStatement(AbstractTypeDeclaration decl) {
2067 TypeDeclarationStatement result = new TypeDeclarationStatement(this);
2068 if (this.apiLevel == AST.JLS2) {
2069 result.internalSetTypeDeclaration((TypeDeclaration) decl);
2071 if (this.apiLevel >= AST.JLS3) {
2072 result.setDeclaration(decl);
2078 * Creates an unparented block node owned by this AST, for an empty list
2081 * @return a new unparented, empty block node
2083 public Block newBlock() {
2084 return new Block(this);
2088 * Creates an unparented continue statement node owned by this AST.
2089 * The continue statement has no label.
2091 * @return a new unparented continue statement node
2093 public ContinueStatement newContinueStatement() {
2094 return new ContinueStatement(this);
2098 * Creates an unparented break statement node owned by this AST.
2099 * The break statement has no label.
2101 * @return a new unparented break statement node
2103 public BreakStatement newBreakStatement() {
2104 return new BreakStatement(this);
2108 * Creates a new unparented expression statement node owned by this AST,
2109 * for the given expression.
2111 * This method can be used to convert an expression
2112 * (<code>Expression</code>) into a statement (<code>Type</code>)
2113 * by wrapping it. Note, however, that the result is only legal for
2114 * limited expression types, including method invocations, assignments,
2115 * and increment/decrement operations.
2118 * @param expression the expression
2119 * @return a new unparented statement node
2120 * @exception IllegalArgumentException if:
2122 * <li>the node belongs to a different AST</li>
2123 * <li>the node already has a parent</li>
2124 * <li>a cycle in would be created</li>
2127 public ExpressionStatement newExpressionStatement(Expression expression) {
2128 ExpressionStatement result = new ExpressionStatement(this);
2129 result.setExpression(expression);
2134 * Creates a new unparented if statement node owned by this AST.
2135 * By default, the expression is unspecified (but legal),
2136 * the then statement is an empty block, and there is no else statement.
2138 * @return a new unparented if statement node
2140 public IfStatement newIfStatement() {
2141 return new IfStatement(this);
2145 * Creates a new unparented while statement node owned by this AST.
2146 * By default, the expression is unspecified (but legal), and
2147 * the body statement is an empty block.
2149 * @return a new unparented while statement node
2151 public WhileStatement newWhileStatement() {
2152 return new WhileStatement(this);
2156 * Creates a new unparented do statement node owned by this AST.
2157 * By default, the expression is unspecified (but legal), and
2158 * the body statement is an empty block.
2160 * @return a new unparented do statement node
2162 public DoStatement newDoStatement() {
2163 return new DoStatement(this);
2167 * Creates a new unparented try statement node owned by this AST.
2168 * By default, the try statement has an empty block, no catch
2169 * clauses, and no finally block.
2171 * @return a new unparented try statement node
2173 public TryStatement newTryStatement() {
2174 return new TryStatement(this);
2178 * Creates a new unparented catch clause node owned by this AST.
2179 * By default, the catch clause declares an unspecified, but legal,
2180 * exception declaration and has an empty block.
2182 * @return a new unparented catch clause node
2184 public CatchClause newCatchClause() {
2185 return new CatchClause(this);
2189 * Creates a new unparented return statement node owned by this AST.
2190 * By default, the return statement has no expression.
2192 * @return a new unparented return statement node
2194 public ReturnStatement newReturnStatement() {
2195 return new ReturnStatement(this);
2199 * Creates a new unparented throw statement node owned by this AST.
2200 * By default, the expression is unspecified, but legal.
2202 * @return a new unparented throw statement node
2204 public ThrowStatement newThrowStatement() {
2205 return new ThrowStatement(this);
2209 * Creates a new unparented assert statement node owned by this AST.
2210 * By default, the first expression is unspecified, but legal, and has no
2211 * message expression.
2213 * @return a new unparented assert statement node
2215 public AssertStatement newAssertStatement() {
2216 return new AssertStatement(this);
2220 * Creates a new unparented empty statement node owned by this AST.
2222 * @return a new unparented empty statement node
2224 public EmptyStatement newEmptyStatement() {
2225 return new EmptyStatement(this);
2229 * Creates a new unparented labeled statement node owned by this AST.
2230 * By default, the label and statement are both unspecified, but legal.
2232 * @return a new unparented labeled statement node
2234 public LabeledStatement newLabeledStatement() {
2235 return new LabeledStatement(this);
2239 * Creates a new unparented switch statement node owned by this AST.
2240 * By default, the expression is unspecified, but legal, and there are
2241 * no statements or switch cases.
2243 * @return a new unparented labeled statement node
2245 public SwitchStatement newSwitchStatement() {
2246 return new SwitchStatement(this);
2250 * Creates a new unparented switch case statement node owned by
2251 * this AST. By default, the expression is unspecified, but legal.
2253 * @return a new unparented switch case node
2255 public SwitchCase newSwitchCase() {
2256 return new SwitchCase(this);
2260 * Creates a new unparented synchronized statement node owned by this AST.
2261 * By default, the expression is unspecified, but legal, and the body is
2264 * @return a new unparented synchronized statement node
2266 public SynchronizedStatement newSynchronizedStatement() {
2267 return new SynchronizedStatement(this);
2271 * Creates a new unparented for statement node owned by this AST.
2272 * By default, there are no initializers, no condition expression,
2273 * no updaters, and the body is an empty block.
2275 * @return a new unparented for statement node
2277 public ForStatement newForStatement() {
2278 return new ForStatement(this);
2282 * Creates a new unparented enhanced for statement node owned by this AST.
2283 * By default, the paramter and expression are unspecified
2284 * but legal subtrees, and the body is an empty block.
2286 * @return a new unparented throw statement node
2287 * @exception UnsupportedOperationException if this operation is used in
2291 public EnhancedForStatement newEnhancedForStatement() {
2292 return new EnhancedForStatement(this);
2295 //=============================== EXPRESSIONS ===========================
2297 * Creates and returns a new unparented string literal node for
2298 * the empty string literal.
2300 * @return a new unparented string literal node
2302 public StringLiteral newStringLiteral() {
2303 return new StringLiteral(this);
2308 * Creates and returns a new unparented character literal node.
2309 * Initially the node has an unspecified character literal.
2311 * @return a new unparented character literal node
2313 public CharacterLiteral newCharacterLiteral() {
2314 return new CharacterLiteral(this);
2318 * Creates and returns a new unparented number literal node.
2320 * @param literal the token for the numeric literal as it would
2321 * appear in Java source code
2322 * @return a new unparented number literal node
2323 * @exception IllegalArgumentException if the literal is null
2325 public NumberLiteral newNumberLiteral(String literal) {
2326 if (literal == null) {
2327 throw new IllegalArgumentException();
2329 NumberLiteral result = new NumberLiteral(this);
2330 result.setToken(literal);
2335 * Creates and returns a new unparented number literal node.
2336 * Initially the number literal token is <code>"0"</code>.
2338 * @return a new unparented number literal node
2340 public NumberLiteral newNumberLiteral() {
2341 NumberLiteral result = new NumberLiteral(this);
2346 * Creates and returns a new unparented null literal node.
2348 * @return a new unparented null literal node
2350 public NullLiteral newNullLiteral() {
2351 return new NullLiteral(this);
2355 * Creates and returns a new unparented boolean literal node.
2357 * For example, the assignment expression <code>foo = true</code>
2358 * is generated by the following snippet:
2361 * Assignment e= ast.newAssignment();
2362 * e.setLeftHandSide(ast.newSimpleName("foo"));
2363 * e.setRightHandSide(ast.newBooleanLiteral(true));
2368 * @param value the boolean value
2369 * @return a new unparented boolean literal node
2371 public BooleanLiteral newBooleanLiteral(boolean value) {
2372 BooleanLiteral result = new BooleanLiteral(this);
2373 result.setBooleanValue(value);
2378 * Creates and returns a new unparented assignment expression node
2379 * owned by this AST. By default, the assignment operator is "=" and
2380 * the left and right hand side expressions are unspecified, but
2383 * @return a new unparented assignment expression node
2385 public Assignment newAssignment() {
2386 Assignment result = new Assignment(this);
2391 * Creates an unparented method invocation expression node owned by this
2392 * AST. By default, the name of the method is unspecified (but legal)
2393 * there is no receiver expression, no type arguments, and the list of
2394 * arguments is empty.
2396 * @return a new unparented method invocation expression node
2398 public MethodInvocation newMethodInvocation() {
2399 MethodInvocation result = new MethodInvocation(this);
2404 * Creates an unparented "super" method invocation expression node owned by
2405 * this AST. By default, the name of the method is unspecified (but legal)
2406 * there is no qualifier, no type arguments, and the list of arguments is empty.
2408 * @return a new unparented "super" method invocation
2411 public SuperMethodInvocation newSuperMethodInvocation() {
2412 SuperMethodInvocation result = new SuperMethodInvocation(this);
2417 * Creates an unparented alternate constructor ("this(...);") invocation
2418 * statement node owned by this AST. By default, the lists of arguments
2419 * and type arguments are both empty.
2421 * Note that this type of node is a Statement, whereas a regular
2422 * method invocation is an Expression. The only valid use of these
2423 * statements are as the first statement of a constructor body.
2426 * @return a new unparented alternate constructor invocation statement node
2428 public ConstructorInvocation newConstructorInvocation() {
2429 ConstructorInvocation result = new ConstructorInvocation(this);
2434 * Creates an unparented alternate super constructor ("super(...);")
2435 * invocation statement node owned by this AST. By default, there is no
2436 * qualifier, no type arguments, and the list of arguments is empty.
2438 * Note that this type of node is a Statement, whereas a regular
2439 * super method invocation is an Expression. The only valid use of these
2440 * statements are as the first statement of a constructor body.
2443 * @return a new unparented super constructor invocation statement node
2445 public SuperConstructorInvocation newSuperConstructorInvocation() {
2446 SuperConstructorInvocation result =
2447 new SuperConstructorInvocation(this);
2452 * Creates a new unparented local variable declaration expression node
2453 * owned by this AST, for the given variable declaration fragment. By
2454 * default, there are no modifiers and the base type is unspecified
2457 * This method can be used to convert a variable declaration fragment
2458 * (<code>VariableDeclarationFragment</code>) into an expression
2459 * (<code>Expression</code>) by wrapping it. Additional variable
2460 * declaration fragments can be added afterwards.
2463 * @param fragment the first variable declaration fragment
2464 * @return a new unparented variable declaration expression node
2465 * @exception IllegalArgumentException if:
2467 * <li>the node belongs to a different AST</li>
2468 * <li>the node already has a parent</li>
2469 * <li>a cycle in would be created</li>
2470 * <li>the given fragment is null</li>
2471 * <li>a cycle in would be created</li>
2474 public VariableDeclarationExpression
2475 newVariableDeclarationExpression(VariableDeclarationFragment fragment) {
2476 if (fragment == null) {
2477 throw new IllegalArgumentException();
2479 VariableDeclarationExpression result =
2480 new VariableDeclarationExpression(this);
2481 result.fragments().add(fragment);
2486 * Creates a new unparented field declaration node owned by this AST,
2487 * for the given variable declaration fragment. By default, there are no
2488 * modifiers, no doc comment, and the base type is unspecified
2491 * This method can be used to wrap a variable declaration fragment
2492 * (<code>VariableDeclarationFragment</code>) into a field declaration
2493 * suitable for inclusion in the body of a type declaration
2494 * (<code>FieldDeclaration</code> implements <code>BodyDeclaration</code>).
2495 * Additional variable declaration fragments can be added afterwards.
2498 * @param fragment the variable declaration fragment
2499 * @return a new unparented field declaration node
2500 * @exception IllegalArgumentException if:
2502 * <li>the node belongs to a different AST</li>
2503 * <li>the node already has a parent</li>
2504 * <li>a cycle in would be created</li>
2505 * <li>the given fragment is null</li>
2508 public FieldDeclaration newFieldDeclaration(VariableDeclarationFragment fragment) {
2509 if (fragment == null) {
2510 throw new IllegalArgumentException();
2512 FieldDeclaration result = new FieldDeclaration(this);
2513 result.fragments().add(fragment);
2518 * Creates and returns a new unparented "this" expression node
2519 * owned by this AST. By default, there is no qualifier.
2521 * @return a new unparented "this" expression node
2523 public ThisExpression newThisExpression() {
2524 ThisExpression result = new ThisExpression(this);
2529 * Creates and returns a new unparented field access expression node
2530 * owned by this AST. By default, the expression and field are both
2531 * unspecified, but legal, names.
2533 * @return a new unparented field access expression node
2535 public FieldAccess newFieldAccess() {
2536 FieldAccess result = new FieldAccess(this);
2541 * Creates and returns a new unparented super field access expression node
2542 * owned by this AST. By default, the expression and field are both
2543 * unspecified, but legal, names.
2545 * @return a new unparented super field access expression node
2547 public SuperFieldAccess newSuperFieldAccess() {
2548 SuperFieldAccess result = new SuperFieldAccess(this);
2553 * Creates and returns a new unparented type literal expression node
2554 * owned by this AST. By default, the type is unspecified (but legal).
2556 * @return a new unparented type literal node
2558 public TypeLiteral newTypeLiteral() {
2559 TypeLiteral result = new TypeLiteral(this);
2564 * Creates and returns a new unparented cast expression node
2565 * owned by this AST. By default, the type and expression are unspecified
2568 * @return a new unparented cast expression node
2570 public CastExpression newCastExpression() {
2571 CastExpression result = new CastExpression(this);
2576 * Creates and returns a new unparented parenthesized expression node
2577 * owned by this AST. By default, the expression is unspecified (but legal).
2579 * @return a new unparented parenthesized expression node
2581 public ParenthesizedExpression newParenthesizedExpression() {
2582 ParenthesizedExpression result = new ParenthesizedExpression(this);
2587 * Creates and returns a new unparented infix expression node
2588 * owned by this AST. By default, the operator and left and right
2589 * operand are unspecified (but legal), and there are no extended
2592 * @return a new unparented infix expression node
2594 public InfixExpression newInfixExpression() {
2595 InfixExpression result = new InfixExpression(this);
2600 * Creates and returns a new unparented instanceof expression node
2601 * owned by this AST. By default, the operator and left and right
2602 * operand are unspecified (but legal).
2604 * @return a new unparented instanceof expression node
2606 public InstanceofExpression newInstanceofExpression() {
2607 InstanceofExpression result = new InstanceofExpression(this);
2612 * Creates and returns a new unparented postfix expression node
2613 * owned by this AST. By default, the operator and operand are
2614 * unspecified (but legal).
2616 * @return a new unparented postfix expression node
2618 public PostfixExpression newPostfixExpression() {
2619 PostfixExpression result = new PostfixExpression(this);
2624 * Creates and returns a new unparented prefix expression node
2625 * owned by this AST. By default, the operator and operand are
2626 * unspecified (but legal).
2628 * @return a new unparented prefix expression node
2630 public PrefixExpression newPrefixExpression() {
2631 PrefixExpression result = new PrefixExpression(this);
2636 * Creates and returns a new unparented array access expression node
2637 * owned by this AST. By default, the array and index expression are
2638 * both unspecified (but legal).
2640 * @return a new unparented array access expression node
2642 public ArrayAccess newArrayAccess() {
2643 ArrayAccess result = new ArrayAccess(this);
2648 * Creates and returns a new unparented array creation expression node
2649 * owned by this AST. By default, the array type is an unspecified
2650 * 1-dimensional array, the list of dimensions is empty, and there is no
2651 * array initializer.
2656 * // new String[len]
2657 * ArrayCreation ac1 = ast.newArrayCreation();
2660 * ast.newSimpleType(ast.newSimpleName("String"))));
2661 * ac1.dimensions().add(ast.newSimpleName("len"));
2663 * // new double[7][24][]
2664 * ArrayCreation ac2 = ast.newArrayCreation();
2667 * ast.newPrimitiveType(PrimitiveType.DOUBLE), 3));
2668 * ac2.dimensions().add(ast.newNumberLiteral("7"));
2669 * ac2.dimensions().add(ast.newNumberLiteral("24"));
2671 * // new int[] {1, 2}
2672 * ArrayCreation ac3 = ast.newArrayCreation();
2675 * ast.newPrimitiveType(PrimitiveType.INT)));
2676 * ArrayInitializer ai = ast.newArrayInitializer();
2677 * ac3.setInitializer(ai);
2678 * ai.expressions().add(ast.newNumberLiteral("1"));
2679 * ai.expressions().add(ast.newNumberLiteral("2"));
2684 * @return a new unparented array creation expression node
2686 public ArrayCreation newArrayCreation() {
2687 ArrayCreation result = new ArrayCreation(this);
2692 * Creates and returns a new unparented class instance creation
2693 * ("new") expression node owned by this AST. By default,
2694 * there is no qualifying expression, no type parameters,
2695 * an unspecified (but legal) type name, an empty list of
2696 * arguments, and does not declare an anonymous class declaration.
2698 * @return a new unparented class instance creation expression node
2700 public ClassInstanceCreation newClassInstanceCreation() {
2701 ClassInstanceCreation result = new ClassInstanceCreation(this);
2706 * Creates and returns a new unparented anonymous class declaration
2707 * node owned by this AST. By default, the body declaration list is empty.
2709 * @return a new unparented anonymous class declaration node
2711 public AnonymousClassDeclaration newAnonymousClassDeclaration() {
2712 AnonymousClassDeclaration result = new AnonymousClassDeclaration(this);
2717 * Creates and returns a new unparented array initializer node
2718 * owned by this AST. By default, the initializer has no expressions.
2720 * @return a new unparented array initializer node
2722 public ArrayInitializer newArrayInitializer() {
2723 ArrayInitializer result = new ArrayInitializer(this);
2728 * Creates and returns a new unparented conditional expression node
2729 * owned by this AST. By default, the condition and both expressions
2730 * are unspecified (but legal).
2732 * @return a new unparented array conditional expression node
2734 public ConditionalExpression newConditionalExpression() {
2735 ConditionalExpression result = new ConditionalExpression(this);
2739 //=============================== ANNOTATIONS ====================
2742 * Creates and returns a new unparented normal annotation node with
2743 * an unspecified type name and an empty list of member value
2746 * @return a new unparented normal annotation node
2747 * @exception UnsupportedOperationException if this operation is used in
2751 public NormalAnnotation newNormalAnnotation() {
2752 NormalAnnotation result = new NormalAnnotation(this);
2757 * Creates and returns a new unparented marker annotation node with
2758 * an unspecified type name.
2760 * @return a new unparented marker annotation node
2761 * @exception UnsupportedOperationException if this operation is used in
2765 public MarkerAnnotation newMarkerAnnotation() {
2766 MarkerAnnotation result = new MarkerAnnotation(this);
2771 * Creates and returns a new unparented single member annotation node with
2772 * an unspecified type name and value.
2774 * @return a new unparented single member annotation node
2775 * @exception UnsupportedOperationException if this operation is used in
2779 public SingleMemberAnnotation newSingleMemberAnnotation() {
2780 SingleMemberAnnotation result = new SingleMemberAnnotation(this);
2785 * Creates and returns a new unparented member value pair node with
2786 * an unspecified member name and value.
2788 * @return a new unparented member value pair node
2789 * @exception UnsupportedOperationException if this operation is used in
2793 public MemberValuePair newMemberValuePair() {
2794 MemberValuePair result = new MemberValuePair(this);
2799 * Enables the recording of changes to the given compilation
2800 * unit and its descendents. The compilation unit must have
2801 * been created by <code>ASTParser</code> and still be in
2802 * its original state. Once recording is on,
2803 * arbitrary changes to the subtree rooted at the compilation
2804 * unit are recorded internally. Once the modification has
2805 * been completed, call <code>rewrite</code> to get an object
2806 * representing the corresponding edits to the original
2807 * source code string.
2809 * @exception IllegalArgumentException if this compilation unit is
2810 * marked as unmodifiable, or if this compilation unit has already
2811 * been tampered with, or if recording has already been enabled,
2812 * or if <code>root</code> is not owned by this AST
2813 * @see CompilationUnit#recordModifications()
2816 void recordModifications(CompilationUnit root) {
2817 if(this.modificationCount != this.originalModificationCount) {
2818 throw new IllegalArgumentException("AST is already modified"); //$NON-NLS-1$
2819 } else if(this.rewriter != null) {
2820 throw new IllegalArgumentException("AST modifications are already recorded"); //$NON-NLS-1$
2821 } else if((root.getFlags() & ASTNode.PROTECT) != 0) {
2822 throw new IllegalArgumentException("Root node is unmodifiable"); //$NON-NLS-1$
2823 } else if(root.getAST() != this) {
2824 throw new IllegalArgumentException("Root node is not owned by this ast"); //$NON-NLS-1$
2827 this.rewriter = new InternalASTRewrite(root);
2828 this.setEventHandler(this.rewriter);
2832 * Converts all modifications recorded into an object
2833 * representing the corresponding text edits to the
2834 * given document containing the original source
2835 * code for the compilation unit that gave rise to
2838 * @param document original document containing source code
2839 * for the compilation unit
2840 * @param options the table of formatter options
2841 * (key type: <code>String</code>; value type: <code>String</code>);
2842 * or <code>null</code> to use the standard global options
2843 * {@link JavaCore#getOptions() JavaCore.getOptions()}.
2844 * @return text edit object describing the changes to the
2845 * document corresponding to the recorded AST modifications
2846 * @exception IllegalArgumentException if the document passed is
2847 * <code>null</code> or does not correspond to this AST
2848 * @exception IllegalStateException if <code>recordModifications</code>
2849 * was not called to enable recording
2850 * @see CompilationUnit#rewrite(IDocument, Map)
2853 TextEdit rewrite(IDocument document, Map options) {
2854 if (document == null) {
2855 throw new IllegalArgumentException();
2857 if (this.rewriter == null) {
2858 throw new IllegalStateException("Modifications record is not enabled"); //$NON-NLS-1$
2860 return this.rewriter.rewriteAST(document, options);
2864 * Returns true if the ast tree was created with bindings, false otherwise
2866 * @return true if the ast tree was created with bindings, false otherwise
2869 public boolean hasResolvedBindings() {
2870 return (this.bits & RESOLVED_BINDINGS) != 0;
2874 * Returns true if the ast tree was created with statements recovery, false otherwise
2876 * @return true if the ast tree was created with statements recovery, false otherwise
2879 public boolean hasStatementsRecovery() {
2880 return (this.bits & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0;
2884 * Returns true if the ast tree was created with bindings recovery, false otherwise
2886 * @return true if the ast tree was created with bindings recovery, false otherwise
2889 public boolean hasBindingsRecovery() {
2890 return (this.bits & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
2893 void setFlag(int newValue) {
2894 this.bits |= newValue;