package net.sourceforge.phpdt.core.dom; /******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ /** * Java compilation unit AST node type. This is the type of the root of an AST. *
* The source range for this type of node is ordinarily the entire source file, * including leading and trailing whitespace and comments. *
* For JLS2: * ** CompilationUnit: * [ PackageDeclaration ] * { ImportDeclaration } * { TypeDeclaration | <b>;</b> } ** * For JLS3, the kinds of type declarations grew to include enum and annotation * type declarations: * *
* CompilationUnit: * [ PackageDeclaration ] * { ImportDeclaration } * { TypeDeclaration | EnumDeclaration | AnnotationTypeDeclaration | <b>;</b> } ** * @since 2.0 */ public class CompilationUnit { // /** // * The "package" structural property of this node type. // * // * @since 3.0 // */ // public static final ChildPropertyDescriptor PACKAGE_PROPERTY = // new ChildPropertyDescriptor(CompilationUnit.class, "package", // PackageDeclaration.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$ // // /** // * The "imports" structural property of this node type. // * // * @since 3.0 // */ // public static final ChildListPropertyDescriptor IMPORTS_PROPERTY = // new ChildListPropertyDescriptor(CompilationUnit.class, "imports", // ImportDeclaration.class, NO_CYCLE_RISK); //$NON-NLS-1$ // // /** // * The "types" structural property of this node type. // * // * @since 3.0 // */ // public static final ChildListPropertyDescriptor TYPES_PROPERTY = // new ChildListPropertyDescriptor(CompilationUnit.class, "types", // AbstractTypeDeclaration.class, CYCLE_RISK); //$NON-NLS-1$ // // /** // * A list of property descriptors (element type: // * {@link StructuralPropertyDescriptor}), // * or null if uninitialized. // * @since 3.0 // */ // private static final List PROPERTY_DESCRIPTORS; // // static { // createPropertyList(CompilationUnit.class); // addProperty(PACKAGE_PROPERTY); // addProperty(IMPORTS_PROPERTY); // addProperty(TYPES_PROPERTY); // PROPERTY_DESCRIPTORS = reapPropertyList(); // } // // /** // * Returns a list of structural property descriptors for this node type. // * Clients must not modify the result. // * // * @param apiLevel the API level; one of the // *
AST.JLS*
constants
//
// * @return a list of property descriptors (element type:
// * {@link StructuralPropertyDescriptor})
// * @since 3.0
// */
// public static List propertyDescriptors(int apiLevel) {
// return PROPERTY_DESCRIPTORS;
// }
//
// /**
// * The comment table, or null
if none; initially
// * null
. This array is the storage underlying
// * the optionalCommentList
ArrayList.
// * @since 3.0
// */
// Comment[] optionalCommentTable = null;
//
// /**
// * The comment list (element type: Comment
,
// * or null
if none; initially null
.
// * @since 3.0
// */
// private List optionalCommentList = null;
//
// /**
// * The package declaration, or null
if none; initially
// * null
.
// */
// private PackageDeclaration optionalPackageDeclaration = null;
//
// /**
// * The list of import declarations in textual order order;
// * initially none (elementType: ImportDeclaration
).
// */
// private ASTNode.NodeList imports =
// new ASTNode.NodeList(IMPORTS_PROPERTY);
//
// /**
// * The list of type declarations in textual order order;
// * initially none (elementType: AbstractTypeDeclaration
)
// */
// private ASTNode.NodeList types =
// new ASTNode.NodeList(TYPES_PROPERTY);
//
// /**
// * Line end table. If lineEndTable[i] == p
then the
// * line number i+1
ends at character position
// * p
. Except for the last line, the positions are that
// * of the last character of the line delimiter.
// * For example, the source string A\nB\nC
has
// * line end table {1, 3} (if \n is one character).
// */
// private int[] lineEndTable = new int[0];
//
// /**
// * Canonical empty list of messages.
// */
// private static final Message[] EMPTY_MESSAGES = new Message[0];
//
// /**
// * Canonical empty list of problems.
// */
// private static final IProblem[] EMPTY_PROBLEMS = new IProblem[0];
//
// /**
// * Messages reported by the compiler during parsing or name resolution.
// */
// private Message[] messages;
//
// /**
// * Problems reported by the compiler during parsing or name resolution.
// */
// private IProblem[] problems = EMPTY_PROBLEMS;
//
// /**
// * The comment mapper, or null
in none;
// * initially null
.
// * @since 3.0
// */
// private DefaultCommentMapper commentMapper = null;
//
// /**
// * Sets the line end table for this compilation unit.
// * If lineEndTable[i] == p
then line number i+1
// * ends at character position p
. Except for the last line,
// the
// * positions are that of (the last character of) the line delimiter.
// * For example, the source string A\nB\nC
has
// * line end table {1, 3, 4}.
// *
// * @param lineEndtable the line end table
// */
// void setLineEndTable(int[] lineEndTable) {
// if (lineEndTable == null) {
// throw new NullPointerException();
// }
// // alternate root is *not* considered a structural property
// // but we protect them nevertheless
// checkModifiable();
// this.lineEndTable = lineEndTable;
// }
//
// /**
// * Creates a new AST node for a compilation owned by the given AST.
// * The compilation unit initially has no package declaration, no
// * import declarations, and no type declarations.
// * // * N.B. This constructor is package-private; all subclasses must be // * declared in the same package; clients are unable to declare // * additional subclasses. // *
// * // * @param ast the AST that is to own this node // */ // CompilationUnit(AST ast) { // super(ast); // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // * @since 3.0 // */ // final List internalStructuralPropertiesForType(int apiLevel) { // return propertyDescriptors(apiLevel); // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // */ // final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor // property, boolean get, ASTNode child) { // if (property == PACKAGE_PROPERTY) { // if (get) { // return getPackage(); // } else { // setPackage((PackageDeclaration) child); // return null; // } // } // // allow default implementation to flag the error // return super.internalGetSetChildProperty(property, get, child); // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // */ // final List internalGetChildListProperty(ChildListPropertyDescriptor // property) { // if (property == IMPORTS_PROPERTY) { // return imports(); // } // if (property == TYPES_PROPERTY) { // return types(); // } // // allow default implementation to flag the error // return super.internalGetChildListProperty(property); // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // */ // final int getNodeType0() { // return COMPILATION_UNIT; // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // */ // ASTNode clone0(AST target) { // CompilationUnit result = new CompilationUnit(target); // // n.b do not copy line number table or messages // result.setSourceRange(this.getStartPosition(), this.getLength()); // result.setPackage( // (PackageDeclaration) ASTNode.copySubtree(target, getPackage())); // result.imports().addAll(ASTNode.copySubtrees(target, imports())); // result.types().addAll(ASTNode.copySubtrees(target, types())); // return result; // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // */ // final boolean subtreeMatch0(ASTMatcher matcher, Object other) { // // dispatch to correct overloaded match method // return matcher.match(this, other); // } // // /* (omit javadoc for this method) // * Method declared on ASTNode. // */ // void accept0(ASTVisitor visitor) { // boolean visitChildren = visitor.visit(this); // if (visitChildren) { // // visit children in normal left to right reading order // acceptChild(visitor, getPackage()); // acceptChildren(visitor, this.imports); // acceptChildren(visitor, this.types); // } // visitor.endVisit(this); // } // // /** // * Returns the node for the package declaration of this compilation // * unit, ornull
if this compilation unit is in the
// * default package.
// *
// * @return the package declaration node, or null
if none
// */
// public PackageDeclaration getPackage() {
// return this.optionalPackageDeclaration;
// }
//
// /**
// * Sets or clears the package declaration of this compilation unit
// * node to the given package declaration node.
// *
// * @param pkgDecl the new package declaration node, or
// * null
if this compilation unit does not have a package
// * declaration (that is in the default package)
// * @exception IllegalArgumentException if:
// * ImportDeclaration
)
// */
// public List imports() {
// return this.imports;
// }
//
// /**
// * Returns the live list of nodes for the top-level type declarations of
// this
// * compilation unit, in order of appearance.
// *
// * Note that in JLS3, the types may include both enum declarations
// * and annotation type declarations introduced in J2SE 1.5.
// * For JLS2, the elements are always TypeDeclaration
.
// *
AbstractTypeDeclaration
)
// */
// public List types() {
// return this.types;
// }
//
// /**
// * Finds the corresponding AST node in the given compilation unit from
// * which the given binding originated. Returns null
if the
// * binding does not correspond to any node in this compilation unit.
// * This method always returns null
if bindings were not
// requested
// * when this AST was built.
// * // * The following table indicates the expected node type for the various // * different kinds of bindings: // *
PackageDeclaration
TypeDeclaration
or a
// * AnonymousClassDeclaration
(for anonymous classes)VariableDeclarationFragment
in a
// * FieldDeclaration
SingleVariableDeclaration
, or
// * a VariableDeclarationFragment
in a
// * VariableDeclarationStatement
or
// * VariableDeclarationExpression
MethodDeclaration
MethodDeclaration
AnnotationTypeDeclaration
AnnotationTypeMemberDeclaration
EnumDeclaration
EnumConstantDeclaration
// * Each call to {@link ASTParser#createAST(IProgressMonitor)} with a
// request for bindings
// * gives rise to separate universe of binding objects. This method always
// returns
// * null
when the binding object comes from a different AST.
// * Use findDeclaringNode(binding.getKey())
when the binding
// comes
// * from a different AST.
// *
null
if the binding does not correspond to a node in
// this
// * compilation unit or if bindings were not requested when this AST was
// built
// * @see #findDeclaringNode(String)
// */
// public ASTNode findDeclaringNode(IBinding binding) {
// return this.ast.getBindingResolver().findDeclaringNode(binding);
// }
//
// /**
// * Finds the corresponding AST node in the given compilation unit from
// * which the binding with the given key originated. Returns
// * null
if the corresponding node cannot be determined.
// * This method always returns null
if bindings were not
// requested
// * when this AST was built.
// * // * The following table indicates the expected node type for the various // * different kinds of binding keys: // *
PackageDeclaration
TypeDeclaration
or a
// * AnonymousClassDeclaration
(for anonymous classes)VariableDeclarationFragment
in a
// * FieldDeclaration
SingleVariableDeclaration
, or
// * a VariableDeclarationFragment
in a
// * VariableDeclarationStatement
or
// * VariableDeclarationExpression
MethodDeclaration
MethodDeclaration
AnnotationTypeDeclaration
AnnotationTypeMemberDeclaration
EnumDeclaration
EnumConstantDeclaration
// * Note that as explained in {@link IBinding#getKey() IBinding.getkey} // * there may be no keys for finding the declaring node for local // variables, // * local or anonymous classes, etc. // *
// * // * @param key the binding key, ornull
// * @return the corresponding node where a binding with the given
// * key is declared, or null
if the key is null
// * or if the key does not correspond to a node in this compilation unit
// * or if bindings were not requested when this AST was built
// * @see IBinding#getKey()
// * @since 2.1
// */
// public ASTNode findDeclaringNode(String key) {
// return this.ast.getBindingResolver().findDeclaringNode(key);
// }
//
// /**
// * Returns the internal comment mapper.
// *
// * @return the comment mapper, or null
if none.
// * @since 3.0
// */
// DefaultCommentMapper getCommentMapper() {
// return this.commentMapper;
// }
//
// /**
// * Initializes the internal comment mapper with the given
// * scanner.
// *
// * @param scanner the scanner
// * @since 3.0
// */
// void initCommentMapper(Scanner scanner) {
// this.commentMapper = new DefaultCommentMapper(this.optionalCommentTable);
// this.commentMapper.initialize(this, scanner);
// }
//
// /**
// * Returns the extended start position of the given node. Unlike
// * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()()},
// * the extended source range may include comments and whitespace
// * immediately before or after the normal source range for the node.
// *
// * @param node the node
// * @return the 0-based character index, or -1
// * if no source position information is recorded for this node
// * @see #getExtendedLength(ASTNode)
// * @since 3.0
// */
// public int getExtendedStartPosition(ASTNode node) {
// if (this.commentMapper == null) {
// return -1;
// } else {
// return this.commentMapper.getExtendedStartPosition(node);
// }
// }
//
// /**
// * Returns the extended source length of the given node. Unlike
// * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()()},
// * the extended source range may include comments and whitespace
// * immediately before or after the normal source range for the node.
// *
// * @param node the node
// * @return a (possibly 0) length, or 0
// * if no source position information is recorded for this node
// * @see #getExtendedStartPosition(ASTNode)
// * @since 3.0
// */
// public int getExtendedLength(ASTNode node) {
// if (this.commentMapper == null) {
// return 0;
// } else {
// return this.commentMapper.getExtendedLength(node);
// }
// }
//
// /**
// * Returns the line number corresponding to the given source character
// * position in the original source string. The initial line of the
// * compilation unit is numbered 1, and each line extends through the
// * last character of the end-of-line delimiter. The very last line extends
// * through the end of the source string and has no line delimiter.
// * For example, the source string class A\n{\n}
has 3 lines
// * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
// * Returns 1 for a character position that does not correspond to any
// * source line, or if no line number information is available for this
// * compilation unit.
// *
// * @param position a 0-based character position, possibly
// * negative or out of range
// * @return the 1-based line number, or 1
if the character
// * position does not correspond to a source line in the original
// * source file or if line number information is not known for this
// * compilation unit
// * @see ASTParser
// */
// public int lineNumber(int position) {
// int length = lineEndTable.length;
// if (length == 0) {
// // no line number info
// return 1;
// }
// int low = 0;
// if (position <= lineEndTable[low]) {
// // position illegal or before the first line delimiter
// return 1;
// }
// // assert position > lineEndTable[low+1] && low == 0
// int hi = length - 1;
// if (position > lineEndTable[hi]) {
// // position beyond the last line separator
// if (position >= getStartPosition() + getLength()) {
// // this is beyond the end of the source length
// return 1;
// } else {
// return length + 1;
// }
// }
// // assert lineEndTable[low] < position <= lineEndTable[hi]
// // && low == 0 && hi == length - 1 && low < hi
//
// // binary search line end table
// while (true) {
// // invariant lineEndTable[low] < position <= lineEndTable[hi]
// // && 0 <= low < hi <= length - 1
// // reducing measure hi - low
// if (low + 1 == hi) {
// // assert lineEndTable[low] < position <= lineEndTable[low+1]
// // position is on line low+1 (line number is low+2)
// return low + 2;
// }
// // assert hi - low >= 2, so average is truly in between
// int mid = (low + hi) / 2;
// // assert 0 <= low < mid < hi <= length - 1
// if (position <= lineEndTable[mid]) {
// // assert lineEndTable[low] < position <= lineEndTable[mid]
// // && 0 <= low < mid < hi <= length - 1
// hi = mid;
// } else {
// // position > lineEndTable[mid]
// // assert lineEndTable[mid] < position <= lineEndTable[hi]
// // && 0 <= low < mid < hi <= length - 1
// low = mid;
// }
// // in both cases, invariant reachieved with reduced measure
// }
// }
//
// /**
// * Returns the list of messages reported by the compiler during the
// parsing
// * or the type checking of this compilation unit. This list might be a
// subset of
// * errors detected and reported by a Java compiler.
// *
// * This list of messages is suitable for simple clients that do little
// * more than log the messages or display them to the user. Clients that
// * need further details should call getProblems
to get
// * compiler problem objects.
// *
// * Simple clients that do little more than log the messages or display
// * them to the user should probably call getMessages
instead.
// *
// * Since the Java language allows comments to appear most anywhere // * in the source text, it is problematic to locate comments in relation // * to the structure of an AST. The one exception is doc comments // * which, by convention, immediately precede type, field, and // * method declarations; these comments are located in the AST // * by {@link BodyDeclaration#getJavadoc BodyDeclaration.getJavadoc}. // * Other comments do not show up in the AST. The table of comments // * is provided for clients that need to find the source ranges of // * all comments in the original source string. It includes entries // * for comments of all kinds (line, block, and doc), arranged in order // * of increasing source position. // *
// * Note on comment parenting: The {@link ASTNode#getParent() getParent()} // * of a doc comment associated with a body declaration is the body // * declaration node; for these comment nodes // * {@link ASTNode#getRoot() getRoot()} will return the compilation unit // * (assuming an unmodified AST) reflecting the fact that these nodes // * are property located in the AST for the compilation unit. // * However, for other comment nodes, {@link ASTNode#getParent() // getParent()} // * will returnnull
, and {@link ASTNode#getRoot() getRoot()}
// * will return the comment node itself, indicating that these comment
// nodes
// * are not directly connected to the AST for the compilation unit. The
// * {@link Comment#getAlternateRoot Comment.getAlternateRoot}
// * method provides a way to navigate from a comment to its compilation
// * unit.
// *
// * // * A note on visitors: The only comment nodes that will be visited when // * visiting a compilation unit are the doc comments parented by body // * declarations. To visit all comments in normal reading order, iterate // * over the comment table and call {@link ASTNode#accept(ASTVisitor) // accept} // * on each element. // *
// *// * Clients cannot modify the resulting list. // *
// * // * @return an unmodifiable list of comments in increasing order of source // * start position, ornull
if comment information
// * for this compilation unit is not available
// * @see ASTParser
// * @since 3.0
// */
// public List getCommentList() {
// return this.optionalCommentList;
// }
//
// /**
// * Sets the list of the comments encountered while parsing
// * this compilation unit.
// *
// * @param commentTable a list of comments in increasing order
// * of source start position, or null
if comment
// * information for this compilation unit is not available
// * @exception IllegalArgumentException if the comment table is
// * not in increasing order of source position
// * @see #getCommentList()
// * @see ASTParser
// * @since 3.0
// */
// void setCommentTable(Comment[] commentTable) {
// // double check table to ensure that all comments have
// // source positions and are in strictly increasing order
// if (commentTable == null) {
// this.optionalCommentList = null;
// this.optionalCommentTable = null;
// } else {
// int nextAvailablePosition = 0;
// for (int i = 0; i < commentTable.length; i++) {
// Comment comment = commentTable[i];
// if (comment == null) {
// throw new IllegalArgumentException();
// }
// int start = comment.getStartPosition();
// int length = comment.getLength();
// if (start < 0 || length < 0 || start < nextAvailablePosition) {
// throw new IllegalArgumentException();
// }
// nextAvailablePosition = comment.getStartPosition() + comment.getLength();
// }
// this.optionalCommentTable = commentTable;
// List commentList = Arrays.asList(commentTable);
// // protect the list from further modification
// this.optionalCommentList = Collections.unmodifiableList(commentList);
// }
// }
//
//
// /* (omit javadoc for this method)
// * Method declared on ASTNode.
// */
// void appendDebugString(StringBuffer buffer) {
// buffer.append("CompilationUnit"); //$NON-NLS-1$
// // include the type names
// buffer.append("["); //$NON-NLS-1$
// for (Iterator it = types().iterator(); it.hasNext(); ) {
// AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next();
// buffer.append(d.getName().getIdentifier());
// if (it.hasNext()) {
// buffer.append(","); //$NON-NLS-1$
// }
// }
// buffer.append("]"); //$NON-NLS-1$
// }
//
// /* (omit javadoc for this method)
// * Method declared on ASTNode.
// */
// int memSize() {
// int size = BASE_NODE_SIZE + 8 * 4;
// if (this.lineEndTable != null) {
// size += HEADERS + 4 * this.lineEndTable.length;
// }
// if (this.optionalCommentTable != null) {
// size += HEADERS + 4 * this.optionalCommentTable.length;
// }
// // ignore the space taken up by optionalCommentList
// return size;
// }
//
// /* (omit javadoc for this method)
// * Method declared on ASTNode.
// */
// int treeSize() {
// int size = memSize();
// if (this.optionalPackageDeclaration != null) {
// size += getPackage().treeSize();
// }
// size += this.imports.listSize();
// size += this.types.listSize();
// // include disconnected comments
// if (this.optionalCommentList != null) {
// for (int i = 0; i < this.optionalCommentList.size(); i++) {
// Comment comment = (Comment) this.optionalCommentList.get(i);
// if (comment != null && comment.getParent() == null) {
// size += comment.treeSize();
// }
// }
// }
// return size;
// }
//
// /**
// * Enables the recording of changes to this compilation
// * unit and its descendents. The compilation unit must have
// * been created by ASTParser
and still be in
// * its original state. Once recording is on,
// * arbitrary changes to the subtree rooted at this compilation
// * unit are recorded internally. Once the modification has
// * been completed, call rewrite
to get an object
// * representing the corresponding edits to the original
// * source code string.
// *
// * @exception IllegalArgumentException if this compilation unit is
// * marked as unmodifiable, or if this compilation unit has already
// * been tampered with, or recording has already been enabled
// * @since 3.0
// */
// public void recordModifications() {
// getAST().recordModifications(this);
// }
//
// /**
// * Converts all modifications recorded for this compilation
// * unit into an object representing the corresponding text
// * edits to the given document containing the original source
// * code for this compilation unit.
// *
// * The compilation unit must have been created by
// * ASTParser
from the source code string in the
// * given document, and recording must have been turned
// * on with a prior call to recordModifications
// * while the AST was still in its original state.
// *
// * Calling this methods does not discard the modifications // * on record. Subsequence modifications made to the AST // * are added to the ones already on record. If this method // * is called again later, the resulting text edit object will // * accurately reflect the net cumulative affect of all those // * changes. // *
// * // * @param document original document containing source code // * for this compilation unit // * @param options the table of formatter options // * (key type:String
; value type: String
);
// * or null
to use the standard global options
// * {@link JavaCore#getOptions() JavaCore.getOptions()}.
// * @return text edit object describing the changes to the
// * document corresponding to the recorded AST modifications
// * @exception IllegalArgumentException if the document passed is
// * null
or does not correspond to this AST
// * @exception IllegalStateException if recordModifications
// * was not called to enable recording
// * @see #recordModifications()
// * @since 3.0
// */
// public TextEdit rewrite(IDocument document, Map options) {
// return getAST().rewrite(document, options);
// }
}