### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model 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.237 diff -u -r1.237 FormatterRegressionTests.java --- src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java 14 Oct 2008 16:26:39 -0000 1.237 +++ src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java 3 Dec 2008 09:09:57 -0000 @@ -10568,4 +10568,174 @@ DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences); runTest(codeFormatter, "test719", "A.java", CodeFormatter.K_COMPILATION_UNIT, false);//$NON-NLS-1$ //$NON-NLS-2$ } + +/** + * @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" + */ +public void testBug198074() throws JavaModelException { + this.formatterPrefs.preserve_existing_line_breaks = true; + String source = + "public class Test {\n" + + "\n" + + " void foo() {\n" + + "String x = \"select x \"\n" + + " + \"from y \"\n" + + " + \"where z=a\";\n" + + " }\n" + + "}\n"; + formatSource(source, + "public class Test {\n" + + "\n" + + " void foo() {\n" + + " String x = \"select x \"\n" + + " + \"from y \"\n" + + " + \"where z=a\";\n" + + " }\n" + + "}\n" + ); +} +// another test case put in bug's comment 1 +public void testBug198074_c1() throws JavaModelException { + this.formatterPrefs.preserve_existing_line_breaks = true; + String source = + "public class Test {\n" + + "\n" + + " String foo(boolean enabled) {\n" + + "if (enabled)\n" + + "{\n" + + " // we need x\n" + + " // we need a select\n" + + " return \"select x \"\n" + + " + \"from X\";}\n" + + " return null;}\n" + + "}\n"; + formatSource(source, + "public class Test {\n" + + "\n" + + " String foo(boolean enabled) {\n" + + " if (enabled) {\n" + + " // we need x\n" + + " // we need a select\n" + + " return \"select x \"\n" + + " + \"from X\";\n" + + " }\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +// another test case put in bug's comment 3 +public void testBug198074_c3() throws JavaModelException { + this.formatterPrefs.preserve_existing_line_breaks = true; + String source = + "public class Test {\n" + + "\n" + + "public String toString() {\n" + + " return \"YAD01: \"\n" + + " + \" nommbr=\'\"+getName()+\"\'\"\n" + + " + \" nomgrp=\'\"+getService().getArgtbl()+\"\'\"\n" + + " + \" typmbr=\'\"+getMemberType().getArgument()+\"\'\"\n" + + " + \" srcpat=\'\"+getPhysicalPath()+\"\'\"\n" + + " + \" nommdl=\'\"+getModel()+\"\'\"\n" + + " ;\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class Test {\n" + + "\n" + + " public String toString() {\n" + + " return \"YAD01: \"\n" + + " + \" nommbr=\'\" + getName() + \"\'\"\n" + + " + \" nomgrp=\'\" + getService().getArgtbl() + \"\'\"\n" + + " + \" typmbr=\'\" + getMemberType().getArgument() + \"\'\"\n" + + " + \" srcpat=\'\" + getPhysicalPath() + \"\'\"\n" + + " + \" nommdl=\'\" + getModel() + \"\'\";\n" + + " }\n" + + "}\n" + ); +} +// duplicate bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=201022 +public void testBug201022() throws JavaModelException { + this.formatterPrefs.preserve_existing_line_breaks = true; + String source = + "public class Test {\n" + + "\n" + + " void foo() {\n" + + " String sQuery =\n" + + " \"select * \" +\n" + + " \"from person p, address a \" +\n" + + " \"where p.person_id = a.person_id \" +\n" + + " \"and p.person_id = ?\";\n" + + " }\n" + + "}\n"; + formatSource(source, + "public class Test {\n" + + "\n" + + " void foo() {\n" + + " String sQuery =\n" + + " \"select * \" +\n" + + " \"from person p, address a \" +\n" + + " \"where p.person_id = a.person_id \" +\n" + + " \"and p.person_id = ?\";\n" + + " }\n" + + "}\n" + ); +} +// duplicate bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=208541 +public void testBug208541() throws JavaModelException { + this.formatterPrefs.preserve_existing_line_breaks = true; + String source = + "public class MyTest {\n" + + "\n" + + " public void testname() throws Exception {\n" + + " int i = 5, j = 6, k = 7;\n" + + " if (new String().length() != 0 &&\n" + + " (i < j && j < k)) {\n" + + "\n" + + " }\n" + + " }\n" + + "}\n"; + formatSource(source, + "public class MyTest {\n" + + "\n" + + " public void testname() throws Exception {\n" + + " int i = 5, j = 6, k = 7;\n" + + " if (new String().length() != 0 &&\n" + + " (i < j && j < k)) {\n" + + "\n" + + " }\n" + + " }\n" + + "}\n" + ); +} +// duplicate bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=213700 +public void testBug213700() throws JavaModelException { + this.formatterPrefs.preserve_existing_line_breaks = true; + String source = + "public class Test {\n" + + "\n" + + " void foo() {\n" + + " int a=0, b=0, c=0, d=0, e=0, f=0, g=0, h=0, i=0;\n" + + "if( (a == b && b == c) &&\n" + + " (d == e) &&\n" + + " (f == g && h == i) \n" + + " ){\n" + + "}\n" + + " }\n" + + "}\n"; + formatSource(source, + "public class Test {\n" + + "\n" + + " void foo() {\n" + + " int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0;\n" + + " if ((a == b && b == c) &&\n" + + " (d == e) &&\n" + + " (f == g && h == i)) {\n" + + " }\n" + + " }\n" + + "}\n" + ); +} } #P org.eclipse.jdt.core Index: formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java,v retrieving revision 1.94 diff -u -r1.94 DefaultCodeFormatterConstants.java --- formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java 11 Sep 2008 11:42:25 -0000 1.94 +++ formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java 3 Dec 2008 09:09:59 -0000 @@ -3115,6 +3115,16 @@ public static final String FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE = JavaCore.PLUGIN_ID + ".formatter.number_of_empty_lines_to_preserve"; //$NON-NLS-1$ /** *
+	 * FORMATTER / Option to specify whether the formatter should preserve existing line breaks or not
+	 *     - option id:         "org.eclipse.jdt.core.formatter.preserve_existing_line_breaks"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * 
+ * @since 3.5 + */ + public static final String FORMATTER_PRESERVE_EXISTING_LINE_BREAKS = JavaCore.PLUGIN_ID + ".formatter.preserve_existing_line_breaks"; //$NON-NLS-1$ + /** + *
 	 * FORMATTER / Option to specify whether or not empty statement should be on a new line
 	 *     - option id:         "org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line"
 	 *     - possible values:   { TRUE, FALSE }
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.153
diff -u -r1.153 Scribe.java
--- formatter/org/eclipse/jdt/internal/formatter/Scribe.java	9 Sep 2008 15:39:07 -0000	1.153
+++ formatter/org/eclipse/jdt/internal/formatter/Scribe.java	3 Dec 2008 09:10:00 -0000
@@ -928,15 +928,28 @@
 		return indent;
 	}
 
