View | Details | Raw Unified | Return to bug 313524 | Differences between
and this patch

Collapse All | Expand All

(-)buildnotes_jdt-core.html (-1 / +52 lines)
Lines 48-56 Link Here
48
<br>Project org.eclipse.jdt.core v_A54
48
<br>Project org.eclipse.jdt.core v_A54
49
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A54">cvs</a>).
49
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A54">cvs</a>).
50
<h2>What's new in this drop</h2>
50
<h2>What's new in this drop</h2>
51
<ul>
52
<li>
53
Added a new preference to force the formatter to try to keep nested expressions on one line.
54
<p>
55
This new preference is controlled with the option:</p>
56
<code>DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE</code>
57
<pre>
58
/**
59
 * FORMATTER / Option to wrap outer expressions first in nested expressions
60
 *     - option id:         "org.eclipse.jdt.core.formatter.wrap_outer_expressions_first_when_nested"
61
 *     - possible values:   { TRUE, FALSE }
62
 *     - default:           TRUE
63
 *
64
 * This option changes the formatter behavior when nested method calls are encountered.
65
 * Since 3.6, the formatter tries to wrap outermost method calls first to have a better output.
66
 * For example, let's say we are using the Eclipse built-in profile with a max line width=40+space for tab policy.
67
 * Then consider the following snippet:
68
 *
69
 * public class X01 {
70
 *     void test() {
71
 *         foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8));
72
 *     }
73
 * }
74
 *
75
 * With this new strategy, the formatter will wrap the line earlier, between the arguments of the message call
76
 * for this example, and then it will allow to keep each nested call on a single line.
77
 * Hence, the output will be:
78
 *
79
 * public class X01 {
80
 *     void test() {
81
 *         foo(bar(1, 2, 3, 4),
82
 *             bar(5, 6, 7, 8));
83
 *     }
84
 * }
85
 *
86
 * Important notes:
87
 * 1. This new behavior is automatically activated (ie. the default value for this preference is {@link #TRUE}).
88
 *    If the backward compatibility regarding previous versions formatter behavior (ie. before 3.6 version) is necessary,
89
 *    then the preference needs to be set to the {@link #FALSE} value to retrieve the previous formatter behavior.
90
 * 2. The new strategy currently only applies to nested method calls, but might be extended to other nested expressions in future versions
91
 * 
92
 * @see #TRUE
93
 * @see #FALSE
94
 * @since 3.6
95
 */
96
</pre>
97
See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313524">313524</a> for more details.
98
</li>
99
</ul>
51
100
52
<h3>Problem Reports Fixed</h3>
101
<h3>Problem Reports Fixed</h3>
53
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313109">313109</a>
102
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313524">313524</a>
103
[formatter] Add preference for improved lines wrapping in nested method calls
104
<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313109">313109</a>
54
@SuppressWarnings on multiple locals is marked unnecessary if any local is never used
105
@SuppressWarnings on multiple locals is marked unnecessary if any local is never used
55
106
56
<a name="v_A53"></a>
107
<a name="v_A53"></a>
(-)formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java (+45 lines)
Lines 3500-3505 Link Here
3500
	public static final String FORMATTER_WRAP_BEFORE_BINARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.wrap_before_binary_operator"; //$NON-NLS-1$
3500
	public static final String FORMATTER_WRAP_BEFORE_BINARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.wrap_before_binary_operator"; //$NON-NLS-1$
