### Eclipse Workspace Patch 1.0 #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.180 diff -u -r1.180 Scribe.java --- formatter/org/eclipse/jdt/internal/formatter/Scribe.java 9 Nov 2009 22:06:43 -0000 1.180 +++ formatter/org/eclipse/jdt/internal/formatter/Scribe.java 15 Nov 2009 17:39:36 -0000 @@ -2793,24 +2793,30 @@ } int lastColumn = this.column + length; while (!this.scanner.atEnd()) { - int token = this.scanner.getNextToken(); - switch (token) { - case TerminalTokens.TokenNameWHITESPACE: - if (CharOperation.indexOf('\n', this.scanner.source, this.scanner.startPosition, this.scanner.currentPosition) >= 0) { - return newLines; - } - length = 1; - break; - case TerminalTokens.TokenNameMULTIPLY: - if (newLine) { - newLine = false; - continue; - } - length = 1; - break; - default: - length = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition; - break; + try { + int token = this.scanner.getNextToken(); + switch (token) { + case TerminalTokens.TokenNameWHITESPACE: + if (CharOperation.indexOf('\n', this.scanner.source, this.scanner.startPosition, this.scanner.currentPosition) >= 0) { + return newLines; + } + length = 1; + break; + case TerminalTokens.TokenNameMULTIPLY: + if (newLine) { + newLine = false; + continue; + } + length = 1; + break; + default: + length = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition; + break; + } + } + catch (InvalidInputException iie) { + // maybe an unterminated string or comment + length = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition; } lastColumn += length; if (lastColumn > maxColumn) { @@ -3008,7 +3014,8 @@ } textLength += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition; } catch (InvalidInputException e) { - return textLength; + // maybe an unterminated string or comment + textLength += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition; } } return textLength; @@ -3167,6 +3174,7 @@ int linePtr = this.scanner.linePtr; int lineCount = 0; int start = textStartPosition; + boolean endsOnMultiply = false; while (!this.scanner.atEnd()) { switch (this.scanner.getNextToken()) { case TerminalTokens.TokenNameMULTIPLY: @@ -3224,6 +3232,10 @@ // next start is just after the current token start = this.scanner.currentPosition; linePtr = this.scanner.linePtr; + endsOnMultiply = true; + break; + default: + endsOnMultiply = false; break; } } @@ -3277,6 +3289,14 @@ } else { output.append(buffer); } + this.needSpace = false; + } else if (endsOnMultiply) { + if (output == null) { + addInsertEdit(textEndPosition+1, " "); //$NON-NLS-1$ + } else { + output.append(' '); + } + this.needSpace = false; } this.column++; } @@ -3427,7 +3447,7 @@ } } else { if (idx > 0 && linesAfter > 0) { - printJavadocGapLines(previousEnd+1, nextStart, linesAfter, clearBlankLines, false, buffer); + printJavadocGapLines(previousEnd+1, nextStart-1, linesAfter, clearBlankLines, false, buffer); textOnNewLine = true; } boolean needIndentation = textOnNewLine; @@ -3506,9 +3526,11 @@ // Format gap lines before code int newLines = linesGap; if (newLines == 0) newLines=1; + this.needSpace = needLeadingSpace; printJavadocGapLines(end+1, nextStart-1, newLines, false/* clear first blank lines inside
 tag as done by old formatter */, false, null);
-						if (needLeadingSpace) {
+						if (this.needSpace) {
 							addInsertEdit(nextStart, " "); //$NON-NLS-1$
+							this.needSpace = false;
 						}
 						// Format the code
 						printCodeSnippet(nextStart, codeEnd);
#P org.eclipse.jdt.core.tests.model
Index: src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java,v
retrieving revision 1.8
diff -u -r1.8 FormatterBugsTests.java
--- src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java	10 Nov 2009 21:38:06 -0000	1.8
+++ src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java	15 Nov 2009 17:39:41 -0000
@@ -1799,4 +1799,181 @@
 		"}\n"
 	);
 }
