### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.core
Index: buildnotes_jdt-core.html
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/buildnotes_jdt-core.html,v
retrieving revision 1.7343
diff -u -r1.7343 buildnotes_jdt-core.html
--- buildnotes_jdt-core.html 2 Mar 2010 12:37:42 -0000 1.7343
+++ buildnotes_jdt-core.html 2 Mar 2010 12:49:51 -0000
@@ -48,6 +48,173 @@
Project org.eclipse.jdt.core v_A38
(cvs).
+These new preferences are controlled with the options:
+DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAGS
+DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAGS
++/** + * FORMATTER / Option to define tags used to disable formatting from the beginning of the comment including one of these tags. + * - option id: "org.eclipse.jdt.core.formatter.disabling_tags" + * - default:+null
+ * + * Note that: + * + * 1. As soon as the formatter encounter a disabling tag, it stops to format the + * code just after the comment including the tag. If it was already inactive, the + * tag is simply ignored. + * Hence, nesting disabling and enabling tags has no specific effect. + * For example, in the following snippet: + * class X { + * // disable-formatter-1 + * void foo1() {} + * // disable-formatter-2 + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * // enable-formatter-1 + * void bar2() {} + * } + * + * the second disabling tag and the second enabling tag will be ignored by the + * formatter, which will format it the same than: + * class X { + * // disable-formatter-1 + * void foo1() {} + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * void bar2() {} + * } + * + * 2. If no enabling tag is found by the formatter after a disabling tag, then the + * end of the snippet won't be formatted. + * For example, to disable the formatting of the entire content of a compilation + * unit, just put a disabling tag at the beginning of the code: + * // disable-formatter + * class X { + * void foo1() {} + * void foo2() {} + * void bar1() {} + * void bar2() {} + * } + * + * In this case, the formatter will not change the content of the class X. + * + * 3. The tag cannot include new line characters but it can have white spaces. + * E.g. "format: off" is a valid disabling tag + * + * 4. If a mix of disabling and enabling tags is done in the same comment, then + * the formatter will take into account the last encountered tag in the comment. + * For example, in the following snippet, the formatter will be disabled after + * the comment: + * class X { + * /* + * * This is a comment with a mix of disabling and enabling tags: + * * disable-formatter-1 + * * enable-formatter-1 + * * disable-formatter-2 + * * The formatter will stop to format after this comment... + * */ + * void foo() {} + * void bar() {} + * } + * + * @see #FORMATTER_ENABLING_TAGS + * @since 3.6 + */ + +/** + * FORMATTER / Option to define tags used to enable formatting after the end of the comment including one of these tags. + * - option id: "org.eclipse.jdt.core.formatter.enabling_tags" + * - default:null
+ * + * Note that: + * + * 1. As soon as the formatter encounter an enabling tag, it starts to format + * the code just after the comment including the tag. If it was already active, + * the tag is simply ignored. + * Hence, nesting disabling and enabling tags has no specific effect. + * For example, in the following snippet: + * class X { + * // disable-formatter-1 + * void foo1() {} + * // disable-formatter-2 + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * // enable-formatter-1 + * void bar2() {} + * } + * + * the second disabling tag and the second enabling tag will be ignored by the + * formatter, which will format it the same than: + * class X { + * // disable-formatter-1 + * void foo1() {} + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * void bar2() {} + * } + * + * 2. The tag cannot include new line characters but it can have white spaces. + * E.g. "format: on" is a valid enabling tag + * + * 3. If a mix of disabling and enabling tags is done in the same comment, then + * the formatter will take into account the last encountered tag in the comment. + * For example, in the following snippet, the formatter will be disabled after + * the comment: + * class X { + * /* + * * This is a comment with a mix of disabling and enabling tags: + * * disable-formatter-1 + * * enable-formatter-1 + * * disable-formatter-2 + * * The formatter will stop to format after this comment... + * */ + * void foo() {} + * void bar() {} + * } + * + * @see #FORMATTER_DISABLING_TAGS + * @since 3.6 + */ +
For example, the following snippet:
++public class Test { +/* disable-formatter */ +void foo( ) { + // unformatted area +} +/* enable-formatter */ +void bar( ) { + // formatted area +} +} ++formatted with disabling tags = "disable-formatter" and enabling tags += "enable-formatter" produces the following output: +
+public class Test { + +/* disable-formatter * +void foo( ) { + // unformatted area +} +/* enable-formatter * + void bar() { + // formatted area + } +} ++See bug 27079 for more details. +
+ * FORMATTER / Option to define tags used to disable formatting from the beginning of the comment including one of these tags.
+ * - option id: "org.eclipse.jdt.core.formatter.disabling_tags"
+ * - default: null
+ *
+ * + * Note that: + *
Hence, nesting disabling and enabling tags has no specific effect.
+ * For example, in the following snippet: + *+ * class X { + * // disable-formatter-1 + * void foo1() {} + * // disable-formatter-2 + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * // enable-formatter-1 + * void bar2() {} + * } + *+ * the second disabling tag and the second enabling tag will be ignored by the + * formatter, which will format it the same than: + *
+ * class X { + * // disable-formatter-1 + * void foo1() {} + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * void bar2() {} + * } + *+ *
+ * // disable-formatter + * class X { + * void foo1() {} + * void foo2() {} + * void bar1() {} + * void bar2() {} + * } + *+ * In this case, the formatter will not change the content of the class X. + *
For example, in the following snippet, the formatter will be disabled after + * the comment:
+ *+ * class X { + * /* + * * This is a comment with a mix of disabling and enabling tags: + * * disable-formatter-1 + * * enable-formatter-1 + * * disable-formatter-2 + * * The formatter will stop to format after this comment... + * */ + * void foo() {} + * void bar() {} + * } + *+ *
+ * FORMATTER / Option to define tags used to enable formatting after the end of the comment including one of these tags.
+ * - option id: "org.eclipse.jdt.core.formatter.enabling_tags"
+ * - default: null
+ *
+ * + * Note that: + *
Hence, nesting disabling and enabling tags has no specific effect.
+ * For example, in the following snippet: + *+ * class X { + * // disable-formatter-1 + * void foo1() {} + * // disable-formatter-2 + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * // enable-formatter-1 + * void bar2() {} + * } + *+ * the second disabling tag and the second enabling tag will be ignored by the + * formatter, which will format it the same than: + *
+ * class X { + * // disable-formatter-1 + * void foo1() {} + * void foo2() {} + * // enable-formatter-2 + * void bar1() {} + * void bar2() {} + * } + *+ *
For example, in the following snippet, the formatter will be disabled after + * the comment:
+ *+ * class X { + * /* + * * This is a comment with a mix of disabling and enabling tags: + * * disable-formatter-1 + * * enable-formatter-1 + * * disable-formatter-2 + * * The formatter will stop to format after this comment... + * */ + * void foo() {} + * void bar() {} + * } + *+ *
* FORMATTER / Option to indent body declarations compare to its enclosing annotation declaration header * - option id: "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" * - possible values: { TRUE, FALSE } Index: formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java,v retrieving revision 1.229 diff -u -r1.229 CodeFormatterVisitor.java --- formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java 23 Feb 2010 15:04:52 -0000 1.229 +++ formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java 2 Mar 2010 12:49:56 -0000 @@ -756,7 +756,7 @@ final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); - this.scribe.initializeScanner(compilationUnitSource); + this.scribe.resetScanner(compilationUnitSource); if (nodes == null) { return null; @@ -793,7 +793,7 @@ final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); - this.scribe.initializeScanner(compilationUnitSource); + this.scribe.resetScanner(compilationUnitSource); this.lastLocalDeclarationSourceStart = -1; try { @@ -822,7 +822,7 @@ final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); - this.scribe.initializeScanner(compilationUnitSource); + this.scribe.resetScanner(compilationUnitSource); if (constructorDeclaration == null) { return null; @@ -866,7 +866,7 @@ final char[] compilationUnitSource = string.toCharArray(); this.localScanner.setSource(compilationUnitSource); - this.scribe.initializeScanner(compilationUnitSource); + this.scribe.resetScanner(compilationUnitSource); if (expression == null) { return null; Index: formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java,v retrieving revision 1.102 diff -u -r1.102 DefaultCodeFormatterOptions.java --- formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java 1 Mar 2010 17:09:36 -0000 1.102 +++ formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java 2 Mar 2010 12:49:58 -0000 @@ -14,8 +14,10 @@ import java.util.HashMap; import java.util.Map; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.internal.compiler.util.Util; import org.eclipse.jdt.internal.formatter.align.Alignment; /** @@ -116,6 +118,9 @@ public boolean comment_insert_new_line_for_parameter; public int comment_line_length; + public char[][] disabling_tags; + public char[][] enabling_tags; + public boolean indent_statements_compare_to_block; public boolean indent_statements_compare_to_body; public boolean indent_body_declarations_compare_to_annotation_declaration_header; @@ -612,6 +617,8 @@ options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, Integer.toString(this.tab_size)); options.put(DefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS, this.use_tabs_only_for_leading_indentations ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE); options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_BINARY_OPERATOR, this.wrap_before_binary_operator ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE); + options.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAGS, this.disabling_tags == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.disabling_tags,','))); + options.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAGS, this.enabling_tags == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.enabling_tags,','))); return options; } @@ -1949,6 +1956,28 @@ if (wrapBeforeBinaryOperatorOption != null) { this.wrap_before_binary_operator = DefaultCodeFormatterConstants.TRUE.equals(wrapBeforeBinaryOperatorOption); } + final Object disableTagsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAGS); + if (disableTagsOption != null) { + if (disableTagsOption instanceof String) { + String stringValue = (String) disableTagsOption; + if (stringValue.trim().length() == 0) { + this.disabling_tags = null; + } else { + this.disabling_tags = CharOperation.splitAndTrimOn(',', stringValue.toCharArray()); + } + } + } + final Object enableTagsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAGS); + if (enableTagsOption != null) { + if (enableTagsOption instanceof String) { + String stringValue = (String) enableTagsOption; + if (stringValue.trim().length() == 0) { + this.enabling_tags = null; + } else { + this.enabling_tags = CharOperation.splitAndTrimOn(',', stringValue.toCharArray()); + } + } + } } /** Index: formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java,v retrieving revision 1.12 diff -u -r1.12 FormatJavadocBlock.java --- formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java 14 Feb 2010 15:57:25 -0000 1.12 +++ formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java 2 Mar 2010 12:49:58 -0000 @@ -358,7 +358,11 @@ boolean inlined = (this.flags & INLINED) != 0; if (inlined) buffer.append(" {"); //$NON-NLS-1$ buffer.append('@'); - buffer.append(TAG_NAMES[this.tagValue]); + if (this.tagValue == TAG_OTHERS_VALUE) { + buffer.append("others_tag"); //$NON-NLS-1$ + } else { + buffer.append(TAG_NAMES[this.tagValue]); + } super.toString(buffer); if (this.reference == null) { buffer.append('\n'); 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.195 diff -u -r1.195 Scribe.java --- formatter/org/eclipse/jdt/internal/formatter/Scribe.java 1 Mar 2010 17:09:35 -0000 1.195 +++ formatter/org/eclipse/jdt/internal/formatter/Scribe.java 2 Mar 2010 12:50:00 -0000 @@ -78,10 +78,14 @@ private int[] lineEnds; private int maxLines; - private String lineSeparator; public Alignment memberAlignment; public boolean needSpace = false; + // Line separator infos + final private String lineSeparator; + final private char firstLS; + final private int lsLength; + public int nlsTagCounter; public int pageWidth; public boolean pendingSpace = false; @@ -100,6 +104,9 @@ private final boolean indentEmptyLines; int blank_lines_between_import_groups = -1; + /** disabling */ + boolean editsEnabled = true; + /* Comments formatting */ private static final int INCLUDE_BLOCK_COMMENTS = CodeFormatter.F_INCLUDE_COMMENTS | CodeFormatter.K_MULTI_LINE_COMMENT; private static final int INCLUDE_JAVA_DOC = CodeFormatter.F_INCLUDE_COMMENTS | CodeFormatter.K_JAVA_DOC; @@ -114,6 +121,7 @@ private int formatComments = 0; private int headerEndPosition = -1; String commentIndentation; // indentation requested in comments (usually in javadoc root tags description) + // Class to store previous line comment information static class LineComment { boolean contiguous = false; @@ -123,12 +131,17 @@ } final LineComment lastLineComment = new LineComment(); - // New way to format javadoc private FormatterCommentParser formatterCommentParser; // specialized parser to format comments + // Disabling and enabling tags + OptimizedReplaceEdit previousDisabledEdit; + private char[][] validationTags; + private int disablingTagsLength; + private int validationTagsLength; + Scribe(CodeFormatterVisitor formatter, long sourceLevel, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil, boolean includeComments) { - this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); + initializeScanner(sourceLevel, formatter.preferences); this.formatter = formatter; this.pageWidth = formatter.preferences.page_width; this.tabLength = formatter.preferences.tab_size; @@ -143,6 +156,8 @@ this.indentationSize = this.tabLength; } this.lineSeparator = formatter.preferences.line_separator; + this.firstLS = this.lineSeparator.charAt(0); + this.lsLength = this.lineSeparator.length(); this.indentationLevel = formatter.preferences.initial_indentation_level * this.indentationSize; this.regions= regions; if (codeSnippetParsingUtil != null) { @@ -447,6 +462,18 @@ } private final void addOptimizedReplaceEdit(int offset, int length, String replacement) { + if (!this.editsEnabled) { + if (this.previousDisabledEdit != null && this.previousDisabledEdit.offset == offset) { + replacement = this.previousDisabledEdit.replacement; + } + this.previousDisabledEdit = null; + if (replacement.indexOf(this.lineSeparator) >= 0) { + if (length == 0 || printNewLinesCharacters(offset, length)) { + this.previousDisabledEdit = new OptimizedReplaceEdit(offset, length, replacement); + } + } + return; + } if (this.editsIndex > 0) { // try to merge last two edits final OptimizedReplaceEdit previous = this.edits[this.editsIndex-1]; @@ -1269,18 +1296,26 @@ this.numberOfIndentations++; } - /** - * @param compilationUnitSource - */ - public void initializeScanner(char[] compilationUnitSource) { - this.scanner.setSource(compilationUnitSource); - this.scannerEndPosition = compilationUnitSource.length; - this.scanner.resetTo(0, this.scannerEndPosition - 1); - this.edits = new OptimizedReplaceEdit[INITIAL_SIZE]; - this.maxLines = this.lineEnds == null ? -1 : this.lineEnds.length - 1; - this.scanner.lineEnds = this.lineEnds; - this.scanner.linePtr = this.maxLines; - initFormatterCommentParser(); + private void initializeScanner(long sourceLevel, DefaultCodeFormatterOptions preferences) { + char[][] disablingTags = preferences.disabling_tags; + char[][] enablingTags = preferences.enabling_tags; + this.disablingTagsLength = disablingTags == null ? 0 : disablingTags.length; + int eLength = enablingTags == null ? 0 : enablingTags.length; + this.validationTagsLength = this.disablingTagsLength + eLength; + char[][] taskTags = null; + if (this.validationTagsLength > 0) { + this.validationTags = new char[this.validationTagsLength][]; + if (this.disablingTagsLength > 0) { + System.arraycopy(disablingTags, 0, this.validationTags, 0, this.disablingTagsLength); + } + if (eLength > 0) { + System.arraycopy(enablingTags, 0, this.validationTags, this.disablingTagsLength, eLength); + } + // copy the task tags array as it will be reordered by the scanner + taskTags = new char[this.validationTagsLength][]; + System.arraycopy(this.validationTags, 0, taskTags, 0, this.validationTagsLength); + } + this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, taskTags, null/*taskPriorities*/, true/*taskCaseSensitive*/); } private void initFormatterCommentParser() { @@ -2153,7 +2188,9 @@ boolean hasLineComment = false; boolean hasWhitespaces = false; int lines = 0; + int previousFoundTaskCount = this.scanner.foundTaskCount; while ((this.currentToken = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { + int foundTaskCount = this.scanner.foundTaskCount; switch(this.currentToken) { case TerminalTokens.TokenNameWHITESPACE : char[] whiteSpaces = this.scanner.getCurrentTokenSource(); @@ -2279,6 +2316,16 @@ currentTokenStartPosition = this.scanner.currentPosition; break; case TerminalTokens.TokenNameCOMMENT_LINE : + if (this.editsEnabled && foundTaskCount > previousFoundTaskCount) { + setEditsEnabled(foundTaskCount, previousFoundTaskCount); + if (!this.editsEnabled && this.editsIndex > 1) { + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { + printNewLinesBeforeDisablingComment(); + } + } + previousFoundTaskCount = foundTaskCount; + } if (rejectLineComment) break; if (lines >= 1) { if (lines > 1) { @@ -2294,8 +2341,21 @@ currentTokenStartPosition = this.scanner.currentPosition; hasLineComment = true; lines = 0; + if (!this.editsEnabled && foundTaskCount > previousFoundTaskCount) { + setEditsEnabled(foundTaskCount, previousFoundTaskCount); + } break; case TerminalTokens.TokenNameCOMMENT_BLOCK : + if (this.editsEnabled && foundTaskCount > previousFoundTaskCount) { + setEditsEnabled(foundTaskCount, previousFoundTaskCount); + if (!this.editsEnabled && this.editsIndex > 1) { + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { + printNewLinesBeforeDisablingComment(); + } + } + previousFoundTaskCount = foundTaskCount; + } if (trailing > NO_TRAILING_COMMENT && lines >= 1) { // a block comment on next line means that there's no trailing comment this.scanner.resetTo(this.scanner.getCurrentTokenStartPosition(), this.scannerEndPosition - 1); @@ -2318,8 +2378,15 @@ hasLineComment = false; hasComment = true; lines = 0; + if (!this.editsEnabled && foundTaskCount > previousFoundTaskCount) { + setEditsEnabled(foundTaskCount, previousFoundTaskCount); + } break; case TerminalTokens.TokenNameCOMMENT_JAVADOC : + if (this.editsEnabled && foundTaskCount > previousFoundTaskCount) { + setEditsEnabled(foundTaskCount, previousFoundTaskCount); + previousFoundTaskCount = foundTaskCount; + } if (trailing > NO_TRAILING_COMMENT) { // a javadoc comment should not be considered as a trailing comment this.scanner.resetTo(this.scanner.getCurrentTokenStartPosition(), this.scannerEndPosition - 1); @@ -2342,6 +2409,9 @@ } else { printBlockComment(true); } + if (!this.editsEnabled && foundTaskCount > previousFoundTaskCount) { + setEditsEnabled(foundTaskCount, previousFoundTaskCount); + } printNewLine(); currentTokenStartPosition = this.scanner.currentPosition; hasLineComment = false; @@ -2354,6 +2424,7 @@ this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1); return; } + previousFoundTaskCount = foundTaskCount; } } catch (InvalidInputException e) { throw new AbortFormatting(e); @@ -2363,7 +2434,7 @@ void printComment(int kind, String source, int start, int end, int level) { // Set scanner - initializeScanner(source.toCharArray()); + resetScanner(source.toCharArray()); this.scanner.resetTo(start, end); // Put back 3.4RC2 code => comment following line as it has an impact on Linux tests // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=234336 @@ -2677,9 +2748,10 @@ } } - // Delete leading whitespaces if any - if (previousToken != -1 && lastTokenEndPosition != commentStart && spaceEndPosition > lastTokenEndPosition) { - addDeleteEdit(lastTokenEndPosition, spaceEndPosition-1); + // Replace the line separator at the end of the comment if any... + int startReplace = previousToken == SKIP_FIRST_WHITESPACE_TOKEN ? spaceStartPosition : lastTokenEndPosition; + if (this.column == 1 && commentEnd >= startReplace) { + addReplaceEdit(startReplace, commentEnd, this.formatter.preferences.line_separator); } } @@ -4319,6 +4391,135 @@ this.lastLineComment.contiguous = false; } + /* + * Print the indentation of a disabling comment + */ + private void printNewLinesBeforeDisablingComment() { + + // Get the beginning of comment line + int linePtr = Arrays.binarySearch(this.lineEnds, this.scanner.startPosition); + if (linePtr < 0) { + linePtr = -linePtr - 1; + } + int indentation = 0; + int beginningOfLine = getLineEnd(linePtr)+1; + if (beginningOfLine == -1) { + beginningOfLine = 0; + } + + // If the comment is in the middle of the line, then there's nothing to do + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + int offset = currentEdit.offset; + if (offset >= beginningOfLine) return; + + // Compute the comment indentation + int scannerStartPosition = this.scanner.startPosition; + int scannerEofPosition = this.scanner.eofPosition; + int scannerCurrentPosition = this.scanner.currentPosition; + char scannerCurrentChar = this.scanner.currentCharacter; + int length = currentEdit.length; + this.scanner.resetTo(beginningOfLine, offset+length-1); + try { + while (!this.scanner.atEnd()) { + char ch = (char) this.scanner.getNextChar(); + switch (ch) { + case '\t' : + if (this.tabLength != 0) { + int reminder = indentation % this.tabLength; + if (reminder == 0) { + indentation += this.tabLength; + } else { + indentation = ((indentation / this.tabLength) + 1) * this.tabLength; + } + } + break; + case ' ': + indentation++; + break; + default: + // Should not happen as the offset of the edit is before the beginning of line + return; + } + } + + // Split the existing edit to keep the change before the beginning of the last line + // but change the indentation after. Note that at this stage, the add*Edit methods + // cannot be longer used as the edits are disabled + StringBuffer indentationBuffer = new StringBuffer(); + int currentIndentation = getCurrentIndentation(this.scanner.currentPosition); + if (currentIndentation > 0 && this.indentationLevel > 0) { + int col = this.column; + printIndentationIfNecessary(indentationBuffer); + this.column = col; + } + String replacement = currentEdit.replacement; + if (replacement.length() == 0) { + // previous edit was a delete, as we're sure to have a new line before + // the comment, then the edit needs to be either replaced entirely with + // the expected indentation + this.edits[this.editsIndex-1] = new OptimizedReplaceEdit(beginningOfLine, offset+length-beginningOfLine, indentationBuffer.toString()); + } else { + int idx = replacement.lastIndexOf(this.lineSeparator); + if (idx >= 0) { + // replace current edit if it contains a line separator + int start = idx + this.lsLength; + StringBuffer buffer = new StringBuffer(replacement.substring(0, start)); + buffer.append(indentationBuffer); + this.edits[this.editsIndex-1] = new OptimizedReplaceEdit(offset, length, buffer.toString()); + } + } + } + finally { + this.scanner.startPosition = scannerStartPosition; + this.scanner.eofPosition = scannerEofPosition; + this.scanner.currentPosition = scannerCurrentPosition; + this.scanner.currentCharacter = scannerCurrentChar; + } + } + + /* + * Print new lines characters when the edits are disabled. In this case, only + * the line separator is replaced if necessary, the other white spaces are untouched. + */ + private boolean printNewLinesCharacters(int offset, int length) { + boolean foundNewLine = false; + int scannerStartPosition = this.scanner.startPosition; + int scannerEofPosition = this.scanner.eofPosition; + int scannerCurrentPosition = this.scanner.currentPosition; + char scannerCurrentChar = this.scanner.currentCharacter; + this.scanner.resetTo(offset, offset+length-1); + try { + while (!this.scanner.atEnd()) { + int start = this.scanner.currentPosition; + char ch = (char) this.scanner.getNextChar(); + boolean needReplace = ch != this.firstLS; + switch (ch) { + case '\r': + if (this.scanner.atEnd()) break; + ch = (char) this.scanner.getNextChar(); + if (ch != '\n') break; + needReplace = needReplace || this.lsLength != 2; + //$FALL-THROUGH$ + case '\n': + if (needReplace) { + if (this.editsIndex == 0 || this.edits[this.editsIndex-1].offset != start) { + this.edits[this.editsIndex++] = new OptimizedReplaceEdit(start, this.scanner.currentPosition-start, this.lineSeparator); + } + } + foundNewLine = true; + break; + } + } + } + finally { + this.scanner.startPosition = scannerStartPosition; + this.scanner.eofPosition = scannerEofPosition; + this.scanner.currentPosition = scannerCurrentPosition; + this.scanner.currentCharacter = scannerCurrentChar; + } + return foundNewLine; + } + public void printNextToken(int expectedTokenType){ printNextToken(expectedTokenType, false); } @@ -4526,10 +4727,41 @@ this.formatter.lastLocalDeclarationSourceStart = location.lastLocalDeclarationSourceStart; } + /** + * @param compilationUnitSource + */ + public void resetScanner(char[] compilationUnitSource) { + this.scanner.setSource(compilationUnitSource); + this.scannerEndPosition = compilationUnitSource.length; + this.scanner.resetTo(0, this.scannerEndPosition - 1); + this.edits = new OptimizedReplaceEdit[INITIAL_SIZE]; + this.maxLines = this.lineEnds == null ? -1 : this.lineEnds.length - 1; + this.scanner.lineEnds = this.lineEnds; + this.scanner.linePtr = this.maxLines; + initFormatterCommentParser(); + } + private void resize() { System.arraycopy(this.edits, 0, (this.edits = new OptimizedReplaceEdit[this.editsIndex * 2]), 0, this.editsIndex); } + /* + * Look for the tags identified by the scanner to see whether some of them + * may change the status of the edition for the formatter. + */ + private void setEditsEnabled(int count, int previous) { + for (int i=previous; i= this.disablingTagsLength; + // do not return yet, as there may have several disabling/enabling + // tags in a comment, hence the last one will be the one really + // changing the formatter behavior... + } + } + } + } + void setIncludeComments(boolean on) { if (on) { this.formatComments |= CodeFormatter.F_INCLUDE_COMMENTS; #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.23 diff -u -r1.23 FormatterBugsTests.java --- src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java 23 Feb 2010 15:00:54 -0000 1.23 +++ src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java 2 Mar 2010 12:50:04 -0000 @@ -15,6 +15,7 @@ import junit.framework.Test; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.core.formatter.IndentManipulation; import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; @@ -66,6 +67,573 @@ } /** + * @bug 27079: [formatter] Tags for disabling/enabling code formatter (feature) + * @test Ensure that the formatter does not format code between specific javadoc comments + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=27079" + */ +public void testBug027079a() throws JavaModelException { + String source = + "public class X01 {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/* enable-formatter */\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + " /* disable-formatter */\n" + + " void foo() {\n" + + " // unformatted comment\n" + + " }\n" + + "\n" + + " /* enable-formatter */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079a1() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/* enable-formatter */\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/* enable-formatter */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079a2() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/** disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/** enable-formatter */\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "/** disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/** enable-formatter */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079a3() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "// disable-formatter\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "// enable-formatter\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "// disable-formatter\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "// enable-formatter\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079a4() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "// disable-formatter\n" + + "void foo( ) { \n" + + " // unformatted comment \n" + + "}\n" + + "// enable-formatter \n" + + "void bar( ) { \n" + + " // formatted comment \n" + + " /* disable-formatter *//* unformatted comment *//* enable-formatter */\n" + + "}\n" + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "// disable-formatter\n" + + "void foo( ) { \n" + + " // unformatted comment \n" + + "}\n" + + "// enable-formatter \n" + + " void bar() {\n" + + " // formatted comment\n" + + " /* disable-formatter *//* unformatted comment *//* enable-formatter */\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079b() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X02 {\n" + + "void foo() {\n" + + "/* disable-formatter */\n" + + " /* unformatted comment */\n" + + " String test1= \"this\"+\n" + + " \"is\"+\n" + + " \"a specific\"+\n" + + " \"line wrapping \";\n" + + "\n" + + "/* enable-formatter */\n" + + " /* formatted comment */\n" + + " String test2= \"this\"+\n" + + " \"is\"+\n" + + " \"a specific\"+\n" + + " \"line wrapping \";\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X02 {\n" + + " void foo() {\n" + + "/* disable-formatter */\n" + + " /* unformatted comment */\n" + + " String test1= \"this\"+\n" + + " \"is\"+\n" + + " \"a specific\"+\n" + + " \"line wrapping \";\n" + + "\n" + + "/* enable-formatter */\n" + + " /* formatted comment */\n" + + " String test2 = \"this\" + \"is\" + \"a specific\" + \"line wrapping \";\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079c() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X03 {\n" + + "void foo() {\n" + + "/* disable-formatter */\n" + + " bar(\n" + + " /** unformatted comment */\n" + + " \"this\" ,\n" + + " \"is\",\n" + + " \"a specific\",\n" + + " \"line wrapping \"\n" + + " );\n" + + "\n" + + "/* enable-formatter */\n" + + " bar(\n" + + " /** formatted comment */\n" + + " \"this\" ,\n" + + " \"is\",\n" + + " \"a specific\",\n" + + " \"line wrapping \"\n" + + " );\n" + + "}\n" + + "void bar(String... str) {}\n" + + "}\n"; + formatSource(source, + "public class X03 {\n" + + " void foo() {\n" + + "/* disable-formatter */\n" + + " bar(\n" + + " /** unformatted comment */\n" + + " \"this\" ,\n" + + " \"is\",\n" + + " \"a specific\",\n" + + " \"line wrapping \"\n" + + " );\n" + + "\n" + + "/* enable-formatter */\n" + + " bar(\n" + + " /** formatted comment */\n" + + " \"this\", \"is\", \"a specific\", \"line wrapping \");\n" + + " }\n" + + "\n" + + " void bar(String... str) {\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079d() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X03b {\n" + + "void foo() {\n" + + " bar(\n" + + "// disable-formatter\n" + + " /** unformatted comment */\n" + + " \"this\" ,\n" + + " \"is\",\n" + + " \"a specific\",\n" + + " \"line wrapping \"\n" + + "// enable-formatter\n" + + " );\n" + + " bar(\n" + + " /** formatted comment */\n" + + " \"this\" ,\n" + + " \"is\",\n" + + " \"a specific\",\n" + + " \"line wrapping \"\n" + + " );\n" + + "}\n" + + "void bar(String... str) {}\n" + + "}\n"; + formatSource(source, + "public class X03b {\n" + + " void foo() {\n" + + " bar(\n" + + "// disable-formatter\n" + + " /** unformatted comment */\n" + + " \"this\" ,\n" + + " \"is\",\n" + + " \"a specific\",\n" + + " \"line wrapping \"\n" + + "// enable-formatter\n" + + " );\n" + + " bar(\n" + + " /** formatted comment */\n" + + " \"this\", \"is\", \"a specific\", \"line wrapping \");\n" + + " }\n" + + "\n" + + " void bar(String... str) {\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079e() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\r\n" + + "\r\n" + + "/* disable-formatter */\r\n" + + "void foo( ) { \r\n" + + " // unformatted comment \r\n" + + "}\r\n" + + "/* enable-formatter */\r\n" + + "void bar( ) { \r\n" + + " // formatted comment \r\n" + + "}\r\n" + + "}\r\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment \n" + + "}\n" + + "/* enable-formatter */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n", + CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, + 0 /* indentation level */, + 0 /* offset */, + -1 /* length (all) */, + "\n", + true/*repeat*/); +} +public void testBug027079f() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment \n" + + "}\n" + + "/* enable-formatter */\n" + + "void bar( ) { \n" + + " // formatted comment \n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\r\n" + + "\r\n" + + "/* disable-formatter */\r\n" + + "void foo( ) { \r\n" + + " // unformatted comment \r\n" + + "}\r\n" + + "/* enable-formatter */\r\n" + + " void bar() {\r\n" + + " // formatted comment\r\n" + + " }\r\n" + + "}\r\n", + CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, + 0 /* indentation level */, + 0 /* offset */, + -1 /* length (all) */, + "\r\n", + true/*repeat*/); +} +public void testBug027079g() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\r\n" + + "\r\n" + + "/* disable-formatter */\r\n" + + "void foo( ) { \r\n" + + " // unformatted comment \r\n" + + "}\r\n" + + "/* enable-formatter */\r\n" + + "void bar( ) { \r\n" + + " // formatted comment \r\n" + + "}\r\n" + + "}\r\n"; + formatSource(source, + "public class X01 {\r\n" + + "\r\n" + + "/* disable-formatter */\r\n" + + "void foo( ) { \r\n" + + " // unformatted comment \r\n" + + "}\r\n" + + "/* enable-formatter */\r\n" + + " void bar() {\r\n" + + " // formatted comment\r\n" + + " }\r\n" + + "}\r\n", + CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, + 0 /* indentation level */, + 0 /* offset */, + -1 /* length (all) */, + "\r\n", + true/*repeat*/); +} +public void testBug027079h() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "disable-formatter".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "enable-formatter".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment \n" + + "}\n" + + "/* enable-formatter */\n" + + "void bar( ) { \n" + + " // formatted comment \n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "/* disable-formatter */\n" + + "void foo( ) { \n" + + " // unformatted comment \n" + + "}\n" + + "/* enable-formatter */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n", + CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, + 0 /* indentation level */, + 0 /* offset */, + -1 /* length (all) */, + "\n", + true/*repeat*/); +} +public void testBug027079i() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "format: off".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "format: on".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/* format: off */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/* format: on */\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "/* format: off */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/* format: on */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079j() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "format: off".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "format: on".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "// format: off\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "// format: on\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "// format: off\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "// format: on\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079k() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { "format: off".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { "format: on".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/** format: off */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/** format: on */\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "/** format: off */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "/** format: on */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079l() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { " format: off ".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { " format: on ".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/* format: off */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "// format: on \n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + "/* format: off */\n" + + "void foo( ) { \n" + + " // unformatted comment\n" + + "}\n" + + "// format: on \n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} +public void testBug027079m() throws JavaModelException { + this.formatterPrefs.disabling_tags = new char[][] { " format: off ".toCharArray() }; + this.formatterPrefs.enabling_tags = new char[][] { " format: on ".toCharArray() }; + String source = + "public class X01 {\n" + + "\n" + + "/* format: off */\n" + + "void foo( ) { \n" + + " // formatted comment\n" + + "}\n" + + "/* format: on */\n" + + "void bar( ) { \n" + + " // formatted comment\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class X01 {\n" + + "\n" + + " /* format: off */\n" + + " void foo() {\n" + + " // formatted comment\n" + + " }\n" + + "\n" + + " /* format: on */\n" + + " void bar() {\n" + + " // formatted comment\n" + + " }\n" + + "}\n" + ); +} + +/** * @bug 198074: [formatter] the code formatter doesn't respect my new lines * @test Ensure that the formatter keep line breaks wrapping set by users in the code * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=198074" Index: src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsTests.java,v retrieving revision 1.28 diff -u -r1.28 FormatterCommentsTests.java --- src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsTests.java 27 Aug 2009 15:26:53 -0000 1.28 +++ src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsTests.java 2 Mar 2010 12:50:05 -0000 @@ -258,7 +258,7 @@ this.workingCopies = new ICompilationUnit[1]; this.workingCopies[0] = getCompilationUnit(JAVA_PROJECT.getElementName() , "", "test."+packageName, unitName); //$NON-NLS-1$ //$NON-NLS-2$ String outputSource = getOutputSource(this.workingCopies[0]); - formatSource(this.workingCopies[0].getSource(), outputSource, kind, indentationLevel, checkNull, offset, length, lineSeparator, true); + formatSource(this.workingCopies[0].getSource(), outputSource, kind, indentationLevel, offset, length, lineSeparator, true); } /** Index: src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java,v retrieving revision 1.258 diff -u -r1.258 FormatterRegressionTests.java --- src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java 23 Feb 2010 10:56:11 -0000 1.258 +++ src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java 2 Mar 2010 12:50:12 -0000 @@ -220,6 +220,11 @@ assertSourceEquals("Different number of length", Util.convertToIndependantLineDelimiter(expectedContents), actualContents); } + void assertLineEquals(String actualContents, String originalSource, String expectedContents) { + String outputSource = expectedContents == null ? originalSource : expectedContents; + assertLineEquals(actualContents, originalSource, outputSource, false /* do not check null */); + } + DefaultCodeFormatter codeFormatter() { if (this.formatterOptions == null) { this.formatterOptions = JAVA_PROJECT.getOptions(true); @@ -227,11 +232,6 @@ DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(this.formatterPrefs, this.formatterOptions); return codeFormatter; } - - void assertLineEquals(String actualContents, String originalSource, String expectedContents) { - String outputSource = expectedContents == null ? originalSource : expectedContents; - assertLineEquals(actualContents, originalSource, outputSource, false /* do not check null */); - } void formatSource(String source) { // expect unchanged source after formatting @@ -279,11 +279,11 @@ } assertLineEquals(result, newSource, formattedOutput); } else { - formatSource(source, formattedOutput, kind, indentationLevel, false, 0, -1, null, repeat); + formatSource(source, formattedOutput, kind, indentationLevel, 0, -1, null, repeat); } } - void formatSource(String source, String formattedOutput, int kind, int indentationLevel, boolean checkNull, int offset, int length, String lineSeparator, boolean repeat) { + void formatSource(String source, String formattedOutput, int kind, int indentationLevel, int offset, int length, String lineSeparator, boolean repeat) { DefaultCodeFormatter codeFormatter = codeFormatter(); String result; if (length == -1) { @@ -291,7 +291,14 @@ } else { result = runFormatter(codeFormatter, source, kind, indentationLevel, offset, length, lineSeparator, repeat); } - assertLineEquals(result, source, formattedOutput); + if (lineSeparator == null) { + assertLineEquals(result, source, formattedOutput); + } else { + // Do not convert line delimiter while comparing result when a specific one is specified + assertNotNull("Error(s) occured while formatting", result); + String outputSource = formattedOutput == null ? source : formattedOutput; + assertSourceEquals("Different number of length", outputSource, result, false/*do not convert line delimiter*/); + } } Index: src/org/eclipse/jdt/core/tests/formatter/comment/SingleLineTestCase.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/comment/SingleLineTestCase.java,v retrieving revision 1.10 diff -u -r1.10 SingleLineTestCase.java --- src/org/eclipse/jdt/core/tests/formatter/comment/SingleLineTestCase.java 22 Feb 2010 11:01:33 -0000 1.10 +++ src/org/eclipse/jdt/core/tests/formatter/comment/SingleLineTestCase.java 2 Mar 2010 12:50:12 -0000 @@ -48,7 +48,7 @@ setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$ setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE); setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE); - String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + DELIMITER + PREFIX + "test"; + String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + "//" + DELIMITER + PREFIX + "test"; assertEquals(expected, testFormat("//test\t\ttest" + DELIMITER + PREFIX + DELIMITER + "//\t\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ } @@ -192,10 +192,10 @@ public void testMultipleComments2() { setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "12"); //$NON-NLS-1$ String expected = "// test test" + DELIMITER + - "// test" + DELIMITER + - "// " + DELIMITER + - "// test test" + DELIMITER + - "// test test"; + "// test" + DELIMITER + + "//" + DELIMITER + + "// test test" + DELIMITER + + "// test test"; assertEquals(expected, testFormat("//test test\ttest" + DELIMITER + PREFIX + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ } Index: src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java,v retrieving revision 1.237 diff -u -r1.237 AbstractJavaModelTests.java --- src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 17 Feb 2010 15:05:54 -0000 1.237 +++ src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 2 Mar 2010 12:50:13 -0000 @@ -725,11 +725,21 @@ * The line separators in 'actual' are converted to '\n' before the comparison. */ protected void assertSourceEquals(String message, String expected, String actual) { + assertSourceEquals(message, expected, actual, true/*convert line delimiter*/); + } + /* + * Asserts that the given actual source is equal to the expected one. + * Note that if the line separators in 'actual' are converted to '\n' before the comparison, + * 'expected' is assumed to have the same '\n' line separator. + */ + protected void assertSourceEquals(String message, String expected, String actual, boolean convert) { if (actual == null) { assertEquals(message, expected, null); return; } - actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(actual); + if (convert) { + actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(actual); + } if (!actual.equals(expected)) { System.out.println("Expected source in "+getName()+" should be:"); System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(actual.toString(), 2));