3501
	/**
3501
	/**
3502
	 * <pre>
3502
	 * <pre>
3503
	 * FORMATTER / Option to wrap outer expressions first in nested expressions
3504
	 *     - option id:         "org.eclipse.jdt.core.formatter.wrap_outer_expressions_first_when_nested"
3505
	 *     - possible values:   { TRUE, FALSE }
3506
	 *     - default:           TRUE
3507
	 * </pre>
3508
	 * <p>
3509
	 * This option changes the formatter behavior when nested method calls are encountered.
3510
	 * Since 3.6, the formatter tries to wrap outermost method calls first to have a better output.</p>
3511
	 * <p>For example, let's say we are using the Eclipse built-in profile with a max line width=40+space for tab policy.
3512
	 * Then consider the following snippet:</p>
3513
	 * <pre>
3514
	 * public class X01 {
3515
	 *     void test() {
3516
	 *         foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8));
3517
	 *     }
3518
	 * }
3519
	 * </pre>
3520
	 * <p>With this new strategy, the formatter will wrap the line earlier, between the arguments of the message call
3521
	 * for this example, and then it will allow to keep each nested call on a single line.</p>
3522
	 * <p>Hence, the output will be:</p>
3523
	 * <pre>
3524
	 * public class X01 {
3525
	 *     void test() {
3526
	 *         foo(bar(1, 2, 3, 4),
3527
	 *             bar(5, 6, 7, 8));
3528
	 *     }
3529
	 * }
3530
	 * </pre>
3531
	 * <p>
3532
	 * </p>
3533
	 * <p><b><u>Important notes</u></b>:</p>
3534
	 * <ol>
3535
	 * <li>This new behavior is automatically activated (ie. the default value for this preference is {@link #TRUE}).
3536
	 * If the backward compatibility regarding previous versions formatter behavior (ie. before 3.6 version) is necessary,
3537
	 * then the preference needs to be set to the {@link #FALSE} value to retrieve the previous formatter behavior.</li>
3538
	 * <li>The new strategy currently only applies to nested method calls, but might be extended to other nested expressions in future versions</li>
3539
	 * </ol>
3540
	 * 
3541
	 * @see #TRUE
3542
	 * @see #FALSE
3543
	 * @since 3.6
3544
	 */
3545
	public static final String FORMATTER_WRAP_OUTER_EXPRESSIONS_FIRST_WHEN_NESTED = JavaCore.PLUGIN_ID + ".formatter.wrap_outer_expressions_first_when_nested"; //$NON-NLS-1$
