Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 7076 Details for
Bug 27134
Add a ASTNode for non-Javadoc comments
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
New version after Jim feedback
v07.txt (text/plain), 220.17 KB, created by
Frederic Fusier
on 2003-12-05 09:14:02 EST
(
hide
)
Description:
New version after Jim feedback
Filename:
MIME Type:
Creator:
Frederic Fusier
Created:
2003-12-05 09:14:02 EST
Size:
220.17 KB
patch
obsolete
>Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java >=================================================================== >retrieving revision 1.34 >diff -u -r1.34 CompletionScanner.java >--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java 17 Nov 2003 10:17:08 -0000 1.34 >+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java 5 Dec 2003 14:08:40 -0000 >@@ -544,7 +544,7 @@ > currentPosition++; > } //jump over the \\ > } >- recordComment(false); >+ recordComment(TokenNameCOMMENT_LINE); > if (startPosition <= cursorLocation && cursorLocation < currentPosition-1){ > throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_COMMENT); > } >@@ -556,7 +556,7 @@ > return TokenNameCOMMENT_LINE; > } > } catch (IndexOutOfBoundsException e) { >- recordComment(false); >+ recordComment(TokenNameCOMMENT_LINE); > if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition-1); > if (tokenizeComments) { > this.currentPosition--; // reset one character behind >@@ -650,14 +650,18 @@ > currentPosition++; > } //jump over the \\ > } >- recordComment(isJavadoc); >+ int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK; >+ recordComment(token); > if (startPosition <= cursorLocation && cursorLocation < currentPosition-1){ > throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_COMMENT); > } > if (tokenizeComments) { >+ /* > if (isJavadoc) > return TokenNameCOMMENT_JAVADOC; > return TokenNameCOMMENT_BLOCK; >+ */ >+ return token; > } > } catch (IndexOutOfBoundsException e) { > throw new InvalidInputException(UNTERMINATED_COMMENT); >Index: compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java >=================================================================== >retrieving revision 1.33 >diff -u -r1.33 CompilationUnitDeclaration.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java 22 Nov 2003 16:01:00 -0000 1.33 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java 5 Dec 2003 14:08:40 -0000 >@@ -23,6 +23,7 @@ > public ImportReference currentPackage; > public ImportReference[] imports; > public TypeDeclaration[] types; >+ public int[][] comments; > > public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors > public boolean ignoreMethodBodies = false; >Index: compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java >=================================================================== >retrieving revision 1.5 >diff -u -r1.5 JavadocParser.java >--- compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 3 Dec 2003 18:27:32 -0000 1.5 >+++ compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java 5 Dec 2003 14:08:40 -0000 >@@ -512,7 +512,7 @@ > if (iToken == 0) { > return null; > } >- if ((iToken % 2) == 0) { // dots must be followed by an identifier >+ if ((iToken % 2) == 0) { // cannot leave on a dot > throw new InvalidInputException(); > } > break nextToken; >Index: compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java >=================================================================== >retrieving revision 1.102 >diff -u -r1.102 Scanner.java >--- compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java 3 Dec 2003 18:28:28 -0000 1.102 >+++ compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java 5 Dec 2003 14:08:40 -0000 >@@ -23,6 +23,8 @@ > * The mirror implementation is using the backward compatible ITerminalSymbols constant > * definitions (stable with 2.0), whereas the internal implementation uses TerminalTokens > * which constant values reflect the latest parser generation state. >+ * @see org.eclipse.jdt.core.compiler.ITerminalSymbols >+ * @see org.eclipse.jdt.internal.core.util.PublicScanner > */ > public class Scanner implements TerminalTokens { > >@@ -395,7 +397,7 @@ > } > > public final char[] getRawTokenSourceEnd() { >- int length = this.eofPosition - this.currentPosition; >+ int length = this.eofPosition - this.currentPosition - 1; > char[] sourceEnd = new char[length]; > System.arraycopy(source, this.currentPosition, sourceEnd, 0, length); > return sourceEnd; >@@ -1312,7 +1314,7 @@ > } > } > } >- recordComment(false); >+ recordComment(TokenNameCOMMENT_LINE); > if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition); > if ((currentCharacter == '\r') || (currentCharacter == '\n')) { > checkNonExternalizedString(); >@@ -1331,7 +1333,7 @@ > } > } catch (IndexOutOfBoundsException e) { > currentPosition--; >- recordComment(false); >+ recordComment(TokenNameCOMMENT_LINE); > if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition); > if (tokenizeComments) { > return TokenNameCOMMENT_LINE; >@@ -1418,12 +1420,16 @@ > currentPosition++; > } //jump over the \\ > } >- recordComment(isJavadoc); >+ int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK; >+ recordComment(token); > if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition); > if (tokenizeComments) { >+ /* > if (isJavadoc) > return TokenNameCOMMENT_JAVADOC; > return TokenNameCOMMENT_BLOCK; >+ */ >+ return token; > } > } catch (IndexOutOfBoundsException e) { > throw new InvalidInputException(UNTERMINATED_COMMENT); >@@ -2221,17 +2227,17 @@ > } > } > } >-public final void recordComment(boolean isJavadoc) { >+public void recordComment(int token) { > > // a new comment is recorded > try { >- this.commentStops[++this.commentPtr] = isJavadoc ? this.currentPosition : -this.currentPosition; >+ this.commentStops[++this.commentPtr] = (token==TokenNameCOMMENT_JAVADOC) ? this.currentPosition : -this.currentPosition; > } catch (IndexOutOfBoundsException e) { > int oldStackLength = this.commentStops.length; > int[] oldStack = this.commentStops; > this.commentStops = new int[oldStackLength + 30]; > System.arraycopy(oldStack, 0, this.commentStops, 0, oldStackLength); >- this.commentStops[this.commentPtr] = isJavadoc ? this.currentPosition : -this.currentPosition; >+ this.commentStops[this.commentPtr] = (token==TokenNameCOMMENT_JAVADOC) ? this.currentPosition : -this.currentPosition; > //grows the positions buffers too > int[] old = this.commentStarts; > this.commentStarts = new int[oldStackLength + 30]; >Index: dom/org/eclipse/jdt/core/dom/AST.java >=================================================================== >retrieving revision 1.58 >diff -u -r1.58 AST.java >--- dom/org/eclipse/jdt/core/dom/AST.java 20 Nov 2003 20:39:52 -0000 1.58 >+++ dom/org/eclipse/jdt/core/dom/AST.java 5 Dec 2003 14:08:40 -0000 >@@ -14,20 +14,11 @@ > import java.util.Map; > > import org.eclipse.jdt.core.*; >-import org.eclipse.jdt.core.IClassFile; >-import org.eclipse.jdt.core.ICompilationUnit; >-import org.eclipse.jdt.core.IJavaProject; >-import org.eclipse.jdt.core.JavaCore; >-import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; >-import org.eclipse.jdt.internal.compiler.parser.Scanner; > import org.eclipse.jdt.internal.compiler.util.SuffixConstants; > import org.eclipse.jdt.internal.core.*; >-import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; >-import org.eclipse.jdt.internal.core.JavaModelManager; >-import org.eclipse.jdt.internal.core.NameLookup; > > /** > * Umbrella owner and abstract syntax tree node factory. >@@ -69,7 +60,7 @@ > * subclassed. > * </p> > * >- * @see #parseCompilationUnit(ICompilationUnit, boolean) >+ * @see #parseCompilationUnit(char[]) and other similar methods > * @see ASTNode > * @since 2.0 > */ >@@ -85,9 +76,16 @@ > * Java Scanner used to validate preconditions for the creation of specific nodes > * like CharacterLiteral, NumberLiteral, StringLiteral or SimpleName. > */ >- Scanner scanner; >+ DOMScanner scanner; > > /** >+ * Flags to set options while DOM parsing. >+ * @since 3.0 >+ */ >+ public final static int ResolveBindings = 0x00000001; // Bit 0: resolve binding while parsing >+ public final static int InsideComments = 0x00000002; // Bit 1: parse comments >+ >+ /** > * Creates a new, empty abstract syntax tree using default options. > * > * @see JavaCore#getDefaultOptions() >@@ -116,7 +114,7 @@ > * @see JavaCore#getDefaultOptions() > */ > public AST(Map options) { >- this.scanner = new Scanner( >+ this.scanner = new DOMScanner( > true /*comment*/, > true /*whitespace*/, > false /*nls*/, >@@ -151,7 +149,7 @@ > * this AST > */ > public long modificationCount() { >- return modCount; >+ return this.modCount; > } > > /** >@@ -181,7 +179,7 @@ > */ > void modifying() { > // increase the modification count >- modCount++; >+ this.modCount++; > } > > /** >@@ -235,16 +233,91 @@ > * @return the compilation unit node > * @exception IllegalArgumentException if the given Java element does not > * exist or if its source string cannot be obtained >+ * @deprecated Replaced by {@link #parseCompilationUnit(CompilationUnit, int)} >+ */ >+ public static CompilationUnit parseCompilationUnit( >+ ICompilationUnit unit, >+ boolean resolveBindings) { >+ >+ return parseCompilationUnit(unit, resolveBindings?ResolveBindings:0); >+ } >+ >+ /** >+ * Parses the source string of the given Java model compilation unit element >+ * and creates and returns a corresponding abstract syntax tree. The source >+ * string is obtained from the Java model element using >+ * <code>ICompilationUnit.getSource()</code>. >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the source string (the source string is not remembered >+ * with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. There are a handful of exceptions >+ * (including compilation units and the various body declarations); the >+ * specification for these node type spells out the details. >+ * Source ranges nest properly: the source range for a child is always >+ * within the source range of its parent, and the source ranges of sibling >+ * nodes never overlap. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the compilation unit: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code> >+ * </p> >+ * >+ * @param unit the Java model compilation unit whose source code is to be parsed >+ * @param options an integer which sets parse options. >+ * @return the compilation unit node >+ * @exception IllegalArgumentException if the given Java element does not >+ * exist or if its source string cannot be obtained > * @see ASTNode#getFlags() > * @see ASTNode#MALFORMED > * @see ASTNode#getStartPosition() > * @see ASTNode#getLength() >+ * @since 3.0 > */ >- public static CompilationUnit parseCompilationUnit( >- ICompilationUnit unit, >- boolean resolveBindings) { >+ public static CompilationUnit parseCompilationUnit(ICompilationUnit unit, int options) { > >- return parseCompilationUnit(unit, resolveBindings, DefaultWorkingCopyOwner.PRIMARY); >+ return parseCompilationUnit(unit, options, DefaultWorkingCopyOwner.PRIMARY); > } > > /** >@@ -311,11 +384,102 @@ > * @see ASTNode#getStartPosition() > * @see ASTNode#getLength() > * @see WorkingCopyOwner >+ * @deprecated Replaced by {@link #parseCompilationUnit(CompilationUnit, int, WorkingCopyOwner)} >+ * @since 3.0 >+ * TODO (frederic) Remove for 3.0 >+ */ >+ public static CompilationUnit parseCompilationUnit( >+ ICompilationUnit unit, >+ boolean resolveBindings, >+ WorkingCopyOwner owner) { >+ return parseCompilationUnit(unit, resolveBindings?ResolveBindings:0, owner); >+ } >+ >+ /** >+ * Parses the source string of the given Java model compilation unit element >+ * and creates and returns a corresponding abstract syntax tree. The source >+ * string is obtained from the Java model element using >+ * <code>ICompilationUnit.getSource()</code>. >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the source string (the source string is not remembered >+ * with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. There are a handful of exceptions >+ * (including compilation units and the various body declarations); the >+ * specification for these node type spells out the details. >+ * Source ranges nest properly: the source range for a child is always >+ * within the source range of its parent, and the source ranges of sibling >+ * nodes never overlap. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the compilation unit: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code> >+ * </p> >+ * <p> >+ * When bindings are created, instead of considering compilation units on disk only >+ * one can supply a <code>WorkingCopyOwner</code>. Working copies owned >+ * by this owner take precedence over the underlying compilation units when looking >+ * up names and drawing the connections. >+ * </p> >+ * >+ * @param unit the Java model compilation unit whose source code is to be parsed >+ * @param options an integer which sets parse options. >+ * @param owner the owner of working copies that take precedence over underlying >+ * compilation units >+ * @return the compilation unit node >+ * @exception IllegalArgumentException if the given Java element does not >+ * exist or if its source string cannot be obtained >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @see WorkingCopyOwner > * @since 3.0 > */ > public static CompilationUnit parseCompilationUnit( > ICompilationUnit unit, >- boolean resolveBindings, >+ int options, > WorkingCopyOwner owner) { > > if (unit == null) { >@@ -333,7 +497,7 @@ > throw new IllegalArgumentException(); > } > >- if (resolveBindings) { >+ if ((options & ResolveBindings) == ResolveBindings) { > NameLookup lookup = null; > CompilationUnitDeclaration compilationUnitDeclaration = null; > try { >@@ -345,7 +509,7 @@ > > // parse and resolve > compilationUnitDeclaration = CompilationUnitResolver.resolve(unit, false/*don't cleanup*/, source); >- ASTConverter converter = new ASTConverter(unit.getJavaProject().getOptions(true), true); >+ ASTConverter converter = new ASTConverter(unit.getJavaProject().getOptions(true), options); > AST ast = new AST(); > BindingResolver resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope); > ast.setBindingResolver(resolver); >@@ -370,7 +534,7 @@ > } > } > } else { >- return parseCompilationUnit(source); >+ return parseCompilationUnit(source, options); > } > } > >@@ -431,14 +595,94 @@ > * @see ASTNode#getStartPosition() > * @see ASTNode#getLength() > * @since 2.1 >+ * @deprecated Replaced by {@link #parseCompilationUnit(IClassFile, int)} > */ > public static CompilationUnit parseCompilationUnit( > IClassFile classFile, > boolean resolveBindings) { > >- return parseCompilationUnit(classFile, resolveBindings, DefaultWorkingCopyOwner.PRIMARY); >+ return parseCompilationUnit(classFile, resolveBindings?ResolveBindings:0); > } >- >+ >+ /** >+ * Parses the source string corresponding to the given Java class file >+ * element and creates and returns a corresponding abstract syntax tree. >+ * The source string is obtained from the Java model element using >+ * <code>IClassFile.getSource()</code>, and is only available for a class >+ * files with attached source. >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the source string (the source string is not remembered >+ * with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. There are a handful of exceptions >+ * (including compilation units and the various body declarations); the >+ * specification for these node type spells out the details. >+ * Source ranges nest properly: the source range for a child is always >+ * within the source range of its parent, and the source ranges of sibling >+ * nodes never overlap. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the compilation unit: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code> >+ * </p> >+ * >+ * @param classFile the Java model compilation unit whose source code is to be parsed >+ * @param options an integer which sets parse options. >+ * @return the compilation unit node >+ * @exception IllegalArgumentException if the given Java element does not >+ * exist or if its source string cannot be obtained >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @since 3.0 >+ */ >+ public static CompilationUnit parseCompilationUnit(IClassFile classFile, int options) { >+ >+ return parseCompilationUnit(classFile, options, DefaultWorkingCopyOwner.PRIMARY); >+ } >+ > /** > * Parses the source string corresponding to the given Java class file > * element and creates and returns a corresponding abstract syntax tree. >@@ -505,10 +749,102 @@ > * @see ASTNode#getLength() > * @see WorkingCopyOwner > * @since 3.0 >+ * @deprecated Replaced by {@link #parseCompilationUnit(IClassFile, int, WorkingCopyOwner)} >+ * TODO (frederic) remove for 3.0 >+ */ >+ public static CompilationUnit parseCompilationUnit( >+ IClassFile classFile, >+ boolean resolveBindings, >+ WorkingCopyOwner owner) { >+ return parseCompilationUnit(classFile, resolveBindings?ResolveBindings:0, owner); >+ } >+ >+ /** >+ * Parses the source string corresponding to the given Java class file >+ * element and creates and returns a corresponding abstract syntax tree. >+ * The source string is obtained from the Java model element using >+ * <code>IClassFile.getSource()</code>, and is only available for a class >+ * files with attached source. >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the source string (the source string is not remembered >+ * with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. There are a handful of exceptions >+ * (including compilation units and the various body declarations); the >+ * specification for these node type spells out the details. >+ * Source ranges nest properly: the source range for a child is always >+ * within the source range of its parent, and the source ranges of sibling >+ * nodes never overlap. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the compilation unit: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code> >+ * </p> >+ * <p> >+ * When bindings are created, instead of considering compilation units on disk only >+ * one can supply a <code>WorkingCopyOwner</code>. Working copies owned >+ * by this owner take precedence over the underlying compilation units when looking >+ * up names and drawing the connections. >+ * </p> >+ * >+ * @param classFile the Java model compilation unit whose source code is to be parsed >+ * @param options an integer which sets parse options. >+ * @param owner the owner of working copies that take precedence over underlying >+ * compilation units >+ * @return the compilation unit node >+ * @exception IllegalArgumentException if the given Java element does not >+ * exist or if its source string cannot be obtained >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @see WorkingCopyOwner >+ * @since 3.0 > */ > public static CompilationUnit parseCompilationUnit( > IClassFile classFile, >- boolean resolveBindings, >+ int options, > WorkingCopyOwner owner) { > > if (classFile == null) { >@@ -528,7 +864,7 @@ > throw new IllegalArgumentException(); > } > source = sourceString.toCharArray(); >- if (!resolveBindings) { >+ if ((options & ResolveBindings) == 0) { > return AST.parseCompilationUnit(source); > } > StringBuffer buffer = new StringBuffer(SuffixConstants.SUFFIX_STRING_java); >@@ -553,7 +889,7 @@ > buffer.toString(), > project, > false/*don't cleanup*/); >- ASTConverter converter = new ASTConverter(project.getOptions(true), true); >+ ASTConverter converter = new ASTConverter(project.getOptions(true), options); > AST ast = new AST(); > BindingResolver resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope); > ast.setBindingResolver(resolver); >@@ -578,7 +914,7 @@ > } > } > } >- >+ > /** > * Parses the given string as the hypothetical contents of the named > * compilation unit and creates and returns a corresponding abstract syntax tree. >@@ -643,13 +979,13 @@ > * @see ASTNode#getLength() > */ > public static CompilationUnit parseCompilationUnit( >- char[] source, >- String unitName, >- IJavaProject project) { >+ char[] source, >+ String unitName, >+ IJavaProject project) { > > return parseCompilationUnit(source, unitName, project, DefaultWorkingCopyOwner.PRIMARY); > } >- >+ > /** > * Parses the given string as the hypothetical contents of the named > * compilation unit and creates and returns a corresponding abstract syntax tree. >@@ -724,7 +1060,109 @@ > * @since 3.0 > */ > public static CompilationUnit parseCompilationUnit( >+ char[] source, >+ String unitName, >+ IJavaProject project, >+ WorkingCopyOwner owner) { >+ return parseCompilationUnit(source, ResolveBindings, unitName, project, owner); >+ } >+ >+ /** >+ * Parses the given string as the hypothetical contents of the named >+ * compilation unit and creates and returns a corresponding abstract syntax tree. >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the given source string (the given source string itself >+ * is not remembered with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. There are a handful of exceptions >+ * (including compilation units and the various body declarations); the >+ * specification for these node type spells out the details. >+ * Source ranges nest properly: the source range for a child is always >+ * within the source range of its parent, and the source ranges of sibling >+ * nodes never overlap. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the compilation unit: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code>. >+ * Note that if the given project is <code>null</code>, bindings won't be >+ * resolved even if resolve binding option is set. >+ * </p> >+ * <p> >+ * When bindings are created, instead of considering compilation units on disk only >+ * one can supply a <code>WorkingCopyOwner</code>. Working copies owned >+ * by this owner take precedence over the underlying compilation units when looking >+ * up names and drawing the connections. >+ * </p> >+ * <p> >+ * The name of the compilation unit must be supplied for resolving bindings. >+ * This name should include the ".java" suffix and match the name of the main >+ * (public) class or interface declared in the source. For example, if the source >+ * declares a public class named "Foo", the name of the compilation should be >+ * "Foo.java". For the purposes of resolving bindings, types declared in the >+ * source string hide types by the same name available through the classpath >+ * of the given project. >+ * </p> >+ * >+ * @param source the string to be parsed as a Java compilation unit >+ * @param options an integer which sets parse options. >+ * @param unitName the name of the compilation unit that would contain the source >+ * string, or <code>null</code> if <code>javaProject</code> is also <code>null</code> >+ * @param project the Java project used to resolve names, or >+ * <code>null</code> if bindings are not resolved >+ * @param owner the owner of working copies that take precedence over underlying >+ * compilation units >+ * @return the compilation unit node >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @see WorkingCopyOwner >+ * @since 3.0 >+ */ >+ public static CompilationUnit parseCompilationUnit( > char[] source, >+ int options, > String unitName, > IJavaProject project, > WorkingCopyOwner owner) { >@@ -759,7 +1197,7 @@ > unitName, > project, > false/*don't cleanup*/); >- ASTConverter converter = new ASTConverter(project.getOptions(true), true); >+ ASTConverter converter = new ASTConverter(project.getOptions(true), (ResolveBindings | options)); > AST ast = new AST(); > BindingResolver resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope); > ast.setBindingResolver(resolver); >@@ -784,7 +1222,7 @@ > } > } > } >- >+ > /** > * Parses the given string as a Java compilation unit and creates and > * returns a corresponding abstract syntax tree. >@@ -819,13 +1257,86 @@ > * @see ASTNode#getLength() > */ > public static CompilationUnit parseCompilationUnit(char[] source) { >+ return parseCompilationUnit(source, 0); // No bindings, no comments >+ } >+ >+ /** >+ * Parses the given string as a Java compilation unit and creates and >+ * returns a corresponding abstract syntax tree. >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the given source string (the given source string itself >+ * is not remembered with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. There are a handful of exceptions >+ * (including compilation units and the various body declarations); the >+ * specification for these node type spells out the details. >+ * Source ranges nest properly: the source range for a child is always >+ * within the source range of its parent, and the source ranges of sibling >+ * nodes never overlap. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the source: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code>. >+ * </p> >+ * >+ * @param source the string to be parsed as a Java compilation unit >+ * @param options an integer which sets parse options. >+ * @return CompilationUnit >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @since 3.0 >+ */ >+ public static CompilationUnit parseCompilationUnit(char[] source, int options) { > if (source == null) { > throw new IllegalArgumentException(); > } > CompilationUnitDeclaration compilationUnitDeclaration = > CompilationUnitResolver.parse(source, JavaCore.getOptions()); // no better custom options > >- ASTConverter converter = new ASTConverter(JavaCore.getOptions(), false); >+ ASTConverter converter = new ASTConverter(JavaCore.getOptions(), options); > AST ast = new AST(); > ast.setBindingResolver(new BindingResolver()); > converter.setAST(ast); >@@ -926,15 +1437,132 @@ > * @see ASTNode#getStartPosition() > * @see ASTNode#getLength() > * @since 3.0 >+ * @deprecated Replaced by {@link #parsePartialCompilationUnit(ICompilationUnit, int, int)} >+ * TODO (frederic) remove for 3.0 > */ > public static CompilationUnit parsePartialCompilationUnit( > ICompilationUnit unit, > int position, > boolean resolveBindings) { >- return parsePartialCompilationUnit(unit, position, resolveBindings, DefaultWorkingCopyOwner.PRIMARY); >+ return parsePartialCompilationUnit( >+ unit, >+ position, >+ resolveBindings?ResolveBindings:0); > } > > /** >+ * Parses the source string of the given Java model compilation unit element >+ * and creates and returns an abridged abstract syntax tree. This method >+ * differs from >+ * {@link #parseCompilationUnit(ICompilationUnit,boolean) >+ * parseCompilationUnit(ICompilationUnit,boolean)} only in >+ * that the resulting AST does not have nodes for the entire compilation >+ * unit. Rather, the AST is only fleshed out for the node that include >+ * the given source position. This kind of limited AST is sufficient for >+ * certain purposes but totally unsuitable for others. In places where it >+ * can be used, the limited AST offers the advantage of being smaller and >+ * faster to faster to construct. >+ * </p> >+ * <p> >+ * The resulting AST always includes nodes for all of the compilation unit's >+ * package, import, and top-level type declarations. It also always contains >+ * nodes for all the body declarations for those top-level types, as well >+ * as body declarations for any member types. However, some of the body >+ * declarations may be abridged. In particular, the statements ordinarily >+ * found in the body of a method declaration node will not be included >+ * (the block will be empty) unless the source position falls somewhere >+ * within the source range of that method declaration node. The same is true >+ * for initializer declarations; the statements ordinarily found in the body >+ * of initializer node will not be included unless the source position falls >+ * somewhere within the source range of that initializer declaration node. >+ * Field declarations are never abridged. Note that the AST for the body of >+ * that one unabridged method (or initializer) is 100% complete; it has all >+ * its statements, including any local or anonymous type declarations >+ * embedded within them. When the the given position is not located within >+ * the source range of any body declaration of a top-level type, the AST >+ * returned is a skeleton that includes nodes for all and only the major >+ * declarations; this kind of AST is still quite useful because it contains >+ * all the constructs that introduce names visible to the world outside the >+ * compilation unit. >+ * </p> >+ * <p> >+ * In all other respects, this method works the same as >+ * {@link #parseCompilationUnit(ICompilationUnit,boolean) >+ * parseCompilationUnit(ICompilationUnit,boolean)}. >+ * The source string is obtained from the Java model element using >+ * <code>ICompilationUnit.getSource()</code>. >+ * </p> >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the source string (the source string is not remembered >+ * with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the source: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code>. >+ * </p> >+ * >+ * @param unit the Java model compilation unit whose source code is to be parsed >+ * @param position a position into the corresponding body declaration >+ * @param options an integer which sets parse options. >+ * @return the abridged compilation unit node >+ * @exception IllegalArgumentException if the given Java element does not >+ * exist or if its source string cannot be obtained >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @since 3.0 >+ */ >+ public static CompilationUnit parsePartialCompilationUnit( >+ ICompilationUnit unit, >+ int position, >+ int options) { >+ return parsePartialCompilationUnit(unit, position, options, DefaultWorkingCopyOwner.PRIMARY); >+ } >+ > /** > * Parses the source string of the given Java model compilation unit element > * and creates and returns an abridged abstract syntax tree. This method >@@ -1032,11 +1660,138 @@ > * @see ASTNode#getStartPosition() > * @see ASTNode#getLength() > * @since 3.0 >+ * @deprecated Replaced by {@link #parsePartialCompilationUnit(ICompilationUnit, int, int, WorkingCopyOwner)} >+ * TODO (frederic) remove for 3.0 >+ */ >+ public static CompilationUnit parsePartialCompilationUnit( >+ ICompilationUnit unit, >+ int position, >+ boolean resolveBindings, >+ WorkingCopyOwner owner) { >+ return parsePartialCompilationUnit( >+ unit, >+ position, >+ resolveBindings ? ResolveBindings : 0, >+ DefaultWorkingCopyOwner.PRIMARY); >+ } >+ /** >+ * Parses the source string of the given Java model compilation unit element >+ * and creates and returns an abridged abstract syntax tree. This method >+ * differs from >+ * {@link #parseCompilationUnit(ICompilationUnit,boolean,WorkingCopyOwner) >+ * parseCompilationUnit(ICompilationUnit,boolean,WorkingCopyOwner)} only in >+ * that the resulting AST does not have nodes for the entire compilation >+ * unit. Rather, the AST is only fleshed out for the node that include >+ * the given source position. This kind of limited AST is sufficient for >+ * certain purposes but totally unsuitable for others. In places where it >+ * can be used, the limited AST offers the advantage of being smaller and >+ * faster to faster to construct. >+ * </p> >+ * <p> >+ * The resulting AST always includes nodes for all of the compilation unit's >+ * package, import, and top-level type declarations. It also always contains >+ * nodes for all the body declarations for those top-level types, as well >+ * as body declarations for any member types. However, some of the body >+ * declarations may be abridged. In particular, the statements ordinarily >+ * found in the body of a method declaration node will not be included >+ * (the block will be empty) unless the source position falls somewhere >+ * within the source range of that method declaration node. The same is true >+ * for initializer declarations; the statements ordinarily found in the body >+ * of initializer node will not be included unless the source position falls >+ * somewhere within the source range of that initializer declaration node. >+ * Field declarations are never abridged. Note that the AST for the body of >+ * that one unabridged method (or initializer) is 100% complete; it has all >+ * its statements, including any local or anonymous type declarations >+ * embedded within them. When the the given position is not located within >+ * the source range of any body declaration of a top-level type, the AST >+ * returned is a skeleton that includes nodes for all and only the major >+ * declarations; this kind of AST is still quite useful because it contains >+ * all the constructs that introduce names visible to the world outside the >+ * compilation unit. >+ * </p> >+ * <p> >+ * In all other respects, this method works the same as >+ * {@link #parseCompilationUnit(ICompilationUnit,boolean,WorkingCopyOwner) >+ * parseCompilationUnit(ICompilationUnit,boolean,WorkingCopyOwner)}. >+ * The source string is obtained from the Java model element using >+ * <code>ICompilationUnit.getSource()</code>. >+ * </p> >+ * <p> >+ * The returned compilation unit node is the root node of a new AST. >+ * Each node in the subtree carries source range(s) information relating back >+ * to positions in the source string (the source string is not remembered >+ * with the AST). >+ * The source range usually begins at the first character of the first token >+ * corresponding to the node; leading whitespace and comments are <b>not</b> >+ * included. The source range usually extends through the last character of >+ * the last token corresponding to the node; trailing whitespace and >+ * comments are <b>not</b> included. >+ * If a syntax error is detected while parsing, the relevant node(s) of the >+ * tree will be flagged as <code>MALFORMED</code>. >+ * </p> >+ * <p> >+ * Several options are available while parsing the source: >+ * <ul> >+ * <li>- <code>ResolveBindings</code> >+ * When this flag is set, the various names and types appearing in >+ * the compilation unit can be resolved to "bindings" by calling >+ * the <code>resolveBinding</code> methods. These bindings draw >+ * connections between the different parts of a program, and generally >+ * afford a more powerful vantage point for clients who wish to >+ * analyze a program's structure more deeply. These bindings come >+ * at a considerable cost in both time and space, however, and should >+ * not be requested frivolously. The additional space is not reclaimed >+ * until the AST, all its nodes, and all its bindings become garbage. >+ * So it is very important to not retain any of these objects longer >+ * than absolutely necessary. Bindings are resolved at the time the >+ * AST is created. Subsequent modifications to the AST do not affect >+ * the bindings returned by <code>resolveBinding</code> methods in >+ * any way; these methods return the same binding as before the AST >+ * was modified (including modifications that rearrange subtrees by >+ * reparenting nodes). >+ * When this flag is not set, the analysis does not go beyond parsing >+ * and building the tree, and all <code>resolveBinding</code> methods >+ * return <code>null</code> from the outset. >+ * </li> >+ * <li>- <code>InsideComments</code> >+ * When this flag is set, all comments of the compilation unit are stored >+ * and parsed to identify possible Javadoc tags. >+ * Comments are stored in a list <code>comments</code> of <code>Comment</code>. >+ * There are three different kind of comments: line, block and javadoc. >+ * Javadoc comments are those which were already defined since version 2.0, >+ * but they are now structured and not only a flat text. >+ * @see Javadoc for more details on this AST node structure >+ * </li> >+ * </ul> >+ * Use OR operator to set several options simultaneously. For example, to set >+ * both bindings resolution and comments, set options parameter to: >+ * <code>ResolveBindings | InsideComments</code>. >+ * </p> >+ * <p> >+ * When bindings are created, instead of considering compilation units on disk only >+ * one can supply a <code>WorkingCopyOwner</code>. Working copies owned >+ * by this owner take precedence over the underlying compilation units when looking >+ * up names and drawing the connections. >+ * </p> >+ * >+ * @param unit the Java model compilation unit whose source code is to be parsed >+ * @param position a position into the corresponding body declaration >+ * @param options an integer which sets parse options. >+ * @param owner the owner of working copies that take precedence over underlying >+ * compilation units >+ * @return the abridged compilation unit node >+ * @exception IllegalArgumentException if the given Java element does not >+ * exist or the source range is null or if its source string cannot be obtained >+ * @see ASTNode#getFlags() >+ * @see ASTNode#MALFORMED >+ * @see ASTNode#getStartPosition() >+ * @see ASTNode#getLength() >+ * @since 3.0 > */ > public static CompilationUnit parsePartialCompilationUnit( > ICompilationUnit unit, > int position, >- boolean resolveBindings, >+ int options, > WorkingCopyOwner owner) { > > if (unit == null) { >@@ -1056,8 +1811,8 @@ > > NodeSearcher searcher = new NodeSearcher(position); > >- final Map options = unit.getJavaProject().getOptions(true); >- if (resolveBindings) { >+ final Map javaOptions = unit.getJavaProject().getOptions(true); >+ if ((options & ResolveBindings) == ResolveBindings) { > NameLookup lookup = null; > CompilationUnitDeclaration compilationUnitDeclaration = null; > try { >@@ -1074,7 +1829,7 @@ > false/*don't cleanup*/, > source); > >- ASTConverter converter = new ASTConverter(options, true); >+ ASTConverter converter = new ASTConverter(javaOptions, options); > AST ast = new AST(); > BindingResolver resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope); > ast.setBindingResolver(resolver); >@@ -1092,9 +1847,9 @@ > CompilationUnitDeclaration compilationUnitDeclaration2 = CompilationUnitResolver.parse( > source, > searcher, >- options); >+ javaOptions); > >- ASTConverter converter = new ASTConverter(options, false); >+ ASTConverter converter = new ASTConverter(javaOptions, options^ResolveBindings); > AST ast = new AST(); > final BindingResolver resolver = new BindingResolver(); > ast.setBindingResolver(resolver); >@@ -1116,9 +1871,9 @@ > CompilationUnitDeclaration compilationUnitDeclaration = CompilationUnitResolver.parse( > source, > searcher, >- options); >+ javaOptions); > >- ASTConverter converter = new ASTConverter(options, false); >+ ASTConverter converter = new ASTConverter(javaOptions, options); > AST ast = new AST(); > final BindingResolver resolver = new BindingResolver(); > ast.setBindingResolver(resolver); >@@ -1143,7 +1898,7 @@ > * @return the binding resolver for this AST > */ > BindingResolver getBindingResolver() { >- return resolver; >+ return this.resolver; > } > > /** >@@ -1498,6 +2253,49 @@ > */ > public Javadoc newJavadoc() { > Javadoc result = new Javadoc(this); >+ return result; >+ } >+ >+ /** >+ * Creates and returns a new line comment node. >+ * Initially the new node has an unspecified, but legal, line comment. >+ * >+ * @return a new unparented LineComment comment node >+ */ >+ public LineComment newLineComment() { >+ LineComment result = new LineComment(this); >+ return result; >+ } >+ >+ /** >+ * Creates and returns a new line comment node. >+ * Initially the new node has an unspecified, but legal, line comment. >+ * >+ * @return a new unparented BlockComment comment node >+ */ >+ public BlockComment newBlockComment() { >+ BlockComment result = new BlockComment(this); >+ return result; >+ } >+ >+ /** >+ * Creates and returns a new javadoc tag node. >+ * By default, the javadoc tag has an empty identifier. >+ * >+ * @return a new unparented JavadocTag node >+ */ >+ public JavadocTag newJavadocTag() { >+ JavadocTag result = new JavadocTag(this); >+ return result; >+ } >+ >+ /** >+ * Creates and returns a new javadoc argument node. >+ * >+ * @return a new unparented JavadocArgument node >+ */ >+ public JavadocArgument newJavadocArgument() { >+ JavadocArgument result = new JavadocArgument(this); > return result; > } > >Index: dom/org/eclipse/jdt/core/dom/ASTConverter.java >=================================================================== >retrieving revision 1.124 >diff -u -r1.124 ASTConverter.java >--- dom/org/eclipse/jdt/core/dom/ASTConverter.java 22 Nov 2003 16:01:01 -0000 1.124 >+++ dom/org/eclipse/jdt/core/dom/ASTConverter.java 5 Dec 2003 14:08:41 -0000 >@@ -12,10 +12,6 @@ > package org.eclipse.jdt.core.dom; > > import java.util.*; >-import java.util.HashSet; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Set; > > import org.eclipse.jdt.core.JavaCore; > import org.eclipse.jdt.core.compiler.IProblem; >@@ -33,20 +29,34 @@ > > private AST ast; > private char[] compilationUnitSource; >- private Scanner scanner; >+ private DOMScanner scanner; > private boolean resolveBindings; >+ private boolean insideComments; > private Set pendingThisExpressionScopeResolution; > private Set pendingNameScopeResolution; > >- public ASTConverter(Map options, boolean resolveBindings) { >+ public ASTConverter(Map compilerOptions, boolean resolveBindings) { > this.resolveBindings = resolveBindings; >- scanner = new Scanner( >- true /*comment*/, >- false /*whitespace*/, >- false /*nls*/, >- JavaCore.VERSION_1_4.equals(options.get(JavaCore.COMPILER_SOURCE)) ? ClassFileConstants.JDK1_4 : ClassFileConstants.JDK1_3 /*sourceLevel*/, >- null /*taskTags*/, >- null/*taskPriorities*/); >+ this.insideComments = false; >+ this.scanner = new DOMScanner( >+ true /*comment*/, >+ false /*whitespace*/, >+ false /*nls*/, >+ JavaCore.VERSION_1_4.equals(compilerOptions.get(JavaCore.COMPILER_SOURCE)) ? ClassFileConstants.JDK1_4 : ClassFileConstants.JDK1_3 /*sourceLevel*/, >+ null /*taskTags*/, >+ null/*taskPriorities*/); >+ } >+ >+ public ASTConverter(Map compilerOptions, int options) { >+ this.resolveBindings = (options & AST.ResolveBindings) != 0; >+ this.insideComments = (options & AST.InsideComments) != 0; >+ this.scanner = new DOMScanner( >+ true /*comment*/, >+ false /*whitespace*/, >+ false /*nls*/, >+ JavaCore.VERSION_1_4.equals(compilerOptions.get(JavaCore.COMPILER_SOURCE)) ? ClassFileConstants.JDK1_4 : ClassFileConstants.JDK1_3 /*sourceLevel*/, >+ null /*taskTags*/, >+ null/*taskPriorities*/); > } > > public void setAST(AST ast) { >@@ -55,11 +65,11 @@ > > public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) { > this.compilationUnitSource = source; >- scanner.setSource(source); >+ this.scanner.setSource(source); > CompilationUnit compilationUnit = this.ast.newCompilationUnit(); > // handle the package declaration immediately > // There is no node corresponding to the package declaration >- if (resolveBindings) { >+ if (this.resolveBindings) { > recordNodes(compilationUnit, unit); > } > if (unit.currentPackage != null) { >@@ -73,6 +83,15 @@ > compilationUnit.imports().add(convertImport(imports[i])); > } > } >+ // Parse comments >+ int[][] comments = unit.comments; >+ if (comments != null) { >+ int commentsLength = comments.length; >+ for (int i = 0; i < commentsLength; i++) { >+ compilationUnit.comments().add(createComment(comments[i])); >+ } >+ } >+ > org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit.types; > if (types != null) { > int typesLength = types.length; >@@ -85,7 +104,7 @@ > if (unit.compilationResult.problemCount != 0) { > propagateErrors(compilationUnit, unit.compilationResult.problems, unit.compilationResult.problemCount); > } >- if (resolveBindings) { >+ if (this.resolveBindings) { > lookupForScopes(); > } > return compilationUnit; >@@ -108,7 +127,7 @@ > } > packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1); > packageDeclaration.setName(name); >- if (resolveBindings) { >+ if (this.resolveBindings) { > recordNodes(packageDeclaration, importReference); > recordNodes(name, compilationUnitDeclaration); > } >@@ -133,7 +152,7 @@ > importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1); > importDeclaration.setName(name); > importDeclaration.setOnDemand(onDemand); >- if (resolveBindings) { >+ if (this.resolveBindings) { > recordNodes(importDeclaration, importReference); > } > return importDeclaration; >@@ -180,7 +199,9 @@ > } > > buildBodyDeclarations(typeDeclaration, typeDecl); >- setJavaDocComment(typeDecl); >+ // The javadoc comment is now got from list store in compilation unit declaration >+ // @see BodyDeclaration#getComment(int) >+ //setJavaDocComment(typeDecl); > if (this.resolveBindings) { > recordNodes(typeDecl, typeDeclaration); > recordNodes(typeName, typeDeclaration); >@@ -257,7 +278,9 @@ > initializer.setBody(convert(oldInitializer.block)); > initializer.setModifiers(oldInitializer.modifiers); > initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1); >- setJavaDocComment(initializer); >+ // The javadoc comment is now got from list store in compilation unit declaration >+ // @see BodyDeclaration#getComment(int) >+ //setJavaDocComment(initializer); > bodyDeclarations.add(initializer); > return; > } >@@ -519,7 +542,7 @@ > PrimitiveType primitiveType = this.ast.newPrimitiveType(getPrimitiveTypeCode(name)); > primitiveType.setSourceRange(sourceStart, end - sourceStart + 1); > type = this.ast.newArrayType(primitiveType, dimensions); >- if (resolveBindings) { >+ if (this.resolveBindings) { > // store keys for inner types > completeRecord((ArrayType) type, typeReference); > } >@@ -716,7 +739,9 @@ > } > } > >- setJavaDocComment(methodDecl); >+ // The javadoc comment is now got from list store in compilation unit declaration >+ // @see BodyDeclaration#getComment(int) >+ //setJavaDocComment(methodDecl); > if (this.resolveBindings) { > recordNodes(methodDecl, methodDeclaration); > recordNodes(methodName, methodDeclaration); >@@ -1768,7 +1793,7 @@ > end = exceptionArgument.sourceEnd + 1; > } > int start = statement.sourceStart; >- int sourceEnd = retrieveEndingSemiColonPosition(end, compilationUnitSource.length); >+ int sourceEnd = retrieveEndingSemiColonPosition(end, this.compilationUnitSource.length); > assertStatement.setSourceRange(start, sourceEnd - start + 1); > return assertStatement; > } >@@ -2176,7 +2201,7 @@ > throw new IllegalArgumentException("Not a primitive type");//$NON-NLS-1$ > } > >- /** >+ /* > * This method is used to set the right end position for expression > * statement. The actual AST nodes don't include the trailing semicolon. > * This method fixes the length of the corresponding node. >@@ -2186,14 +2211,14 @@ > int length = node.getLength(); > int end = start + length; > int count = 0; >- scanner.resetTo(end, this.compilationUnitSource.length); >+ this.scanner.resetTo(end, this.compilationUnitSource.length); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameSEMICOLON: > if (count == 0) { >- node.setSourceRange(start, scanner.currentPosition - start); >+ node.setSourceRange(start, this.scanner.currentPosition - start); > return; > } > break; >@@ -2230,13 +2255,13 @@ > int start = node.getStartPosition(); > int length = node.getLength(); > int end = start + length; >- scanner.resetTo(end, this.compilationUnitSource.length); >+ this.scanner.resetTo(end, this.compilationUnitSource.length); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameCOLON: >- node.setSourceRange(start, scanner.currentPosition - start); >+ node.setSourceRange(start, this.scanner.currentPosition - start); > return; > } > } >@@ -2247,14 +2272,14 @@ > > private int retrieveEndingSemiColonPosition(int start, int end) { > int count = 0; >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameSEMICOLON: > if (count == 0) { >- return scanner.currentPosition - 1; >+ return this.scanner.currentPosition - 1; > } > break; > case TerminalTokens.TokenNameLBRACE : >@@ -2291,11 +2316,11 @@ > * @return int the dimension found > */ > private int retrieveExtraDimension(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > int dimensions = 0; > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameRBRACKET://166 > dimensions++; >@@ -2322,11 +2347,11 @@ > * @return int the dimension found > */ > private int retrieveEndOfDimensionsPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > int foundPosition = -1; > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameLBRACKET: > case TerminalTokens.TokenNameCOMMENT_BLOCK: >@@ -2334,7 +2359,7 @@ > case TerminalTokens.TokenNameCOMMENT_LINE: > break; > case TerminalTokens.TokenNameRBRACKET://166 >- foundPosition = scanner.currentPosition - 1; >+ foundPosition = this.scanner.currentPosition - 1; > break; > default: > return foundPosition; >@@ -2351,13 +2376,13 @@ > * @return int the dimension found, -1 if none > */ > private int retrieveStartingCatchPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNamecatch://225 >- return scanner.startPosition; >+ return this.scanner.startPosition; > } > } > } catch(InvalidInputException e) { >@@ -2371,10 +2396,10 @@ > * @return int the dimension found, -1 if none > */ > private int retrieveEndOfElementTypeNamePosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameIdentifier: > case TerminalTokens.TokenNamebyte: >@@ -2384,7 +2409,7 @@ > case TerminalTokens.TokenNameint: > case TerminalTokens.TokenNamelong: > case TerminalTokens.TokenNameshort: >- return scanner.currentPosition - 1; >+ return this.scanner.currentPosition - 1; > } > } > } catch(InvalidInputException e) { >@@ -2398,13 +2423,13 @@ > * @return int the dimension found, -1 if none > */ > private int retrieveRightBracketPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameRBRACKET: >- return scanner.currentPosition - 1; >+ return this.scanner.currentPosition - 1; > } > } > } catch(InvalidInputException e) { >@@ -2418,13 +2443,13 @@ > * @return int the position found > */ > private int retrieveEndOfRightParenthesisPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameRPAREN: >- return scanner.currentPosition; >+ return this.scanner.currentPosition; > } > } > } catch(InvalidInputException e) { >@@ -2434,15 +2459,15 @@ > } > > private int retrieveProperRightBracketPosition(int bracketNumber, int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token, count = 0; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameRBRACKET: > count++; > if (count == bracketNumber) { >- return scanner.currentPosition - 1; >+ return this.scanner.currentPosition - 1; > } > } > } >@@ -2457,13 +2482,13 @@ > * @return int the dimension found, -1 if none > */ > private int retrieveStartBlockPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameLBRACE://110 >- return scanner.startPosition; >+ return this.scanner.startPosition; > } > } > } catch(InvalidInputException e) { >@@ -2477,13 +2502,13 @@ > * @return int the dimension found, -1 if none > */ > private int retrieveIdentifierEndPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameIdentifier://110 >- return scanner.getCurrentTokenEndPosition(); >+ return this.scanner.getCurrentTokenEndPosition(); > } > } > } catch(InvalidInputException e) { >@@ -2497,11 +2522,11 @@ > * @return int the dimension found, -1 if none > */ > private int retrieveEndBlockPosition(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > int count = 0; > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameLBRACE://110 > count++; >@@ -2509,7 +2534,7 @@ > case TerminalTokens.TokenNameRBRACE://95 > count--; > if (count == 0) { >- return scanner.currentPosition - 1; >+ return this.scanner.currentPosition - 1; > } > } > } >@@ -2525,11 +2550,11 @@ > */ > private int retrieveRightBraceOrSemiColonPosition(MethodDeclaration node, org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) { > int start = node.getStartPosition(); >- scanner.resetTo(start, methodDeclaration.declarationSourceEnd); >+ this.scanner.resetTo(start, methodDeclaration.declarationSourceEnd); > try { > int token; > int braceCounter = 0; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameLBRACE : > braceCounter++; >@@ -2537,12 +2562,12 @@ > case TerminalTokens.TokenNameRBRACE : > braceCounter--; > if (braceCounter == 0) { >- return scanner.currentPosition; >+ return this.scanner.currentPosition; > } > break; > case TerminalTokens.TokenNameSEMICOLON : > if (braceCounter == 0) { >- return scanner.currentPosition; >+ return this.scanner.currentPosition; > } > } > } >@@ -2557,11 +2582,11 @@ > * @return int the position found. > */ > private int retrievePositionBeforeNextCommaOrSemiColon(int start, int end) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > int braceCounter = 0; > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameLBRACE : > braceCounter++; >@@ -2584,7 +2609,7 @@ > case TerminalTokens.TokenNameCOMMA : > case TerminalTokens.TokenNameSEMICOLON : > if (braceCounter == 0) { >- return scanner.startPosition - 1; >+ return this.scanner.startPosition - 1; > } > } > } >@@ -2669,7 +2694,9 @@ > fieldDeclaration.setModifiers(fieldDecl.modifiers & legalModifiers); > fieldDeclaration.setFlags(ASTNode.MALFORMED); > } >- setJavaDocComment(fieldDeclaration); >+ // The javadoc comment is now got from list store in compilation unit declaration >+ // @see BodyDeclaration#getComment(int) >+ //setJavaDocComment(fieldDeclaration); > return fieldDeclaration; > } > >@@ -2917,17 +2944,18 @@ > variableDeclarationExpression.setType(type); > } > } >- >+ >+ /* > private void setJavaDocComment(BodyDeclaration bodyDeclaration) { >- scanner.resetTo(bodyDeclaration.getStartPosition(), bodyDeclaration.getStartPosition() + bodyDeclaration.getLength()); >+ this.scanner.resetTo(bodyDeclaration.getStartPosition(), bodyDeclaration.getStartPosition() + bodyDeclaration.getLength()); > try { > int token; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameCOMMENT_JAVADOC: //1003 > Javadoc javadocComment = this.ast.newJavadoc(); >- int start = scanner.startPosition; >- int length = scanner.currentPosition - start; >+ int start = this.scanner.startPosition; >+ int length = this.scanner.currentPosition - start; > char[] contents = new char[length]; > System.arraycopy(this.compilationUnitSource, start, contents, 0, length); > javadocComment.setComment(new String(contents)); >@@ -2942,7 +2970,32 @@ > // ignore > } > } >- >+ */ >+ >+ private Comment createComment(int[] positions) { >+ // Create comment node >+ Comment comment = null; >+ int start = positions[0]; >+ int end = positions[1]; >+ if (positions[1]>0) { // Javadoc comments have positive end position >+ comment = this.ast.newJavadoc(); >+ } else { >+ end = -end; >+ if (positions[0]>0) { // Block comment have positive start position >+ comment = this.ast.newBlockComment(); >+ } else { // Line comment have negative start and end position >+ start = -start; >+ comment = this.ast.newLineComment(); >+ } >+ } >+ int length = end - start; >+ String contents = new String(this.compilationUnitSource, start, length); >+ comment.setSourceRange(start, length); >+ comment.setParseOn(this.insideComments); >+ comment.setComment(contents); >+ return comment; >+ } >+ > private void propagateErrors(CompilationUnit unit, IProblem[] problems, int problemLength) { > // resize the problem array to the proper size > IProblem[] resizeProblems = null; >@@ -3007,12 +3060,12 @@ > int end = expression.sourceEnd; > int leftParentCount = 1; > int rightParentCount = 0; >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > try { >- int token = scanner.getNextToken(); >- expression.sourceStart = scanner.currentPosition; >+ int token = this.scanner.getNextToken(); >+ expression.sourceStart = this.scanner.currentPosition; > boolean stop = false; >- while (!stop && ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) { >+ while (!stop && ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) { > switch(token) { > case TerminalTokens.TokenNameLPAREN: > leftParentCount++; >@@ -3025,20 +3078,20 @@ > } > } > } >- expression.sourceEnd = scanner.startPosition - 1; >+ expression.sourceEnd = this.scanner.startPosition - 1; > } catch(InvalidInputException e) { > // ignore > } > } > > private void retrieveIdentifierAndSetPositions(int start, int end, Name name) { >- scanner.resetTo(start, end); >+ this.scanner.resetTo(start, end); > int token; > try { >- while((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > if (token == TerminalTokens.TokenNameIdentifier) { >- int startName = scanner.startPosition; >- int endName = scanner.currentPosition - 1; >+ int startName = this.scanner.startPosition; >+ int endName = this.scanner.currentPosition - 1; > name.setSourceRange(startName, endName - startName + 1); > return; > } >@@ -3053,11 +3106,11 @@ > */ > private void removeTrailingCommentFromExpressionEndingWithAParen(ASTNode node) { > int start = node.getStartPosition(); >- scanner.resetTo(start, start + node.getLength()); >+ this.scanner.resetTo(start, start + node.getLength()); > int token; > int parenCounter = 0; > try { >- while((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameLPAREN : > parenCounter++; >@@ -3065,7 +3118,7 @@ > case TerminalTokens.TokenNameRPAREN : > parenCounter--; > if (parenCounter == 0) { >- int end = scanner.currentPosition - 1; >+ int end = this.scanner.currentPosition - 1; > node.setSourceRange(start, end - start + 1); > } > } >@@ -3080,11 +3133,11 @@ > */ > private void removeLeadingAndTrailingCommentsFromLiteral(ASTNode node) { > int start = node.getStartPosition(); >- scanner.resetTo(start, start + node.getLength()); >+ this.scanner.resetTo(start, start + node.getLength()); > int token; > int startPosition = -1; > try { >- while((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >+ while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { > switch(token) { > case TerminalTokens.TokenNameIntegerLiteral : > case TerminalTokens.TokenNameFloatingPointLiteral : >@@ -3092,13 +3145,13 @@ > case TerminalTokens.TokenNameDoubleLiteral : > case TerminalTokens.TokenNameCharacterLiteral : > if (startPosition == -1) { >- startPosition = scanner.startPosition; >+ startPosition = this.scanner.startPosition; > } >- int end = scanner.currentPosition; >+ int end = this.scanner.currentPosition; > node.setSourceRange(startPosition, end - startPosition); > return; > case TerminalTokens.TokenNameMINUS : >- startPosition = scanner.startPosition; >+ startPosition = this.scanner.startPosition; > break; > } > } >Index: dom/org/eclipse/jdt/core/dom/ASTMatcher.java >=================================================================== >retrieving revision 1.15 >diff -u -r1.15 ASTMatcher.java >--- dom/org/eclipse/jdt/core/dom/ASTMatcher.java 28 Jul 2003 14:51:30 -0000 1.15 >+++ dom/org/eclipse/jdt/core/dom/ASTMatcher.java 5 Dec 2003 14:08:41 -0000 >@@ -40,7 +40,7 @@ > * matchers. > * </p> > * >- * @see ASTNode#subtreeMatch >+ * @see ASTNode#subtreeMatch(ASTMatcher, Object) > * @since 2.0 > */ > public class ASTMatcher { >@@ -843,7 +843,101 @@ > return false; > } > Javadoc o = (Javadoc) other; >- return safeEquals(node.getComment(), o.getComment()); >+ if (node.isParseOn() && o.isParseOn()) { >+ return safeSubtreeListMatch(node.tags(), o.tags()); >+ } else { >+ return safeEquals(node.getText(), o.getText()); >+ } >+ } >+ >+ /** >+ * Returns whether the given node and the other object match. >+ * <p> >+ * The default implementation provided by this class tests whether the >+ * other object is a node of the same type with structurally isomorphic >+ * child subtrees. Subclasses may override this method as needed. >+ * </p> >+ * >+ * @param node the node >+ * @param other the other object, or <code>null</code> >+ * @return <code>true</code> if the subtree matches, or >+ * <code>false</code> if they do not match or the other object has a >+ * different node type or is <code>null</code> >+ */ >+ public boolean match(LineComment node, Object other) { >+ if (!(other instanceof LineComment)) { >+ return false; >+ } >+ LineComment o = (LineComment) other; >+ return safeSubtreeListMatch(node.tags(), o.tags()); >+ } >+ >+ /** >+ * Returns whether the given node and the other object match. >+ * <p> >+ * The default implementation provided by this class tests whether the >+ * other object is a node of the same type with structurally isomorphic >+ * child subtrees. Subclasses may override this method as needed. >+ * </p> >+ * >+ * @param node the node >+ * @param other the other object, or <code>null</code> >+ * @return <code>true</code> if the subtree matches, or >+ * <code>false</code> if they do not match or the other object has a >+ * different node type or is <code>null</code> >+ */ >+ public boolean match(BlockComment node, Object other) { >+ if (!(other instanceof BlockComment)) { >+ return false; >+ } >+ BlockComment o = (BlockComment) other; >+ return safeSubtreeListMatch(node.tags(), o.tags()); >+ } >+ >+ /** >+ * Returns whether the given node and the other object match. >+ * <p> >+ * The default implementation provided by this class tests whether the >+ * other object is a node of the same type with structurally isomorphic >+ * child subtrees. Subclasses may override this method as needed. >+ * </p> >+ * >+ * @param node the node >+ * @param other the other object, or <code>null</code> >+ * @return <code>true</code> if the subtree matches, or >+ * <code>false</code> if they do not match or the other object has a >+ * different node type or is <code>null</code> >+ */ >+ public boolean match(JavadocTag node, Object other) { >+ if (!(other instanceof JavadocTag)) { >+ return false; >+ } >+ JavadocTag o = (JavadocTag) other; >+ return (node.getIdentifier().equals(o.getIdentifier()) && >+ safeEquals(node.getDescription(), o.getDescription()) && >+ safeSubtreeMatch(node.getReference(), o.getReference())); >+ } >+ >+ /** >+ * Returns whether the given node and the other object match. >+ * <p> >+ * The default implementation provided by this class tests whether the >+ * other object is a node of the same type with structurally isomorphic >+ * child subtrees. Subclasses may override this method as needed. >+ * </p> >+ * >+ * @param node the node >+ * @param other the other object, or <code>null</code> >+ * @return <code>true</code> if the subtree matches, or >+ * <code>false</code> if they do not match or the other object has a >+ * different node type or is <code>null</code> >+ */ >+ public boolean match(JavadocArgument node, Object other) { >+ if (!(other instanceof JavadocArgument)) { >+ return false; >+ } >+ JavadocArgument o = (JavadocArgument) other; >+ return (node.getArgument().equals(o.getArgument())); > } > > /** >Index: dom/org/eclipse/jdt/core/dom/ASTNode.java >=================================================================== >retrieving revision 1.32 >diff -u -r1.32 ASTNode.java >--- dom/org/eclipse/jdt/core/dom/ASTNode.java 25 Nov 2003 17:22:15 -0000 1.32 >+++ dom/org/eclipse/jdt/core/dom/ASTNode.java 5 Dec 2003 14:08:41 -0000 >@@ -108,7 +108,7 @@ > * problem (support for this is planned for a future release). > * </p> > * >- * @see AST#parseCompilationUnit >+ * @see AST#parseCompilationUnit(char[]) and other similar methods > * @see ASTVisitor > * @since 2.0 > */ >@@ -549,6 +549,35 @@ > public static final int INSTANCEOF_EXPRESSION = 62; > > /** >+ * Node type constant indicating a node of type >+ * <code>LineComment</code>. >+ * @see LineComment >+ */ >+ public static final int LINE_COMMENT = 63; >+ >+ >+ /** >+ * Node type constant indicating a node of type >+ * <code>BlockComment</code>. >+ * @see BlockComment >+ */ >+ public static final int BLOCK_COMMENT = 64; >+ >+ /** >+ * Node type constant indicating a node of type >+ * <code>JavadocTag</code>. >+ * @see JavadocTag >+ */ >+ public static final int JAVADOC_TAG = 65; >+ >+ /** >+ * Node type constant indicating a node of type >+ * <code>JavadocArgument</code>. >+ * @see JavadocArgument >+ */ >+ public static final int JAVADOC_ARGUMENT = 66; >+ >+ /** > * Owning AST. > */ > private final AST owner; >@@ -562,7 +591,7 @@ > /** > * An unmodifiable empty map (used to implement <code>properties()</code>). > * >- * @see #properties >+ * @see #properties() > */ > private static Map UNMODIFIABLE_EMPTY_MAP > = Collections.unmodifiableMap(new HashMap(1)); >@@ -927,7 +956,7 @@ > public ASTNode getParent() { > return parent; > } >- >+ > /** > * Returns the root node at or above this node; returns this node if > * it is a root. >@@ -947,6 +976,23 @@ > } > > /** >+ * Returns the compilation unit which owns this node; returns this node if >+ * it is a compilation unit or null if none was found. >+ * >+ * @return the compilation unit node founds in node hierarchy or null if none was found >+ */ >+ public CompilationUnit getCompilationUnit() { >+ ASTNode candidate = this; >+ while (candidate != null) { >+ if (candidate instanceof CompilationUnit) { >+ return (CompilationUnit) candidate; >+ } >+ candidate = candidate.getParent(); >+ } >+ return null; >+ } >+ >+ /** > * Internal callback indicating that a field of this node is about to > * be modified. > */ >@@ -1062,7 +1108,7 @@ > * > * @param propertyName the property name > * @return the property value, or <code>null</code> if none >- * @see #setProperty >+ * @see #setProperty(String, Object) > */ > public Object getProperty(String propertyName) { > if (propertyName == null) { >@@ -1102,7 +1148,7 @@ > * > * @param propertyName the property name > * @param data the new property value, or <code>null</code> if none >- * @see #getProperty >+ * @see #getProperty(String) > */ > public void setProperty(String propertyName, Object data) { > if (propertyName == null) { >@@ -1208,7 +1254,7 @@ > * </p> > * > * @return the bitwise-or of individual flags >- * @see #setFlags >+ * @see #setFlags(int) > * @see #MALFORMED > */ > public int getFlags() { >@@ -1228,7 +1274,7 @@ > * </p> > * > * @param flags the bitwise-or of individual flags >- * @see #getFlags >+ * @see #getFlags() > * @see #MALFORMED > */ > public void setFlags(int flags) { >@@ -1438,11 +1484,27 @@ > * > * @return the 0-based character index, or <code>-1</code> > * if no source position information is recorded for this node >- * @see #getLength >+ * @see #getLength() > * @see AST#parseCompilationUnit > */ > public int getStartPosition() { >- return startPosition; >+ return this.startPosition; >+ } >+ >+ /** >+ * Returns the character index into the original source file indicating >+ * where the source fragment corresponding to this node ends. >+ * >+ * @return the 0-based character index, or <code>-1</code> >+ * if no source position information is recorded for this node >+ * @see #getLength() >+ */ >+ public int getEndPosition() { >+ if (this.length==0) { >+ return -1; >+ }else { >+ return this.startPosition+this.length-1; >+ } > } > > /** >@@ -1460,7 +1522,7 @@ > * @see AST#parseCompilationUnit > */ > public int getLength() { >- return length; >+ return this.length; > } > > /** >@@ -1477,8 +1539,8 @@ > * @param length a (possibly 0) length, > * or <code>0</code> if no source position information is recorded > * for this node >- * @see #getStartPosition >- * @see #getLength >+ * @see #getStartPosition() >+ * @see #getLength() > * @see AST#parseCompilationUnit > */ > public void setSourceRange(int startPosition, int length) { >@@ -1537,7 +1599,7 @@ > // print the subtree by default > appendPrintString(buffer); > } >- >+ > /** > * Appends a standard Java source code representation of this subtree to the given > * string buffer. >@@ -1549,19 +1611,19 @@ > this.accept(printer); > buffer.append(printer.getResult()); > } >- >+ > /** > * Estimate of size of an object header in bytes. > */ > static final int HEADERS = 12; >- >+ > /** > * Approximate base size of an AST node instance in bytes, > * including object header and instance fields. > * That is, HEADERS + (# instance vars in ASTNode)*4. > */ > static final int BASE_NODE_SIZE = HEADERS + 7 * 4; >- >+ > /** > * Returns an estimate of the memory footprint in bytes of the entire > * subtree rooted at this node. >@@ -1571,7 +1633,7 @@ > public final int subtreeBytes() { > return treeSize(); > } >- >+ > /** > * Returns an estimate of the memory footprint in bytes of the entire > * subtree rooted at this node. >Index: dom/org/eclipse/jdt/core/dom/ASTVisitor.java >=================================================================== >retrieving revision 1.10 >diff -u -r1.10 ASTVisitor.java >--- dom/org/eclipse/jdt/core/dom/ASTVisitor.java 28 Jul 2003 14:51:30 -0000 1.10 >+++ dom/org/eclipse/jdt/core/dom/ASTVisitor.java 5 Dec 2003 14:08:41 -0000 >@@ -93,7 +93,7 @@ > * </ul> > * </p> > * >- * @see ASTNode#accept >+ * @see ASTNode#accept(ASTVisitor) > */ > public abstract class ASTVisitor { > >@@ -165,6 +165,9 @@ > public boolean visit(ClassInstanceCreation node) { > return true; > } >+ public boolean visit(Comment node) { >+ return true; >+ } > public boolean visit(CompilationUnit node) { > return true; > } >@@ -210,9 +213,21 @@ > public boolean visit(Initializer node) { > return true; > } >+ public boolean visit(LineComment node) { >+ return true; >+ } >+ public boolean visit(BlockComment node) { >+ return true; >+ } > public boolean visit(Javadoc node) { > return true; > } >+ public boolean visit(JavadocTag node) { >+ return true; >+ } >+ public boolean visit(JavadocArgument node) { >+ return true; >+ } > public boolean visit(LabeledStatement node) { > return true; > } >@@ -355,6 +370,9 @@ > public void endVisit(CompilationUnit node) { > // default implementation: do nothing > } >+ public void endVisit(Comment node) { >+ // default implementation: do nothing >+ } > public void endVisit(ConditionalExpression node) { > // default implementation: do nothing > } >@@ -397,7 +415,19 @@ > public void endVisit(Initializer node) { > // default implementation: do nothing > } >+ public void endVisit(LineComment node) { >+ // default implementation: do nothing >+ } >+ public void endVisit(BlockComment node) { >+ // default implementation: do nothing >+ } > public void endVisit(Javadoc node) { >+ // default implementation: do nothing >+ } >+ public void endVisit(JavadocTag node) { >+ // default implementation: do nothing >+ } >+ public void endVisit(JavadocArgument node) { > // default implementation: do nothing > } > public void endVisit(LabeledStatement node) { >Index: dom/org/eclipse/jdt/core/dom/BodyDeclaration.java >=================================================================== >retrieving revision 1.6 >diff -u -r1.6 BodyDeclaration.java >--- dom/org/eclipse/jdt/core/dom/BodyDeclaration.java 15 Nov 2003 02:12:57 -0000 1.6 >+++ dom/org/eclipse/jdt/core/dom/BodyDeclaration.java 5 Dec 2003 14:08:41 -0000 >@@ -72,9 +72,17 @@ > * Returns the Javadoc comment node. > * > * @return the javadoc comment node, or <code>null</code> if none >+ * TODO (frederic) See if it could be interesting to store the javadoc comment instead of looking for it systematically... > */ > public Javadoc getJavadoc() { >- return optionalJavadoc; >+ CompilationUnit unit = getCompilationUnit(); >+ if (unit != null) { >+ Comment comment = unit.getComment(getStartPosition()); >+ if (comment != null && comment.isJavadoc()) { >+ return (Javadoc) comment; >+ } >+ } >+ return this.optionalJavadoc; > } > > /** >Index: dom/org/eclipse/jdt/core/dom/CompilationUnit.java >=================================================================== >retrieving revision 1.33 >diff -u -r1.33 CompilationUnit.java >--- dom/org/eclipse/jdt/core/dom/CompilationUnit.java 15 Nov 2003 02:11:09 -0000 1.33 >+++ dom/org/eclipse/jdt/core/dom/CompilationUnit.java 5 Dec 2003 14:08:41 -0000 >@@ -55,6 +55,13 @@ > new ASTNode.NodeList(false, TypeDeclaration.class); > > /** >+ * The list of comments in textual order; >+ * initially none (elementType: <code>Comment</code>) >+ */ >+ private ASTNode.NodeList comments = >+ new ASTNode.NodeList(false, Comment.class); >+ >+ /** > * Line end table. If <code>lineEndTable[i] == p</code> then the > * line number <code>i+1</code> ends at character position > * <code>p</code>. Except for the last line, the positions are that >@@ -92,7 +99,7 @@ > * For example, the source string <code>A\nB\nC</code> has > * line end table {1, 3, 4}. > * >- * @param lineEndtable the line end table >+ * @param lineEndTable the line end table > */ > void setLineEndTable(int[] lineEndTable) { > if (lineEndTable == null) { >@@ -155,8 +162,8 @@ > if (visitChildren) { > // visit children in normal left to right reading order > acceptChild(visitor, getPackage()); >- acceptChildren(visitor, imports); >- acceptChildren(visitor, types); >+ acceptChildren(visitor, this.imports); >+ acceptChildren(visitor, this.types); > } > visitor.endVisit(this); > } >@@ -169,7 +176,7 @@ > * @return the package declaration node, or <code>null</code> if none > */ > public PackageDeclaration getPackage() { >- return optionalPackageDeclaration; >+ return this.optionalPackageDeclaration; > } > > /** >@@ -198,7 +205,7 @@ > * (elementType: <code>ImportDeclaration</code>) > */ > public List imports() { >- return imports; >+ return this.imports; > } > > /** >@@ -209,7 +216,18 @@ > * nodes (elementType: <code>TypeDeclaration</code>) > */ > public List types() { >- return types; >+ return this.types; >+ } >+ >+ /** >+ * Returns the live list of nodes for all comments declared in this >+ * compilation unit, in order of appearance. >+ * >+ * @return the live list of comment nodes >+ * (elementType: <code>Comment</code>) >+ */ >+ public List comments() { >+ return this.comments; > } > > /** >@@ -293,7 +311,7 @@ > * key is declared, or <code>null</code> if the key is <code>null</code> > * 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 >+ * @see IBinding#getKey() > * @since 2.1 > */ > public ASTNode findDeclaringNode(String key) { >@@ -318,22 +336,22 @@ > * 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 AST#parseCompilationUnit >+ * @see AST#parseCompilationUnit(char[]) and other similar methods > */ > public int lineNumber(int position) { >- int length = lineEndTable.length; >+ int length = this.lineEndTable.length; > if (length == 0) { > // no line number info > return 1; > } > int low = 0; >- if (position <= lineEndTable[low]) { >+ if (position <= this.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]) { >+ if (position > this.lineEndTable[hi]) { > // position beyond the last line separator > if (position >= getStartPosition() + getLength()) { > // this is beyond the end of the source length >@@ -358,7 +376,7 @@ > // 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]) { >+ if (position <= this.lineEndTable[mid]) { > // assert lineEndTable[low] < position <= lineEndTable[mid] > // && 0 <= low < mid < hi <= length - 1 > hi = mid; >@@ -384,8 +402,8 @@ > * </p> > * > * @return the list of messages, possibly empty >- * @see #getProblems >- * @see AST#parseCompilationUnit >+ * @see #getProblems() >+ * @see AST#parseCompilationUnit(char[]) and other similar methods > */ > public Message[] getMessages() { > if (this.messages == null) { >@@ -398,7 +416,7 @@ > IProblem problem = this.problems[i]; > int start = problem.getSourceStart(); > int end = problem.getSourceEnd(); >- messages[i] = new Message(problem.getMessage(), start, end - start + 1); >+ this.messages[i] = new Message(problem.getMessage(), start, end - start + 1); > } > } > } >@@ -416,12 +434,12 @@ > * </p> > * > * @return the list of detailed problem objects, possibly empty >- * @see #getMessages >- * @see AST#parseCompilationUnit >+ * @see #getMessages() >+ * @see AST#parseCompilationUnit(char[]) and other similar methods > * @since 2.1 > */ > public IProblem[] getProblems() { >- return problems; >+ return this.problems; > } > > /** >@@ -459,8 +477,8 @@ > */ > int memSize() { > int size = BASE_NODE_SIZE + 4 * 4; >- if (lineEndTable != null) { >- size += HEADERS + 4 * lineEndTable.length; >+ if (this.lineEndTable != null) { >+ size += HEADERS + 4 * this.lineEndTable.length; > } > return size; > } >@@ -471,9 +489,53 @@ > int treeSize() { > return > memSize() >- + (optionalPackageDeclaration == null ? 0 : getPackage().treeSize()) >- + imports.listSize() >- + types.listSize(); >+ + (this.optionalPackageDeclaration == null ? 0 : getPackage().treeSize()) >+ + this.imports.listSize() >+ + this.types.listSize(); >+ } >+ >+ /** >+ * Get comment of the list which includes a given position >+ * >+ * @param position The position belonging to the looked up comment >+ * @return Javadoc The comment which includes the given position or null if none was found >+ */ >+ public Comment getComment(int position) { >+ >+ if (this.comments == null) { >+ return null; >+ } >+ int size = this.comments.size(); >+ if (size == 0) { >+ return null; >+ } >+ int bottom = 0, top = size - 1; >+ int i = 0, index = -1; >+ Comment comment = null; >+ while (bottom <= top) { >+ i = (bottom + top) /2; >+ comment = (Comment) this.comments.get(i); >+ if (position < comment.getStartPosition()) { >+ top = i-1; >+ } else if (position >= comment.getEndPosition()) { >+ bottom = i+1; >+ } else { >+ index = i; >+ break; >+ } >+ } >+ if (index<0) { >+ /* >+ comment = (Comment) this.comments.get(i); >+ if (position < comment.getStartPosition()) { >+ index = i; >+ } else { >+ index = i+1; >+ } >+ */ >+ return null; >+ } >+ return (Comment) this.comments.get(index); > } > } > >Index: dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java >=================================================================== >retrieving revision 1.50 >diff -u -r1.50 CompilationUnitResolver.java >--- dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java 22 Nov 2003 16:01:01 -0000 1.50 >+++ dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java 5 Dec 2003 14:08:41 -0000 >@@ -11,22 +11,21 @@ > > package org.eclipse.jdt.core.dom; > >-import org.eclipse.jdt.internal.compiler.Compiler; >-import org.eclipse.jdt.internal.compiler.*; >-import org.eclipse.jdt.internal.compiler.env.*; >-import org.eclipse.jdt.core.ICompilationUnit; >+import java.util.Map; >+ > import org.eclipse.jdt.core.*; >-import org.eclipse.jdt.core.compiler.*; >-import org.eclipse.jdt.internal.core.*; >-import org.eclipse.jdt.internal.compiler.impl.*; >+import org.eclipse.jdt.core.compiler.CharOperation; >+import org.eclipse.jdt.internal.compiler.*; >+import org.eclipse.jdt.internal.compiler.Compiler; > import org.eclipse.jdt.internal.compiler.ast.*; >+import org.eclipse.jdt.internal.compiler.env.INameEnvironment; >+import org.eclipse.jdt.internal.compiler.env.ISourceType; >+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers; > import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; >-import org.eclipse.jdt.internal.compiler.parser.Parser; > import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter; > import org.eclipse.jdt.internal.compiler.problem.*; >- >-import java.util.*; >+import org.eclipse.jdt.internal.core.*; > > class CompilationUnitResolver extends Compiler { > >@@ -77,6 +76,8 @@ > > /** > * Add additional source types >+ * @param sourceTypes >+ * @param packageBinding > */ > public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) { > CompilationResult result = >@@ -88,7 +89,7 @@ > SourceTypeConverter.FIELD_AND_METHOD // need field and methods > | SourceTypeConverter.MEMBER_TYPE // need member types > | SourceTypeConverter.FIELD_INITIALIZATION, // need field initialization: see bug 40476 >- lookupEnvironment.problemReporter, >+ this.lookupEnvironment.problemReporter, > result); > > if (unit != null) { >@@ -97,51 +98,6 @@ > } > } > >- private static Parser createDomParser(ProblemReporter problemReporter) { >- >- return new Parser(problemReporter, false) { >- // old annotation style check which doesn't include all leading comments into declaration >- // for backward compatibility with 2.1 DOM >- public void checkComment() { >- >- if (this.currentElement != null && this.scanner.commentPtr >= 0) { >- flushCommentsDefinedPriorTo(endStatementPosition); // discard obsolete comments >- } >- boolean deprecated = false; >- boolean checkDeprecated = false; >- int lastCommentIndex = -1; >- >- //since jdk1.2 look only in the last java doc comment... >- //look for @deprecated into the first javadoc comment preceeding the declaration >- int commentSourceStart = scanner.commentStarts[lastCommentIndex]; >- // javadoc only (non javadoc comment have negative end positions.) >- if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) { >- continue nextComment; >- } >- if (scanner.commentStops[lastCommentIndex] < 0) { >- continue nextComment; >- } >- checkDeprecated = true; >- int commentSourceEnd = scanner.commentStops[lastCommentIndex] - 1; //stop is one over >- >- deprecated = >- this.javadocParser.checkDeprecation(commentSourceStart, commentSourceEnd); >- this.javadoc = this.javadocParser.javadoc; >- break nextComment; >- } >- if (deprecated) { >- checkAndSetModifiers(AccDeprecated); >- } >- // modify the modifier source start to point at the first comment >- if (lastCommentIndex >= 0 && checkDeprecated) { >- modifiersSourceStart = scanner.commentStarts[lastCommentIndex]; >- } >- >- } >- }; >- } >- > /* > * Low-level API performing the actual compilation > */ >@@ -185,7 +141,7 @@ > * @see org.eclipse.jdt.internal.compiler.Compiler#initializeParser() > */ > public void initializeParser() { >- this.parser = createDomParser(this.problemReporter); >+ this.parser = new DOMParser(this.problemReporter, false); > } > /* > * Compiler crash recovery in case of unexpected runtime exceptions >@@ -260,11 +216,11 @@ > throw new IllegalArgumentException(); > } > CompilerOptions compilerOptions = new CompilerOptions(settings); >- Parser parser = createDomParser( >+ DOMParser parser = new DOMParser( > new ProblemReporter( > DefaultErrorHandlingPolicies.proceedWithAllProblems(), > compilerOptions, >- new DefaultProblemFactory())); >+ new DefaultProblemFactory()), false); > org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = > new org.eclipse.jdt.internal.compiler.batch.CompilationUnit( > source, >@@ -294,11 +250,11 @@ > throw new IllegalArgumentException(); > } > CompilerOptions compilerOptions = new CompilerOptions(settings); >- Parser parser = createDomParser( >+ DOMParser parser = new DOMParser( > new ProblemReporter( > DefaultErrorHandlingPolicies.proceedWithAllProblems(), > compilerOptions, >- new DefaultProblemFactory())); >+ new DefaultProblemFactory()), false); > org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = > new org.eclipse.jdt.internal.compiler.batch.CompilationUnit( > source, >@@ -500,7 +456,7 @@ > } > } > >- /** >+ /* > * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process > */ > public CompilationUnitDeclaration resolve( >@@ -513,10 +469,10 @@ > CompilationUnitDeclaration unit = null; > try { > >- parseThreshold = 0; // will request a diet parse >+ this.parseThreshold = 0; // will request a diet parse > beginToCompile(new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] { compilationUnit}); > // process all units (some more could be injected in the loop by the lookup environment) >- unit = unitsToProcess[0]; >+ unit = this.unitsToProcess[0]; > > int searchPosition = nodeSearcher.position; > if (searchPosition >= 0 && searchPosition <= compilationUnit.getContents().length) { >@@ -527,12 +483,12 @@ > if (node != null) { > org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingTypeDeclaration = nodeSearcher.enclosingType; > if (node instanceof AbstractMethodDeclaration) { >- ((AbstractMethodDeclaration)node).parseStatements(parser, unit); >+ ((AbstractMethodDeclaration)node).parseStatements(this.parser, unit); > } else if (enclosingTypeDeclaration != null) { > if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) { >- ((org.eclipse.jdt.internal.compiler.ast.Initializer) node).parseStatements(parser, enclosingTypeDeclaration, unit); >+ ((org.eclipse.jdt.internal.compiler.ast.Initializer) node).parseStatements(this.parser, enclosingTypeDeclaration, unit); > } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { >- ((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)node).parseMethod(parser, unit); >+ ((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)node).parseMethod(this.parser, unit); > } > } > } >@@ -543,7 +499,7 @@ > if (unit.scope != null && verifyMethods) { > // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117 > // verify inherited methods >- unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); >+ unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier()); > } > // type checking > unit.resolve(); >@@ -554,8 +510,8 @@ > // code generation > if (generateCode) unit.generateCode(); > } >- if (unitsToProcess != null) unitsToProcess[0] = null; // release reference to processed unit declaration >- requestor.acceptResult(unit.compilationResult.tagAsAccepted()); >+ if (this.unitsToProcess != null) this.unitsToProcess[0] = null; // release reference to processed unit declaration >+ this.requestor.acceptResult(unit.compilationResult.tagAsAccepted()); > return unit; > } catch (AbortCompilation e) { > this.handleInternalException(e, unit); >@@ -576,7 +532,7 @@ > // this.reset(); > } > } >- /** >+ /* > * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process > */ > public CompilationUnitDeclaration resolve( >@@ -593,7 +549,7 @@ > generateCode); > } > >- /** >+ /* > * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process > */ > public CompilationUnitDeclaration resolve( >@@ -606,16 +562,16 @@ > try { > if (unit == null) { > // build and record parsed units >- parseThreshold = 0; // will request a full parse >+ this.parseThreshold = 0; // will request a full parse > beginToCompile(new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] { sourceUnit }); > // process all units (some more could be injected in the loop by the lookup environment) >- unit = unitsToProcess[0]; >+ unit = this.unitsToProcess[0]; > } else { > // initial type binding creation >- lookupEnvironment.buildTypeBindings(unit); >+ this.lookupEnvironment.buildTypeBindings(unit); > > // binding resolution >- lookupEnvironment.completeTypeBindings(); >+ this.lookupEnvironment.completeTypeBindings(); > } > this.parser.getMethodBodies(unit); > if (unit.scope != null) { >@@ -624,7 +580,7 @@ > if (unit.scope != null && verifyMethods) { > // http://dev.eclipse.org/bugs/show_bug.cgi?id=23117 > // verify inherited methods >- unit.scope.verifyMethods(lookupEnvironment.methodVerifier()); >+ unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier()); > } > // type checking > unit.resolve(); >@@ -635,12 +591,12 @@ > // code generation > if (generateCode) unit.generateCode(); > } >- if (unitsToProcess != null) unitsToProcess[0] = null; // release reference to processed unit declaration >- requestor.acceptResult(unit.compilationResult.tagAsAccepted()); >+ if (this.unitsToProcess != null) this.unitsToProcess[0] = null; // release reference to processed unit declaration >+ this.requestor.acceptResult(unit.compilationResult.tagAsAccepted()); > return unit; > } catch (AbortCompilation e) { > this.handleInternalException(e, unit); >- return unit == null ? unitsToProcess[0] : unit; >+ return unit == null ? this.unitsToProcess[0] : unit; > } catch (Error e) { > this.handleInternalException(e, unit, null); > throw e; // rethrow >Index: dom/org/eclipse/jdt/core/dom/IBinding.java >=================================================================== >retrieving revision 1.9 >diff -u -r1.9 IBinding.java >--- dom/org/eclipse/jdt/core/dom/IBinding.java 26 Nov 2003 14:21:08 -0000 1.9 >+++ dom/org/eclipse/jdt/core/dom/IBinding.java 5 Dec 2003 14:08:41 -0000 >@@ -33,7 +33,7 @@ > * Kind constant (value 1) indicating a package binding. > * Bindings of this kind can be safely cast to <code>IPackageBinding</code>. > * >- * @see #getKind >+ * @see #getKind() > * @see IPackageBinding > */ > public static final int PACKAGE = 1; >@@ -42,7 +42,7 @@ > * Kind constant (value 2) indicating a type binding. > * Bindings of this kind can be safely cast to <code>ITypeBinding</code>. > * >- * @see #getKind >+ * @see #getKind() > * @see ITypeBinding > */ > public static final int TYPE = 2; >@@ -51,7 +51,7 @@ > * Kind constant (value 3) indicating a field or local variable binding. > * Bindings of this kind can be safely cast to <code>IVariableBinding</code>. > * >- * @see #getKind >+ * @see #getKind() > * @see IVariableBinding > */ > public static final int VARIABLE = 3; >@@ -60,7 +60,7 @@ > * Kind constant (value 4) indicating a method or constructor binding. > * Bindings of this kind can be safely cast to <code>IMethodBinding</code>. > * >- * @see #getKind >+ * @see #getKind() > * @see IMethodBinding > */ > public static final int METHOD = 4; >@@ -172,7 +172,10 @@ > * not be different; in these cases, the client should compare bindings > * via their binding keys (<code>getKey</code>) if available. > * >- * @see #getKey >+ * @see #getKey() >+ * >+ * @param obj >+ * @return > */ > public boolean equals(Object obj); > >Index: dom/org/eclipse/jdt/core/dom/Javadoc.java >=================================================================== >retrieving revision 1.15 >diff -u -r1.15 Javadoc.java >--- dom/org/eclipse/jdt/core/dom/Javadoc.java 11 Mar 2003 15:03:51 -0000 1.15 >+++ dom/org/eclipse/jdt/core/dom/Javadoc.java 5 Dec 2003 14:08:41 -0000 >@@ -8,26 +8,17 @@ > * Contributors: > * IBM Corporation - initial API and implementation > *******************************************************************************/ >- > package org.eclipse.jdt.core.dom; > >-import org.eclipse.jdt.core.compiler.InvalidInputException; >-import org.eclipse.jdt.internal.compiler.parser.Scanner; >-import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; > > /** > * AST node for a Javadoc comment. > * > * @since 2.0 > */ >-public class Javadoc extends ASTNode { >+public class Javadoc extends Comment { >+ > >- /** >- * The javadoc comment string, including opening and closing comment >- * delimiters; defaults to an unspecified, but legal, Javadoc comment. >- */ >- private String comment = "/** */";//$NON-NLS-1$ >- > /** > * Creates a new AST node for a Javadoc comment owned by the given AST. > * The new node has an unspecified, but legal, Javadoc comment. >@@ -41,6 +32,7 @@ > */ > Javadoc(AST ast) { > super(ast); >+ this.text = "/** */"; //$NON-NLS-1$ > } > > /* (omit javadoc for this method) >@@ -56,7 +48,7 @@ > ASTNode clone(AST target) { > Javadoc result = new Javadoc(target); > result.setSourceRange(this.getStartPosition(), this.getLength()); >- result.setComment(getComment()); >+ result.setText(this.text); > return result; > } > >@@ -81,66 +73,55 @@ > * and ending comment delimiters, and any embedded line breaks. > * > * @return the javadoc comment string >+ * @deprecated Replaced by {@link #getText()} > */ > public String getComment() { >- return comment; >+ return getText(); > } > > /** >- * Sets or clears the Javadoc comment string. The documentation >- * string must include the starting and ending comment delimiters, >- * and any embedded line breaks. >- * >- * @param javadocComment the javadoc comment string >- * @exception IllegalArgumentException if the Java comment string is invalid >+ * Returns whether the comment is a line comment or not. >+ * @return false > */ >- public void setComment(String javadocComment) { >- if (javadocComment == null) { >- throw new IllegalArgumentException(); >- } >- char[] source = javadocComment.toCharArray(); >- Scanner scanner = this.getAST().scanner; >- scanner.resetTo(0, source.length); >- scanner.setSource(source); >- try { >- int token; >- boolean onlyOneComment = false; >- while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { >- switch(token) { >- case TerminalTokens.TokenNameCOMMENT_JAVADOC : >- if (onlyOneComment) { >- throw new IllegalArgumentException(); >- } >- onlyOneComment = true; >- break; >- default: >- onlyOneComment = false; >- } >- } >- if (!onlyOneComment) { >- throw new IllegalArgumentException(); >- } >- } catch (InvalidInputException e) { >- throw new IllegalArgumentException(); >- } >- modifying(); >- this.comment = javadocComment; >+ public boolean isLine() { >+ return false; > } >- >- /* (omit javadoc for this method) >- * Method declared on ASTNode. >+ >+ /** >+ * Returns whether the comment is a javadoc comment or not. >+ * @return true > */ >- int memSize() { >- int size = BASE_NODE_SIZE + 1 * 4; >- size += HEADERS + 2 * 4 + HEADERS + 2 * comment.length(); >- return size; >+ public boolean isJavadoc() { >+ return true; > } > >- /* (omit javadoc for this method) >- * Method declared on ASTNode. >+ /** >+ * Returns the description as string. >+ * @return String >+ */ >+ public String getDescription() { >+ JavadocTag tag = getDescriptionTag(); >+ if (tag != null) { >+ return tag.getDescription(); >+ } >+ return ""; //$NON-NLS-1$ >+ } >+ >+ /** >+ * Returns the description as a tag javadoc. >+ * @return JavadocTag > */ >- int treeSize() { >- return memSize(); >+ public JavadocTag getDescriptionTag() { >+ if (this.tags.size() > 0) { >+ JavadocTag tag = (JavadocTag) tags().get(0); >+ if (tag.getIdentifier().length() == 0) { >+ return tag; >+ } >+ } >+ // No tag was found => create it >+ JavadocTag tag = getAST().newJavadocTag(); >+ this.tags.add(0, tag); >+ return tag; > } > } > >Index: dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java >=================================================================== >retrieving revision 1.14 >diff -u -r1.14 NaiveASTFlattener.java >--- dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java 25 Nov 2003 17:22:15 -0000 1.14 >+++ dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java 5 Dec 2003 14:08:41 -0000 >@@ -54,14 +54,14 @@ > * @return the serialized > */ > public String getResult() { >- return buffer.toString(); >+ return this.buffer.toString(); > } > > /** > * Resets this printer so that it can be used again. > */ > public void reset() { >- buffer.setLength(0); >+ this.buffer.setLength(0); > } > > /** >@@ -71,37 +71,37 @@ > */ > void printModifiers(int modifiers) { > if (Modifier.isPublic(modifiers)) { >- buffer.append("public ");//$NON-NLS-1$ >+ this.buffer.append("public ");//$NON-NLS-1$ > } > if (Modifier.isProtected(modifiers)) { >- buffer.append("protected ");//$NON-NLS-1$ >+ this.buffer.append("protected ");//$NON-NLS-1$ > } > if (Modifier.isPrivate(modifiers)) { >- buffer.append("private ");//$NON-NLS-1$ >+ this.buffer.append("private ");//$NON-NLS-1$ > } > if (Modifier.isStatic(modifiers)) { >- buffer.append("static ");//$NON-NLS-1$ >+ this.buffer.append("static ");//$NON-NLS-1$ > } > if (Modifier.isAbstract(modifiers)) { >- buffer.append("abstract ");//$NON-NLS-1$ >+ this.buffer.append("abstract ");//$NON-NLS-1$ > } > if (Modifier.isFinal(modifiers)) { >- buffer.append("final ");//$NON-NLS-1$ >+ this.buffer.append("final ");//$NON-NLS-1$ > } > if (Modifier.isSynchronized(modifiers)) { >- buffer.append("synchronized ");//$NON-NLS-1$ >+ this.buffer.append("synchronized ");//$NON-NLS-1$ > } > if (Modifier.isVolatile(modifiers)) { >- buffer.append("volatile ");//$NON-NLS-1$ >+ this.buffer.append("volatile ");//$NON-NLS-1$ > } > if (Modifier.isNative(modifiers)) { >- buffer.append("native ");//$NON-NLS-1$ >+ this.buffer.append("native ");//$NON-NLS-1$ > } > if (Modifier.isStrictfp(modifiers)) { >- buffer.append("strictfp ");//$NON-NLS-1$ >+ this.buffer.append("strictfp ");//$NON-NLS-1$ > } > if (Modifier.isTransient(modifiers)) { >- buffer.append("transient ");//$NON-NLS-1$ >+ this.buffer.append("transient ");//$NON-NLS-1$ > } > } > >@@ -109,12 +109,12 @@ > * @see ASTVisitor#visit(AnonymousClassDeclaration) > */ > public boolean visit(AnonymousClassDeclaration node) { >- buffer.append("{");//$NON-NLS-1$ >+ this.buffer.append("{");//$NON-NLS-1$ > for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) { > BodyDeclaration b = (BodyDeclaration) it.next(); > b.accept(this); > } >- buffer.append("}");//$NON-NLS-1$ >+ this.buffer.append("}");//$NON-NLS-1$ > return false; > } > >@@ -123,9 +123,9 @@ > */ > public boolean visit(ArrayAccess node) { > node.getArray().accept(this); >- buffer.append("[");//$NON-NLS-1$ >+ this.buffer.append("[");//$NON-NLS-1$ > node.getIndex().accept(this); >- buffer.append("]");//$NON-NLS-1$ >+ this.buffer.append("]");//$NON-NLS-1$ > return false; > } > >@@ -133,24 +133,24 @@ > * @see ASTVisitor#visit(ArrayCreation) > */ > public boolean visit(ArrayCreation node) { >- buffer.append("new ");//$NON-NLS-1$ >+ this.buffer.append("new ");//$NON-NLS-1$ > ArrayType at = node.getType(); > int dims = at.getDimensions(); > Type elementType = at.getElementType(); > elementType.accept(this); > for (Iterator it = node.dimensions().iterator(); it.hasNext(); ) { >- buffer.append("[");//$NON-NLS-1$ >+ this.buffer.append("[");//$NON-NLS-1$ > Expression e = (Expression) it.next(); > e.accept(this); >- buffer.append("]");//$NON-NLS-1$ >+ this.buffer.append("]");//$NON-NLS-1$ > dims--; > } > // add empty "[]" for each extra array dimension > for (int i= 0; i < dims; i++) { >- buffer.append("[]");//$NON-NLS-1$ >+ this.buffer.append("[]");//$NON-NLS-1$ > } > if (node.getInitializer() != null) { >- buffer.append("=");//$NON-NLS-1$ >+ this.buffer.append("=");//$NON-NLS-1$ > node.getInitializer().accept(this); > } > return false; >@@ -160,13 +160,13 @@ > * @see ASTVisitor#visit(ArrayInitializer) > */ > public boolean visit(ArrayInitializer node) { >- buffer.append("{");//$NON-NLS-1$ >+ this.buffer.append("{");//$NON-NLS-1$ > for (Iterator it = node.expressions().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } >- buffer.append("}");//$NON-NLS-1$ >+ this.buffer.append("}");//$NON-NLS-1$ > return false; > } > >@@ -175,7 +175,7 @@ > */ > public boolean visit(ArrayType node) { > node.getComponentType().accept(this); >- buffer.append("[]");//$NON-NLS-1$ >+ this.buffer.append("[]");//$NON-NLS-1$ > return false; > } > >@@ -183,13 +183,13 @@ > * @see ASTVisitor#visit(AssertStatement) > */ > public boolean visit(AssertStatement node) { >- buffer.append("assert ");//$NON-NLS-1$ >+ this.buffer.append("assert ");//$NON-NLS-1$ > node.getExpression().accept(this); > if (node.getMessage() != null) { > node.getMessage().accept(this); > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -198,7 +198,7 @@ > */ > public boolean visit(Assignment node) { > node.getLeftHandSide().accept(this); >- buffer.append(node.getOperator().toString()); >+ this.buffer.append(node.getOperator().toString()); > node.getRightHandSide().accept(this); > return false; > } >@@ -207,12 +207,12 @@ > * @see ASTVisitor#visit(Block) > */ > public boolean visit(Block node) { >- buffer.append("{");//$NON-NLS-1$ >+ this.buffer.append("{");//$NON-NLS-1$ > for (Iterator it = node.statements().iterator(); it.hasNext(); ) { > Statement s = (Statement) it.next(); > s.accept(this); > } >- buffer.append("}");//$NON-NLS-1$ >+ this.buffer.append("}");//$NON-NLS-1$ > return false; > } > >@@ -221,9 +221,9 @@ > */ > public boolean visit(BooleanLiteral node) { > if (node.booleanValue() == true) { >- buffer.append("true");//$NON-NLS-1$ >+ this.buffer.append("true");//$NON-NLS-1$ > } else { >- buffer.append("false");//$NON-NLS-1$ >+ this.buffer.append("false");//$NON-NLS-1$ > } > return false; > } >@@ -232,12 +232,12 @@ > * @see ASTVisitor#visit(BreakStatement) > */ > public boolean visit(BreakStatement node) { >- buffer.append("break");//$NON-NLS-1$ >+ this.buffer.append("break");//$NON-NLS-1$ > if (node.getLabel() != null) { >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > node.getLabel().accept(this); > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -245,9 +245,9 @@ > * @see ASTVisitor#visit(CastExpression) > */ > public boolean visit(CastExpression node) { >- buffer.append("(");//$NON-NLS-1$ >+ this.buffer.append("(");//$NON-NLS-1$ > node.getType().accept(this); >- buffer.append(")");//$NON-NLS-1$ >+ this.buffer.append(")");//$NON-NLS-1$ > node.getExpression().accept(this); > return false; > } >@@ -256,9 +256,9 @@ > * @see ASTVisitor#visit(CatchClause) > */ > public boolean visit(CatchClause node) { >- buffer.append("catch (");//$NON-NLS-1$ >+ this.buffer.append("catch (");//$NON-NLS-1$ > node.getException().accept(this); >- buffer.append(") ");//$NON-NLS-1$ >+ this.buffer.append(") ");//$NON-NLS-1$ > node.getBody().accept(this); > return false; > } >@@ -267,7 +267,7 @@ > * @see ASTVisitor#visit(CharacterLiteral) > */ > public boolean visit(CharacterLiteral node) { >- buffer.append(node.getEscapedValue()); >+ this.buffer.append(node.getEscapedValue()); > return false; > } > >@@ -277,19 +277,19 @@ > public boolean visit(ClassInstanceCreation node) { > if (node.getExpression() != null) { > node.getExpression().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > } >- buffer.append("new ");//$NON-NLS-1$ >+ this.buffer.append("new ");//$NON-NLS-1$ > node.getName().accept(this); >- buffer.append("(");//$NON-NLS-1$ >+ this.buffer.append("(");//$NON-NLS-1$ > for (Iterator it = node.arguments().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > if (it.hasNext()) { >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } > } >- buffer.append(")");//$NON-NLS-1$ >+ this.buffer.append(")");//$NON-NLS-1$ > if (node.getAnonymousClassDeclaration() != null) { > node.getAnonymousClassDeclaration().accept(this); > } >@@ -319,9 +319,9 @@ > */ > public boolean visit(ConditionalExpression node) { > node.getExpression().accept(this); >- buffer.append("?");//$NON-NLS-1$ >+ this.buffer.append("?");//$NON-NLS-1$ > node.getThenExpression().accept(this); >- buffer.append(":");//$NON-NLS-1$ >+ this.buffer.append(":");//$NON-NLS-1$ > node.getElseExpression().accept(this); > return false; > } >@@ -330,15 +330,15 @@ > * @see ASTVisitor#visit(ConstructorInvocation) > */ > public boolean visit(ConstructorInvocation node) { >- buffer.append("this(");//$NON-NLS-1$ >+ this.buffer.append("this(");//$NON-NLS-1$ > for (Iterator it = node.arguments().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > if (it.hasNext()) { >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } > } >- buffer.append(");");//$NON-NLS-1$ >+ this.buffer.append(");");//$NON-NLS-1$ > return false; > } > >@@ -346,12 +346,12 @@ > * @see ASTVisitor#visit(ContinueStatement) > */ > public boolean visit(ContinueStatement node) { >- buffer.append("continue");//$NON-NLS-1$ >+ this.buffer.append("continue");//$NON-NLS-1$ > if (node.getLabel() != null) { >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > node.getLabel().accept(this); > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -359,11 +359,11 @@ > * @see ASTVisitor#visit(DoStatement) > */ > public boolean visit(DoStatement node) { >- buffer.append("do ");//$NON-NLS-1$ >+ this.buffer.append("do ");//$NON-NLS-1$ > node.getBody().accept(this); >- buffer.append(" while (");//$NON-NLS-1$ >+ this.buffer.append(" while (");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(");");//$NON-NLS-1$ >+ this.buffer.append(");");//$NON-NLS-1$ > return false; > } > >@@ -371,7 +371,7 @@ > * @see ASTVisitor#visit(EmptyStatement) > */ > public boolean visit(EmptyStatement node) { >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -380,7 +380,7 @@ > */ > public boolean visit(ExpressionStatement node) { > node.getExpression().accept(this); >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -389,7 +389,7 @@ > */ > public boolean visit(FieldAccess node) { > node.getExpression().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > node.getName().accept(this); > return false; > } >@@ -403,15 +403,15 @@ > } > printModifiers(node.getModifiers()); > node.getType().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > for (Iterator it = node.fragments().iterator(); it.hasNext(); ) { > VariableDeclarationFragment f = (VariableDeclarationFragment) it.next(); > f.accept(this); > if (it.hasNext()) { >- buffer.append(", ");//$NON-NLS-1$ >+ this.buffer.append(", ");//$NON-NLS-1$ > } > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -419,21 +419,21 @@ > * @see ASTVisitor#visit(ForStatement) > */ > public boolean visit(ForStatement node) { >- buffer.append("for (");//$NON-NLS-1$ >+ this.buffer.append("for (");//$NON-NLS-1$ > for (Iterator it = node.initializers().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > } >- buffer.append("; ");//$NON-NLS-1$ >+ this.buffer.append("; ");//$NON-NLS-1$ > if (node.getExpression() != null) { > node.getExpression().accept(this); > } >- buffer.append("; ");//$NON-NLS-1$ >+ this.buffer.append("; ");//$NON-NLS-1$ > for (Iterator it = node.updaters().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > } >- buffer.append(") ");//$NON-NLS-1$ >+ this.buffer.append(") ");//$NON-NLS-1$ > node.getBody().accept(this); > return false; > } >@@ -442,12 +442,12 @@ > * @see ASTVisitor#visit(IfStatement) > */ > public boolean visit(IfStatement node) { >- buffer.append("if (");//$NON-NLS-1$ >+ this.buffer.append("if (");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(") ");//$NON-NLS-1$ >+ this.buffer.append(") ");//$NON-NLS-1$ > node.getThenStatement().accept(this); > if (node.getElseStatement() != null) { >- buffer.append(" else ");//$NON-NLS-1$ >+ this.buffer.append(" else ");//$NON-NLS-1$ > node.getElseStatement().accept(this); > } > return false; >@@ -457,12 +457,12 @@ > * @see ASTVisitor#visit(ImportDeclaration) > */ > public boolean visit(ImportDeclaration node) { >- buffer.append("import ");//$NON-NLS-1$ >+ this.buffer.append("import ");//$NON-NLS-1$ > node.getName().accept(this); > if (node.isOnDemand()) { >- buffer.append(".*");//$NON-NLS-1$ >+ this.buffer.append(".*");//$NON-NLS-1$ > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -471,10 +471,10 @@ > */ > public boolean visit(InfixExpression node) { > node.getLeftOperand().accept(this); >- buffer.append(node.getOperator().toString()); >+ this.buffer.append(node.getOperator().toString()); > node.getRightOperand().accept(this); > for (Iterator it = node.extendedOperands().iterator(); it.hasNext(); ) { >- buffer.append(node.getOperator().toString()); >+ this.buffer.append(node.getOperator().toString()); > Expression e = (Expression) it.next(); > e.accept(this); > } >@@ -486,7 +486,7 @@ > */ > public boolean visit(InstanceofExpression node) { > node.getLeftOperand().accept(this); >- buffer.append(" instanceof ");//$NON-NLS-1$ >+ this.buffer.append(" instanceof ");//$NON-NLS-1$ > node.getRightOperand().accept(this); > return false; > } >@@ -507,16 +507,58 @@ > * @see ASTVisitor#visit(Javadoc) > */ > public boolean visit(Javadoc node) { >- buffer.append(node.getComment()); >+ this.buffer.append("/**"); //$NON-NLS-1$ >+ for (Iterator it = node.tags().iterator(); it.hasNext(); ) { >+ JavadocTag tag = (JavadocTag) it.next(); >+ this.buffer.append("\n * "); //$NON-NLS-1$ >+ tag.accept(this); >+ } >+ this.buffer.append("\n*/"); //$NON-NLS-1$ > return false; > } > > /* >+ * @see ASTVisitor#visit(JavadocTag) >+ */ >+ public boolean visit(JavadocTag node) { >+ boolean hasIdentifier = node.getIdentifier().length() > 0; >+ if (hasIdentifier) { >+ this.buffer.append('@'); >+ this.buffer.append(node.getIdentifier()); >+ } >+ boolean hasReference = node.getReference() != null; >+ if (hasReference) { >+ if (hasIdentifier) { >+ this.buffer.append(' '); >+ } >+ node.getReference().accept(this); >+ } >+ String txt = node.getDescription(); >+ if (txt.length() > 0) { >+ if (hasIdentifier || hasReference) { >+ this.buffer.append(' '); >+ } >+ this.buffer.append(txt); >+ } >+ return false; >+ } >+ >+ /* >+ * @see ASTVisitor#visit(JavadocArgument) >+ */ >+ public boolean visit(JavadocArgument node) { >+ if (node.getArgument() != null) { >+ node.getArgument().accept(this); >+ } >+ return false; >+ } >+ >+ /* > * @see ASTVisitor#visit(LabeledStatement) > */ > public boolean visit(LabeledStatement node) { > node.getLabel().accept(this); >- buffer.append(": ");//$NON-NLS-1$ >+ this.buffer.append(": ");//$NON-NLS-1$ > node.getBody().accept(this); > return false; > } >@@ -531,31 +573,31 @@ > printModifiers(node.getModifiers()); > if (!node.isConstructor()) { > node.getReturnType().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > } > node.getName().accept(this); >- buffer.append("(");//$NON-NLS-1$ >+ this.buffer.append("(");//$NON-NLS-1$ > for (Iterator it = node.parameters().iterator(); it.hasNext(); ) { > SingleVariableDeclaration v = (SingleVariableDeclaration) it.next(); > v.accept(this); > if (it.hasNext()) { >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } > } >- buffer.append(")");//$NON-NLS-1$ >+ this.buffer.append(")");//$NON-NLS-1$ > if (!node.thrownExceptions().isEmpty()) { >- buffer.append(" throws ");//$NON-NLS-1$ >+ this.buffer.append(" throws ");//$NON-NLS-1$ > for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) { > Name n = (Name) it.next(); > n.accept(this); > if (it.hasNext()) { >- buffer.append(", ");//$NON-NLS-1$ >+ this.buffer.append(", ");//$NON-NLS-1$ > } > } >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > } > if (node.getBody() == null) { >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > } else { > node.getBody().accept(this); > } >@@ -568,18 +610,18 @@ > public boolean visit(MethodInvocation node) { > if (node.getExpression() != null) { > node.getExpression().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > } > node.getName().accept(this); >- buffer.append("(");//$NON-NLS-1$ >+ this.buffer.append("(");//$NON-NLS-1$ > for (Iterator it = node.arguments().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > if (it.hasNext()) { >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } > } >- buffer.append(")");//$NON-NLS-1$ >+ this.buffer.append(")");//$NON-NLS-1$ > return false; > } > >@@ -587,7 +629,7 @@ > * @see ASTVisitor#visit(NullLiteral) > */ > public boolean visit(NullLiteral node) { >- buffer.append("null");//$NON-NLS-1$ >+ this.buffer.append("null");//$NON-NLS-1$ > return false; > } > >@@ -595,7 +637,7 @@ > * @see ASTVisitor#visit(NumberLiteral) > */ > public boolean visit(NumberLiteral node) { >- buffer.append(node.getToken()); >+ this.buffer.append(node.getToken()); > return false; > } > >@@ -603,9 +645,9 @@ > * @see ASTVisitor#visit(PackageDeclaration) > */ > public boolean visit(PackageDeclaration node) { >- buffer.append("package ");//$NON-NLS-1$ >+ this.buffer.append("package ");//$NON-NLS-1$ > node.getName().accept(this); >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -613,9 +655,9 @@ > * @see ASTVisitor#visit(ParenthesizedExpression) > */ > public boolean visit(ParenthesizedExpression node) { >- buffer.append("(");//$NON-NLS-1$ >+ this.buffer.append("(");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(")");//$NON-NLS-1$ >+ this.buffer.append(")");//$NON-NLS-1$ > return false; > } > >@@ -624,7 +666,7 @@ > */ > public boolean visit(PostfixExpression node) { > node.getOperand().accept(this); >- buffer.append(node.getOperator().toString()); >+ this.buffer.append(node.getOperator().toString()); > return false; > } > >@@ -632,7 +674,7 @@ > * @see ASTVisitor#visit(PrefixExpression) > */ > public boolean visit(PrefixExpression node) { >- buffer.append(node.getOperator().toString()); >+ this.buffer.append(node.getOperator().toString()); > node.getOperand().accept(this); > return false; > } >@@ -641,7 +683,7 @@ > * @see ASTVisitor#visit(PrimitiveType) > */ > public boolean visit(PrimitiveType node) { >- buffer.append(node.getPrimitiveTypeCode().toString()); >+ this.buffer.append(node.getPrimitiveTypeCode().toString()); > return false; > } > >@@ -650,7 +692,7 @@ > */ > public boolean visit(QualifiedName node) { > node.getQualifier().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > node.getName().accept(this); > return false; > } >@@ -659,12 +701,12 @@ > * @see ASTVisitor#visit(ReturnStatement) > */ > public boolean visit(ReturnStatement node) { >- buffer.append("return");//$NON-NLS-1$ >+ this.buffer.append("return");//$NON-NLS-1$ > if (node.getExpression() != null) { >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > node.getExpression().accept(this); > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -672,7 +714,7 @@ > * @see ASTVisitor#visit(SimpleName) > */ > public boolean visit(SimpleName node) { >- buffer.append(node.getIdentifier()); >+ this.buffer.append(node.getIdentifier()); > return false; > } > >@@ -689,10 +731,10 @@ > public boolean visit(SingleVariableDeclaration node) { > printModifiers(node.getModifiers()); > node.getType().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > node.getName().accept(this); > if (node.getInitializer() != null) { >- buffer.append("=");//$NON-NLS-1$ >+ this.buffer.append("=");//$NON-NLS-1$ > node.getInitializer().accept(this); > } > return false; >@@ -702,7 +744,7 @@ > * @see ASTVisitor#visit(StringLiteral) > */ > public boolean visit(StringLiteral node) { >- buffer.append(node.getEscapedValue()); >+ this.buffer.append(node.getEscapedValue()); > return false; > } > >@@ -712,17 +754,17 @@ > public boolean visit(SuperConstructorInvocation node) { > if (node.getExpression() != null) { > node.getExpression().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > } >- buffer.append("super(");//$NON-NLS-1$ >+ this.buffer.append("super(");//$NON-NLS-1$ > for (Iterator it = node.arguments().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > if (it.hasNext()) { >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } > } >- buffer.append(");");//$NON-NLS-1$ >+ this.buffer.append(");");//$NON-NLS-1$ > return false; > } > >@@ -732,9 +774,9 @@ > public boolean visit(SuperFieldAccess node) { > if (node.getQualifier() != null) { > node.getQualifier().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > } >- buffer.append("super.");//$NON-NLS-1$ >+ this.buffer.append("super.");//$NON-NLS-1$ > node.getName().accept(this); > return false; > } >@@ -745,19 +787,19 @@ > public boolean visit(SuperMethodInvocation node) { > if (node.getQualifier() != null) { > node.getQualifier().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > } >- buffer.append("super.");//$NON-NLS-1$ >+ this.buffer.append("super.");//$NON-NLS-1$ > node.getName().accept(this); >- buffer.append("(");//$NON-NLS-1$ >+ this.buffer.append("(");//$NON-NLS-1$ > for (Iterator it = node.arguments().iterator(); it.hasNext(); ) { > Expression e = (Expression) it.next(); > e.accept(this); > if (it.hasNext()) { >- buffer.append(",");//$NON-NLS-1$ >+ this.buffer.append(",");//$NON-NLS-1$ > } > } >- buffer.append(")");//$NON-NLS-1$ >+ this.buffer.append(")");//$NON-NLS-1$ > return false; > } > >@@ -766,11 +808,11 @@ > */ > public boolean visit(SwitchCase node) { > if (node.isDefault()) { >- buffer.append("default :");//$NON-NLS-1$ >+ this.buffer.append("default :");//$NON-NLS-1$ > } else { >- buffer.append("case ");//$NON-NLS-1$ >+ this.buffer.append("case ");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(":");//$NON-NLS-1$ >+ this.buffer.append(":");//$NON-NLS-1$ > } > return false; > } >@@ -779,15 +821,15 @@ > * @see ASTVisitor#visit(SwitchStatement) > */ > public boolean visit(SwitchStatement node) { >- buffer.append("switch (");//$NON-NLS-1$ >+ this.buffer.append("switch (");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(") ");//$NON-NLS-1$ >- buffer.append("{");//$NON-NLS-1$ >+ this.buffer.append(") ");//$NON-NLS-1$ >+ this.buffer.append("{");//$NON-NLS-1$ > for (Iterator it = node.statements().iterator(); it.hasNext(); ) { > Statement s = (Statement) it.next(); > s.accept(this); > } >- buffer.append("}");//$NON-NLS-1$ >+ this.buffer.append("}");//$NON-NLS-1$ > return false; > } > >@@ -795,9 +837,9 @@ > * @see ASTVisitor#visit(SynchronizedStatement) > */ > public boolean visit(SynchronizedStatement node) { >- buffer.append("synchronized (");//$NON-NLS-1$ >+ this.buffer.append("synchronized (");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(") ");//$NON-NLS-1$ >+ this.buffer.append(") ");//$NON-NLS-1$ > node.getBody().accept(this); > return false; > } >@@ -808,9 +850,9 @@ > public boolean visit(ThisExpression node) { > if (node.getQualifier() != null) { > node.getQualifier().accept(this); >- buffer.append(".");//$NON-NLS-1$ >+ this.buffer.append(".");//$NON-NLS-1$ > } >- buffer.append("this");//$NON-NLS-1$ >+ this.buffer.append("this");//$NON-NLS-1$ > return false; > } > >@@ -818,9 +860,9 @@ > * @see ASTVisitor#visit(ThrowStatement) > */ > public boolean visit(ThrowStatement node) { >- buffer.append("throw ");//$NON-NLS-1$ >+ this.buffer.append("throw ");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -828,15 +870,15 @@ > * @see ASTVisitor#visit(TryStatement) > */ > public boolean visit(TryStatement node) { >- buffer.append("try ");//$NON-NLS-1$ >+ this.buffer.append("try ");//$NON-NLS-1$ > node.getBody().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > for (Iterator it = node.catchClauses().iterator(); it.hasNext(); ) { > CatchClause cc = (CatchClause) it.next(); > cc.accept(this); > } > if (node.getFinally() != null) { >- buffer.append("finally ");//$NON-NLS-1$ >+ this.buffer.append("finally ");//$NON-NLS-1$ > node.getFinally().accept(this); > } > return false; >@@ -850,31 +892,31 @@ > node.getJavadoc().accept(this); > } > printModifiers(node.getModifiers()); >- buffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$ >+ this.buffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$ > node.getName().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > if (node.getSuperclass() != null) { >- buffer.append("extends ");//$NON-NLS-1$ >+ this.buffer.append("extends ");//$NON-NLS-1$ > node.getSuperclass().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > } > if (!node.superInterfaces().isEmpty()) { >- buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$ >+ this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$ > for (Iterator it = node.superInterfaces().iterator(); it.hasNext(); ) { > Name n = (Name) it.next(); > n.accept(this); > if (it.hasNext()) { >- buffer.append(", ");//$NON-NLS-1$ >+ this.buffer.append(", ");//$NON-NLS-1$ > } > } >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > } >- buffer.append("{");//$NON-NLS-1$ >+ this.buffer.append("{");//$NON-NLS-1$ > for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) { > BodyDeclaration d = (BodyDeclaration) it.next(); > d.accept(this); > } >- buffer.append("}");//$NON-NLS-1$ >+ this.buffer.append("}");//$NON-NLS-1$ > return false; > } > >@@ -883,7 +925,7 @@ > */ > public boolean visit(TypeDeclarationStatement node) { > node.getTypeDeclaration().accept(this); >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -892,7 +934,7 @@ > */ > public boolean visit(TypeLiteral node) { > node.getType().accept(this); >- buffer.append(".class");//$NON-NLS-1$ >+ this.buffer.append(".class");//$NON-NLS-1$ > return false; > } > >@@ -902,15 +944,15 @@ > public boolean visit(VariableDeclarationExpression node) { > printModifiers(node.getModifiers()); > node.getType().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > for (Iterator it = node.fragments().iterator(); it.hasNext(); ) { > VariableDeclarationFragment f = (VariableDeclarationFragment) it.next(); > f.accept(this); > if (it.hasNext()) { >- buffer.append(", ");//$NON-NLS-1$ >+ this.buffer.append(", ");//$NON-NLS-1$ > } > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -920,10 +962,10 @@ > public boolean visit(VariableDeclarationFragment node) { > node.getName().accept(this); > for (int i = 0; i < node.getExtraDimensions(); i++) { >- buffer.append("[]");//$NON-NLS-1$ >+ this.buffer.append("[]");//$NON-NLS-1$ > } > if (node.getInitializer() != null) { >- buffer.append("=");//$NON-NLS-1$ >+ this.buffer.append("=");//$NON-NLS-1$ > node.getInitializer().accept(this); > } > return false; >@@ -935,15 +977,15 @@ > public boolean visit(VariableDeclarationStatement node) { > printModifiers(node.getModifiers()); > node.getType().accept(this); >- buffer.append(" ");//$NON-NLS-1$ >+ this.buffer.append(" ");//$NON-NLS-1$ > for (Iterator it = node.fragments().iterator(); it.hasNext(); ) { > VariableDeclarationFragment f = (VariableDeclarationFragment) it.next(); > f.accept(this); > if (it.hasNext()) { >- buffer.append(", ");//$NON-NLS-1$ >+ this.buffer.append(", ");//$NON-NLS-1$ > } > } >- buffer.append(";");//$NON-NLS-1$ >+ this.buffer.append(";");//$NON-NLS-1$ > return false; > } > >@@ -951,9 +993,9 @@ > * @see ASTVisitor#visit(WhileStatement) > */ > public boolean visit(WhileStatement node) { >- buffer.append("while (");//$NON-NLS-1$ >+ this.buffer.append("while (");//$NON-NLS-1$ > node.getExpression().accept(this); >- buffer.append(") ");//$NON-NLS-1$ >+ this.buffer.append(") ");//$NON-NLS-1$ > node.getBody().accept(this); > return false; > } >Index: dom/org/eclipse/jdt/core/dom/NullLiteral.java >=================================================================== >retrieving revision 1.8 >diff -u -r1.8 NullLiteral.java >--- dom/org/eclipse/jdt/core/dom/NullLiteral.java 11 Mar 2003 15:03:51 -0000 1.8 >+++ dom/org/eclipse/jdt/core/dom/NullLiteral.java 5 Dec 2003 14:08:41 -0000 >@@ -65,7 +65,7 @@ > * Method declared on ASTNode. > */ > int memSize() { >- return BASE_NODE_SIZE + 1 * 4; >+ return BASE_NODE_SIZE; > } > > /* (omit javadoc for this method) >Index: dom/org/eclipse/jdt/core/dom/QualifiedName.java >=================================================================== >retrieving revision 1.20 >diff -u -r1.20 QualifiedName.java >--- dom/org/eclipse/jdt/core/dom/QualifiedName.java 15 Nov 2003 01:29:00 -0000 1.20 >+++ dom/org/eclipse/jdt/core/dom/QualifiedName.java 5 Dec 2003 14:08:41 -0000 >@@ -112,7 +112,7 @@ > /** > * Sets the qualifier of this qualified name to the given name. > * >- * @param the qualifier of this qualified name >+ * @param qualifier the qualifier of this qualified name > * @exception IllegalArgumentException if: > * <ul> > * <li>the node belongs to a different AST</li> >Index: model/org/eclipse/jdt/internal/core/util/PublicScanner.java >=================================================================== >retrieving revision 1.34 >diff -u -r1.34 PublicScanner.java >--- model/org/eclipse/jdt/internal/core/util/PublicScanner.java 17 Nov 2003 10:17:08 -0000 1.34 >+++ model/org/eclipse/jdt/internal/core/util/PublicScanner.java 5 Dec 2003 14:08:41 -0000 >@@ -431,6 +431,9 @@ > * e.g. getLineStart(1) --> 0 indicates that the first line starts at character 0. > * > * In case the given line number is inconsistent, answers -1. >+ * >+ * @param lineNumber >+ * @return int > */ > public final int getLineStart(int lineNumber) { > >@@ -2228,8 +2231,8 @@ > * Reposition the scanner on some portion of the original source. The given endPosition is the last valid position. > * Beyond this position, the scanner will answer EOF tokens (<code>ITerminalSymbols.TokenNameEOF</code>). > * >- * @param startPosition the given start position >- * @param endPosition the given end position >+ * @param begin the given start position >+ * @param end the given end position > */ > public void resetTo(int begin, int end) { > //reset the scanner to a given position where it may rescan again >@@ -3036,6 +3039,8 @@ > /** > * Search the line number corresponding to a specific position > * >+ * @param position >+ * @return int > */ > public final int getLineNumber(int position) { > >Index: dom/org/eclipse/jdt/core/dom/BlockComment.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/BlockComment.java >diff -N dom/org/eclipse/jdt/core/dom/BlockComment.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/BlockComment.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,87 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+ >+/** >+ * AST node for a block comment. >+ * >+ * @see Comment >+ * @since 3.0 >+ */ >+public class BlockComment extends Comment { >+ >+ /** >+ * Creates a new AST node for a block comment owned by the given AST. >+ * The new node has an unspecified, but legal, block comment. >+ * <p> >+ * N.B. This constructor is package-private; all subclasses must be >+ * declared in the same package; clients are unable to declare >+ * additional subclasses. >+ * </p> >+ * >+ * @param ast the AST that is to own this node >+ */ >+ BlockComment(AST ast) { >+ super(ast); >+ this.text = "/* */"; //$NON-NLS-1$ >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ public int getNodeType() { >+ return BLOCK_COMMENT; >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ ASTNode clone(AST target) { >+ BlockComment result = new BlockComment(target); >+ result.setSourceRange(this.getStartPosition(), this.getLength()); >+ result.setText(this.text); >+ return result; >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ public boolean subtreeMatch(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) { >+ visitor.visit(this); >+ visitor.endVisit(this); >+ } >+ >+ /** >+ * Returns whether the comment is a line comment or not. >+ * @return false >+ */ >+ public boolean isLine() { >+ return false; >+ } >+ >+ /** >+ * Returns whether the comment is a javadoc comment or not. >+ * @return false >+ */ >+ public boolean isJavadoc() { >+ return false; >+ } >+} >+ >Index: dom/org/eclipse/jdt/core/dom/Comment.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/Comment.java >diff -N dom/org/eclipse/jdt/core/dom/Comment.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/Comment.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,176 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+import java.util.Iterator; >+import java.util.List; >+ >+/** >+ * AST node for a comment. >+ * This is a abstract class which represents all comments which can be found in code: >+ * <ul> >+ * <li>line comment: <code>// comment</code></li> >+ * <li>block comment: <code>/* comment \*\/</code></li> >+ * <li>javadoc comment: <code>/** comment \*\/</code></li> >+ * </ul> >+ * >+ * Javadoc comment are still representated with Javadoc class which is now a sub-class >+ * of this class. >+ * >+ * @see LineComment >+ * @see BlockComment >+ * @see Javadoc >+ * @since 3.0 >+ */ >+public abstract class Comment extends ASTNode { >+ >+ /** >+ * The comment text, including opening and closing comment >+ * delimiters; defaults has to be set by sub-classes. >+ */ >+ String text = null; >+ >+ /** >+ * The tags included in the comment (element type: <code>JavadocTag</code>). >+ * Defaults to none. >+ */ >+ ASTNode.NodeList tags = new ASTNode.NodeList(true, JavadocTag.class); >+ >+ /** >+ * Flag to indicate whether the comment has to be parsed or not. >+ * Default is false. >+ */ >+ boolean parse = false; >+ >+ /** >+ * Creates a new AST node for a Javadoc comment owned by the given AST. >+ * The new node has an unspecified, but legal, Javadoc comment. >+ * <p> >+ * N.B. This constructor is package-private; all subclasses must be >+ * declared in the same package; clients are unable to declare >+ * additional subclasses. >+ * </p> >+ * >+ * @param ast the AST that is to own this node >+ */ >+ Comment(AST ast) { >+ super(ast); >+ } >+ >+ /** >+ * Returns the Javadoc comment string, including the starting >+ * and ending comment delimiters, and any embedded line breaks. >+ * >+ * @return the javadoc comment string >+ */ >+ public String getText() { >+ return this.text; >+ } >+ >+ /** >+ * Sets or clears the Javadoc comment string. The documentation >+ * string must include the starting and ending comment delimiters, >+ * and any embedded line breaks. >+ * >+ * @param textComment the javadoc comment string >+ * @exception IllegalArgumentException if the Java comment string is invalid >+ */ >+ public void setText(String textComment) { >+ if (textComment == null) { >+ throw new IllegalArgumentException(); >+ } >+ modifying(); >+ this.text = textComment; >+ } >+ >+ /** >+ * Sets or clears the Javadoc comment string. The documentation >+ * string must include the starting and ending comment delimiters, >+ * and any embedded line breaks. >+ * >+ * @param comment the javadoc comment string >+ * @exception IllegalArgumentException if the Java comment string is invalid >+ */ >+ public void setComment(String comment) { >+ setText(comment); >+ if (isParseOn() && !isLine()) { >+ DOMCommentParser parser = new DOMCommentParser(this.getAST()); >+ if (parser.parse(this)) { >+ if ((getStartPosition() > 0) && (this.tags != null)) { >+ for(Iterator it = this.tags.iterator(); it.hasNext(); ) { >+ JavadocTag tag = (JavadocTag) it.next(); >+ tag.setSourceRange(tag.getStartPosition()+getStartPosition(), tag.getLength()); >+ } >+ } >+ } else { >+ throw new IllegalArgumentException(); >+ } >+ } >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ int memSize() { >+ int size = BASE_NODE_SIZE; >+ if (this.text != null) { >+ // Strings usually have 4 instance fields, one of which is a char[] >+ size += HEADERS + 4 * 4; >+ // char[] has 2 bytes per character >+ size += HEADERS + 2 * this.text.length(); >+ } >+ size += 4; // size for tags >+ return size; >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ int treeSize() { >+ return memSize() + this.tags.listSize(); >+ } >+ >+ /** >+ * @return Returns the tagDeclarations. >+ */ >+ public List tags() { >+ return this.tags; >+ } >+ >+ /** >+ * Returns whether the comment is a comment line or not. >+ * @return boolean >+ */ >+ public abstract boolean isLine(); >+ >+ /** >+ * Returns whether the comment is a javadoc comment or not. >+ * @return boolean >+ */ >+ public abstract boolean isJavadoc(); >+ >+ /** >+ * Set whether the comment should be been parsed or not. >+ * @param parseOn true if the comment should be parsed. >+ */ >+ public void setParseOn(boolean parseOn) { >+ this.parse = parseOn; >+ } >+ >+ /** >+ * Returns whether the comment has been parsed or not. >+ * @return true if some tags are written in the comment, false otherwise. >+ */ >+ public boolean isParseOn() { >+ return this.parse; >+ } >+} >+ >Index: dom/org/eclipse/jdt/core/dom/DOMCommentParser.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/DOMCommentParser.java >diff -N dom/org/eclipse/jdt/core/dom/DOMCommentParser.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/DOMCommentParser.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,917 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+import java.util.ArrayList; >+ >+import org.eclipse.jdt.core.compiler.CharOperation; >+import org.eclipse.jdt.core.compiler.InvalidInputException; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; >+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; >+ >+/** >+ * Parser specialized for decoding comments. >+ */ >+public class DOMCommentParser { >+ >+ // recognized tags >+ public static final char[] TAG_DEPRECATED = "deprecated".toCharArray(); //$NON-NLS-1$ >+ public static final char[] TAG_PARAM = "param".toCharArray(); //$NON-NLS-1$ >+ public static final char[] TAG_RETURN = "return".toCharArray(); //$NON-NLS-1$ >+ public static final char[] TAG_THROWS = "throws".toCharArray(); //$NON-NLS-1$ >+ public static final char[] TAG_EXCEPTION = "exception".toCharArray(); //$NON-NLS-1$ >+ public static final char[] TAG_SEE = "see".toCharArray(); //$NON-NLS-1$ >+ public static final char[] EMBEDDED_TAG_INHERIT_DOC = "inheritdDoc".toCharArray(); //$NON-NLS-1$ >+ public static final char[] EMBEDDED_TAG_LINK = "link".toCharArray(); //$NON-NLS-1$ >+ public static final char[] EMBEDDED_TAG_LINKPLAIN = "linkplain".toCharArray(); //$NON-NLS-1$ >+ >+ // tags expected positions >+ public final static int ORDERED_TAGS_NUMBER = 3; >+ public final static int PARAM_TAG_EXPECTED_ORDER = 0; >+ public final static int THROWS_TAG_EXPECTED_ORDER = 1; >+ public final static int SEE_TAG_EXPECTED_ORDER = 2; >+ >+ // Public fields >+ private Comment comment; >+ private DOMScanner scanner; >+ private AST ast; >+ >+ // Private fields >+ private int currentTokenType = -1; >+ private int index, linePtr; >+ private char[] source; >+ >+ // Identifier stack >+ protected int identifierPtr; >+ protected String[] identifierStack; >+ protected int identifierLengthPtr; >+ protected int[] identifierLengthStack; >+ protected long[] identifierPositionStack; >+ // Ast stack >+ protected static int AstStackIncrement = 10; >+ protected int astPtr; >+ protected ASTNode[] astStack; >+ //protected int astLengthPtr; >+ //protected int[] astLengthStack; >+ >+ DOMCommentParser(AST ast) { >+ this.ast = ast; >+ this.scanner = new DOMScanner(true, true, false, ClassFileConstants.JDK1_3, null, null); >+ this.scanner.recordLineSeparator = true; >+ this.identifierStack = new String[10]; >+ this.identifierPositionStack = new long[10]; >+ this.identifierLengthStack = new int[20]; >+ this.astStack = new ASTNode[20]; >+ //this.astLengthStack = new int[30]; >+ } >+ >+ /* (non-Javadoc) >+ * Returns true if tag @deprecated is present in annotation. >+ * >+ * If annotation checking is enabled, will also construct an Annotation node, which will be stored into Parser.annotation >+ * slot for being consumed later on. >+ */ >+ public boolean parse(Comment astComment) { >+ >+ // Init >+ this.scanner.setSource(astComment.getText().toCharArray()); >+ reset(); >+ boolean valid = false; >+ this.comment = astComment; >+ Javadoc javadoc = astComment.isJavadoc() ? (Javadoc) astComment : null; >+ >+ // Parse >+ try { >+ // Verify first characters >+ if (readChar() != '/' || readChar() != '*') { >+ return false; >+ } >+ >+ // Go to first non blank char >+ if (this.source[this.index] == '*') { >+ readChar(); >+ if (!astComment.isJavadoc()) { >+ return readChar() == '/' && this.index == this.scanner.eofPosition; >+ } >+ } >+ this.scanner.restartFrom(this.index); >+ skipWhiteChars(true); >+ int tagStart = this.index; >+ >+ // We got some text before first tag declaration >+ if (this.source[this.index] != '@') { >+ // read sentences before first tag >+ int textStart = this.index; >+ this.linePtr = this.scanner.linePtr; >+ boolean endComment = false; >+ while (!endComment && (this.source[this.index] != '@') && (this.index < this.scanner.eofPosition)) { >+ endComment = readLine(true); // skip '*' after line >+ } >+ >+ // Store first sentence in javadoc >+ if (javadoc != null) { >+ // description >+ int textEnd = this.scanner.getCurrentTokenEndPosition(); >+ if (this.scanner.linePtr > this.linePtr) { >+ textEnd = this.scanner.getLineEnd(this.scanner.linePtr+1); >+ } >+ JavadocTag firstSentence = javadoc.getDescriptionTag(); >+ firstSentence.setSourceRange(textStart, textEnd-textStart+1); >+ firstSentence.setDescription(new String(this.source, textStart, textEnd-textStart+1)); >+ >+ // embedded tags >+ if (this.scanner.embeddedPtr >= 0) { >+ for (int i=0; i<=this.scanner.embeddedPtr; i++) { >+ JavadocTag embeddedTag = parseEmbeddedTag(this.scanner.embeddedTagStarts[i], this.scanner.embeddedTagStops[i]); >+ firstSentence.embedded().add(embeddedTag); >+ } >+ } >+ } >+ >+ // verify end of comment >+ if (this.index >= this.scanner.eofPosition) { >+ return endComment; >+ } >+ if (endComment) { >+ skipWhiteChars(false); >+ return this.index == this.scanner.eofPosition; >+ } >+ } >+ >+ // Loop on each @tag >+ this.linePtr = this.scanner.linePtr; >+ loopTag: while (this.index < this.scanner.eofPosition) { >+ >+ // We should be at the beginning of a tag declaration... >+ skipWhiteChars(false); >+ if (this.source[this.index] != '@') { >+ break; >+ } >+ tagStart = this.index; >+ readChar(); >+ this.scanner.restartFrom(this.index); >+ >+ // Consume tag declaration >+ int tk = readTokenAndConsume(); // tag name >+ JavadocTag javadocTag = null; >+ switch (tk) { >+ case TerminalTokens.TokenNameIdentifier : >+ char[] tag = this.scanner.getCurrentIdentifierSource(); >+ skipWhiteChars(false); >+ if (CharOperation.equals(tag, TAG_PARAM)) { >+ javadocTag = parseParam(); >+ } else if (CharOperation.equals(tag, TAG_EXCEPTION)) { >+ javadocTag = parseThrows(); >+ } else if (CharOperation.equals(tag, TAG_SEE)) { >+ javadocTag = parseSee(); >+ } else { >+ javadocTag = parseTag(new String(tag)); >+ } >+ break; >+ case TerminalTokens.TokenNamereturn : >+ javadocTag = parseTag(new String(TAG_RETURN)); >+ break; >+ case TerminalTokens.TokenNamethrows : >+ javadocTag = parseThrows(); >+ break; >+ } >+ if (javadocTag == null) { // invalid tag break parse and return false >+ break; >+ } >+ >+ // Consume tag description >+ int textStart = this.index; >+ if (this.currentTokenType == -1) { >+ skipWhiteChars(false); >+ textStart = this.index; // store start again as it might be changed >+ } else { >+ if (this.currentTokenType != TerminalTokens.TokenNameWHITESPACE) { >+ textStart = this.scanner.getCurrentTokenStartPosition(); // one token was already read, start is at the beginning of this token >+ } >+ consumeToken(); >+ } >+ >+ // If new line was encountered while parsing tag declaration then do not read the first line >+ // (if this happens, this means that first line of description was empty and we're already on the second one) >+ boolean firstLineEmpty = this.scanner.linePtr > this.linePtr; >+ >+ // Loop on lines for tag description >+ loopText: while (this.index < this.scanner.eofPosition) { >+ this.linePtr = this.scanner.linePtr; >+ if (!firstLineEmpty) { >+ // stop right now if end of the comment is encountered >+ if (readLine(false/*keep '*' after line*/)) { >+ setJavadocTagText(javadocTag, tagStart, textStart); >+ skipWhiteChars(false); >+ valid = this.index == this.scanner.eofPosition; >+ break loopTag; >+ } >+ >+ // add embedded tags if necessary >+ if (this.scanner.embeddedPtr >= 0) { >+ for (int i=0; i<=this.scanner.embeddedPtr; i++) { >+ JavadocTag embeddedTag = parseEmbeddedTag(this.scanner.embeddedTagStarts[i], this.scanner.embeddedTagStops[i]); >+ javadocTag.embedded().add(embeddedTag); >+ } >+ } >+ >+ } >+ >+ // after reading a line, we should have a new line starting with a '*' or a new tag >+ // (since JDK 1.4, '*' is not mandatory at the beginning of the line...) >+ switch (this.source[this.index]) { >+ case '*' : >+ readChar(); >+ if (this.source[this.index] == '/') { >+ // sounds like end of comment, prepare to leave >+ readChar(); >+ skipWhiteChars(false); >+ valid = this.index == this.scanner.eofPosition; >+ } else { >+ skipWhiteChars(false); >+ if (this.source[this.index] != '@') { >+ // we're not on a new tag declaration, then read following line of description >+ break; >+ } >+ } >+ // fall through following case as we got a new tag or end of comment >+ case '@': >+ if (firstLineEmpty && (javadocTag.getReference() != null)) { // we're on an empty first line, end of text is on previous line... >+ int textEnd = javadocTag.getReference().getEndPosition(); >+ javadocTag.setSourceRange(tagStart, textEnd-tagStart+1); >+ //javadocTag.setDescription(new String(this.source, textStart, textEnd-textStart+1)); >+ this.linePtr = this.scanner.linePtr; >+ //this.linesPtr = -1; >+ } else { >+ setJavadocTagText(javadocTag, tagStart, textStart); >+ } >+ this.comment.tags().add(javadocTag); >+ break loopText; >+ default : >+ break loopTag; >+ } >+ firstLineEmpty = false; // we only want to skip first line read >+ } >+ } >+ } catch (Exception e) { >+ valid = false; >+ } finally { >+ this.source = null; // release source as soon as finished >+ } >+ return valid; >+ } >+ >+ private void consumeToken() { >+ this.currentTokenType = -1; // flush token cache >+ } >+ >+ private SimpleType getEnclosingType() { >+ ASTNode parent = this.comment.getParent(); >+ while (parent != null) { >+ if (parent instanceof SimpleType) { >+ return (SimpleType) parent; >+ } >+ parent = parent.getParent(); >+ } >+ return null; >+ } >+ >+ /* >+ * Parse argument in @see tag method reference >+ */ >+ private Expression parseArguments(SimpleType receiver) throws InvalidInputException { >+ >+ // Init >+ int modulo = 0; // should be 2 for (Type,Type,...) or 3 for (Type arg,Type arg,...) >+ int iToken = 0; >+ String argName = null; >+ int ptr = this.astPtr; >+ //int lptr = this.astLengthPtr; >+ int start = this.scanner.getCurrentTokenStartPosition(); >+ >+ // Decide whether we have a constructor or not >+ SimpleName simpleName = null; >+ Name receiverName = receiver.getName(); >+ if (receiverName.isQualifiedName()) { >+ simpleName = ((QualifiedName) receiverName).getName(); >+ } else { >+ simpleName = (SimpleName) receiverName; >+ } >+ boolean isConstructor = simpleName.getIdentifier().equals(this.identifierStack[0]); >+ >+ // Parse arguments declaration if method reference >+ nextArg : while (this.index < this.scanner.eofPosition) { >+ >+ // Read argument type reference >+ Type type; >+ try { >+ type = parseQualifiedName(false); >+ } catch (InvalidInputException e) { >+ break nextArg; >+ } >+ boolean firstArg = modulo == 0; >+ if (firstArg) { // verify position >+ if (iToken != 0) >+ break nextArg; >+ } else if ((iToken % modulo) != 0) { >+ break nextArg; >+ } >+ if (type == null) { >+ if (firstArg && this.currentTokenType == TerminalTokens.TokenNameRPAREN) { >+ int idStart = (int) (this.identifierPositionStack[0] >>> 32); >+ int idLength = ((int) this.identifierPositionStack[0]) - idStart + 1; >+ if (isConstructor) { >+ ClassInstanceCreation invocation = this.ast.newClassInstanceCreation(); >+ invocation.setSourceRange(idStart, idLength); >+ invocation.setName(receiver.getName()); >+ return invocation; >+ } else { >+ SimpleName methodName = this.ast.newSimpleName(this.identifierStack[0]); >+ methodName.setSourceRange(idStart, idLength); >+ MethodInvocation invocation = this.ast.newMethodInvocation(); >+ invocation.setName(methodName); >+ invocation.setSourceRange(start, this.scanner.getCurrentTokenEndPosition()-start+1); >+ return invocation; >+ } >+ } >+ break nextArg; >+ } >+ int argStart = type.getStartPosition(); >+ int argLength = type.getLength(); >+ iToken++; >+ >+ // Read possible array declaration >+ if (readToken() == TerminalTokens.TokenNameLBRACKET) { >+ while (readToken() == TerminalTokens.TokenNameLBRACKET) { >+ consumeToken(); >+ if (readToken() != TerminalTokens.TokenNameRBRACKET) { >+ break nextArg; >+ } >+ consumeToken(); >+ type = this.ast.newArrayType(type); >+ } >+ type.setSourceRange(argStart, this.scanner.getCurrentTokenEndPosition()-argStart+1); >+ } >+ >+ // Read argument name >+ if (readToken() == TerminalTokens.TokenNameIdentifier) { >+ consumeToken(); >+ if (firstArg) { // verify position >+ if (iToken != 1) >+ break nextArg; >+ } else if ((iToken % modulo) != 1) { >+ break nextArg; >+ } >+ if (argName == null) { // verify that all arguments name are declared >+ if (!firstArg) { >+ break nextArg; >+ } >+ } >+ argName = this.scanner.getCurrentIdentifierSourceAsString(); >+ argLength = this.scanner.getCurrentTokenEndPosition()-argStart+1; >+ iToken++; >+ } else if (argName != null) { // verify that no argument name is declared >+ break nextArg; >+ } >+ >+ // Verify token position >+ if (firstArg) { >+ modulo = iToken + 1; >+ } else { >+ if ((iToken % modulo) != (modulo - 1)) { >+ break nextArg; >+ } >+ } >+ >+ // Read separator or end arguments declaration >+ int token = readToken(); >+ String name = argName == null ? new String() : argName; >+ if (token == TerminalTokens.TokenNameCOMMA) { >+ // Create new argument >+ SingleVariableDeclaration variable = this.ast.newSingleVariableDeclaration(); >+ variable.setSourceRange(argStart, argLength); >+ variable.setName(this.ast.newSimpleName(name)); >+ variable.setType(type); >+ JavadocArgument argument = this.ast.newJavadocArgument(); >+ argument.setSourceRange(argStart, argLength); >+ argument.setArgument(variable); >+ pushOnAstStack(argument); >+ consumeToken(); >+ iToken++; >+ } else if (token == TerminalTokens.TokenNameRPAREN) { >+ // Create new argument >+ SingleVariableDeclaration variable = this.ast.newSingleVariableDeclaration(); >+ variable.setSourceRange(argStart, argLength); >+ variable.setName(this.ast.newSimpleName(name)); >+ variable.setType(type); >+ JavadocArgument argument = this.ast.newJavadocArgument(); >+ argument.setSourceRange(argStart, argLength); >+ argument.setArgument(variable); >+ pushOnAstStack(argument); >+ // Build arguments array >+ //int size = this.astLengthStack[this.astLengthPtr--]; >+ ArrayList arguments = new ArrayList(this.astPtr); >+ while (this.astPtr >=0) { >+ arguments.add(this.astStack[this.astPtr--]); >+ } >+ // Create message send >+ if (isConstructor) { >+ ClassInstanceCreation invocation = this.ast.newClassInstanceCreation(); >+ invocation.setSourceRange(start, this.scanner.getCurrentTokenEndPosition()-start+1); >+ invocation.setName(receiver.getName()); >+ invocation.arguments().addAll(arguments); >+ return invocation; >+ } else { >+ int idStart = (int) (this.identifierPositionStack[0] >>> 32); >+ int idLength = ((int) this.identifierPositionStack[0]) - idStart + 1; >+ SimpleName methodName = this.ast.newSimpleName(this.identifierStack[0]); >+ methodName.setSourceRange(idStart, idLength); >+ MethodInvocation invocation = this.ast.newMethodInvocation(); >+ invocation.setSourceRange(start, this.scanner.getCurrentTokenEndPosition()-start+1); >+ invocation.setName(methodName); >+ invocation.arguments().addAll(arguments); >+ return invocation; >+ } >+ } else { >+ break nextArg; >+ } >+ } >+ >+ // Invalid input: reset ast stacks pointers >+ consumeToken(); >+ if (iToken > 0) { >+ this.astPtr = ptr; >+ //this.astLengthPtr = lptr; >+ } >+ throw new InvalidInputException(); >+ } >+ >+ private JavadocTag parseEmbeddedTag(int start, int end) throws InvalidInputException { >+ // Init specific scanner with text wihtout braces >+ int sourceLength = end - (start+1); >+ char[] tagSource = new char[sourceLength]; >+ System.arraycopy(this.source, start+1, tagSource, 0, sourceLength); >+ DOMCommentParser parser = new DOMCommentParser(this.ast); >+ parser.scanner.setSource(tagSource); >+ parser.reset(); >+ >+ // Read embedded tag identifier >+ if (parser.readChar() != '@') { >+ throw new InvalidInputException(); >+ } >+ parser.scanner.restartFrom(parser.index); >+ if (parser.readTokenAndConsume() != TerminalTokens.TokenNameIdentifier) { >+ throw new InvalidInputException(); >+ } >+ >+ // Read embedded tag declaration >+ JavadocTag tag = null; >+ char[] tagName = parser.scanner.getCurrentIdentifierSource(); >+ parser.skipWhiteChars(false); >+ if (CharOperation.equals(tagName, EMBEDDED_TAG_INHERIT_DOC)) { >+ if (!parser.scanner.atEnd()) { >+ throw new InvalidInputException(); >+ } >+ } >+ else if (CharOperation.equals(tagName, EMBEDDED_TAG_LINK) || >+ (CharOperation.equals(tagName, EMBEDDED_TAG_LINKPLAIN))) >+ { >+ tag = parser.parseSee(); >+ if (tag == null) { >+ throw new InvalidInputException(); >+ } >+ tag.setIdentifier(new String(tagName)); >+ if (parser.index < parser.scanner.eofPosition) { >+ int textStart = parser.index; >+ if (parser.currentTokenType == -1) { >+ parser.skipWhiteChars(false); >+ textStart = parser.index; >+ } else { >+ if (parser.currentTokenType != TerminalTokens.TokenNameWHITESPACE) { >+ textStart = parser.scanner.getCurrentTokenStartPosition(); >+ } >+ } >+ tag.setDescription(new String(parser.source, textStart, sourceLength-textStart)); >+ } >+ } >+ >+ // Throw exception if the tag is invalid >+ if (tag == null) { >+ tag = this.ast.newJavadocTag(); >+ tag.setSourceRange(start, end-start+1); >+ tag.setIdentifier(new String(tagName)); >+ } >+ return tag; >+ } >+ >+ /* >+ * Parse a method reference in @see tag >+ */ >+ private Expression parseMember(SimpleType receiver) throws InvalidInputException { >+ // Init >+ this.identifierPtr = -1; >+ this.identifierLengthPtr = -1; >+ >+ // Get type ref >+ SimpleType type = receiver; >+ if (type == null) { >+ type = getEnclosingType(); >+ if (type == null) { >+ return null; >+ } >+ } >+ >+ // Get member identifier >+ if (readTokenAndConsume() == TerminalTokens.TokenNameIdentifier) { >+ pushIdentifier(true); >+ if (readTokenAndConsume() == TerminalTokens.TokenNameLPAREN) { >+ try { >+ return parseArguments(type); >+ } catch (InvalidInputException e) { >+ // ignore >+ } >+ return null; >+ } >+ FieldAccess fieldAccess = this.ast.newFieldAccess(); >+ fieldAccess.setName(this.ast.newSimpleName(this.identifierStack[0])); >+ int idStart = (int) (this.identifierPositionStack[0] >>> 32); >+ int idLength = ((int) this.identifierPositionStack[0]) - idStart + 1; >+ fieldAccess.setSourceRange(idStart, idLength); >+ return fieldAccess; >+ } >+ return null; >+ } >+ >+ /* >+ * Parse @param tag declaration >+ */ >+ private JavadocTag parseParam() { >+ try { >+ int token = readTokenAndConsume(); >+ if (token == TerminalTokens.TokenNameIdentifier) { >+ JavadocTag tag = this.ast.newJavadocTag(); >+ tag.setIdentifier(new String(TAG_PARAM)); >+ SimpleName name = this.ast.newSimpleName(new String(this.scanner.getCurrentIdentifierSource())); >+ VariableDeclarationFragment variable = this.ast.newVariableDeclarationFragment(); >+ variable.setSourceRange(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition()-this.scanner.getCurrentTokenStartPosition()+1); >+ variable.setName(name); >+ tag.setReference(variable); >+ return tag; >+ } >+ } catch (InvalidInputException e) { >+ consumeToken(); >+ } >+ return null; >+ } >+ >+ /* >+ * Parse a qualified name and built a type reference if the syntax is valid. >+ */ >+ private Type parseQualifiedName(boolean reset) throws InvalidInputException { >+ >+ // Reset identifier stack if requested >+ int start = this.scanner.getCurrentTokenStartPosition(); >+ if (reset) { >+ this.identifierPtr = -1; >+ this.identifierLengthPtr = -1; >+ } >+ >+ // Scan tokens >+ int typeTokenEnd = -1; >+ nextToken : for (int iToken = 0; ; iToken++) { >+ int lptr = this.scanner.linePtr; >+ int token = readToken(); >+ switch (token) { >+ case TerminalTokens.TokenNameIdentifier : >+ if (((iToken % 2) > 0)) { // identifiers must be odd tokens >+ break nextToken; >+ } >+ pushIdentifier(iToken == 0); >+ consumeToken(); >+ typeTokenEnd = this.scanner.getCurrentTokenEndPosition(); >+ break; >+ >+ case TerminalTokens.TokenNameDOT : >+ if ((iToken % 2) == 0) { // dots must be even tokens >+ throw new InvalidInputException(); >+ } >+ consumeToken(); >+ break; >+ >+ case TerminalTokens.TokenNamevoid : >+ if (iToken > 0) throw new InvalidInputException(); >+ PrimitiveType type = this.ast.newPrimitiveType(PrimitiveType.VOID); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNameboolean : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.BOOLEAN); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNamebyte : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.BYTE); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNamechar : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.CHAR); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNamedouble : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.DOUBLE); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNamefloat : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.FLOAT); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNameint : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.INT); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNamelong : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.LONG); >+ consumeToken(); >+ return type; >+ case TerminalTokens.TokenNameshort : >+ if (iToken > 0) throw new InvalidInputException(); >+ type = this.ast.newPrimitiveType(PrimitiveType.SHORT); >+ consumeToken(); >+ return type; >+ >+ case TerminalTokens.TokenNameWHITESPACE: >+ // Ignore white spaces >+ if (this.scanner.linePtr > lptr) { >+ // Leave if new line was encountered >+ break nextToken; >+ } >+ iToken--; >+ consumeToken(); >+ break; >+ default : >+ if (iToken == 0) { >+ return null; >+ } >+ if ((iToken % 2) == 0) { // cannot leave on a dot >+ throw new InvalidInputException(); >+ } >+ break nextToken; >+ } >+ } >+ >+ // We should have stored a end position for the type >+ if (typeTokenEnd == -1) { >+ throw new InvalidInputException(); >+ } >+ >+ // Build type reference from read tokens >+ int size = this.identifierLengthStack[this.identifierLengthPtr--]; >+ String[] identifiers = new String[size]; >+ int pos = this.identifierPtr - size + 1; >+ System.arraycopy(this.identifierStack, pos, identifiers, 0, size); >+ SimpleType type = this.ast.newSimpleType( this.ast.newName(identifiers)); >+ type.setSourceRange(start, typeTokenEnd-start+1); >+ this.identifierPtr -= size; >+ return type; >+ } >+ >+ /* >+ * Parse a reference in @see tag >+ */ >+ private ASTNode parseReference() throws InvalidInputException { >+ SimpleType type = null; >+ nextToken : while (this.index < this.scanner.eofPosition) { >+ int token = readToken(); >+ switch (token) { >+ case TerminalTokens.TokenNameStringLiteral : >+ case TerminalTokens.TokenNameLESS : >+ readLine(true); >+ return null; >+ case TerminalTokens.TokenNameERROR : >+ consumeToken(); >+ if (this.scanner.currentCharacter == '#') { // @see ...#member >+ return parseMember(type); >+ } >+ break nextToken; >+ case TerminalTokens.TokenNameIdentifier : >+ if (type == null) { >+ Type refType = parseQualifiedName(true); >+ if (refType instanceof SimpleType) { >+ type = (SimpleType) refType; >+ break; >+ } >+ } >+ default : >+ break nextToken; >+ } >+ } >+ return type; >+ } >+ >+ /* >+ * Parse @return tag declaration >+ */ >+ private JavadocTag parseTag(String tagName) { >+ JavadocTag tag = this.ast.newJavadocTag(); >+ tag.setIdentifier(tagName); >+ try { >+ readLine(true); >+ return tag; >+ } >+ catch (InvalidInputException e) { >+ return null; >+ } >+ } >+ >+ /* >+ * Parse @see tag declaration >+ */ >+ private JavadocTag parseSee() { >+ int start = this.scanner.currentPosition; >+ try { >+ JavadocTag tag = this.ast.newJavadocTag(); >+ tag.setIdentifier(new String(TAG_SEE)); >+ ASTNode ref = parseReference(); >+ if (ref != null) { >+ ref.setSourceRange(start, this.scanner.getCurrentTokenEndPosition()-start+1); >+ tag.setReference(ref); >+ return tag; >+ } >+ } catch (InvalidInputException ex) { >+ // ignore >+ } >+ return null; >+ } >+ >+ /* >+ * Parse @throws tag declaration >+ */ >+ private JavadocTag parseThrows() { >+ try { >+ JavadocTag tag = this.ast.newJavadocTag(); >+ tag.setIdentifier(new String(TAG_THROWS)); >+ Type type = parseQualifiedName(true); >+ if (type != null && type instanceof SimpleType) { >+ tag.setReference(type); >+ return tag; >+ } >+ } catch (InvalidInputException ex) { >+ // ignore >+ } >+ return null; >+ } >+ >+ /* >+ * push the consumeToken on the identifier stack. Increase the total number of identifier in the stack. >+ */ >+ private void pushIdentifier(boolean newLength) { >+ >+ String identifier = new String(this.scanner.getCurrentTokenSource()); >+ try { >+ this.identifierStack[++this.identifierPtr] = identifier; >+ this.identifierPositionStack[this.identifierPtr] = (((long) this.scanner.startPosition) << 32) >+ + (this.scanner.currentPosition - 1); >+ } catch (IndexOutOfBoundsException e) { >+ //---stack reallaocation (identifierPtr is correct)--- >+ int oldStackLength = this.identifierStack.length; >+ String[] oldStack = this.identifierStack; >+ this.identifierStack = new String[oldStackLength + 10]; >+ System.arraycopy(oldStack, 0, this.identifierStack, 0, oldStackLength); >+ this.identifierStack[this.identifierPtr] = identifier; >+ // identifier position stack >+ long[] oldPos = this.identifierPositionStack; >+ this.identifierPositionStack = new long[oldStackLength + 10]; >+ System.arraycopy(oldPos, 0, this.identifierPositionStack, 0, oldStackLength); >+ this.identifierPositionStack[this.identifierPtr] = (((long) this.scanner.startPosition) << 32) >+ + (this.scanner.currentPosition - 1); >+ } >+ >+ if (newLength) { >+ try { >+ this.identifierLengthStack[++this.identifierLengthPtr] = 1; >+ } catch (IndexOutOfBoundsException e) { >+ /* ---stack reallocation (identifierLengthPtr is correct)--- */ >+ int oldStackLength = this.identifierLengthStack.length; >+ int oldStack[] = this.identifierLengthStack; >+ this.identifierLengthStack = new int[oldStackLength + 10]; >+ System.arraycopy(oldStack, 0, this.identifierLengthStack, 0, oldStackLength); >+ this.identifierLengthStack[this.identifierLengthPtr] = 1; >+ } >+ } else { >+ this.identifierLengthStack[this.identifierLengthPtr]++; >+ } >+ } >+ >+ /* >+ * Add a new obj on top of the ast stack. >+ * If new length is required, then add also a new length in length stack. >+ */ >+ private void pushOnAstStack(ASTNode node) { >+ >+ try { >+ this.astStack[++this.astPtr] = node; >+ } catch (IndexOutOfBoundsException e) { >+ int oldStackLength = this.astStack.length; >+ ASTNode[] oldStack = this.astStack; >+ this.astStack = new ASTNode[oldStackLength + AstStackIncrement]; >+ System.arraycopy(oldStack, 0, this.astStack, 0, oldStackLength); >+ this.astPtr = oldStackLength; >+ this.astStack[this.astPtr] = node; >+ } >+ } >+ >+ /* >+ * Read next char using parser source. Do NOT change scanner current position. >+ */ >+ private char readChar() { >+ char c = this.source[this.index++]; >+ if (c == '\\') { >+ int c1, c2, c3, c4; >+ this.index++; >+ while (this.source[this.index] == 'u') >+ this.index++; >+ if (!(((c1 = Character.getNumericValue(this.source[this.index++])) > 15 || c1 < 0) >+ || ((c2 = Character.getNumericValue(this.source[this.index++])) > 15 || c2 < 0) >+ || ((c3 = Character.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = Character.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) { >+ c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); >+ } >+ } >+ return c; >+ } >+ >+ /* >+ * Read until the end of the line. If previous token was not consumed, >+ * then push it at the beginning of the line. >+ */ >+ private boolean readLine(boolean skipStar) throws InvalidInputException { >+ boolean endComment = this.scanner.skipCommentLine(); >+ this.index = this.scanner.currentPosition; >+ skipWhiteChars(skipStar); >+ return endComment; >+ } >+ >+ /* >+ * Read token only if previous was consumed >+ */ >+ private int readToken() throws InvalidInputException { >+ if (this.currentTokenType < 0) { >+ this.currentTokenType = this.scanner.getNextToken(); >+ this.index = this.scanner.currentPosition; >+ } >+ return this.currentTokenType; >+ } >+ >+ private int readTokenAndConsume() throws InvalidInputException { >+ int token = readToken(); >+ consumeToken(); >+ return token; >+ } >+ >+ private void reset() { >+ this.scanner.embeddedPtr = -1; >+ this.source = this.scanner.source; >+ this.index = 0; >+ this.source = this.scanner.source; >+ this.astPtr = -1; >+ this.identifierPtr = -1; >+ this.linePtr = -1; >+ this.currentTokenType = -1; >+ } >+ >+ private void setJavadocTagText(JavadocTag javadocTag, int tagStart, int textStart) { >+ int textEnd = this.scanner.getCurrentTokenEndPosition(); >+ if (this.scanner.linePtr > this.linePtr) { >+ textEnd = this.scanner.getLineEnd(this.scanner.linePtr+1); >+ } >+ javadocTag.setSourceRange(tagStart, textEnd-tagStart+1); >+ javadocTag.setDescription(new String(this.source, textStart, textEnd-textStart+1)); >+ this.linePtr = this.scanner.linePtr; >+ } >+ >+ private void skipWhiteChars(boolean skipStar) { >+ while (this.index<this.scanner.eofPosition && ((skipStar && this.source[this.index] == '*') || Character.isWhitespace(this.source[this.index]))) { >+ this.scanner.currentCharacter = this.source[this.index]; >+ readChar(); >+ } >+ this.scanner.currentPosition = this.index; >+ } >+ >+ public String toString() { >+ StringBuffer buffer = new StringBuffer(); >+ buffer.append(this.comment).append("\n"); //$NON-NLS-1$ >+ return buffer.toString(); >+ } >+} >Index: dom/org/eclipse/jdt/core/dom/DOMParser.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/DOMParser.java >diff -N dom/org/eclipse/jdt/core/dom/DOMParser.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/DOMParser.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,224 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+import org.eclipse.jdt.internal.compiler.CompilationResult; >+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; >+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; >+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >+import org.eclipse.jdt.internal.compiler.parser.Parser; >+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; >+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; >+ >+/** >+ * Specific parser to use while parsing source to create DOM AST nodes. >+ */ >+class DOMParser extends Parser { >+ >+ // support for comments >+ int[] commentStops = new int[10]; >+ int[] commentStarts = new int[10]; >+ int commentPtr = -1; // no comment test with commentPtr value -1 >+ protected final static int CommentIncrement = 100; >+ >+ /** >+ * @param problemReporter >+ * @param optimizeStringLiterals >+ */ >+ public DOMParser(ProblemReporter problemReporter, boolean optimizeStringLiterals) { >+ super(problemReporter, optimizeStringLiterals); >+ this.javadocParser.checkJavadoc = true; >+ } >+ >+ // old javadoc style check which doesn't include all leading comments into declaration >+ // for backward compatibility with 2.1 DOM >+ public void checkComment() { >+ >+ if (this.currentElement != null && this.scanner.commentPtr >= 0) { >+ flushCommentsDefinedPriorTo(this.endStatementPosition); // discard obsolete comments >+ } >+ boolean deprecated = false; >+ boolean checkDeprecated = false; >+ int lastCommentIndex = -1; >+ >+ // >+ >+ //since jdk1.2 look only in the last java doc comment... >+ nextComment : for (lastCommentIndex = this.scanner.commentPtr; lastCommentIndex >= 0; lastCommentIndex--){ >+ //look for @deprecated into the first javadoc comment preceeding the declaration >+ int commentSourceStart = this.scanner.commentStarts[lastCommentIndex]; >+ // javadoc only (non javadoc comment have negative end positions.) >+ if ((commentSourceStart < 0) || >+ (this.modifiersSourceStart != -1 && this.modifiersSourceStart < commentSourceStart) || >+ (this.scanner.commentStops[lastCommentIndex] < 0)) >+ { >+ continue nextComment; >+ } >+ checkDeprecated = true; >+ int commentSourceEnd = this.scanner.commentStops[lastCommentIndex] - 1; //stop is one over >+ >+ deprecated = >+ this.javadocParser.checkDeprecation(commentSourceStart, commentSourceEnd); >+ this.javadoc = this.javadocParser.javadoc; >+ break nextComment; >+ } >+ if (deprecated) { >+ checkAndSetModifiers(AccDeprecated); >+ } >+ // modify the modifier source start to point at the first comment >+ if (lastCommentIndex >= 0 && checkDeprecated) { >+ this.modifiersSourceStart = this.scanner.commentStarts[lastCommentIndex]; >+ if (this.modifiersSourceStart < 0) { >+ this.modifiersSourceStart = -this.modifiersSourceStart; >+ } >+ } >+ >+ } >+ >+ >+ /* (non-Javadoc) >+ * Save all source comments currently stored before flushing them. >+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#flushCommentsDefinedPriorTo(int) >+ */ >+ public int flushCommentsDefinedPriorTo(int position) { >+ >+ int lastCommentIndex = this.scanner.commentPtr; >+ if (lastCommentIndex < 0) return position; // no comment >+ >+ // compute the index of the first obsolete comment >+ int index = lastCommentIndex; >+ int validCount = 0; >+ while (index >= 0){ >+ int commentEnd = this.scanner.commentStops[index]; >+ if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments >+ if (commentEnd <= position){ >+ break; >+ } >+ index--; >+ validCount++; >+ } >+ // if the source at <position> is immediately followed by a line comment, then >+ // flush this comment and shift <position> to the comment end. >+ if (validCount > 0){ >+ int immediateCommentEnd = -this.scanner.commentStops[index+1]; //non-javadoc comment end positions are negative >+ if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments >+ // is there any line break until the end of the immediate comment ? (thus only tolerating line comment) >+ immediateCommentEnd--; // comment end in one char too far >+ if (this.scanner.getLineNumber(position) == this.scanner.getLineNumber(immediateCommentEnd)){ >+ position = immediateCommentEnd; >+ validCount--; // flush this comment >+ index++; >+ } >+ } >+ } >+ >+ if (index < 0) return position; // no obsolete comment >+ pushOnCommentsStack(0, index); // store comment before flushing them >+ >+ if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos >+ System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount); >+ System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount); >+ } >+ this.scanner.commentPtr = validCount - 1; >+ return position; >+ } >+ >+ /* >+ * Push all stored comments in stack. >+ */ >+ private void pushOnCommentsStack(int start, int end) { >+ >+ for (int i=start; i<=end; i++) { >+ try { >+ this.commentPtr++; >+ this.commentStarts[this.commentPtr] = this.scanner.commentStarts[i]; >+ this.commentStops[this.commentPtr] = this.scanner.commentStops[i]; >+ } catch (IndexOutOfBoundsException e) { >+ // this.commentPtr is still correct >+ int oldStackLength = this.commentStarts.length; >+ int oldCommentStarts[] = this.commentStarts; >+ this.commentStarts = new int[oldStackLength + CommentIncrement]; >+ System.arraycopy(oldCommentStarts, 0, this.commentStarts, 0, oldStackLength); >+ this.commentStarts[this.commentPtr] = this.scanner.commentStarts[i]; >+ int oldCommentStops[] = this.commentStops; >+ this.commentStops = new int[oldStackLength + CommentIncrement]; >+ System.arraycopy(oldCommentStops, 0, this.commentStops, 0, oldStackLength); >+ this.commentStops[this.commentPtr] = this.scanner.commentStops[i]; >+ } >+ } >+ } >+ /* (non-Javadoc) >+ * Save all source comments currently stored before flushing them. >+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#resetModifiers() >+ */ >+ protected void resetModifiers() { >+ pushOnCommentsStack(0, this.scanner.commentPtr); >+ super.resetModifiers(); >+ } >+ >+ /** >+ * Store comments positions saved in stack in compilation unit declaration. >+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#dietParse(org.eclipse.jdt.internal.compiler.env.ICompilationUnit, org.eclipse.jdt.internal.compiler.CompilationResult) >+ */ >+ public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) { >+ CompilationUnitDeclaration unit = super.dietParse(sourceUnit, compilationResult); >+ unit.comments = getCommentsPositions(); >+ return unit; >+ } >+ >+ /** >+ * Insure that start position is always positive. >+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#containsComment(int, int) >+ */ >+ public boolean containsComment(int sourceStart, int sourceEnd) { >+ int iComment = this.scanner.commentPtr; >+ for (; iComment >= 0; iComment--) { >+ int commentStart = this.scanner.commentStarts[iComment]; >+ if (commentStart < 0) { >+ commentStart = -commentStart; >+ } >+ // ignore comments before start >+ if (commentStart < sourceStart) continue; >+ // ignore comments after end >+ if (commentStart > sourceEnd) continue; >+ return true; >+ } >+ return false; >+ } >+ >+ /* >+ * Build a n*2 matrix of comments positions. >+ * For each position, 0 is for start position and 1 for end position of the comment. >+ */ >+ public int[][] getCommentsPositions() { >+ int[][] positions = new int[this.commentPtr+1][2]; >+ for (int i = 0, max = this.commentPtr; i <= max; i++){ >+ positions[i][0] = this.commentStarts[i]; >+ positions[i][1] = this.commentStops[i]; >+ } >+ return positions; >+ } >+ >+ /* (non-Javadoc) >+ * Create and store a specific DOM scanner. >+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#initializeScanner() >+ */ >+ public void initializeScanner() { >+ this.scanner = new DOMScanner( >+ false /*comment*/, >+ false /*whitespace*/, >+ this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /*nls*/, >+ this.options.sourceLevel /*sourceLevel*/, >+ this.options.taskTags/*taskTags*/, >+ this.options.taskPriorites/*taskPriorities*/); >+ } >+ >+} >Index: dom/org/eclipse/jdt/core/dom/DOMScanner.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/DOMScanner.java >diff -N dom/org/eclipse/jdt/core/dom/DOMScanner.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/DOMScanner.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,179 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+import org.eclipse.jdt.core.compiler.InvalidInputException; >+import org.eclipse.jdt.internal.compiler.parser.Scanner; >+ >+/** >+ * Specialized scanner for DOM AST nodes. >+ */ >+class DOMScanner extends Scanner { >+ >+ // Tell whether an end of comment was reached >+ int embeddedPtr = -1; >+ int[] embeddedTagStarts = new int[10]; >+ int[] embeddedTagStops = new int[10]; >+ >+ public DOMScanner() { >+ super(); >+ } >+ >+ public DOMScanner( >+ boolean tokenizeComments, >+ boolean tokenizeWhiteSpace, >+ boolean checkNonExternalizedStringLiterals, >+ long sourceLevel, >+ char[][] taskTags, >+ char[][] taskPriorities) { >+ super(tokenizeComments, tokenizeWhiteSpace, checkNonExternalizedStringLiterals, sourceLevel, taskTags, taskPriorities); >+ } >+ >+ /** >+ * Return the current token source as a string. Do not call getCurrentTokenSourceString() >+ * method of superclass in order to avoid unnecessary array copy. >+ * @see org.eclipse.jdt.internal.compiler.parser.Scanner#getCurrentTokenSource() >+ * @return String >+ */ >+ public final String getCurrentTokenSourceAsString() { >+ //return the token REAL source (aka unicodes are precomputed). >+ >+ if (this.withoutUnicodePtr != 0) { >+ //0 is used as a fast test flag so the real first char is in position 1 >+ return new String(this.withoutUnicodeBuffer, 0, this.withoutUnicodePtr); >+ } else { >+ if (this.currentPosition < this.startPosition) { >+ return ""; //$NON-NLS-1$ >+ } >+ return new String(this.source, this.startPosition, this.currentPosition - this.startPosition); >+ } >+ } >+ >+ /** >+ * Return the current identifier source as a string. Do not call getCurrentTokenSourceString() >+ * method of superclass in order to avoid unnecessary array copy. >+ * @see org.eclipse.jdt.internal.compiler.parser.Scanner#getCurrentIdentifierSource() >+ * @return String >+ */ >+ public String getCurrentIdentifierSourceAsString() { >+ //return the token REAL source (aka unicodes are precomputed) >+ >+ if (this.withoutUnicodePtr != 0) { >+ //0 is used as a fast test flag so the real first char is in position 1 >+ return new String(this.withoutUnicodeBuffer, 1, this.withoutUnicodePtr); >+ } else { >+ int length = this.currentPosition - this.startPosition; >+ //no optimization >+ return new String(this.source, this.startPosition, length); >+ } >+ } >+ >+ /* >+ * Skip a line in a comment. Returns an positions array of possible embedded tags. >+ * Also store whether the end of comment has been reached or not. >+ */ >+ public boolean skipCommentLine() throws InvalidInputException { >+ boolean endComment = this.currentCharacter == '*'; >+ int endLine = this.currentPosition; >+ if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { >+ endLine--; >+ } >+ int startEmbedded = this.currentCharacter == '{' ? this.getCurrentTokenStartPosition() : this.currentPosition; >+ while ((this.currentPosition < this.eofPosition) && (this.currentCharacter != '\r') && (this.currentCharacter != '\n')) { >+ // Look for end comment >+ if (endComment && this.currentCharacter == '/') { >+ break; >+ } >+ endComment = false; >+ // Look for embedded tag declaration >+ if (this.currentCharacter == '{') { >+ int endEmbedded = this.currentPosition; >+ getNextChar(); >+ if ((this.currentPosition >= this.eofPosition) || >+ (this.currentCharacter == '\r') || >+ (this.currentCharacter == '\n')) { >+ // End of text of new line was found before end of embedded tag => break from loop >+ break; >+ } >+ if (this.currentCharacter == '@') { >+ // Loop on embedded tag declaration >+ while ((this.currentCharacter != '}')) { >+ if (((endComment && this.currentCharacter == '/')) || >+ (this.currentPosition >= this.eofPosition) || >+ (this.currentCharacter == '\r') || >+ (this.currentCharacter == '\n')) { >+ // End of text of new line was found before end of embedded tag => the text is not valid >+ throw new InvalidInputException(); >+ } >+ endEmbedded = this.currentPosition; >+ endComment = this.currentCharacter == '*'; >+ getNextChar(); >+ } >+ recordEmbeddedTag(startEmbedded, endEmbedded); >+ } >+ } >+ // Read next char >+ endComment = this.currentCharacter == '*'; >+ endLine = this.currentPosition; >+ startEmbedded = this.currentPosition; >+ getNextChar(); >+ } >+ // Push line separator if needed >+ if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { >+ pushLineSeparator(); >+ this.lineEnds[this.linePtr] = endLine - 1; >+ } >+ return endComment; >+ } >+ >+ /** >+ * Set start position negative for line comments. >+ * @see org.eclipse.jdt.internal.compiler.parser.Scanner#recordComment(int) >+ */ >+ public void recordComment(int token) { >+ super.recordComment(token); >+ if (token == TokenNameCOMMENT_LINE) { >+ // for comment line both positions are negative >+ this.commentStarts[this.commentPtr] = -this.commentStarts[this.commentPtr]; >+ } >+ } >+ >+ private void recordEmbeddedTag(int start, int end) { >+ >+ // a new comment is recorded >+ try { >+ this.embeddedTagStops[++this.embeddedPtr] = end; >+ } catch (IndexOutOfBoundsException e) { >+ int oldStackLength = this.embeddedTagStops.length; >+ int[] oldStack = this.embeddedTagStops; >+ this.embeddedTagStops = new int[oldStackLength + 10]; >+ System.arraycopy(oldStack, 0, this.embeddedTagStops, 0, oldStackLength); >+ this.embeddedTagStops[this.embeddedPtr] = end; >+ //grows the positions buffers too >+ int[] old = this.embeddedTagStarts; >+ this.embeddedTagStarts = new int[oldStackLength + 10]; >+ System.arraycopy(old, 0, this.embeddedTagStarts, 0, oldStackLength); >+ } >+ >+ //the buffer is of a correct size here >+ this.embeddedTagStarts[this.embeddedPtr] = start; >+ } >+ >+ /** >+ * Reset initial, start and current positions. >+ * @param begin Position from which we want to restart >+ * @see org.eclipse.jdt.internal.compiler.parser.Scanner#resetTo(int, int) >+ */ >+ public void restartFrom(int begin) { >+ this.initialPosition = this.startPosition = this.currentPosition = begin; >+ this.embeddedPtr = -1; >+ } >+} >Index: dom/org/eclipse/jdt/core/dom/JavadocArgument.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/JavadocArgument.java >diff -N dom/org/eclipse/jdt/core/dom/JavadocArgument.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/JavadocArgument.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,100 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+/** >+ */ >+public class JavadocArgument extends Expression { >+ >+ /** >+ * The argument; lazily initialized; defaults to an unspecified, >+ * but legal, single variable declaration. >+ */ >+ private SingleVariableDeclaration argument; >+ >+ /** >+ * @param ast >+ */ >+ public JavadocArgument(AST ast) { >+ super(ast); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#getNodeType() >+ */ >+ public int getNodeType() { >+ return JAVADOC_ARGUMENT; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(org.eclipse.jdt.core.dom.ASTMatcher, java.lang.Object) >+ */ >+ public boolean subtreeMatch(ASTMatcher matcher, Object other) { >+ return matcher.match(this, other); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#clone(org.eclipse.jdt.core.dom.AST) >+ */ >+ ASTNode clone(AST target) { >+ JavadocArgument result = new JavadocArgument(target); >+ result.setSourceRange(this.getStartPosition(), this.getLength()); >+ result.setArgument(getArgument()); >+ return result; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#accept0(org.eclipse.jdt.core.dom.ASTVisitor) >+ */ >+ void accept0(ASTVisitor visitor) { >+ visitor.visit(this); >+ visitor.endVisit(this); >+ >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#treeSize() >+ */ >+ int treeSize() { >+ return this.argument==null?0:this.argument.treeSize(); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#memSize() >+ */ >+ int memSize() { >+ return BASE_NODE_SIZE + 4; >+ } >+ >+ /** >+ * @return Returns the argument. >+ */ >+ public SingleVariableDeclaration getArgument() { >+ if (this.argument == null) { >+ // lazy initialize - use setter to ensure parent link set too >+ setArgument(getAST().newSingleVariableDeclaration()); >+ } >+ return this.argument; >+ } >+ >+ /** >+ * @param argument The argument to set. >+ */ >+ public void setArgument(SingleVariableDeclaration argument) { >+ if (argument == null) { >+ throw new IllegalArgumentException(); >+ } >+ replaceChild(this.argument, argument, false); >+ modifying(); >+ this.argument = argument; >+ } >+ >+} >Index: dom/org/eclipse/jdt/core/dom/JavadocTag.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/JavadocTag.java >diff -N dom/org/eclipse/jdt/core/dom/JavadocTag.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/JavadocTag.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,200 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+import java.util.List; >+ >+ >+/** >+ * AST node for a Javadoc tag of a comment. >+ * >+ * @since 3.0 >+ */ >+public class JavadocTag extends ASTNode { >+ >+ /** >+ * An unspecified (but externally observable) legal Javadoc tag identifier. >+ */ >+ static final String EMPTY = "";//$NON-NLS-1$ >+ >+ /** >+ * The tag identifier; defaults to an empty string. >+ */ >+ private String identifier = EMPTY; >+ >+ /** >+ * An other AST node the tag refers to; defaults is null >+ */ >+ private ASTNode reference; >+ >+ /** >+ * The tag description; defaults to an empty string. >+ */ >+ private String description = EMPTY; //$NON-NLS-1$ >+ >+ /** >+ * The embedded tags included in the tag description (element type: <code>JavadocTag</code>). >+ * Defaults to none. >+ */ >+ private ASTNode.NodeList embedded = new ASTNode.NodeList(true, JavadocTag.class); >+ >+ >+ /** >+ * Creates a new AST node for a Javadoc tag owned by the given Javadoc or >+ * block comment. >+ * The new node has legal but empty identifier and description. >+ * <p> >+ * N.B. This constructor is package-private; all subclasses must be >+ * declared in the same package; clients are unable to declare >+ * additional subclasses. >+ * </p> >+ * >+ * @param ast the AST that is to own this node >+ */ >+ JavadocTag(AST ast) { >+ super(ast); >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ void accept0(ASTVisitor visitor) { >+ visitor.visit(this); >+ visitor.endVisit(this); >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ public int getNodeType() { >+ return JAVADOC_TAG; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#clone(org.eclipse.jdt.core.dom.AST) >+ */ >+ ASTNode clone(AST target) { >+ JavadocTag result = new JavadocTag(target); >+ result.setSourceRange(this.getStartPosition(), this.getLength()); >+ result.setIdentifier(this.identifier); >+ result.setDescription(getDescription()); >+ result.setReference(getReference()); >+ return result; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#memSize() >+ */ >+ int memSize() { >+ int size = BASE_NODE_SIZE; >+ if (this.identifier!= null) { >+ // Strings usually have 4 instance fields, one of which is a char[] >+ size += HEADERS + 4 * 4; >+ // char[] has 2 bytes per character >+ size += HEADERS + 2 * this.identifier.length(); >+ } >+ size += 4; // reference >+ if (this.description!= null) { >+ // Strings usually have 4 instance fields, one of which is a char[] >+ size += HEADERS + 4 * 4; >+ // char[] has 2 bytes per character >+ size += HEADERS + 2 * this.description.length(); >+ } >+ size += 4; // embedded >+ return size; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(org.eclipse.jdt.core.dom.ASTMatcher, java.lang.Object) >+ */ >+ public boolean subtreeMatch(ASTMatcher matcher, Object other) { >+ return matcher.match(this, other); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jdt.core.dom.ASTNode#treeSize() >+ */ >+ int treeSize() { >+ return memSize() >+ + (this.reference == null ? 0 : this.reference.treeSize()) >+ + (this.embedded == null ? 0 : this.embedded.listSize()); >+ } >+ >+ /** >+ * @return Returns the reference. >+ */ >+ public ASTNode getReference() { >+ return this.reference; >+ } >+ >+ /** >+ * @param reference The reference to set. >+ */ >+ public void setReference(ASTNode reference) { >+ if (reference == null) { >+ throw new IllegalArgumentException(); >+ } >+ replaceChild(this.reference, reference, false); >+ this.reference = reference; >+ } >+ >+ /** >+ * @return Returns the name. >+ */ >+ public String getIdentifier() { >+ return this.identifier; >+ } >+ >+ /** >+ * @param id The name to set. >+ */ >+ public void setIdentifier(String id) { >+ if (id == null) { >+ throw new IllegalArgumentException(); >+ } >+ modifying(); >+ this.identifier = id; >+ } >+ >+ /** >+ * @return Returns the text. >+ */ >+ public String getDescription() { >+ return this.description; >+ } >+ >+ /** >+ * @param text The text to set. >+ */ >+ public void setDescription(String text) { >+ if (text == null) { >+ throw new IllegalArgumentException(); >+ } >+ modifying(); >+ this.description = text; >+ } >+ >+ /** >+ * Returns the list of embedded tags. >+ * @return ASTNode.List of JavadocTag. The list is empty list if no tag is embedded. >+ */ >+ public List embedded() { >+ return this.embedded; >+ } >+ >+ /** >+ * Returns whether the tag is embedded in another tag or not. >+ * @return boolean >+ */ >+ public boolean isEmbedded() { >+ return getParent() instanceof JavadocTag; >+ } >+} >Index: dom/org/eclipse/jdt/core/dom/LineComment.java >=================================================================== >RCS file: dom/org/eclipse/jdt/core/dom/LineComment.java >diff -N dom/org/eclipse/jdt/core/dom/LineComment.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ dom/org/eclipse/jdt/core/dom/LineComment.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,87 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2003 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 >+ *******************************************************************************/ >+package org.eclipse.jdt.core.dom; >+ >+ >+/** >+ * AST node for a line comment. >+ * >+ * @see Comment >+ * @since 3.0 >+ */ >+public class LineComment extends Comment { >+ >+ /** >+ * Creates a new AST node for a line comment owned by the given AST. >+ * The new node has an unspecified, but legal, line comment. >+ * <p> >+ * N.B. This constructor is package-private; all subclasses must be >+ * declared in the same package; clients are unable to declare >+ * additional subclasses. >+ * </p> >+ * >+ * @param ast the AST that is to own this node >+ */ >+ LineComment(AST ast) { >+ super(ast); >+ this.text = "//"; //$NON-NLS-1$ >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ public int getNodeType() { >+ return JAVADOC; >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ ASTNode clone(AST target) { >+ LineComment result = new LineComment(target); >+ result.setSourceRange(this.getStartPosition(), this.getLength()); >+ result.setText(this.text); >+ return result; >+ } >+ >+ /* (omit javadoc for this method) >+ * Method declared on ASTNode. >+ */ >+ public boolean subtreeMatch(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) { >+ visitor.visit(this); >+ visitor.endVisit(this); >+ } >+ >+ /** >+ * Returns whether the comment is a line comment or not. >+ * @return false >+ */ >+ public boolean isLine() { >+ return true; >+ } >+ >+ /** >+ * Returns whether the comment is a javadoc comment or not. >+ * @return false >+ */ >+ public boolean isJavadoc() { >+ return false; >+ } >+} >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 27134
:
7016
|
7020
| 7076