+	/*
+	 * Preserve empty lines depending on given count and preferences.
+	 */
 	private String getPreserveEmptyLines(int count) {
-		if (count > 0) {
-			if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
-				int linesToPreserve = Math.min(count, this.formatter.preferences.number_of_empty_lines_to_preserve);
-				return getEmptyLines(linesToPreserve);
+		if (count == 0) {
+			// preserve line breaks in wrapping if specified
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=198074
+			if (this.currentAlignment != null && this.formatter.preferences.preserve_existing_line_breaks) {
+				int savedIndentation = this.indentationLevel;
+				StringBuffer buffer = new StringBuffer(getNewLine());
+				this.indentationLevel = this.currentAlignment.breakIndentationLevel;
+				printIndentationIfNecessary(buffer);
+				this.indentationLevel = savedIndentation;
+				return buffer.toString();
 			}
-			return getNewLine();
+			return Util.EMPTY_STRING;
+		}
+		if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
+			int linesToPreserve = Math.min(count, this.formatter.preferences.number_of_empty_lines_to_preserve);
+			return getEmptyLines(linesToPreserve);
 		}
-		return Util.EMPTY_STRING;
+		return getNewLine();
 	}
 
 	private IRegion getAdaptedRegionAt(int offset) {
@@ -1921,8 +1934,8 @@
 						} else if (hasLineComment) {
 							preserveEmptyLines(count, this.scanner.getCurrentTokenStartPosition());
 							addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
-						} else if (count != 0 && this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
-							addReplaceEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition(), getPreserveEmptyLines(count - 1));
+						} else if (count != 0 && (this.formatter.preferences.preserve_existing_line_breaks || this.formatter.preferences.number_of_empty_lines_to_preserve != 0)) {
+							addReplaceEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition(), getPreserveEmptyLines(count-1));
 						} else {
 							addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
 						}
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.92
diff -u -r1.92 DefaultCodeFormatterOptions.java
--- formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java	27 Jun 2008 16:04:07 -0000	1.92
+++ formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java	3 Dec 2008 09:10:00 -0000
@@ -302,6 +302,7 @@
 	public boolean never_indent_block_comments_on_first_column;
 	public boolean never_indent_line_comments_on_first_column;
 	public int number_of_empty_lines_to_preserve;
+	public boolean preserve_existing_line_breaks;
 	public boolean put_empty_statement_on_new_line;
 	public int tab_size;
 	public final char filling_space = ' ';
@@ -579,6 +580,7 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN, this.never_indent_block_comments_on_first_column ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, this.never_indent_line_comments_on_first_column ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, Integer.toString(this.number_of_empty_lines_to_preserve));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_PRESERVE_EXISTING_LINE_BREAKS, this.preserve_existing_line_breaks ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE, this.put_empty_statement_on_new_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, Integer.toString(this.page_width));
 		switch(this.tab_char) {
@@ -1846,6 +1848,10 @@
 				this.number_of_empty_lines_to_preserve = 0;
 			}
 		}
+		final Object preserveExistingLineBreaksOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_PRESERVE_EXISTING_LINE_BREAKS);
+		if (preserveExistingLineBreaksOption != null) {
+			this.preserve_existing_line_breaks = DefaultCodeFormatterConstants.TRUE.equals(preserveExistingLineBreaksOption);
+		}
 		final Object putEmptyStatementOnNewLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE);
 		if (putEmptyStatementOnNewLineOption != null) {
 			this.put_empty_statement_on_new_line = DefaultCodeFormatterConstants.TRUE.equals(putEmptyStatementOnNewLineOption);
@@ -2185,6 +2191,7 @@
 		this.never_indent_block_comments_on_first_column = false;
 		this.never_indent_line_comments_on_first_column = false;
 		this.number_of_empty_lines_to_preserve = 1;
+		this.preserve_existing_line_breaks = false;
 		this.put_empty_statement_on_new_line = false;
 		this.tab_size = 4;
 		this.page_width = 80;
@@ -2449,6 +2456,7 @@
 		this.never_indent_block_comments_on_first_column = false;
 		this.never_indent_line_comments_on_first_column = false;
 		this.number_of_empty_lines_to_preserve = 1;
+		this.preserve_existing_line_breaks = false;
 		this.put_empty_statement_on_new_line = true;
 		this.tab_size = 8;
 		this.page_width = 80;