3546
	/**
3547
	 * <pre>
3503
	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
3548
	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
3504
	 * </pre>
3549
	 * </pre>
3505
	 * @since 3.0
3550
	 * @since 3.0
(-)formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java (-2 / +4 lines)
Lines 1364-1370 Link Here
1364
			}
1364
			}
1365
			startingPositionInCascade = 2;
1365
			startingPositionInCascade = 2;
1366
		}
1366
		}
1367
		int tieBreakRule = size-startingPositionInCascade > 2 ? Alignment.R_OUTERMOST : Alignment.R_INNERMOST;
1367
		int tieBreakRule = this.preferences.wrap_outer_expressions_first_when_nested && size-startingPositionInCascade > 2
1368
			? Alignment.R_OUTERMOST
1369
			: Alignment.R_INNERMOST;
1368
		Alignment cascadingMessageSendAlignment =
1370
		Alignment cascadingMessageSendAlignment =
1369
			this.scribe.createAlignment(
1371
			this.scribe.createAlignment(
1370
				Alignment.CASCADING_MESSAGE_SEND,
1372
				Alignment.CASCADING_MESSAGE_SEND,
Lines 1676-1682 Link Here
1676
		Alignment messageAlignment) {
1678
		Alignment messageAlignment) {
1677
1679
1678
		if (messageAlignment != null) {
1680
		if (messageAlignment != null) {
1679
			if (messageAlignment.canAlign()) {
1681
			if (!this.preferences.wrap_outer_expressions_first_when_nested || messageAlignment.canAlign()) {
1680
				this.scribe.alignFragment(messageAlignment, 0);
1682
				this.scribe.alignFragment(messageAlignment, 0);
1681
			}
1683
			}
1682
			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
1684
			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
(-)formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java (+8 lines)
Lines 325-330 Link Here
325
	public int tab_char;
325
	public int tab_char;
326
	public boolean use_tabs_only_for_leading_indentations;
326
	public boolean use_tabs_only_for_leading_indentations;
327
	public boolean wrap_before_binary_operator;
327
	public boolean wrap_before_binary_operator;
328
	public boolean wrap_outer_expressions_first_when_nested;
328
329
329
	public int initial_indentation_level;
330
	public int initial_indentation_level;
330
	public String line_separator;
331
	public String line_separator;
Lines 622-627 Link Here
622
		options.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, this.disabling_tag == null ? Util.EMPTY_STRING : new String(this.disabling_tag));
623
		options.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, this.disabling_tag == null ? Util.EMPTY_STRING : new String(this.disabling_tag));
623
		options.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, this.enabling_tag == null ? Util.EMPTY_STRING : new String(this.enabling_tag));
624
		options.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, this.enabling_tag == null ? Util.EMPTY_STRING : new String(this.enabling_tag));
624
		options.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, this.use_tags ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
625
		options.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, this.use_tags ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
626
		options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_OUTER_EXPRESSIONS_FIRST_WHEN_NESTED, this.wrap_outer_expressions_first_when_nested ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
625
		return options;
627
		return options;
626
	}
628
	}
627
629
Lines 1997-2002 Link Here
1997
				}
1999
				}
1998
			}
2000
			}
1999
		}
2001
		}
2002
		final Object wrapWrapOuterExpressionsFirstWhenNestedOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_WRAP_OUTER_EXPRESSIONS_FIRST_WHEN_NESTED);
2003
		if (wrapWrapOuterExpressionsFirstWhenNestedOption != null) {
2004
			this.wrap_outer_expressions_first_when_nested = DefaultCodeFormatterConstants.TRUE.equals(wrapWrapOuterExpressionsFirstWhenNestedOption);
2005
		}
2000
	}
2006
	}
2001
2007
2002
	/**
2008
	/**
Lines 2310-2315 Link Here
2310
		this.use_tags = false;
2316
		this.use_tags = false;
2311
		this.disabling_tag = DEFAULT_DISABLING_TAG;
2317
		this.disabling_tag = DEFAULT_DISABLING_TAG;
2312
		this.enabling_tag = DEFAULT_ENABLING_TAG;
2318
		this.enabling_tag = DEFAULT_ENABLING_TAG;
2319
		this.wrap_outer_expressions_first_when_nested = true;
2313
	}
2320
	}
2314
2321
2315
	public void setEclipseDefaultSettings() {
2322
	public void setEclipseDefaultSettings() {
Lines 2584-2588 Link Here
2584
		this.use_tags = false;
2591
		this.use_tags = false;
2585
		this.disabling_tag = DEFAULT_DISABLING_TAG;
2592
		this.disabling_tag = DEFAULT_DISABLING_TAG;
2586
		this.enabling_tag = DEFAULT_ENABLING_TAG;
2593
		this.enabling_tag = DEFAULT_ENABLING_TAG;
2594
		this.wrap_outer_expressions_first_when_nested = true;
2587
	}
2595
	}
2588
}
2596
}
(-)formatter/org/eclipse/jdt/internal/formatter/Scribe.java (+32 lines)
Lines 1258-1263 Link Here
1258
	}
1258
	}
1259
1259
1260
	public void handleLineTooLong() {
1260
	public void handleLineTooLong() {
1261
		if (this.formatter.preferences.wrap_outer_expressions_first_when_nested) {
1262
			handleLineTooLongSmartly();
1263
			return;
1264
		}
1265
		// search for closest breakable alignment, using tiebreak rules
1266
		// look for outermost breakable one
1267
		int relativeDepth = 0, outerMostDepth = -1;
1268
		Alignment targetAlignment = this.currentAlignment;
1269
		while (targetAlignment != null){
1270
			if (targetAlignment.tieBreakRule == Alignment.R_OUTERMOST && targetAlignment.couldBreak()){
1271
				outerMostDepth = relativeDepth;
1272
			}
1273
			targetAlignment = targetAlignment.enclosing;
1274
			relativeDepth++;
1275
		}
1276
		if (outerMostDepth >= 0) {
1277
			throw new AlignmentException(AlignmentException.LINE_TOO_LONG, outerMostDepth);
1278
		}
1279
		// look for innermost breakable one
1280
		relativeDepth = 0;
1281
		targetAlignment = this.currentAlignment;
1282
		while (targetAlignment != null){
1283
			if (targetAlignment.couldBreak()){
1284
				throw new AlignmentException(AlignmentException.LINE_TOO_LONG, relativeDepth);
1285
			}
1286
			targetAlignment = targetAlignment.enclosing;
1287
			relativeDepth++;
1288
		}
1289
		// did not find any breakable location - proceed
1290
	}
1291
1292
	private void handleLineTooLongSmartly() {
1261
		// search for closest breakable alignment, using tiebreak rules
1293
		// search for closest breakable alignment, using tiebreak rules
1262
		// look for outermost breakable one
1294
		// look for outermost breakable one
1263
		int relativeDepth = 0, outerMostDepth = -1;
1295
		int relativeDepth = 0, outerMostDepth = -1;

Return to bug 313524