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 104887 Details for
Bug 236230
[formatter] SIOOBE while formatting a compilation unit.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Proposed patch
v04.txt (text/plain), 75.36 KB, created by
Frederic Fusier
on 2008-06-13 12:33:50 EDT
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Frederic Fusier
Created:
2008-06-13 12:33:50 EDT
Size:
75.36 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core.tests.model >Index: src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsMassiveTests.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsMassiveTests.java,v >retrieving revision 1.21 >diff -u -r1.21 FormatterCommentsMassiveTests.java >--- src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsMassiveTests.java 29 May 2008 09:31:52 -0000 1.21 >+++ src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsMassiveTests.java 13 Jun 2008 16:21:14 -0000 >@@ -15,12 +15,10 @@ > import java.io.IOException; > import java.text.SimpleDateFormat; > import java.util.ArrayList; >-import java.util.Arrays; > import java.util.Date; > import java.util.HashMap; > import java.util.List; > import java.util.Map; >-import java.util.StringTokenizer; > > import junit.framework.AssertionFailedError; > import junit.framework.ComparisonFailure; >@@ -30,16 +28,9 @@ > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.Path; > import org.eclipse.jdt.core.formatter.CodeFormatter; >-import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; > import org.eclipse.jdt.core.tests.model.ModelTestsUtil; > import org.eclipse.jdt.core.tests.util.Util; >-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; >-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; >-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >-import org.eclipse.jdt.internal.compiler.parser.Scanner; >-import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil; >-import org.eclipse.jdt.internal.core.util.SimpleDocument; > import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; > import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions; > import org.eclipse.text.edits.TextEdit; >@@ -102,77 +93,106 @@ > * <code>linesLeading</code> (e.g. ignore white spaces at the beginning of the > * lines, including the star inside javadoc or block comments): > * <ul> >- * <li>Eclipse 3.0 performance workspace (9951 units):<ul> >+ * <li>JUnit 3.8.2 workspace (71 units): >+ * <ul> > * <li>0 error</li> > * <li>0 failures</li> >- * <li>8 failures due to old formatter</li> >- * <li>723 files have different lines leading spaces</li> >- * <li>9 files have different spaces</li> >+ * <li>0 failures due to old formatter</li> >+ * <li>8 files have different lines leading spaces</li> >+ * <li>0 files have different spaces</li> > * </ul></li> >- * <li>Eclipse 3.4 workspace (16592 units):<ul> >+ * <li>Eclipse 3.0 performance workspace (9951 units): >+ * <ul> > * <li>0 error</li> >- * <li>11 failures</li> >- * <li>17 failures due to old formatter</li> >- * <li>1244 files have different lines leading spaces</li> >- * <li>11 files have different spaces</li> >+ * <li>1 failures</li> >+ * <li>8 failures due to old formatter</li> >+ * <li>722 files have different lines leading spaces</li> >+ * <li>9 files have different spaces</li> > * </ul></li> >- * <li>ganymede M5 workspace (25819 units):<ul> >+ * <li>Eclipse 3.4 workspace (17890 units): >+ * <ul> > * <li>0 error</li> >- * <li>12 failures due to different output while reformatting!</li> >- * <li>15 failures due to old formatter</li> >- * <li>1371 files have different line leading spaces when reformatting!</li> >- * <li>14 files have different spaces when reformatting!</li> >+ * <li>17 failures</li> >+ * <li>21 failures due to old formatter</li> >+ * <li>1372 files have different lines leading spaces</li> >+ * <li>12 files have different spaces</li> > * </ul></li> >- * <li>ganymede M6a workspace (26336 units):<ul> >- * <li>0 error</li> >- * <li>16 failures due to different output while reformatting!</li> >- * <li>17 failures due to old formatter</li> >- * <li>1469 files have different line leading spaces when reformatting!</li> >- * <li>14 files have different spaces when reformatting!</li> >+ * <li>ganymede workspace (33190 units): >+ * <ul> >+ * <li>1 error</li> >+ * <li>21 failures due to different output while reformatting!</li> >+ * <li>21 failures due to old formatter</li> >+ * <li>1780 files have different line leading spaces when reformatting!</li> >+ * <li>20 files have different spaces when reformatting!</li> > * </ul></li> > * </ul> > */ > public class FormatterCommentsMassiveTests extends FormatterRegressionTests { > >- private static final String LINE_SEPARATOR = org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; > final File file; > final IPath path; >- List failures = new ArrayList(); >- List expectedFailures = new ArrayList(); >- List leadingWhitespacesFailures = new ArrayList(); >- List whitespacesFailures= new ArrayList(); > boolean hasSpaceFailure; >- private int changedHeaderFooter; >- private int changedPreTags; >- private int changedCodeTags; >- private final static boolean DEBUG_TESTS = "true".equals(System.getProperty("debugTests")); >- private final static String DIR = System.getProperty("dir"); //$NON-NLS-1$ >- private final static String COMPARE = System.getProperty("compare"); //$NON-NLS-1$ >- private final static int IGNORE_SPACES; >- private final static int ALL_SPACES = 1; // ignore all spaces >- private final static int LINES_LEADING_SPACES = 2; // ignore all spaces at the beginning of all lines >- private final static int ALL_COMMENTS_SPACES = 3; // ignore all spaces inside all comments >- private final static int ALL_COMMENTS_LINES_LEADING_SPACES = 4; // ignore all spaces at the beginning of all comments lines >+ private DefaultCodeFormatterOptions preferences; >+ private final static File INPUT_DIR = new File(System.getProperty("inputDir")); >+ private final static File OUTPUT_DIR; >+ private final static boolean COMPARE; > static { >- String ignoreSpaces = System.getProperty("ignoreSpaces"); //$NON-NLS-1$ >- int filterValue; >- if ("all".equals(ignoreSpaces)) { >- filterValue = ALL_SPACES; >- } else if ("linesLeading".equals(ignoreSpaces)) { >- filterValue = LINES_LEADING_SPACES; >- } else if ("comments".equals(ignoreSpaces)) { >- filterValue = ALL_COMMENTS_SPACES; >- } else if ("commentsLinesLeading".equals(ignoreSpaces)) { >- filterValue = ALL_COMMENTS_LINES_LEADING_SPACES; >- } else { >- filterValue = 0; // no filter >+ String dir = System.getProperty("outputDir"); //$NON-NLS-1$ >+ File outputDir = null; >+ boolean compare = true; >+ if (dir != null) { >+ outputDir = new File(dir); >+ if (!outputDir.exists()) { >+ compare = false; >+ System.err.println("WARNING: The output directory "+dir+" does not exist..."); >+ System.err.println("=> NO comparison will be done! The formatted files will be written there instead."); >+ try { >+ Thread.sleep(1000); >+ } catch (InterruptedException e) { >+ // skip >+ } >+ } > } >- IGNORE_SPACES = filterValue; >+ OUTPUT_DIR = outputDir; >+ COMPARE = compare; > } > private final static int FORMAT_REPEAT = Integer.parseInt(System.getProperty("repeat", "2")); //$NON-NLS-1$ >+ >+ // Failures management >+ final static int NO_OUTPUT_FAILURE = 0; >+ final static int COMPARISON_FAILURE = 1; >+ final static int REFORMATTING_FAILURE = 2; >+ final static int REFORMATTING_LEADING_FAILURE = 4; >+ final static int REFORMATTING_WHITESPACES_FAILURE = 5; >+ final static int REFORMATTING_EXPECTED_FAILURE = 3; >+ class FormattingFailure { >+ String action; >+ List failures = new ArrayList(); >+ public FormattingFailure() { >+ } >+ public FormattingFailure(String action) { >+ this.action = action; >+ } >+ public String toString() { >+ if (action == null) { >+ return "no output while formatting"; >+ } >+ return "different output while "+action; >+ } >+ >+ } >+ final static FormattingFailure[] FAILURES = new FormattingFailure[6]; >+ { >+ FAILURES[NO_OUTPUT_FAILURE] = new FormattingFailure(); >+ FAILURES[COMPARISON_FAILURE] = new FormattingFailure("comparing with previous version"); >+ FAILURES[REFORMATTING_FAILURE] = new FormattingFailure("reformatting twice"); >+ FAILURES[REFORMATTING_LEADING_FAILURE] = new FormattingFailure("reformatting twice but only by leading whitespaces"); >+ FAILURES[REFORMATTING_WHITESPACES_FAILURE] = new FormattingFailure("reformatting twice but only by whitespaces"); >+ FAILURES[REFORMATTING_EXPECTED_FAILURE] = new FormattingFailure("reformatting twice but was expected"); >+ } > private static final int MAX_FAILURES = Integer.parseInt(System.getProperty("maxFailures", "100")); // Max failures using string comparison > private static boolean ASSERT_EQUALS_STRINGS = MAX_FAILURES > 0; >- private final static IPath[] EXPECTED_FAILURES = DIR.indexOf("v34") < 0 >+ private final static IPath[] EXPECTED_FAILURES = INPUT_DIR.getPath().indexOf("v34") < 0 > ? new IPath[] { > new Path("org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java"), > new Path("org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java"), >@@ -184,6 +204,7 @@ > new Path("org/eclipse/team/internal/ccvs/ui/wizards/UpdateWizard.java"), > } > : new IPath[] { >+ // Eclipse > new Path("org/eclipse/equinox/internal/p2/director/NewDependencyExpander.java"), > new Path("org/eclipse/jdt/core/JavaCore.java"), > new Path("org/eclipse/jdt/internal/codeassist/CompletionEngine.java"), >@@ -203,21 +224,16 @@ > new Path("org/eclipse/jdt/internal/core/search/JavaSearchScope.java"), > new Path("org/eclipse/jdt/internal/eval/EvaluationContext.java"), > new Path("org/eclipse/jdt/internal/ui/text/javadoc/JavadocContentAccess2.java"), >+ new Path("org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeJavaSourceOutputStream.java"), > new Path("org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceSubscriberContext.java"), >+ // Ganymede >+ new Path("com/ibm/icu/text/Collator.java"), >+ new Path("org/apache/lucene/analysis/ISOLatin1AccentFilter.java"), > }; >- static { >- // Sort expected failures to allow binary search >- Arrays.sort(EXPECTED_FAILURES); >- } > > public static Test suite() { > TestSuite suite = new Suite(FormatterCommentsMassiveTests.class.getName()); > try { >- File testDir = ModelTestsUtil.getWorkspaceRoot().getLocation().toFile(); >- if (DIR != null) { >- File dir = new File(DIR); >- if (dir.exists()) testDir = dir; >- } > FileFilter filter = new FileFilter() { > public boolean accept(File pathname) { > return pathname.isDirectory() || pathname.getPath().endsWith(".java"); >@@ -227,14 +243,13 @@ > SimpleDateFormat format = new SimpleDateFormat(); > Date now = new Date(start); > System.out.println("Date of test: "+format.format(now)); >- System.out.print("Get all Java files located in "+testDir+"..."); >- File[] allFiles = ModelTestsUtil.getAllFiles(testDir, filter); >+ System.out.print("Get all Java files located in "+INPUT_DIR+"..."); >+ File[] allFiles = ModelTestsUtil.getAllFiles(INPUT_DIR, filter); > int length = allFiles.length; > System.out.println(length+" found in " + (System.currentTimeMillis() - start) + "ms"); > for (int i=0; i<length; i++) { > suite.addTest(new FormatterCommentsMassiveTests(allFiles[i])); > } >-// ASSERT_EQUALS_STRINGS = length < 15000; > } catch (Exception e) { > // skip > } >@@ -244,7 +259,7 @@ > public FormatterCommentsMassiveTests(File file) { > super("testCompare"); > this.file = file; >- this.path = new Path(file.getPath().substring(DIR.length()+1)); >+ this.path = new Path(file.getPath().substring(INPUT_DIR.getPath().length()+1)); > } > > /* (non-Javadoc) >@@ -260,6 +275,7 @@ > public void setUp() throws Exception { > super.setUp(); > this.hasSpaceFailure = false; >+ this.preferences = DefaultCodeFormatterOptions.getEclipseDefaultSettings(); > } > > /* (non-Javadoc) >@@ -280,56 +296,38 @@ > * @see org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests#tearDownSuite() > */ > public void tearDownSuite() throws Exception { >- // skip standard model suite tear down >- int sFailures = this.failures.size(); >- int seFailures = this.expectedFailures.size(); >- int swFailures = this.whitespacesFailures.size(); >- int slwFailures = this.leadingWhitespacesFailures.size(); >- String failuresType = COMPARE != null ? "than old formatter" : "when reformatting"; >- System.out.println(); >- if (sFailures > 0) { >- System.out.println(sFailures+" files has still different output while reformatting!"); >- } >- if (seFailures > 0) { >- System.out.println(seFailures+" files has still different output while reformatting due to old formatter bugs!"); >- } >- if (slwFailures == 0) { >- System.out.println("No file has different line leading spaces "+failuresType+" :-)"); >- } else { >- System.out.println(slwFailures+" files have different line leading spaces "+failuresType+"!"); >- } >- if (swFailures > 0) { >- System.out.println(swFailures+" files have different spaces "+failuresType+"!"); >- } >- if (this.changedHeaderFooter >0) { >- System.out.println(this.changedHeaderFooter+" differences in header/footer have been found"); >- } >- if (this.changedPreTags >0) { >- System.out.println(this.changedPreTags+" differences in <pre> tags (blank lines) have been found"); >- } >- System.out.println(); >- if (sFailures > 0) { >- System.out.println("List of files with different output "+failuresType+":"); >- for (int i=0; i<sFailures; i++) { >- System.out.println(" - "+this.failures.get(i)); >+ if (OUTPUT_DIR != null) { >+ if (COMPARE) { >+ System.out.println("Comparison done with output files located in "+OUTPUT_DIR); > } > } >- if (seFailures > 0) { >- System.out.println("List of files with different output "+failuresType+" (due to old formatter bugs):"); >- for (int i=0; i<seFailures; i++) { >- System.out.println(" - "+this.expectedFailures.get(i)); >- } >- } >- if (slwFailures > 0) { >- System.out.println("List of files with different line leading spaces "+failuresType+":"); >- for (int i=0; i<slwFailures; i++) { >- System.out.println(" - "+this.leadingWhitespacesFailures.get(i)); >+ // skip standard model suite tear down >+ System.out.println(); >+ int max = FAILURES.length; >+ for (int i=0; i<max; i++) { >+ List failures = FAILURES[i].failures; >+ int size = failures.size(); >+ if (size > 0) { >+ System.out.print(size); >+ System.out.print(" file"); >+ if (size == 1) { >+ System.out.print(" has "); >+ } else { >+ System.out.print("s have "); >+ } >+ System.out.print(FAILURES[i]); >+ System.out.println('!'); > } > } >- if (swFailures > 0) { >- System.out.println("List of files with different spaces "+failuresType+":"); >- for (int i=0; i<swFailures; i++) { >- System.out.println(" - "+this.whitespacesFailures.get(i)); >+ System.out.println(); >+ for (int i=0; i<max; i++) { >+ List failures = FAILURES[i].failures; >+ int size = failures.size(); >+ if (size > 0) { >+ System.out.println("List of file(s) with "+FAILURES[i]+":"); >+ for (int j=0; j<size; j++) { >+ System.out.println(" - "+failures.get(j)); >+ } > } > } > } >@@ -340,203 +338,52 @@ > * The line separators in 'actual' are converted to '\n' before the comparison. > */ > protected void assertSourceEquals(String message, String expected, String actual) { >+ if (expected == null) { >+ assertNull(message, actual); >+ return; >+ } > if (actual == null) { > assertEquals(message, expected, null); > return; > } >+ expected = Util.convertToIndependantLineDelimiter(expected); > actual = Util.convertToIndependantLineDelimiter(actual); >- try { >- if (ASSERT_EQUALS_STRINGS) { >- assertEquals(message, expected, actual); >- } else { >- assertTrue(message, actual.equals(expected)); >- } >- } >- catch (ComparisonFailure cf) { >- if ("true".equals(COMPARE)) { >- String trimmedExpected = expected; >- String trimmedActual = actual; >- switch (IGNORE_SPACES) { >- case ALL_SPACES: >- trimmedExpected = ModelTestsUtil.removeWhiteSpace(expected); >- trimmedActual= ModelTestsUtil.removeWhiteSpace(actual); >- if (trimmedExpected.equals(trimmedActual)) { >- this.whitespacesFailures.add(this.path); >- return; >- } >- break; >- case LINES_LEADING_SPACES: >- trimmedExpected = ModelTestsUtil.trimLinesLeadingWhitespaces(expected); >- trimmedActual= ModelTestsUtil.trimLinesLeadingWhitespaces(actual); >- if (trimmedExpected.equals(trimmedActual)) { >- this.leadingWhitespacesFailures.add(this.path); >- return; >- } >- trimmedExpected = ModelTestsUtil.removeWhiteSpace(expected); >- trimmedActual= ModelTestsUtil.removeWhiteSpace(actual); >- if (trimmedExpected.equals(trimmedActual)) { >- this.whitespacesFailures.add(this.path); >- return; >- } >- break; >- } >- if (DEBUG_TESTS && ASSERT_EQUALS_STRINGS) { >- assertEquals(message, trimmedExpected, trimmedActual); >- } >- } >- this.failures.add(this.path); >- ASSERT_EQUALS_STRINGS = this.failures.size() < MAX_FAILURES; >- throw cf; >- } >- catch (AssertionFailedError afe) { >- this.failures.add(this.path); >- throw afe; >- } >-} >- >-private String cleanAllKnownDifferences(String comment) { >- int kind = comment.charAt(1) == '/' ? 1 : comment.charAt(2) == '*' ? 3 : 2; >- String cleanedComment = comment; >- switch (kind) { >- case 1: // line comment >- cleanedComment = cleanBlankLinesAfterLineComment(comment); >- break; >- case 3: // javadoc comment >- cleanedComment = cleanHeaderAndFooter(comment); >- String newComment = cleanPreTags(cleanedComment); >- if (cleanedComment == newComment) { >- cleanedComment = cleanCodeTags(cleanedComment); >- } else { >- cleanedComment = newComment; >- } >- break; >- } >- return cleanedComment; >-} >-private String cleanHeaderAndFooter(String comment) { >- int start = 1; // skip starting '/' >- int length = comment.length(); >- int end = length - 1; // skip ending '/' >- while (comment.charAt(start) == '*') { >- // remove all contiguous '*' in header >- start++; >- } >- while (comment.charAt(--end) == '*') { >- // remove all contiguous '*' in header >- } >- if (start > 3 || end < (length - 2)) { >- this.changedHeaderFooter++; >- return comment.substring(start, end); >- } >- return comment; >-} >- >-private String cleanBlankLinesAfterLineComment(String comment) { >- int length = comment.length(); >- if (comment.charAt(length-1) == '\n') { >- length--; >- if (comment.charAt(length-1) == '\r') { >- length--; >- } >- return comment.substring(0, length); >- } >- return comment; >-} >- >-private String cleanCodeTags(String comment) { >- if (comment.indexOf("<code>") < 0) return comment; >- StringTokenizer tokenizer = new StringTokenizer(comment, "\r\n\f"); >- StringBuffer buffer = new StringBuffer(); >- while (tokenizer.hasMoreTokens()) { >- String line = tokenizer.nextToken(); >- if (line.indexOf("<pre>") >= 0) { >- while (line.indexOf("</pre>") < 0) { >- line = tokenizer.nextToken(); >- } >- } else { >- buffer.append(line); >- buffer.append("\n"); >- } >- } >- this.changedCodeTags++; >- return buffer.toString(); >-} >- >-private String cleanPreTags(String comment) { >- if (comment.indexOf("<pre>") < 0) return comment; >- StringTokenizer tokenizer = new StringTokenizer(comment, "\r\n\f"); >- StringBuffer buffer = new StringBuffer(); >- StringBuffer emptyLines = new StringBuffer(); >- String previousLine = null; >- while (tokenizer.hasMoreTokens()) { >- String line = tokenizer.nextToken(); >- if (line.trim() == "*") { >- if (previousLine == null || previousLine.indexOf("<pre>") < 0) { >- buffer.append(line); >- buffer.append("\n"); >- continue; >- } else { >- emptyLines.append(line); >- emptyLines.append("\n"); >- } >- } else if (line.indexOf("<code>") >= 0) { >- while (line.indexOf("</code>") < 0) { >- line = tokenizer.nextToken(); >- } >- } else if (emptyLines.length() != 0) { >- if (line.indexOf("</pre>") < 0) { >- buffer.append(emptyLines); >- emptyLines.setLength(0); >- } >- buffer.append(line); >- buffer.append("\n"); >- } else { >- buffer.append(line); >- buffer.append("\n"); >- } >- previousLine = line; >+ if (ASSERT_EQUALS_STRINGS) { >+ assertEquals(message, expected, actual); >+ } else { >+ assertTrue(message, actual.equals(expected)); > } >- this.changedPreTags++; >- return buffer.toString(); > } > > DefaultCodeFormatter codeFormatter() { >- DefaultCodeFormatterOptions preferences = DefaultCodeFormatterOptions.getEclipseDefaultSettings(); >- DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences); >+ DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(this.preferences, getDefaultCompilerOptions()); > return codeFormatter; > } > > void compareFormattedSource() throws IOException, Exception { >- DefaultCodeFormatter codeFormatter = codeFormatter(); > String source = new String(org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.file, null)); > try { >- if ("comments".equals(COMPARE)) { >- String[] oldFormattedComments = formattedComments(source, true); >- String[] newFormattedComments = formattedComments(source, false); >- int length = oldFormattedComments == null ? 0 : oldFormattedComments.length; >- this.abortOnFailure = false; >- assertEquals("Unexpected number of comments!", length, newFormattedComments == null ? 0 : newFormattedComments.length); >- for (int i=0; i<length; i++) { >- String oldComment = oldFormattedComments[i]; >- String newComment = newFormattedComments[i]; >- if (oldComment == null) { >- assertNull("Unexpected non-null new comment", newComment); >- } else { >- String expected = cleanAllKnownDifferences(oldComment); >- String actual = cleanAllKnownDifferences(newComment); >- if (!expected.equals(actual)) { >- String actualResult = runFormatter(codeFormatter, source, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, 0, source.length(), null); >- String expectedResult = expectedFormattedSource(source); >- assertEquals("Unexpected difference with formatted comment "+(i+1), Util.convertToIndependantLineDelimiter(expectedResult), Util.convertToIndependantLineDelimiter(actualResult)); >- } >- } >+ // Format the source >+ String actualResult = runFormatter(codeFormatter(), source, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, 0, source.length(), null); >+ >+ // Look for output to compare with >+ File outputFile = new Path(OUTPUT_DIR.getPath()).append(this.path).toFile(); >+ if (COMPARE) { >+ String expectedResult = new String(org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(outputFile, null)); >+ try { >+ assertSourceEquals("Unexpected format output!", expectedResult, actualResult); >+ } >+ catch (ComparisonFailure cf) { >+ FAILURES[COMPARISON_FAILURE].failures.add(this.path); >+ throw cf; >+ } >+ catch (AssertionFailedError afe) { >+ FAILURES[COMPARISON_FAILURE].failures.add(this.path); >+ throw afe; > } > } else { >- String actualResult = runFormatter(codeFormatter, source, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, 0, source.length(), null); >- if (!this.hasSpaceFailure && "true".equals(COMPARE)) { >- String expectedResult = expectedFormattedSource(source); >- assertLineEquals(actualResult, source, expectedResult, false); >- } >+ outputFile.getParentFile().mkdirs(); >+ Util.writeToFile(actualResult, outputFile.getAbsolutePath()); > } > } > catch (Exception e) { >@@ -566,142 +413,6 @@ > return buffer.toString(); > } > >-private String expectedFormattedSource(String source) { >- boolean enableNewCommentFormatter = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT; >- try { >- DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT = false; >- DefaultCodeFormatter codeFormatter = codeFormatter(); >- Scanner scanner = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_4/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); >- CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil(); >- CompilationUnitDeclaration compilationUnitDeclaration = codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true); >- final TypeDeclaration[] types = compilationUnitDeclaration.types; >- int headerEndPosition = types == null ? compilationUnitDeclaration.sourceEnd : types[0].declarationSourceStart; >- scanner.setSource(source.toCharArray()); >- scanner.lineEnds = codeSnippetParsingUtil.recordedParsingInformation.lineEnds; >- int[][] commentsPositions = compilationUnitDeclaration.comments; >- int length = commentsPositions == null ? 0 : commentsPositions.length; >- String[] formattedComments = new String[length]; >- for (int i=0; i<length; i++) { >- int[] positions = commentsPositions[i]; >- int commentKind = CodeFormatter.K_JAVA_DOC; >- int commentStart = positions [0]; >- int commentEnd = positions [1]; >- if (commentEnd < 0) { // line or block comments have negative end position >- commentEnd = -commentEnd; >- if (commentStart > 0) { // block comments have positive start position >- commentKind = CodeFormatter.K_MULTI_LINE_COMMENT; >- } else { >- commentStart = -commentStart; >- commentKind = CodeFormatter.K_SINGLE_LINE_COMMENT; >- } >- } >- if (commentStart >= headerEndPosition) { >- int indentationLevel = getIndentationLevel(scanner, commentStart); >- formattedComments[i] = runFormatter(codeFormatter, source.substring(commentStart, commentEnd), commentKind, indentationLevel, 0, commentEnd - commentStart, LINE_SEPARATOR); >- } >- } >- SimpleDocument document = new SimpleDocument(source); >- for (int i=length-1; i>=0; i--) { >- if (formattedComments[i] != null) { >- int[] positions = commentsPositions[i]; >- int commentStart = positions [0]; >- int commentEnd = positions [1]; >- if (commentEnd < 0) { // line or block comments have negative end position >- commentEnd = -commentEnd; >- if (commentStart < 0) { // line comments have negative start position >- commentStart = -commentStart; >- } >- } >- document.replace(commentStart, commentEnd - commentStart, formattedComments[i]); >- } >- } >- String newSource = document.get(); >- String oldResult = runFormatter(codeFormatter, newSource, CodeFormatter.K_COMPILATION_UNIT, 0, 0, newSource.length(), null); >- return oldResult == null ? newSource : oldResult; >- } >- finally { >- DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT = enableNewCommentFormatter; >- } >-} >-private String[] formattedComments(String source, boolean old) { >- boolean enableNewCommentFormatter = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT; >- try { >- DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT = !old; >- DefaultCodeFormatter codeFormatter = codeFormatter(); >- Scanner scanner = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_4/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); >- CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil(); >- CompilationUnitDeclaration compilationUnitDeclaration = codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true); >- final TypeDeclaration[] types = compilationUnitDeclaration.types; >- int headerEndPosition = types == null ? compilationUnitDeclaration.sourceEnd : types[0].declarationSourceStart; >- scanner.setSource(source.toCharArray()); >- scanner.lineEnds = codeSnippetParsingUtil.recordedParsingInformation.lineEnds; >- int[][] commentsPositions = compilationUnitDeclaration.comments; >- int length = commentsPositions == null ? 0 : commentsPositions.length; >- String[] formattedComments = new String[length]; >- for (int i=0; i<length; i++) { >- int[] positions = commentsPositions[i]; >- int commentKind = CodeFormatter.K_JAVA_DOC; >- int commentStart = positions [0]; >- int commentEnd = positions [1]; >- if (commentEnd < 0) { // line or block comments have negative end position >- commentEnd = -commentEnd; >- if (commentStart > 0) { // block comments have positive start position >- commentKind = CodeFormatter.K_MULTI_LINE_COMMENT; >- } else { >- commentStart = -commentStart; >- commentKind = CodeFormatter.K_SINGLE_LINE_COMMENT; >- } >- } >- if (commentStart >= headerEndPosition) { >- int indentationLevel = getIndentationLevel(scanner, commentStart); >- formattedComments[i] = runFormatter(codeFormatter, source.substring(commentStart, commentEnd), commentKind, indentationLevel, 0, commentEnd - commentStart, LINE_SEPARATOR); >- } >- } >- return formattedComments; >- } >- finally { >- DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT = enableNewCommentFormatter; >- } >-} >- >-private int getIndentationLevel(Scanner scanner, int position) { >- int indentationLevel = 0; >- int numberOfIndentations = 0; >- int indentationSize; >- try { >- indentationSize = Integer.parseInt(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE); >- } catch (NumberFormatException nfe) { >- indentationSize = 4; >- } >- int lineNumber = scanner.getLineNumber(position); >- int lineStart = scanner.getLineStart(lineNumber); >- scanner.resetTo(lineStart, position-1); >- while (!scanner.atEnd()) { >- int ch = scanner.getNextChar(); >- switch (ch) { >- case '\n': >- indentationLevel = 0; >- numberOfIndentations = 0; >- break; >- case '\t': >- numberOfIndentations++; >- indentationLevel = numberOfIndentations * indentationSize; >- break; >- default: >- indentationLevel++; >- if ((indentationLevel%indentationSize) == 0) { >- numberOfIndentations++; >- } >- break; >- } >- } >- if ((indentationLevel%indentationSize) != 0) { >- numberOfIndentations++; >- indentationLevel = numberOfIndentations * indentationSize; >- } >- return numberOfIndentations; >-} >- > private Map getDefaultCompilerOptions() { > Map optionsMap = new HashMap(30); > optionsMap.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); >@@ -751,8 +462,8 @@ > optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, CompilerOptions.IGNORE); > optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, CompilerOptions.DISABLED); > optionsMap.put(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, CompilerOptions.IGNORE); >- optionsMap.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4); >- optionsMap.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); >+ optionsMap.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); >+ optionsMap.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); > optionsMap.put(CompilerOptions.OPTION_TaskTags, ""); //$NON-NLS-1$ > optionsMap.put(CompilerOptions.OPTION_TaskPriorities, ""); //$NON-NLS-1$ > optionsMap.put(CompilerOptions.OPTION_TaskCaseSensitive, CompilerOptions.DISABLED); >@@ -761,7 +472,7 @@ > optionsMap.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED); > optionsMap.put(CompilerOptions.OPTION_MaxProblemPerUnit, String.valueOf(100)); > optionsMap.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.DISABLED); >- optionsMap.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); >+ optionsMap.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); > return optionsMap; > } > >@@ -769,62 +480,107 @@ > int length = EXPECTED_FAILURES.length; > for (int i=0; i<length; i++) { > IPath expectedFailure= EXPECTED_FAILURES[i]; >- if (this.path.matchingFirstSegments(expectedFailure) == expectedFailure.segmentCount()) { >- this.expectedFailures.add(this.path); >+ if (this.path.toString().indexOf(expectedFailure.toString()) >= 0) { >+ FAILURES[REFORMATTING_EXPECTED_FAILURE].failures.add(this.path); > return true; > } > } > return false; > } > >+/* >+private boolean runFormatterWithoutComments(CodeFormatter codeFormatter, String source, int kind, int indentationLevel, int offset, int length, String lineSeparator) { >+ DefaultCodeFormatterOptions preferencesWithoutComment = DefaultCodeFormatterOptions.getEclipseDefaultSettings(); >+ preferencesWithoutComment.comment_format_line_comment = false; >+ preferencesWithoutComment.comment_format_block_comment = false; >+ preferencesWithoutComment.comment_format_javadoc_comment = false; >+ DefaultCodeFormatter codeFormatterWithoutComment = new DefaultCodeFormatter(preferencesWithoutComment); >+ >+ TextEdit edit = codeFormatterWithoutComment.format(kind, source, offset, length, indentationLevel, lineSeparator);//$NON-NLS-1$ >+ if (edit == null) return false; >+ String initialResult = org.eclipse.jdt.internal.core.util.Util.editedString(source, edit); >+ >+ int count = 1; >+ String result = initialResult; >+ String previousResult = result; >+ while (count++ < FORMAT_REPEAT) { >+ edit = codeFormatterWithoutComment.format(kind, result, 0, result.length(), indentationLevel, lineSeparator);//$NON-NLS-1$ >+ if (edit == null) return false; >+ previousResult = result; >+ result = org.eclipse.jdt.internal.core.util.Util.editedString(result, edit); >+ } >+ return previousResult.equals(result); >+} >+*/ >+ > String runFormatter(CodeFormatter codeFormatter, String source, int kind, int indentationLevel, int offset, int length, String lineSeparator) { > TextEdit edit = codeFormatter.format(kind, source, offset, length, indentationLevel, lineSeparator);//$NON-NLS-1$ >- if (edit == null) return null; >- String result = org.eclipse.jdt.internal.core.util.Util.editedString(source, edit); >+ try { >+ assertNotNull("Formatted source should not be null!", edit); >+ } >+ catch (ComparisonFailure cf) { >+ FAILURES[NO_OUTPUT_FAILURE].failures.add(this.path); >+ throw cf; >+ } >+ catch (AssertionFailedError afe) { >+ FAILURES[NO_OUTPUT_FAILURE].failures.add(this.path); >+ throw afe; >+ } >+ String initialResult = org.eclipse.jdt.internal.core.util.Util.editedString(source, edit); > > int count = 1; >- if (COMPARE == null && length == source.length()) { >- String previousResult = result; >- while (count++ < FORMAT_REPEAT) { >- edit = codeFormatter.format(kind, result, 0, result.length(), indentationLevel, lineSeparator);//$NON-NLS-1$ >- if (edit == null) return null; >- previousResult = result; >- result = org.eclipse.jdt.internal.core.util.Util.editedString(result, edit); >- } >- if (!previousResult.equals(result)) { >- switch (IGNORE_SPACES) { >- case ALL_SPACES: >- String trimmedExpected = ModelTestsUtil.removeWhiteSpace(previousResult); >- String trimmedActual= ModelTestsUtil.removeWhiteSpace(result); >- if (trimmedExpected.equals(trimmedActual)) { >- this.whitespacesFailures.add(this.path); >- this.hasSpaceFailure = true; >- return previousResult; >- } >- break; >- case LINES_LEADING_SPACES: >- trimmedExpected = ModelTestsUtil.trimLinesLeadingWhitespaces(previousResult); >- trimmedActual= ModelTestsUtil.trimLinesLeadingWhitespaces(result); >- if (trimmedExpected.equals(trimmedActual)) { >- this.leadingWhitespacesFailures.add(this.path); >- this.hasSpaceFailure = true; >- return previousResult; >- } >- if (ModelTestsUtil.removeWhiteSpace(previousResult).equals(ModelTestsUtil.removeWhiteSpace(result))) { >- this.whitespacesFailures.add(this.path); >- this.hasSpaceFailure = true; >- return previousResult; >- } >- break; >- } >- if (!isExpectedFailure()) { >- String counterString = counterToString(count-1); >- assertSourceEquals(counterString+" formatting is different from first one!", Util.convertToIndependantLineDelimiter(previousResult), Util.convertToIndependantLineDelimiter(result)); >+ String result = initialResult; >+ String previousResult = result; >+ while (count++ < FORMAT_REPEAT) { >+ edit = codeFormatter.format(kind, result, 0, result.length(), indentationLevel, lineSeparator);//$NON-NLS-1$ >+ if (edit == null) return null; >+ previousResult = result; >+ result = org.eclipse.jdt.internal.core.util.Util.editedString(result, edit); >+ } >+ if (!previousResult.equals(result)) { >+ >+ // Try to compare without leading spaces >+ String trimmedExpected = ModelTestsUtil.trimLinesLeadingWhitespaces(previousResult); >+ String trimmedActual= ModelTestsUtil.trimLinesLeadingWhitespaces(result); >+ if (trimmedExpected.equals(trimmedActual)) { >+ FAILURES[REFORMATTING_LEADING_FAILURE].failures.add(this.path); >+ this.hasSpaceFailure = true; >+ return initialResult; >+ } >+ >+ // Try to compare without spaces at all >+ if (ModelTestsUtil.removeWhiteSpace(previousResult).equals(ModelTestsUtil.removeWhiteSpace(result))) { >+ FAILURES[REFORMATTING_WHITESPACES_FAILURE].failures.add(this.path); >+ this.hasSpaceFailure = true; >+ return initialResult; >+ } >+ >+ /* >+ // Try to see if the formatting also fails without comments >+ if (!runFormatterWithoutComments(null, source, kind, indentationLevel, offset, length, lineSeparator)) { >+ return initialResult; >+ } >+ >+ // format without comments is OK => there's a problem with comment formatting >+ String counterString = counterToString(count-1); >+ assertSourceEquals(counterString+" formatting is different from first one!", previousResult, result); >+ */ >+ if (!isExpectedFailure()) { >+ String counterString = counterToString(count-1); >+ try { >+ assertSourceEquals(counterString+" formatting is different from first one!", previousResult, result); >+ } >+ catch (ComparisonFailure cf) { >+ FAILURES[REFORMATTING_FAILURE].failures.add(this.path); >+ throw cf; >+ } >+ catch (AssertionFailedError afe) { >+ FAILURES[REFORMATTING_FAILURE].failures.add(this.path); >+ throw afe; > } >- result = previousResult; > } > } >- return result; >+ return initialResult; > } > > public void testCompare() throws IOException, Exception { >Index: src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java,v >retrieving revision 1.11 >diff -u -r1.11 FormatterCommentsBugsTest.java >--- src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java 29 May 2008 09:28:37 -0000 1.11 >+++ src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java 13 Jun 2008 16:21:14 -0000 >@@ -977,4 +977,206 @@ > 1 /* indentation level */ > ); > } >+ >+/** >+ * @bug 236230: [formatter] SIOOBE while formatting a compilation unit. >+ * @test Ensure that no exception occurs while formatting >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=236230" >+ */ >+public void testBug236230() throws JavaModelException { >+ String source = >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>If there is an authority, it is:\n" + >+ " * <pre>\n" + >+ " * //authority/device/pathSegment1/pathSegment2...</pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n"; >+ formatSource(source, >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>\n" + >+ " * If there is an authority, it is:\n" + >+ " * \n" + >+ " * <pre>\n" + >+ " * // authority/device/pathSegment1/pathSegment2...\n" + >+ " * </pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ ); >+} >+public void testBug236230b() throws JavaModelException { >+ String source = >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>If there is an authority, it is:\n" + >+ " * <pre>//authority/device/pathSegment1/pathSegment2...</pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n"; >+ formatSource(source, >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>\n" + >+ " * If there is an authority, it is:\n" + >+ " * \n" + >+ " * <pre>\n" + >+ " * // authority/device/pathSegment1/pathSegment2...\n" + >+ " * </pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ ); >+} >+public void testBug236230c() throws JavaModelException { >+ this.preferences.comment_format_header = true; >+ String source = >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>If there is an authority, it is:\n" + >+ " * <pre>\n" + >+ " import java.util.List;\n" + >+ " // CU snippet\n" + >+ " public class X implements List {}\n" + >+ " </pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n"; >+ formatSource(source, >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>\n" + >+ " * If there is an authority, it is:\n" + >+ " * \n" + >+ " * <pre>\n" + >+ " * import java.util.List;\n" + >+ " * \n" + >+ " * // CU snippet\n" + >+ " * public class X implements List {\n" + >+ " * }\n" + >+ " * </pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ ); >+} >+public void testBug236230d() throws JavaModelException { >+ String source = >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>If there is an authority, it is:\n" + >+ " * <pre>\n" + >+ " //class body snippet\n" + >+ " public class X {}\n" + >+ " </pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n"; >+ // TODO (frederic) line comment should be formatted when F_INCLUDE_COMMENTS >+ // flag will work for all snippet kinds >+ formatSource(source, >+ "/**\n" + >+ " * Need a javadoc comment before to get the exception.\n" + >+ " */\n" + >+ "public class Test {\n" + >+ "\n" + >+ " /**\n" + >+ " * <p>\n" + >+ " * If there is an authority, it is:\n" + >+ " * \n" + >+ " * <pre>\n" + >+ " * //class body snippet\n" + >+ " * public class X {\n" + >+ " * }\n" + >+ " * </pre>\n" + >+ " */\n" + >+ " public String devicePath() {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ ); >+} >+// Following tests showed possible regressions while implementing the fix... >+public void testBug236230e() throws JavaModelException { >+ String source = >+ "public class X02 {\n" + >+ "\n" + >+ "\n" + >+ " /**\n" + >+ " /**\n" + >+ " * Removes the Java nature from the project.\n" + >+ " */\n" + >+ " void foo() {\n" + >+ " }\n" + >+ "}\n"; >+ formatSource(source, >+ "public class X02 {\n" + >+ "\n" + >+ " /**\n" + >+ " * /** Removes the Java nature from the project.\n" + >+ " */\n" + >+ " void foo() {\n" + >+ " }\n" + >+ "}\n" >+ ); >+} >+public void testBug236230f() throws JavaModelException { >+ String source = >+ "public class X03 {\n" + >+ " /** The value of <tt>System.getProperty(\"java.version\")<tt>. **/\n" + >+ " static final String JAVA_VERSION = System.getProperty(\"java.version\");\n" + >+ "\n" + >+ "}\n"; >+ formatSource(source, >+ "public class X03 {\n" + >+ " /** The value of <tt>System.getProperty(\"java.version\")<tt>. **/\n" + >+ " static final String JAVA_VERSION = System.getProperty(\"java.version\");\n" + >+ "\n" + >+ "}\n" >+ ); >+} > } >Index: src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java,v >retrieving revision 1.79 >diff -u -r1.79 ASTConverterJavadocTest.java >--- src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java 27 May 2008 23:59:54 -0000 1.79 >+++ src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java 13 Jun 2008 16:21:14 -0000 >@@ -30,6 +30,30 @@ > import org.eclipse.jdt.core.dom.*; > import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; > >+/** >+ * Class to test DOM/AST nodes built for Javadoc comments. >+ * >+ * Most of tests are 'automatic'. It means that to add a new tests, you only need to >+ * create one or several CUs and put them in org.eclipse.jdt.core.model.tests/workspace/Converter/src/javadoc/testXXX >+ * folder and add the corresponding test in this class: >+ * <pre> >+ * public void testXXX() throws JavaModelException { >+ * verifyComments("testXXX"); >+ * } >+ * </pre> >+ * >+ * Note that when a test fails, the easiest way to debug it is to open >+ * a runtime workbench, create a project 'Converter', delete the default 'src' source folder >+ * and replace it by a linked source to the 'src' folder of org.eclipse.jdt.core.model.tests/workspace/Converter/src >+ * in your workspace. >+ * >+ * Then open the CU on which the test fails in a ASTView and verify the offset/length >+ * of the offending node located at the positions displayed in the console when the test failed... >+ * >+ * Since 3.4, the failing test also provides the comparision between the source of the comment >+ * and the string get from the built DOM/AST nodes in the comment (see {@link ASTConverterJavadocFlattener}) >+ * but this may be not enough to see precisely the origin of the problem. >+ */ > public class ASTConverterJavadocTest extends ConverterTestSetup { > > // Flag to know whether Converter directory should be copied from org.eclipse.jdt.core.tests.model project >@@ -244,221 +268,6 @@ > return runConversion(source, unitName, project); > } > >-// NOT USED >-// class ASTConverterJavadocFlattener extends ASTVisitor { >-// >-// /** >-// * The string buffer into which the serialized representation of the AST is >-// * written. >-// */ >-// private StringBuffer buffer; >-// >-// private String comment; >-// >-// /** >-// * Creates a new AST printer. >-// */ >-// ASTConverterJavadocFlattener(String comment) { >-// buffer = new StringBuffer(); >-// comment = comment; >-// } >-// >-// /** >-// * Returns the string accumulated in the visit. >-// * >-// * @return the serialized >-// */ >-// public String getResult() { >-// return buffer.toString(); >-// } >-// >-// /** >-// * Resets this printer so that it can be used again. >-// */ >-// public void reset() { >-// buffer.setLength(0); >-// } >-// >-// /* >-// * @see ASTVisitor#visit(ArrayType) >-// */ >-// public boolean visit(ArrayType node) { >-// node.getComponentType().accept(this); >-// buffer.append("[]");//$NON-NLS-1$ >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(BlockComment) >-// * @since 3.0 >-// */ >-// public boolean visit(BlockComment node) { >-// buffer.append(comment); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(Javadoc) >-// */ >-// public boolean visit(Javadoc node) { >-// >-// // ignore deprecated node.getComment() >-// buffer.append("/**");//$NON-NLS-1$ >-// ASTNode e = null; >-// int start = 3; >-// for (Iterator it = node.tags().iterator(); it.hasNext(); ) { >-// e = (ASTNode) it.next(); >-// try { >-// buffer.append(comment.substring(start, e.getStartPosition()-node.getStartPosition())); >-// start = e.getStartPosition()-node.getStartPosition(); >-// } catch (IndexOutOfBoundsException ex) { >-// // do nothing >-// } >-// e.accept(this); >-// start += e.getLength(); >-// } >-// buffer.append(comment.substring(start, node.getLength())); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(LineComment) >-// * @since 3.0 >-// */ >-// public boolean visit(LineComment node) { >-// buffer.append(comment); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(MemberRef) >-// * @since 3.0 >-// */ >-// public boolean visit(MemberRef node) { >-// if (node.getQualifier() != null) { >-// node.getQualifier().accept(this); >-// } >-// buffer.append("#");//$NON-NLS-1$ >-// node.getName().accept(this); >-// return true; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(MethodRef) >-// * @since 3.0 >-// */ >-// public boolean visit(MethodRef node) { >-// if (node.getQualifier() != null) { >-// node.getQualifier().accept(this); >-// } >-// buffer.append("#");//$NON-NLS-1$ >-// node.getName().accept(this); >-// buffer.append("(");//$NON-NLS-1$ >-// for (Iterator it = node.parameters().iterator(); it.hasNext(); ) { >-// MethodRefParameter e = (MethodRefParameter) it.next(); >-// e.accept(this); >-// if (it.hasNext()) { >-// buffer.append(",");//$NON-NLS-1$ >-// } >-// } >-// buffer.append(")");//$NON-NLS-1$ >-// return true; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(MethodRefParameter) >-// * @since 3.0 >-// */ >-// public boolean visit(MethodRefParameter node) { >-// node.getType().accept(this); >-// if (node.getName() != null) { >-// buffer.append(" ");//$NON-NLS-1$ >-// node.getName().accept(this); >-// } >-// return true; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(TagElement) >-// * @since 3.0 >-// */ >-// public boolean visit(TagElement node) { >-// Javadoc javadoc = null; >-// int start = 0; >-// if (node.isNested()) { >-// // nested tags are always enclosed in braces >-// buffer.append("{");//$NON-NLS-1$ >-// javadoc = (Javadoc) node.getParent().getParent(); >-// start++; >-// } else { >-// javadoc = (Javadoc) node.getParent(); >-// } >-// start += node.getStartPosition()-javadoc.getStartPosition(); >-// if (node.getTagName() != null) { >-// buffer.append(node.getTagName()); >-// start += node.getTagName().length(); >-// } >-// for (Iterator it = node.fragments().iterator(); it.hasNext(); ) { >-// ASTNode e = (ASTNode) it.next(); >-// try { >-// buffer.append(comment.substring(start, e.getStartPosition()-javadoc.getStartPosition())); >-// start = e.getStartPosition()-javadoc.getStartPosition(); >-// } catch (IndexOutOfBoundsException ex) { >-// // do nothing >-// } >-// start += e.getLength(); >-// e.accept(this); >-// } >-// if (node.isNested()) { >-// buffer.append("}");//$NON-NLS-1$ >-// } >-// return true; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(TextElement) >-// * @since 3.0 >-// */ >-// public boolean visit(TextElement node) { >-// buffer.append(node.getText()); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(PrimitiveType) >-// */ >-// public boolean visit(PrimitiveType node) { >-// buffer.append(node.getPrimitiveTypeCode().toString()); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(QualifiedName) >-// */ >-// public boolean visit(QualifiedName node) { >-// node.getQualifier().accept(this); >-// buffer.append(".");//$NON-NLS-1$ >-// node.getName().accept(this); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(SimpleName) >-// */ >-// public boolean visit(SimpleName node) { >-// buffer.append(node.getIdentifier()); >-// return false; >-// } >-// >-// /* >-// * @see ASTVisitor#visit(SimpleName) >-// */ >-// public boolean visit(SimpleType node) { >-// node.getName().accept(this); >-// return false; >-// } >-// } >- > private char getNextChar(char[] source, int idx) { > // get next char > char ch = source[idx]; >@@ -820,7 +629,7 @@ > */ > private void verifyPositions(Javadoc docComment, char[] source) { > boolean stop = stopOnFailure; >-// stopOnFailure = false; >+ stopOnFailure = false; > // Verify javadoc start and end position > int start = docComment.getStartPosition(); > int end = start+docComment.getLength()-1; >@@ -845,7 +654,12 @@ > assumeTrue(prefix+"Misplaced javadoc end at <"+tagStart+'>', source[tagStart-1] == '*' && source[tagStart] == '/'); > assumeEquals(prefix+"Wrong javadoc length at <"+end+">: ", tagStart, end); > stopOnFailure = stop; >- assertTrue(!stop || failures.size()==0); >+ if (stop && failures.size() > 0) { >+ String expected = new String(source, docComment.getStartPosition(), docComment.getLength()); >+ ASTConverterJavadocFlattener flattener = new ASTConverterJavadocFlattener(expected); >+ docComment.accept(flattener); >+ assertEquals("Unexpected errors while verifying javadoc comment positions!", expected, flattener.getResult()); >+ } > } > > /** >Index: src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocFlattener.java >=================================================================== >RCS file: src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocFlattener.java >diff -N src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocFlattener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocFlattener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,236 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.dom; >+ >+import java.util.Iterator; >+ >+import org.eclipse.jdt.core.dom.*; >+ >+public class ASTConverterJavadocFlattener extends ASTVisitor { >+ >+ /** >+ * The string buffer into which the serialized representation of the AST is >+ * written. >+ */ >+ private StringBuffer buffer; >+ private int indent = 0; >+ private String comment; >+ >+/** >+ * Creates a new AST printer. >+ */ >+ASTConverterJavadocFlattener(String comment) { >+ buffer = new StringBuffer(); >+ this.comment = comment; >+} >+ >+/** >+ * Returns the string accumulated in the visit. >+ * >+ * @return the serialized >+ */ >+public String getResult() { >+ return buffer.toString(); >+} >+ >+/** >+ * Resets this printer so that it can be used again. >+ */ >+public void reset() { >+ buffer.setLength(0); >+} >+ >+/* >+ * @see ASTVisitor#visit(ArrayType) >+ */ >+public boolean visit(ArrayType node) { >+ node.getComponentType().accept(this); >+ buffer.append("[]");//$NON-NLS-1$ >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(BlockComment) >+ * @since 3.0 >+ */ >+public boolean visit(BlockComment node) { >+ buffer.append(comment); >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(Javadoc) >+ */ >+public boolean visit(Javadoc javadoc) { >+ printIndent(); >+ this.buffer.append("/**");//$NON-NLS-1$ >+ for (Iterator it = javadoc.tags().iterator(); it.hasNext(); ) { >+ ASTNode e = (ASTNode) it.next(); >+ e.accept(this); >+ } >+ this.buffer.append("\n */\n");//$NON-NLS-1$ >+ return false; >+} >+ >+private void printIndent() { >+ for (int i=0; i<this.indent; i++) { >+ buffer.append('\t'); >+ } >+} >+ >+/* >+private void printNewLine() { >+ buffer.append('\n'); >+ printIndent(); >+ buffer.append(" * "); >+} >+*/ >+ >+/* >+ * @see ASTVisitor#visit(LineComment) >+ * @since 3.0 >+ */ >+public boolean visit(LineComment node) { >+ buffer.append(comment); >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(MemberRef) >+ * @since 3.0 >+ */ >+public boolean visit(MemberRef node) { >+ if (node.getQualifier() != null) { >+ node.getQualifier().accept(this); >+ } >+ buffer.append("#");//$NON-NLS-1$ >+ node.getName().accept(this); >+ return true; >+} >+ >+/* >+ * @see ASTVisitor#visit(MethodRef) >+ * @since 3.0 >+ */ >+public boolean visit(MethodRef node) { >+ if (node.getQualifier() != null) { >+ node.getQualifier().accept(this); >+ } >+ buffer.append("#");//$NON-NLS-1$ >+ node.getName().accept(this); >+ buffer.append("(");//$NON-NLS-1$ >+ for (Iterator it = node.parameters().iterator(); it.hasNext(); ) { >+ MethodRefParameter e = (MethodRefParameter) it.next(); >+ e.accept(this); >+ if (it.hasNext()) { >+ buffer.append(",");//$NON-NLS-1$ >+ } >+ } >+ buffer.append(")");//$NON-NLS-1$ >+ return true; >+} >+ >+/* >+ * @see ASTVisitor#visit(MethodRefParameter) >+ * @since 3.0 >+ */ >+public boolean visit(MethodRefParameter node) { >+ node.getType().accept(this); >+ if (node.getName() != null) { >+ buffer.append(" ");//$NON-NLS-1$ >+ node.getName().accept(this); >+ } >+ return true; >+} >+ >+/* >+ * @see ASTVisitor#visit(TagElement) >+ * @since 3.0 >+ */ >+public boolean visit(TagElement node) { >+ if (node.isNested()) { >+ // nested tags are always enclosed in braces >+ this.buffer.append("{");//$NON-NLS-1$ >+ } else { >+ // top-level tags always begin on a new line >+ this.buffer.append("\n * ");//$NON-NLS-1$ >+ } >+ boolean previousRequiresWhiteSpace = false; >+ if (node.getTagName() != null) { >+ this.buffer.append(node.getTagName()); >+ previousRequiresWhiteSpace = true; >+ } >+ boolean previousRequiresNewLine = false; >+ for (Iterator it = node.fragments().iterator(); it.hasNext(); ) { >+ ASTNode e = (ASTNode) it.next(); >+ // assume text elements include necessary leading and trailing whitespace >+ // but Name, MemberRef, MethodRef, and nested TagElement do not include white space >+ boolean currentIncludesWhiteSpace = (e instanceof TextElement); >+ if (previousRequiresNewLine && currentIncludesWhiteSpace) { >+ this.buffer.append("\n * ");//$NON-NLS-1$ >+ } >+ previousRequiresNewLine = currentIncludesWhiteSpace; >+ // add space if required to separate >+ if (previousRequiresWhiteSpace && !currentIncludesWhiteSpace) { >+ this.buffer.append(" "); //$NON-NLS-1$ >+ } >+ e.accept(this); >+ previousRequiresWhiteSpace = !currentIncludesWhiteSpace && !(e instanceof TagElement); >+ } >+ if (node.isNested()) { >+ this.buffer.append("}");//$NON-NLS-1$ >+ } >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(TextElement) >+ * @since 3.0 >+ */ >+public boolean visit(TextElement node) { >+ buffer.append(node.getText()); >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(PrimitiveType) >+ */ >+public boolean visit(PrimitiveType node) { >+ buffer.append(node.getPrimitiveTypeCode().toString()); >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(QualifiedName) >+ */ >+public boolean visit(QualifiedName node) { >+ node.getQualifier().accept(this); >+ buffer.append(".");//$NON-NLS-1$ >+ node.getName().accept(this); >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(SimpleName) >+ */ >+public boolean visit(SimpleName node) { >+ buffer.append(node.getIdentifier()); >+ return false; >+} >+ >+/* >+ * @see ASTVisitor#visit(SimpleName) >+ */ >+public boolean visit(SimpleType node) { >+ node.getName().accept(this); >+ return false; >+} >+} >#P org.eclipse.jdt.core >Index: formatter/org/eclipse/jdt/internal/formatter/Scribe.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java,v >retrieving revision 1.143 >diff -u -r1.143 Scribe.java >--- formatter/org/eclipse/jdt/internal/formatter/Scribe.java 29 May 2008 09:28:43 -0000 1.143 >+++ formatter/org/eclipse/jdt/internal/formatter/Scribe.java 13 Jun 2008 16:21:16 -0000 >@@ -1715,8 +1715,9 @@ > } > > // 3 - process snippet (@see JavaDocRegion#formatCodeSnippet) >+ // include comments in case of line comments are present in the snippet > String formattedSnippet = convertedSnippet; >- TextEdit edit= CommentFormatterUtil.format2(CodeFormatter.K_UNKNOWN, convertedSnippet, 0, this.lineSeparator, this.formatter.preferences.getMap()); >+ TextEdit edit= CommentFormatterUtil.format2(CodeFormatter.K_UNKNOWN | CodeFormatter.F_INCLUDE_COMMENTS, convertedSnippet, 0, this.lineSeparator, this.formatter.preferences.getMap()); > if (edit != null) { > formattedSnippet= CommentFormatterUtil.evaluateFormatterEdit(convertedSnippet, edit, null); > } >Index: formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java,v >retrieving revision 1.13 >diff -u -r1.13 FormatterCommentParser.java >--- formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java 22 May 2008 15:34:15 -0000 1.13 >+++ formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java 13 Jun 2008 16:21:16 -0000 >@@ -475,22 +475,7 @@ > } > > // Add the text >- int textEnd = end; >- if (this.javadocTextEnd > 0 && end >= this.javadocTextEnd) { >- // Special case on javadoc text end, need to retrieve the space >- // position by rescanning the text >- int restart = this.spacePosition == -1 ? start : this.spacePosition; >- this.scanner.resetTo(restart, end-1/* before last star*/); >- try { >- if (this.scanner.getNextToken() == TerminalTokens.TokenNameEOF) { >- textEnd = this.spacePosition; >- } >- } >- catch (InvalidInputException iie) { >- // do nothing >- } >- } >- FormatJavadocText text = new FormatJavadocText(start, textEnd-1, lineStart, htmlIndex, htmlDepth); >+ FormatJavadocText text = new FormatJavadocText(start, end-1, lineStart, htmlIndex, htmlDepth); > previousBlock.addText(text); > previousBlock.sourceStart = previousStart; > if (lineStart == previousBlock.lineStart) { >Index: formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java,v >retrieving revision 1.72 >diff -u -r1.72 DefaultCodeFormatter.java >--- formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java 21 May 2008 10:58:04 -0000 1.72 >+++ formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java 13 Jun 2008 16:21:16 -0000 >@@ -25,6 +25,7 @@ > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.parser.Scanner; >+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; > import org.eclipse.jdt.internal.compiler.util.Util; > import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil; > import org.eclipse.jdt.internal.formatter.comment.CommentRegion; >@@ -487,8 +488,9 @@ > > private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) { > if (PROBING_SCANNER == null) { >- // scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT >- PROBING_SCANNER = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_3, ClassFileConstants.JDK1_3, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); >+ // scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT >+ // do not tokenize white spaces to get single comments even with spaces before... >+ PROBING_SCANNER = new Scanner(true, false/*do not tokenize whitespaces*/, false/*nls*/, ClassFileConstants.JDK1_6, ClassFileConstants.JDK1_6, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); > } > PROBING_SCANNER.setSource(source.toCharArray()); > >@@ -496,22 +498,22 @@ > int offset = coveredRegion.getOffset(); > int length = coveredRegion.getLength(); > >- PROBING_SCANNER.resetTo(offset, offset + length); >+ PROBING_SCANNER.resetTo(offset, offset + length - 1); > try { > int kind = -1; > switch(PROBING_SCANNER.getNextToken()) { > case ITerminalSymbols.TokenNameCOMMENT_BLOCK : >- if (PROBING_SCANNER.getCurrentTokenEndPosition() == offset + length - 1) { >+ if (PROBING_SCANNER.getNextToken() == TerminalTokens.TokenNameEOF) { > kind = K_MULTI_LINE_COMMENT; > } > break; > case ITerminalSymbols.TokenNameCOMMENT_LINE : >- if (PROBING_SCANNER.getCurrentTokenEndPosition() == offset + length - 1) { >+ if (PROBING_SCANNER.getNextToken() == TerminalTokens.TokenNameEOF) { > kind = K_SINGLE_LINE_COMMENT; > } > break; > case ITerminalSymbols.TokenNameCOMMENT_JAVADOC : >- if (PROBING_SCANNER.getCurrentTokenEndPosition() == offset + length - 1) { >+ if (PROBING_SCANNER.getNextToken() == TerminalTokens.TokenNameEOF) { > kind = K_JAVA_DOC; > } > break; >Index: compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java,v >retrieving revision 1.75 >diff -u -r1.75 AbstractCommentParser.java >--- compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 15 May 2008 17:45:49 -0000 1.75 >+++ compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java 13 Jun 2008 16:21:16 -0000 >@@ -62,7 +62,7 @@ > protected int javadocTextStart, javadocTextEnd = -1; > protected int firstTagPosition; > protected int index, lineEnd; >- protected int tokenPreviousPosition, lastIdentifierEndPosition, starPosition, spacePosition; >+ protected int tokenPreviousPosition, lastIdentifierEndPosition, starPosition; > protected int textStart, memberStart; > protected int tagSourceStart, tagSourceEnd; > protected int inlineTagStart; >@@ -133,7 +133,6 @@ > this.deprecated = false; > this.lastLinePtr = getLineNumber(javadocEnd); > this.textStart = -1; >- this.spacePosition = -1; > char previousChar = 0; > int invalidTagLineEnd = -1; > int invalidInlineTagLineEnd = -1; >@@ -163,9 +162,13 @@ > this.javadocTextStart = this.index; > } > this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.javadocEnd: this.scanner.getLineEnd(this.linePtr) - 1; >+ this.javadocTextEnd = this.javadocEnd - 2; // supposed text end, it will be refined later... > > // Loop on each comment character >+ int textEndPosition = -1; > while (!abort && this.index < this.javadocEnd) { >+ >+ // Store previous position and char > previousPosition = this.index; > previousChar = nextCharacter; > >@@ -206,10 +209,6 @@ > this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end); > } > validComment = false; >- int textEndPosition = previousPosition; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } > if (this.textStart != -1 && this.textStart < textEndPosition) { > if (pushText) pushText(this.textStart, textEndPosition); > } >@@ -219,10 +218,6 @@ > } > if (previousChar == '{') { > if (this.textStart != -1) { >- int textEndPosition = this.inlineTagStart; >- if (isFormatterParser && this.spacePosition == (this.inlineTagStart-1)) { >- textEndPosition = this.spacePosition; >- } > if (this.textStart < textEndPosition) { > if (pushText) pushText(this.textStart, textEndPosition); > } >@@ -230,11 +225,7 @@ > this.inlineTagStarted = true; > invalidInlineTagLineEnd = this.lineEnd; > } else if (this.textStart != -1 && this.textStart < invalidTagLineEnd) { >- int textEndPosition = invalidTagLineEnd; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } >- if (pushText) pushText(this.textStart, textEndPosition); >+ if (pushText) pushText(this.textStart, invalidTagLineEnd); > } > this.scanner.resetTo(this.index, this.javadocEnd); > this.currentTokenType = -1; // flush token cache at line begin >@@ -250,27 +241,26 @@ > } > this.textStart = this.tagSourceEnd+1; > invalidTagLineEnd = this.lineEnd; >+ textEndPosition = this.index; > } > } catch (InvalidInputException e) { > consumeToken(); > } >- } else if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) { >- refreshReturnStatement(); >- } else if (isFormatterParser) { >- if (this.textStart == -1) this.textStart = previousPosition; >+ } else { >+ textEndPosition = this.index; >+ if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) { >+ refreshReturnStatement(); >+ } else if (isFormatterParser) { >+ if (this.textStart == -1) this.textStart = previousPosition; >+ } > } > this.lineStarted = true; > break; > case '\r': > case '\n': > if (this.lineStarted) { >- int textEndPosition = previousPosition; >- if (isFormatterParser) { >- if (ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } else { >- this.spacePosition = previousPosition; >- } >+ if (isFormatterParser && !ScannerHelper.isWhitespace(previousChar)) { >+ textEndPosition = previousPosition; > } > if (this.textStart != -1 && this.textStart < textEndPosition) { > if (pushText) pushText(this.textStart, textEndPosition); >@@ -287,10 +277,6 @@ > } > if (this.inlineTagStarted) { > if (pushText) { >- int textEndPosition = previousPosition; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } > if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) { > pushText(this.textStart, textEndPosition); > } >@@ -304,6 +290,7 @@ > } > } > this.lineStarted = true; >+ textEndPosition = this.index; > break; > case '{' : > if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) { >@@ -318,15 +305,14 @@ > this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end); > } > if (pushText) { >- int textEndPosition = previousPosition; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } > if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) { > pushText(this.textStart, textEndPosition); > } > refreshInlineTagPosition(textEndPosition); > } >+ textEndPosition = this.index; >+ } else if (peekChar() != '@') { >+ textEndPosition = this.index; > } > if (!this.lineStarted) { > this.textStart = previousPosition; >@@ -352,9 +338,13 @@ > case '\u000c' : /* FORM FEED */ > case ' ' : /* SPACE */ > case '\t' : /* HORIZONTAL TABULATION */ >- // Store first space position while formatting >- if (isFormatterParser && !ScannerHelper.isWhitespace(previousChar)) { >- this.spacePosition = previousPosition; >+ // Do not include trailing spaces in text while formatting >+ if (isFormatterParser) { >+ if (!ScannerHelper.isWhitespace(previousChar)) { >+ textEndPosition = previousPosition; >+ } >+ } else if (this.lineStarted) { >+ textEndPosition = this.index; > } > break; > case '/': >@@ -368,8 +358,10 @@ > // html tags are meaningful for formatter parser > int initialIndex = this.index; > this.scanner.resetTo(this.index, this.javadocEnd); >- int endTextPosition = ScannerHelper.isWhitespace(previousChar) ? this.spacePosition : previousPosition; >- if (parseHtmlTag(previousPosition, endTextPosition)) { >+ if (!ScannerHelper.isWhitespace(previousChar)) { >+ textEndPosition = previousPosition; >+ } >+ if (parseHtmlTag(previousPosition, textEndPosition)) { > break; > } > if (this.abort) return false; >@@ -384,6 +376,7 @@ > this.textStart = previousPosition; > } > this.lineStarted = true; >+ textEndPosition = this.index; > break; > } > } >@@ -398,18 +391,14 @@ > this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end); > } > if (pushText) { >- int textEndPosition = this.javadocTextEnd; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } > if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) { > pushText(this.textStart, textEndPosition); > } > refreshInlineTagPosition(textEndPosition); > } > this.inlineTagStarted = false; >- } else if (pushText && this.lineStarted && this.textStart != -1 && this.textStart <= this.javadocTextEnd) { >- pushText(this.textStart, this.starPosition); >+ } else if (pushText && this.lineStarted && this.textStart != -1 && this.textStart <= textEndPosition) { >+ pushText(this.textStart, textEndPosition); > } > updateDocComment(); > } catch (Exception ex) { >@@ -1539,13 +1528,12 @@ > * Note that end of comment may be preceding by several contiguous '*' chars. > */ > protected boolean verifyEndLine(int textPosition) { >- boolean isDomParser = (this.kind & DOM_PARSER) != 0; >- boolean isFormatterParser = (this.kind & FORMATTER_COMMENT_PARSER) != 0; >+ boolean domParser = (this.kind & DOM_PARSER) != 0; > // Special case for inline tag > if (this.inlineTagStarted) { > // expecting closing brace > if (peekChar() == '}') { >- if (isDomParser || isFormatterParser) { >+ if (domParser) { > createTag(); > pushText(textPosition, this.starPosition); > } >@@ -1556,30 +1544,21 @@ > > int startPosition = this.index; > int previousPosition = this.index; >- int spacePos = this.index; > this.starPosition = -1; > char ch = readChar(); >- char previousChar = ch; > nextChar: while (true) { > switch (ch) { > case '\r': > case '\n': >- if (isDomParser || isFormatterParser) { >+ if (domParser) { > createTag(); >- int textEndPosition = previousPosition; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = spacePos; >- } >- pushText(textPosition, textEndPosition); >+ pushText(textPosition, previousPosition); > } > this.index = previousPosition; > return true; > case '\u000c' : /* FORM FEED */ > case ' ' : /* SPACE */ > case '\t' : /* HORIZONTAL TABULATION */ >- if (isFormatterParser && previousChar != ch && !ScannerHelper.isWhitespace(previousChar)) { >- this.spacePosition = previousPosition; >- } > if (this.starPosition >= 0) break nextChar; > break; > case '*': >@@ -1587,13 +1566,9 @@ > break; > case '/': > if (this.starPosition >= textPosition) { >- if (isDomParser || isFormatterParser) { >+ if (domParser) { > createTag(); >- int textEndPosition = this.starPosition; >- if (isFormatterParser && ScannerHelper.isWhitespace(previousChar)) { >- textEndPosition = this.spacePosition; >- } >- pushText(textPosition, textEndPosition); >+ pushText(textPosition, this.starPosition); > } > return true; > } >@@ -1603,7 +1578,6 @@ > > } > previousPosition = this.index; >- previousChar = ch; > ch = readChar(); > } > this.index = startPosition;
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 236230
:
104144
|
104887
|
105505