### 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.214 diff -u -r1.214 Scribe.java --- formatter/org/eclipse/jdt/internal/formatter/Scribe.java 12 Aug 2010 07:12:18 -0000 1.214 +++ formatter/org/eclipse/jdt/internal/formatter/Scribe.java 12 Aug 2010 10:06:14 -0000 @@ -108,6 +108,7 @@ /** disabling */ boolean editsEnabled; boolean useTags; + int tagsKind; /* Comments formatting */ private static final int INCLUDE_BLOCK_COMMENTS = CodeFormatter.F_INCLUDE_COMMENTS | CodeFormatter.K_MULTI_LINE_COMMENT; @@ -1419,6 +1420,7 @@ private void initializeScanner(long sourceLevel, DefaultCodeFormatterOptions preferences) { this.useTags = preferences.use_tags; + this.tagsKind = 0; char[][] taskTags = null; if (this.useTags) { this.disablingTag = preferences.disabling_tag; @@ -1433,6 +1435,23 @@ taskTags = new char[][] { this.disablingTag, this.enablingTag }; } } + if (taskTags != null) { + loop: for (int i=0,length=taskTags.length; i 2 && taskTags[i][0] == '/') { + switch (taskTags[i][1]) { + case '/': + this.tagsKind = TerminalTokens.TokenNameCOMMENT_LINE; + break loop; + case '*': + if (taskTags[i][2] != '*') { + this.tagsKind = TerminalTokens.TokenNameCOMMENT_BLOCK; + break loop; + } + break; + } + } + } + } this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, taskTags, null/*taskPriorities*/, true/*taskCaseSensitive*/); this.editsEnabled = true; } @@ -2368,11 +2387,11 @@ int lines = 0; while ((this.currentToken = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { int foundTaskCount = this.scanner.foundTaskCount; + int tokenStartPosition = this.scanner.getCurrentTokenStartPosition(); + int tokenEndPosition = this.scanner.getCurrentTokenEndPosition(); switch(this.currentToken) { case TerminalTokens.TokenNameWHITESPACE : char[] whiteSpaces = this.scanner.getCurrentTokenSource(); - int whitespacesStartPosition = this.scanner.getCurrentTokenStartPosition(); - int whitespacesEndPosition = this.scanner.getCurrentTokenEndPosition(); lines = 0; for (int i = 0, max = whiteSpaces.length; i < max; i++) { switch(whiteSpaces[i]) { @@ -2445,9 +2464,9 @@ // if a line comment is consumed, no other comment can be on the same line after if (hasLineComment) { if (lines >= 1) { - currentTokenStartPosition = whitespacesStartPosition; + currentTokenStartPosition = tokenStartPosition; preserveEmptyLines(lines, currentTokenStartPosition); - addDeleteEdit(currentTokenStartPosition, whitespacesEndPosition); + addDeleteEdit(currentTokenStartPosition, tokenEndPosition); this.scanner.resetTo(this.scanner.currentPosition, this.scannerEndPosition - 1); return; } @@ -2457,7 +2476,7 @@ // if one or several new lines are consumed, following comments cannot be considered as trailing ones if (lines >= 1) { if (hasComment) { - this.printNewLine(whitespacesStartPosition); + this.printNewLine(tokenStartPosition); } this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1); return; @@ -2465,37 +2484,48 @@ // delete consumed white spaces hasWhitespaces = true; currentTokenStartPosition = this.scanner.currentPosition; - addDeleteEdit(whitespacesStartPosition, whitespacesEndPosition); + addDeleteEdit(tokenStartPosition, tokenEndPosition); } else { if (lines == 0) { hasWhitespaces = true; - addDeleteEdit(whitespacesStartPosition, whitespacesEndPosition); + addDeleteEdit(tokenStartPosition, tokenEndPosition); } else if (hasLineComment) { - currentTokenStartPosition = whitespacesStartPosition; + currentTokenStartPosition = tokenStartPosition; preserveEmptyLines(lines, currentTokenStartPosition); - addDeleteEdit(currentTokenStartPosition, whitespacesEndPosition); + addDeleteEdit(currentTokenStartPosition, tokenEndPosition); } else if (hasComment) { if (lines == 1) { - this.printNewLine(whitespacesStartPosition); + this.printNewLine(tokenStartPosition); } else { - preserveEmptyLines(lines - 1, whitespacesStartPosition); + preserveEmptyLines(lines - 1, tokenStartPosition); } - addDeleteEdit(whitespacesStartPosition, whitespacesEndPosition); + addDeleteEdit(tokenStartPosition, tokenEndPosition); } else if (lines != 0 && (!this.formatter.preferences.join_wrapped_lines || this.formatter.preferences.number_of_empty_lines_to_preserve != 0 || this.blank_lines_between_import_groups > 0)) { - addReplaceEdit(whitespacesStartPosition, whitespacesEndPosition, getPreserveEmptyLines(lines-1)); + addReplaceEdit(tokenStartPosition, tokenEndPosition, getPreserveEmptyLines(lines-1)); } else { - addDeleteEdit(whitespacesStartPosition, whitespacesEndPosition); + addDeleteEdit(tokenStartPosition, tokenEndPosition); } } currentTokenStartPosition = this.scanner.currentPosition; break; case TerminalTokens.TokenNameCOMMENT_LINE : - if (this.useTags && this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); - if (!this.editsEnabled && this.editsIndex > 1) { - OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; - if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { - printNewLinesBeforeDisablingComment(); + tokenEndPosition = -this.scanner.commentStops[this.scanner.commentPtr]; + if (this.useTags && this.editsEnabled) { + boolean turnOff = false; + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + turnOff = true; + } else if (this.tagsKind == this.currentToken + && CharOperation.equals(this.disablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition)) { + this.editsEnabled = false; + turnOff = true; + } + if (turnOff) { + if (!this.editsEnabled && this.editsIndex > 1) { + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { + printNewLinesBeforeDisablingComment(); + } } } } @@ -2514,17 +2544,31 @@ currentTokenStartPosition = this.scanner.currentPosition; hasLineComment = true; lines = 0; - if (this.useTags && !this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); + if (this.useTags && !this.editsEnabled) { + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + } else if (this.tagsKind == this.currentToken) { + this.editsEnabled = CharOperation.equals(this.enablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition); + } } break; case TerminalTokens.TokenNameCOMMENT_BLOCK : - if (this.useTags && this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); - if (!this.editsEnabled && this.editsIndex > 1) { - OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; - if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { - printNewLinesBeforeDisablingComment(); + if (this.useTags && this.editsEnabled) { + boolean turnOff = false; + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + turnOff = true; + } else if (this.tagsKind == this.currentToken + && CharOperation.equals(this.disablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition+1)) { + this.editsEnabled = false; + turnOff = true; + } + if (turnOff) { + if (!this.editsEnabled && this.editsIndex > 1) { + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { + printNewLinesBeforeDisablingComment(); + } } } } @@ -2550,8 +2594,12 @@ hasLineComment = false; hasComment = true; lines = 0; - if (this.useTags && !this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); + if (this.useTags && !this.editsEnabled) { + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + } else if (this.tagsKind == this.currentToken) { + this.editsEnabled = CharOperation.equals(this.enablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition+1); + } } break; case TerminalTokens.TokenNameCOMMENT_JAVADOC : @@ -4430,6 +4478,8 @@ boolean hasModifiers = false; while ((this.currentToken = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) { int foundTaskCount = this.scanner.foundTaskCount; + int tokenStartPosition = this.scanner.getCurrentTokenStartPosition(); + int tokenEndPosition = this.scanner.getCurrentTokenEndPosition(); switch(this.currentToken) { case TerminalTokens.TokenNamepublic : case TerminalTokens.TokenNameprotected : @@ -4494,35 +4544,64 @@ break; case TerminalTokens.TokenNameCOMMENT_BLOCK : case TerminalTokens.TokenNameCOMMENT_JAVADOC : - if (this.useTags && this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); - if (!this.editsEnabled && this.editsIndex > 1) { - OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; - if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { - printNewLinesBeforeDisablingComment(); + if (this.useTags && this.editsEnabled) { + boolean turnOff = false; + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + turnOff = true; + } else if (this.tagsKind == this.currentToken + && CharOperation.equals(this.disablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition+1)) { + this.editsEnabled = false; + turnOff = true; + } + if (turnOff) { + if (!this.editsEnabled && this.editsIndex > 1) { + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { + printNewLinesBeforeDisablingComment(); + } } } } printBlockComment(this.currentToken == TerminalTokens.TokenNameCOMMENT_JAVADOC); - if (this.useTags && !this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); + if (this.useTags && !this.editsEnabled) { + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + } else if (this.tagsKind == this.currentToken) { + this.editsEnabled = CharOperation.equals(this.enablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition+1); + } } currentTokenStartPosition = this.scanner.currentPosition; hasComment = true; break; case TerminalTokens.TokenNameCOMMENT_LINE : - if (this.useTags && this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); - if (!this.editsEnabled && this.editsIndex > 1) { - OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; - if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { - printNewLinesBeforeDisablingComment(); + tokenEndPosition = -this.scanner.commentStops[this.scanner.commentPtr]; + if (this.useTags && this.editsEnabled) { + boolean turnOff = false; + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + turnOff = true; + } else if (this.tagsKind == this.currentToken + && CharOperation.equals(this.disablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition)) { + this.editsEnabled = false; + turnOff = true; + } + if (turnOff) { + if (!this.editsEnabled && this.editsIndex > 1) { + OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1]; + if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) { + printNewLinesBeforeDisablingComment(); + } } } } printLineComment(); - if (this.useTags && !this.editsEnabled && foundTaskCount > 0) { - setEditsEnabled(foundTaskCount); + if (this.useTags && !this.editsEnabled) { + if (foundTaskCount > 0) { + setEditsEnabled(foundTaskCount); + } else if (this.tagsKind == this.currentToken) { + this.editsEnabled = CharOperation.equals(this.enablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition); + } } currentTokenStartPosition = this.scanner.currentPosition; break; #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.32 diff -u -r1.32 FormatterBugsTests.java --- src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java 12 Aug 2010 07:12:14 -0000 1.32 +++ src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java 12 Aug 2010 10:06:18 -0000 @@ -6046,6 +6046,350 @@ } /** + * @bug 311578: [formatter] Enable/disable tag detection should include comment start/end tokens + * @test Ensure that the formatter now accepts tags with comment start/end tokens + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=311578" + */ +public void testBug311578a() throws JavaModelException { + this.formatterPrefs.use_tags = true; + this.formatterPrefs.disabling_tag = "//J-".toCharArray(); + this.formatterPrefs.enabling_tag = "//J+".toCharArray(); + String source = + "package a;\n" + + "public class Bug {\n" + + "int a = - 1 + 42;\n" + + "\n" + + "//J-\n" + + "int b = - 1 + 42;\n" + + "//J+\n" + + "\n" + + "char x;\n" + + "\n" + + "////J-\n" + + "int c = - 1 + 42;\n" + + "////J+\n" + + "\n" + + "char y;\n" + + "\n" + + "/* J- */\n" + + "int d = - 1 + 42;\n" + + "/* J+ */\n" + + "\n" + + "char z;\n" + + "\n" + + "/* //J- */\n" + + "int e = - 1 + 42;\n" + + "/* //J+ */\n" + + "\n" + + "/** J-1 blabla */\n" + + "char t;\n" + + "}\n"; + formatSource(source, + "package a;\n" + + "\n" + + "public class Bug {\n" + + " int a = -1 + 42;\n" + + "\n" + + "//J-\n" + + "int b = - 1 + 42;\n" + + "//J+\n" + + "\n" + + " char x;\n" + + "\n" + + "////J-\n" + + "int c = - 1 + 42;\n" + + "////J+\n" + + "\n" + + " char y;\n" + + "\n" + + " /* J- */\n" + + " int d = -1 + 42;\n" + + " /* J+ */\n" + + "\n" + + " char z;\n" + + "\n" + + "/* //J- */\n" + + "int e = - 1 + 42;\n" + + "/* //J+ */\n" + + "\n" + + " /** J-1 blabla */\n" + + " char t;\n" + + "}\n" + ); +} +public void testBug311578b() throws JavaModelException { + this.formatterPrefs.use_tags = true; + this.formatterPrefs.disabling_tag = "/* J- */".toCharArray(); + this.formatterPrefs.enabling_tag = "/* J+ */".toCharArray(); + String source = + "package a;\n" + + "public class Bug {\n" + + "int a = - 1 + 42;\n" + + "\n" + + "//J-\n" + + "int b = - 1 + 42;\n" + + "//J+\n" + + "\n" + + "char x;\n" + + "\n" + + "////J-\n" + + "int c = - 1 + 42;\n" + + "////J+\n" + + "\n" + + "char y;\n" + + "\n" + + "/* J- */\n" + + "int d = - 1 + 42;\n" + + "/* J+ */\n" + + "\n" + + "char z;\n" + + "\n" + + "/* //J- */\n" + + "int e = - 1 + 42;\n" + + "/* //J+ */\n" + + "\n" + + "/** J-1 blabla */\n" + + "char t;\n" + + "}\n"; + formatSource(source, + "package a;\n" + + "\n" + + "public class Bug {\n" + + " int a = -1 + 42;\n" + + "\n" + + " // J-\n" + + " int b = -1 + 42;\n" + + " // J+\n" + + "\n" + + " char x;\n" + + "\n" + + " // //J-\n" + + " int c = -1 + 42;\n" + + " // //J+\n" + + "\n" + + " char y;\n" + + "\n" + + "/* J- */\n" + + "int d = - 1 + 42;\n" + + "/* J+ */\n" + + "\n" + + " char z;\n" + + "\n" + + " /* //J- */\n" + + " int e = -1 + 42;\n" + + " /* //J+ */\n" + + "\n" + + " /** J-1 blabla */\n" + + " char t;\n" + + "}\n" + ); +} +public void testBug311578c() throws JavaModelException { + this.formatterPrefs = null; + this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, DefaultCodeFormatterConstants.TRUE); + this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, "//F--"); + this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, "//F++"); + String source = + "package a;\n" + + "public class Bug {\n" + + "int a = - 1 + 42;\n" + + "\n" + + "//F--\n" + + "int b = - 1 + 42;\n" + + "//F++\n" + + "\n" + + "char x;\n" + + "\n" + + "////F--\n" + + "int c = - 1 + 42;\n" + + "////F++\n" + + "\n" + + "char y;\n" + + "\n" + + "/* F-- */\n" + + "int d = - 1 + 42;\n" + + "/* F++ */\n" + + "\n" + + "char z;\n" + + "\n" + + "/* //F-- */\n" + + "int e = - 1 + 42;\n" + + "/* //F++ */\n" + + "\n" + + "/** F--1 blabla */\n" + + "char t;\n" + + "}\n"; + formatSource(source, + "package a;\n" + + "\n" + + "public class Bug {\n" + + " int a = -1 + 42;\n" + + "\n" + + "//F--\n" + + "int b = - 1 + 42;\n" + + "//F++\n" + + "\n" + + " char x;\n" + + "\n" + + "////F--\n" + + "int c = - 1 + 42;\n" + + "////F++\n" + + "\n" + + " char y;\n" + + "\n" + + " /* F-- */\n" + + " int d = -1 + 42;\n" + + " /* F++ */\n" + + "\n" + + " char z;\n" + + "\n" + + "/* //F-- */\n" + + "int e = - 1 + 42;\n" + + "/* //F++ */\n" + + "\n" + + " /** F--1 blabla */\n" + + " char t;\n" + + "}\n" + ); +} +public void testBug311578d() throws JavaModelException { + this.formatterPrefs = null; + this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, DefaultCodeFormatterConstants.TRUE); + this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, "/*F--*/"); + this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, "/*F++*/"); + String source = + "package a;\n" + + "public class Bug {\n" + + "int a = - 1 + 42;\n" + + "\n" + + "//F--\n" + + "int b = - 1 + 42;\n" + + "//F++\n" + + "\n" + + "char x;\n" + + "\n" + + "////F--\n" + + "int c = - 1 + 42;\n" + + "////F++\n" + + "\n" + + "char y;\n" + + "\n" + + "/* F-- */\n" + + "int d = - 1 + 42;\n" + + "/* F++ */\n" + + "\n" + + "char y2;\n" + + "\n" + + "/*F--*/\n" + + "int d2 = - 1 + 42;\n" + + "/*F++*/\n" + + "\n" + + "char z;\n" + + "\n" + + "/* //F-- */\n" + + "int e = - 1 + 42;\n" + + "/* //F++ */\n" + + "\n" + + "/** F--1 blabla */\n" + + "char t;\n" + + "}\n"; + formatSource(source, + "package a;\n" + + "\n" + + "public class Bug {\n" + + " int a = -1 + 42;\n" + + "\n" + + " // F--\n" + + " int b = -1 + 42;\n" + + " // F++\n" + + "\n" + + " char x;\n" + + "\n" + + " // //F--\n" + + " int c = -1 + 42;\n" + + " // //F++\n" + + "\n" + + " char y;\n" + + "\n" + + " /* F-- */\n" + + " int d = -1 + 42;\n" + + " /* F++ */\n" + + "\n" + + " char y2;\n" + + "\n" + + "/*F--*/\n" + + "int d2 = - 1 + 42;\n" + + "/*F++*/\n" + + "\n" + + " char z;\n" + + "\n" + + " /* //F-- */\n" + + " int e = -1 + 42;\n" + + " /* //F++ */\n" + + "\n" + + " /** F--1 blabla */\n" + + " char t;\n" + + "}\n" + ); +} +public void testBug311578_320754a() throws JavaModelException { + this.formatterPrefs.use_tags = true; + this.formatterPrefs.disabling_tag = "//J-".toCharArray(); + this.formatterPrefs.enabling_tag = "//J+".toCharArray(); + String source = + "//J-\n" + + "@MyAnnot (\n" + + " testAttribute = {\"test1\", \"test2\", \"test3\"}\n" + + ")\n" + + "//J+\n" + + "public class X\n" + + "{\n" + + " public void foo()\n" + + " {\n" + + " }\n" + + "}\n"; + formatSource(source, + "//J-\n" + + "@MyAnnot (\n" + + " testAttribute = {\"test1\", \"test2\", \"test3\"}\n" + + ")\n" + + "//J+\n" + + "public class X {\n" + + " public void foo() {\n" + + " }\n" + + "}\n" + ); +} +public void testBug311578_320754b() throws JavaModelException { + this.formatterPrefs.use_tags = true; + this.formatterPrefs.disabling_tag = "/*J-*/".toCharArray(); + this.formatterPrefs.enabling_tag = "/*J+*/".toCharArray(); + String source = + "/*J-*/\n" + + "@MyAnnot (\n" + + " testAttribute = {\"test1\", \"test2\", \"test3\"}\n" + + ")\n" + + "/*J+*/\n" + + "public class X\n" + + "{\n" + + " public void foo()\n" + + " {\n" + + " }\n" + + "}\n"; + formatSource(source, + "/*J-*/\n" + + "@MyAnnot (\n" + + " testAttribute = {\"test1\", \"test2\", \"test3\"}\n" + + ")\n" + + "/*J+*/\n" + + "public class X {\n" + + " public void foo() {\n" + + " }\n" + + "}\n" + ); +} + +/** * @bug 311582: [formatter] Master switch to enable/disable on/off tags * @test Ensure that the formatter does not take care of formatting tags by default * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=311582" @@ -6693,9 +7037,8 @@ } /** - * @bug 320754: [formatter] Add preference for improved lines wrapping in nested method calls - * @test Ensure that the formatter keep previous eclipse versions behavior when - * the "Try to keep nested expressions on one line" preference is set. + * @bug 320754: [formatter] formatter:off/on tags does not work correctly + * @test Ensure disabling/enabling tags work properly around annotations * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=320754" */ public void testBug320754_00() throws JavaModelException {