+
+/**
+ * @bug 295175: [formatter] Missing space before a string at the beginning of a javadoc comment
+ * @test Verify that space is well inserted before the leading string
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=295175"
+ */
+public void testBug295175a() {
+	String source = 
+		"public class X {\n" + 
+		"/**\n" + 
+		" * 

\n" + + " * \"String\", this string may be not well formatted in certain circumstances,\n" + + " * typically after bug 294529 has been fixed...\n" + + " */\n" + + "void foo() {}\n" + + "}\n"; + formatSource(source, + "public class X {\n" + + " /**\n" + + " *

\n" + + " * \"String\", this string may be not well formatted in certain circumstances,\n" + + " * typically after bug 294529 has been fixed...\n" + + " */\n" + + " void foo() {\n" + + " }\n" + + "}\n" + ); +} +public void testBug295175b() { + String source = + "package wksp2;\n" + + "\n" + + "public interface X {\n" + + "\n" + + " /**\n" + + " *

\n" + + " *
\n" + + " *NOTE
\n" + + " * Formatter can miss a space before the previous B tag...\n" + + " **/\n" + + " void foo();\n" + + "}\n"; + formatSource(source, + "package wksp2;\n" + + "\n" + + "public interface X {\n" + + "\n" + + " /**\n" + + " *

\n" + + " *
\n" + + " * NOTE
\n" + + " * Formatter can miss a space before the previous B tag...\n" + + " **/\n" + + " void foo();\n" + + "}\n" + ); +} +public void testBug295175c() { + String source = + "package wksp2;\n" + + "\n" + + "public interface X {\n" + + "\n" + + " /**\n" + + " *

Following p tag can miss a space before after formatting\n" + + " *

\n" + + " * end of comment.\n" + + " **/\n" + + " void foo();\n" + + "}\n"; + formatSource(source, + "package wksp2;\n" + + "\n" + + "public interface X {\n" + + "\n" + + " /**\n" + + " *

\n" + + " * Following p tag can miss a space before after formatting\n" + + " *

\n" + + " * end of comment.\n" + + " **/\n" + + " void foo();\n" + + "}\n" + ); +} +public void testBug295175d() { + String source = + "package wksp2;\n" + + "\n" + + "public interface X {\n" + + "\n" + + " /**\n" + + " *

Following p tag can miss a space before after formatting\n" + + " *\n" + + " *

\n" + + " *
\n" + + " *NOTE
\n" + + " * Formatter can miss a space before the previous B tag...\n" + + " **/\n" + + " void foo();\n" + + "}\n"; + formatSource(source, + "package wksp2;\n" + + "\n" + + "public interface X {\n" + + "\n" + + " /**\n" + + " *

\n" + + " * Following p tag can miss a space before after formatting\n" + + " * \n" + + " *

\n" + + " *
\n" + + " * NOTE
\n" + + " * Formatter can miss a space before the previous B tag...\n" + + " **/\n" + + " void foo();\n" + + "}\n" + ); +} +public void testBug295175e() { + String source = + "package wksp3;\n" + + "\n" + + "public class X01 {\n" + + " /** \n" + + " * In this peculiar config true, the comment is not___ \n" + + " * really well formatted. The problem is that the first_ code tag\n" + + " * here_______ /* and */ go at the end of the previous line\n" + + " * instead of staying on the 3rd one... \n" + + " */\n" + + " void foo() {}\n" + + "}\n"; + formatSource(source, + "package wksp3;\n" + + "\n" + + "public class X01 {\n" + + " /**\n" + + " * In this peculiar config true, the comment is not___ really\n" + + " * well formatted. The problem is that the first_ code tag here_______\n" + + " * /* and */ go at the end of the previous\n" + + " * line instead of staying on the 3rd one...\n" + + " */\n" + + " void foo() {\n" + + " }\n" + + "}\n" + ); +} +public void testBug295175f() { + String source = + "package wksp1;\n" + + "\n" + + "public class X01 {\n" + + "\n" + + " /**\n" + + " * Finds the deepest IJavaElement in the hierarchy of\n" + + " * elt's children (including elt itself)\n" + + " * which has a source range that encloses position\n" + + " * according to mapper.\n" + + " */\n" + + " void foo() {}\n" + + "}\n"; + formatSource(source, + "package wksp1;\n" + + "\n" + + "public class X01 {\n" + + "\n" + + " /**\n" + + " * Finds the deepest IJavaElement in the hierarchy of\n" + + " * elt\'s children (including elt itself) which has\n" + + " * a source range that encloses position according to\n" + + " * mapper.\n" + + " */\n" + + " void foo() {\n" + + " }\n" + + "}\n" + ); +} }