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

Collapse All | Expand All

(-)buildnotes_jdt-core.html (+21 lines)
Lines 48-53 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 try to keep nested expressions on one line
60
 *     - option id:         "org.eclipse.jdt.core.formatter.keep_nested_expressions_on_one_line"
61
 *     - possible values:   { TRUE, FALSE }
62
 *     - default:           FALSE
63
 *
64
 * @see #TRUE
65
 * @see #FALSE
66
 * @since 3.6
67
 */
68
</pre>
69
See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313524">313524</a> for more details.
70
</li>
71
</ul>
51
72
52
<h3>Problem Reports Fixed</h3>
73
<h3>Problem Reports Fixed</h3>
53
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313109">313109</a>
74
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313109">313109</a>
(-)formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java (+12 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 try to keep nested expressions on one line
3504
	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_nested_expressions_on_one_line"
3505
	 *     - possible values:   { TRUE, FALSE }
3506
	 *     - default:           FALSE
3507
	 * </pre>
3508
	 * @see #TRUE
3509
	 * @see #FALSE
3510
	 * @since 3.6
3511
	 */
3512
	public static final String FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_nested_expressions_on_one_line"; //$NON-NLS-1$
3513
	/**
3514
	 * <pre>
3503
	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
3515
	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
3504
	 * </pre>
3516
	 * </pre>
3505
	 * @since 3.0
3517
	 * @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.keep_nested_expression_on_one_line && 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.keep_nested_expression_on_one_line || 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 keep_nested_expression_on_one_line;
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_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, this.keep_nested_expression_on_one_line ? 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 wrapKeepNestedExpressionsOnOneLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE);
2003
		if (wrapKeepNestedExpressionsOnOneLineOption != null) {
2004
			this.keep_nested_expression_on_one_line = DefaultCodeFormatterConstants.TRUE.equals(wrapKeepNestedExpressionsOnOneLineOption);
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.keep_nested_expression_on_one_line = false;
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.keep_nested_expression_on_one_line = false;
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.keep_nested_expression_on_one_line) {
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;
(-)src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java (-4 / +549 lines)
Lines 6050-6056 Link Here
6050
 * @test Ensure that the formatter does not take care of formatting tags by default
6050
 * @test Ensure that the formatter does not take care of formatting tags by default
6051
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=311582"
6051
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=311582"
6052
 */
6052
 */
6053
public void testBug0311582a() throws JavaModelException {
6053
public void testBug311582a() throws JavaModelException {
6054
	this.formatterPrefs.disabling_tag = "disable-formatter".toCharArray();
6054
	this.formatterPrefs.disabling_tag = "disable-formatter".toCharArray();
6055
	this.formatterPrefs.enabling_tag = "enable-formatter".toCharArray();
6055
	this.formatterPrefs.enabling_tag = "enable-formatter".toCharArray();
6056
	String source =
6056
	String source =
Lines 6080-6086 Link Here
6080
		"}\n"
6080
		"}\n"
6081
	);
6081
	);
6082
}
6082
}
6083
public void testBug0311582b() {
6083
public void testBug311582b() {
6084
	this.formatterPrefs = null;
6084
	this.formatterPrefs = null;
6085
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, "off");
6085
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, "off");
6086
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, "");
6086
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, "");
Lines 6106-6112 Link Here
6106
 * @test Ensure that the formatter does not take care of formatting tags by default
6106
 * @test Ensure that the formatter does not take care of formatting tags by default
6107
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=311617"
6107
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=311617"
6108
 */
6108
 */
6109
public void testBug0311617() throws JavaModelException {
6109
public void testBug311617() throws JavaModelException {
6110
	this.formatterPrefs.use_tags = true;
6110
	this.formatterPrefs.use_tags = true;
6111
	String source =
6111
	String source =
6112
		"public class X01 {\n" + 
6112
		"public class X01 {\n" + 
Lines 6134-6140 Link Here
6134
		"}\n"
6134
		"}\n"
6135
	);
6135
	);
6136
}
6136
}
6137
public void testBug0311617b() {
6137
public void testBug311617b() {
6138
	this.formatterPrefs = null;
6138
	this.formatterPrefs = null;
6139
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, DefaultCodeFormatterConstants.TRUE);
6139
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, DefaultCodeFormatterConstants.TRUE);
6140
	String source =
6140
	String source =
Lines 6147-6150 Link Here
6147
	formatSource(source);
6147
	formatSource(source);
6148
}
6148
}
6149
6149
6150
/**
6151
 * @bug 313524: [formatter] Add preference for improved lines wrapping in nested method calls
6152
 * @test Ensure that the formatter keep previous eclipse versions behavior when
6153
 * 		the "Try to keep nested expressions on one line" preference is set.
6154
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=313524"
6155
 */
6156
public void testBug313524_01() throws JavaModelException {
6157
	this.formatterPrefs.page_width = 40;
6158
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6159
	String source =
6160
		"public class X01 {\n" +
6161
		"	void test() {\n" + 
6162
		"		foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8));\n" + 
6163
		"	}\n" + 
6164
		"}\n";
6165
	formatSource(source,
6166
		"public class X01 {\n" + 
6167
		"	void test() {\n" + 
6168
		"		foo(bar(1, 2, 3, 4), bar(5, 6,\n" + 
6169
		"				7, 8));\n" + 
6170
		"	}\n" + 
6171
		"}\n"
6172
	);
6173
}
6174
public void testBug313524_01b() throws JavaModelException {
6175
	this.formatterPrefs = null;
6176
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "40");
6177
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE);
6178
	this.formatterOptions.put(
6179
			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
6180
			DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_COMPACT, DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
6181
	String source =
6182
		"public class X01 {\n" +
6183
		"	void test() {\n" + 
6184
		"		foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8));\n" + 
6185
		"	}\n" + 
6186
		"}\n";
6187
	formatSource(source,
6188
		"public class X01 {\n" + 
6189
		"	void test() {\n" + 
6190
		"		foo(bar(1, 2, 3, 4), bar(	5,\n" + 
6191
		"									6,\n" + 
6192
		"									7,\n" + 
6193
		"									8));\n" + 
6194
		"	}\n" + 
6195
		"}\n"
6196
	);
6197
}
6198
public void testBug313524_02() throws JavaModelException {
6199
	this.formatterPrefs.page_width = 40;
6200
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6201
	String source =
6202
		"public class X02 {\n" +
6203
		"	void test() {\n" + 
6204
		"		foo(bar(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), bar(11, 12, 13, 14, 15, 16, 17, 18, 19, 20));\n" + 
6205
		"	}\n" + 
6206
		"}\n";
6207
	formatSource(source,
6208
		"public class X02 {\n" + 
6209
		"	void test() {\n" + 
6210
		"		foo(bar(1, 2, 3, 4, 5, 6, 7, 8,\n" + 
6211
		"				9, 10), bar(11, 12, 13,\n" + 
6212
		"				14, 15, 16, 17, 18, 19,\n" + 
6213
		"				20));\n" + 
6214
		"	}\n" + 
6215
		"}\n"
6216
	);
6217
}
6218
public void testBug313524_02b() throws JavaModelException {
6219
	this.formatterPrefs = null;
6220
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "40");
6221
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE);
6222
	this.formatterOptions.put(
6223
			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
6224
			DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_COMPACT, DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
6225
	String source =
6226
		"public class X02 {\n" +
6227
		"	void test() {\n" + 
6228
		"		foo(bar(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), bar(11, 12, 13, 14, 15, 16, 17, 18, 19, 20));\n" + 
6229
		"	}\n" + 
6230
		"}\n";
6231
	formatSource(source,
6232
		"public class X02 {\n" + 
6233
		"	void test() {\n" + 
6234
		"		foo(bar(1, 2, 3, 4, 5, 6, 7, 8,\n" + 
6235
		"				9, 10), bar(11, 12, 13,\n" + 
6236
		"							14, 15, 16,\n" + 
6237
		"							17, 18, 19,\n" + 
6238
		"							20));\n" + 
6239
		"	}\n" + 
6240
		"}\n"
6241
	);
6242
}
6243
public void testBug313524_03() throws JavaModelException {
6244
	this.formatterPrefs.page_width = 40;
6245
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6246
	String source =
6247
		"public class X03 {\n" +
6248
		"	void test() {\n" + 
6249
		"		foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8), bar(9, 10, 11, 12));\n" + 
6250
		"	}\n" + 
6251
		"}\n";
6252
	formatSource(source,
6253
		"public class X03 {\n" + 
6254
		"	void test() {\n" + 
6255
		"		foo(bar(1, 2, 3, 4), bar(5, 6,\n" + 
6256
		"				7, 8), bar(9, 10, 11,\n" + 
6257
		"				12));\n" + 
6258
		"	}\n" + 
6259
		"}\n"
6260
	);
6261
}
6262
public void testBug313524_03b() throws JavaModelException {
6263
	this.formatterPrefs = null;
6264
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "40");
6265
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE);
6266
	this.formatterOptions.put(
6267
			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
6268
			DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_COMPACT, DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
6269
	String source =
6270
		"public class X03 {\n" +
6271
		"	void test() {\n" + 
6272
		"		foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8), bar(9, 10, 11, 12));\n" + 
6273
		"	}\n" + 
6274
		"}\n";
6275
	formatSource(source,
6276
		"public class X03 {\n" + 
6277
		"	void test() {\n" + 
6278
		"		foo(bar(1, 2, 3, 4), bar(	5,\n" + 
6279
		"									6,\n" + 
6280
		"									7,\n" + 
6281
		"									8),\n" + 
6282
		"			bar(9, 10, 11, 12));\n" + 
6283
		"	}\n" + 
6284
		"}\n"
6285
	);
6286
}
6287
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=146175
6288
public void testBug313524_146175() throws JavaModelException {
6289
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6290
	String source =
6291
		"public class FormatterDemo {\n" + 
6292
		"\n" + 
6293
		"    public void fooBar() {\n" + 
6294
		"        SomeOtherClass instanceOfOtherClass = new SomeOtherClass();\n" + 
6295
		"\n" + 
6296
		"        /* The following statement demonstrates the formatter issue */\n" + 
6297
		"        SomeOtherClass.someMethodInInnerClass(\n" + 
6298
		"            instanceOfOtherClass.anotherMethod(\"Value of paramter 1\"),\n" + 
6299
		"            instanceOfOtherClass.anotherMethod(\"Value of paramter 2\"));\n" + 
6300
		"\n" + 
6301
		"    }\n" + 
6302
		"\n" + 
6303
		"    private static class SomeOtherClass {\n" + 
6304
		"        public static void someMethodInInnerClass(\n" + 
6305
		"            String param1,\n" + 
6306
		"            String param2) {\n" + 
6307
		"        }\n" + 
6308
		"        public String anotherMethod(String par) {\n" + 
6309
		"            return par;\n" + 
6310
		"        }\n" + 
6311
		"    }\n" + 
6312
		"}\n";
6313
	formatSource(source,
6314
		"public class FormatterDemo {\n" + 
6315
		"\n" + 
6316
		"	public void fooBar() {\n" + 
6317
		"		SomeOtherClass instanceOfOtherClass = new SomeOtherClass();\n" + 
6318
		"\n" + 
6319
		"		/* The following statement demonstrates the formatter issue */\n" + 
6320
		"		SomeOtherClass.someMethodInInnerClass(instanceOfOtherClass\n" + 
6321
		"				.anotherMethod(\"Value of paramter 1\"), instanceOfOtherClass\n" + 
6322
		"				.anotherMethod(\"Value of paramter 2\"));\n" + 
6323
		"\n" + 
6324
		"	}\n" + 
6325
		"\n" + 
6326
		"	private static class SomeOtherClass {\n" + 
6327
		"		public static void someMethodInInnerClass(String param1, String param2) {\n" + 
6328
		"		}\n" + 
6329
		"\n" + 
6330
		"		public String anotherMethod(String par) {\n" + 
6331
		"			return par;\n" + 
6332
		"		}\n" + 
6333
		"	}\n" + 
6334
		"}\n"
6335
	);
6336
}
6337
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=164093
6338
public void testBug313524_164093_01() throws JavaModelException {
6339
	this.formatterPrefs = null;
6340
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "30");
6341
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE);
6342
	this.formatterOptions.put(
6343
			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION,
6344
			DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_COMPACT, DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
6345
	String source =
6346
		"public class Test {\n" + 
6347
		"    int someLongMethodName(int foo,  boolean bar, String yetAnotherArg) {\n" + 
6348
		"        return 0;\n" + 
6349
		"    }\n" + 
6350
		"}\n";
6351
	formatSource(source,
6352
		"public class Test {\n" + 
6353
		"	int someLongMethodName(	int foo,\n" + 
6354
		"							boolean bar,\n" + 
6355
		"							String yetAnotherArg) {\n" + 
6356
		"		return 0;\n" + 
6357
		"	}\n" + 
6358
		"}\n"
6359
	);
6360
}
6361
public void testBug313524_164093_02() throws JavaModelException {
6362
	this.formatterPrefs = null;
6363
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "55");
6364
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
6365
	this.formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE);
6366
	this.formatterOptions.put(
6367
			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION,
6368
			DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_COMPACT, DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
6369
	String source =
6370
		"public class X01 {\n" + 
6371
		"    void foo() {\n" + 
6372
		"           someIdentifier(someArg).someMethodName().someMethodName(foo, bar).otherMethod(arg0, arg1);\n" + 
6373
		"    }\n" + 
6374
		"}\n";
6375
	formatSource(source,
6376
		"public class X01 {\n" + 
6377
		"    void foo() {\n" + 
6378
		"        someIdentifier(someArg).someMethodName()\n" + 
6379
		"                               .someMethodName(foo,\n" + 
6380
		"                                       bar)\n" + 
6381
		"                               .otherMethod(arg0, arg1);\n" + 
6382
		"    }\n" + 
6383
		"}\n"
6384
	);
6385
}
6386
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=203588
6387
public void testBug313524_203588() throws JavaModelException {
6388
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6389
	String source =
6390
		"public class Test {\n" + 
6391
		"public void a()\n" + 
6392
		"{\n" + 
6393
		"  if(true)\n" + 
6394
		"  {\n" + 
6395
		"    allocation.add(idx_ta + 1, Double.valueOf(allocation.get(idx_ta).doubleValue() + q));\n" + 
6396
		"  }\n" + 
6397
		"}\n" + 
6398
		"}\n";
6399
	formatSource(source,
6400
		"public class Test {\n" + 
6401
		"	public void a() {\n" + 
6402
		"		if (true) {\n" + 
6403
		"			allocation.add(idx_ta + 1, Double.valueOf(allocation.get(idx_ta)\n" + 
6404
		"					.doubleValue()\n" + 
6405
		"					+ q));\n" + 
6406
		"		}\n" + 
6407
		"	}\n" + 
6408
		"}\n"
6409
	);
6410
}
6411
// wksp1
6412
public void testBug313524_wksp1_01() throws JavaModelException {
6413
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6414
	String source =
6415
		"public class X01 {\n" + 
6416
		"	private void reportError(String name) throws ParseError {\n" + 
6417
		"		throw new ParseError(MessageFormat.format(AntDTDSchemaMessages.getString(\"NfmParser.Ambiguous\"), new String[]{name})); //$NON-NLS-1$\n" + 
6418
		"	}\n" + 
6419
		"}\n";
6420
	formatSource(source,
6421
		"public class X01 {\n" + 
6422
		"	private void reportError(String name) throws ParseError {\n" + 
6423
		"		throw new ParseError(MessageFormat.format(AntDTDSchemaMessages\n" + 
6424
		"				.getString(\"NfmParser.Ambiguous\"), new String[] { name })); //$NON-NLS-1$\n" + 
6425
		"	}\n" + 
6426
		"}\n"
6427
	);
6428
}
6429
public void testBug313524_wksp1_02() throws JavaModelException {
6430
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6431
	String source =
6432
		"public class X02 {\n" + 
6433
		"	private void parseBuildFile(Project project) {\n" + 
6434
		"		if (!buildFile.exists()) {\n" + 
6435
		"			throw new BuildException(MessageFormat.format(InternalAntMessages.getString(\"InternalAntRunner.Buildfile__{0}_does_not_exist_!_1\"), //$NON-NLS-1$\n" + 
6436
		"						 new String[]{buildFile.getAbsolutePath()}));\n" + 
6437
		"		}\n" + 
6438
		"		if (!buildFile.isFile()) {\n" + 
6439
		"			throw new BuildException(MessageFormat.format(InternalAntMessages.getString(\"InternalAntRunner.Buildfile__{0}_is_not_a_file_1\"), //$NON-NLS-1$\n" + 
6440
		"							new String[]{buildFile.getAbsolutePath()}));\n" + 
6441
		"		}\n" + 
6442
		"	}\n" + 
6443
		"}\n";
6444
	formatSource(source,
6445
		"public class X02 {\n" + 
6446
		"	private void parseBuildFile(Project project) {\n" + 
6447
		"		if (!buildFile.exists()) {\n" + 
6448
		"			throw new BuildException(\n" + 
6449
		"					MessageFormat\n" + 
6450
		"							.format(InternalAntMessages\n" + 
6451
		"									.getString(\"InternalAntRunner.Buildfile__{0}_does_not_exist_!_1\"), //$NON-NLS-1$\n" + 
6452
		"							new String[] { buildFile.getAbsolutePath() }));\n" + 
6453
		"		}\n" + 
6454
		"		if (!buildFile.isFile()) {\n" + 
6455
		"			throw new BuildException(\n" + 
6456
		"					MessageFormat\n" + 
6457
		"							.format(InternalAntMessages\n" + 
6458
		"									.getString(\"InternalAntRunner.Buildfile__{0}_is_not_a_file_1\"), //$NON-NLS-1$\n" + 
6459
		"							new String[] { buildFile.getAbsolutePath() }));\n" + 
6460
		"		}\n" + 
6461
		"	}\n" + 
6462
		"}\n"
6463
	);
6464
}
6465
public void testBug313524_wksp1_03() throws JavaModelException {
6466
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6467
	String source =
6468
		"public class X03 {\n" + 
6469
		"\n" + 
6470
		"	protected void foo() {\n" + 
6471
		"		printTargets(project, subNames, null, InternalAntMessages.getString(\"InternalAntRunner.Subtargets__5\"), 0); //$NON-NLS-1$\n" + 
6472
		"	}\n" + 
6473
		"}\n";
6474
	formatSource(source,
6475
		"public class X03 {\n" + 
6476
		"\n" + 
6477
		"	protected void foo() {\n" + 
6478
		"		printTargets(project, subNames, null, InternalAntMessages\n" + 
6479
		"				.getString(\"InternalAntRunner.Subtargets__5\"), 0); //$NON-NLS-1$\n" + 
6480
		"	}\n" + 
6481
		"}\n"
6482
	);
6483
}
6484
public void testBug313524_wksp1_04() throws JavaModelException {
6485
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6486
	String source =
6487
		"public class X04 {\n" + 
6488
		"	void foo() {\n" + 
6489
		"		if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR)) {\n" + 
6490
		"			synchronizeOutlinePage(node, true);\n" + 
6491
		"		}\n" + 
6492
		"	}\n" + 
6493
		"}\n";
6494
	formatSource(source,
6495
		"public class X04 {\n" + 
6496
		"	void foo() {\n" + 
6497
		"		if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(\n" + 
6498
		"				IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR)) {\n" + 
6499
		"			synchronizeOutlinePage(node, true);\n" + 
6500
		"		}\n" + 
6501
		"	}\n" + 
6502
		"}\n"
6503
	);
6504
}
6505
public void testBug313524_wksp1_05() throws JavaModelException {
6506
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6507
	String source =
6508
		"public class X05 {\n" + 
6509
		"void foo() {\n" + 
6510
		"		if (false && AntUIPlugin.getDefault().getPreferenceStore().getBoolean(AntEditorPreferenceConstants.TEMPLATES_USE_CODEFORMATTER)) {\n" + 
6511
		"		}\n" + 
6512
		"}\n" + 
6513
		"}\n";
6514
	formatSource(source,
6515
		"public class X05 {\n" + 
6516
		"	void foo() {\n" + 
6517
		"		if (false && AntUIPlugin.getDefault().getPreferenceStore().getBoolean(\n" + 
6518
		"				AntEditorPreferenceConstants.TEMPLATES_USE_CODEFORMATTER)) {\n" + 
6519
		"		}\n" + 
6520
		"	}\n" + 
6521
		"}\n"
6522
	);
6523
}
6524
// TODO Improve this formatting as it let the message send argument in one line over the max width
6525
public void testBug313524_wksp1_06() throws JavaModelException {
6526
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6527
	String source =
6528
		"public class X06 {\n" + 
6529
		"	public void launch() {\n" + 
6530
		"		try {\n" + 
6531
		"			if ((javaProject == null) || !javaProject.exists()) {\n" + 
6532
		"				abort(PDEPlugin________.getResourceString(\"JUnitLaunchConfig_____\"), null, IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT);\n" + 
6533
		"			}\n" + 
6534
		"		} catch (CoreException e) {\n" + 
6535
		"		}\n" + 
6536
		"	}\n" + 
6537
		"}\n";
6538
	formatSource(source,
6539
		"public class X06 {\n" + 
6540
		"	public void launch() {\n" + 
6541
		"		try {\n" + 
6542
		"			if ((javaProject == null) || !javaProject.exists()) {\n" + 
6543
		"				abort(PDEPlugin________\n" + 
6544
		"						.getResourceString(\"JUnitLaunchConfig_____\"),\n" + 
6545
		"						null,\n" + 
6546
		"						IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT);\n" + 
6547
		"			}\n" + 
6548
		"		} catch (CoreException e) {\n" + 
6549
		"		}\n" + 
6550
		"	}\n" + 
6551
		"}\n"
6552
	);
6553
}
6554
public void testBug313524_wksp1_07() throws JavaModelException {
6555
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6556
	String source =
6557
		"public class X07 {\n" + 
6558
		"	void foo() {\n" + 
6559
		"		if (true) {\n" + 
6560
		"			configureAntObject(result, element, task, task.getTaskName(), InternalCoreAntMessages.getString(\"AntCorePreferences.No_library_for_task\")); //$NON-NLS-1$\n" + 
6561
		"		}\n" + 
6562
		"	}\n" + 
6563
		"}\n";
6564
	formatSource(source,
6565
		"public class X07 {\n" + 
6566
		"	void foo() {\n" + 
6567
		"		if (true) {\n" + 
6568
		"			configureAntObject(\n" + 
6569
		"					result,\n" + 
6570
		"					element,\n" + 
6571
		"					task,\n" + 
6572
		"					task.getTaskName(),\n" + 
6573
		"					InternalCoreAntMessages\n" + 
6574
		"							.getString(\"AntCorePreferences.No_library_for_task\")); //$NON-NLS-1$\n" + 
6575
		"		}\n" + 
6576
		"	}\n" + 
6577
		"}\n"
6578
	);
6579
}
6580
public void testBug313524_wksp1_08() throws JavaModelException {
6581
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6582
	String source =
6583
		"public class X08 {\n" + 
6584
		"	public void foo() {\n" + 
6585
		"		if (true) {\n" + 
6586
		"			IStatus status= new Status(IStatus.ERROR, AntCorePlugin.PI_ANTCORE, AntCorePlugin.ERROR_RUNNING_BUILD, MessageFormat.format(InternalCoreAntMessages.getString(\"AntRunner.Already_in_progess\"), new String[]{buildFileLocation}), null); //$NON-NLS-1$\n" + 
6587
		"		}\n" + 
6588
		"	}\n" + 
6589
		"}\n";
6590
	formatSource(source,
6591
		"public class X08 {\n" + 
6592
		"	public void foo() {\n" + 
6593
		"		if (true) {\n" + 
6594
		"			IStatus status = new Status(\n" + 
6595
		"					IStatus.ERROR,\n" + 
6596
		"					AntCorePlugin.PI_ANTCORE,\n" + 
6597
		"					AntCorePlugin.ERROR_RUNNING_BUILD,\n" + 
6598
		"					MessageFormat\n" + 
6599
		"							.format(InternalCoreAntMessages\n" + 
6600
		"									.getString(\"AntRunner.Already_in_progess\"), new String[] { buildFileLocation }), null); //$NON-NLS-1$\n" + 
6601
		"		}\n" + 
6602
		"	}\n" + 
6603
		"}\n"
6604
	);
6605
}
6606
public void testBug313524_wksp1_09() throws JavaModelException {
6607
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6608
	String source =
6609
		"public class X09 {\n" + 
6610
		"	void foo() {\n" + 
6611
		"		if (true) {\n" + 
6612
		"			String secondFileName = secondDirectoryAbsolutePath + File.separator + currentFile.substring(firstDirectoryAbsolutePath.length() + 1);\n" + 
6613
		"		}\n" + 
6614
		"	}\n" + 
6615
		"}\n";
6616
	formatSource(source,
6617
		"public class X09 {\n" + 
6618
		"	void foo() {\n" + 
6619
		"		if (true) {\n" + 
6620
		"			String secondFileName = secondDirectoryAbsolutePath\n" + 
6621
		"					+ File.separator\n" + 
6622
		"					+ currentFile\n" + 
6623
		"							.substring(firstDirectoryAbsolutePath.length() + 1);\n" + 
6624
		"		}\n" + 
6625
		"	}\n" + 
6626
		"}\n"
6627
	);
6628
}
6629
public void testBug313524_wksp1_10() throws JavaModelException {
6630
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6631
	String source =
6632
		"public class X10 {\n" + 
6633
		"	void foo() {\n" + 
6634
		"		if (true) {\n" + 
6635
		"			if (true) {\n" + 
6636
		"				throw new BuildException(InternalAntMessages.getString(\"InternalAntRunner.Could_not_load_the_version_information._10\")); //$NON-NLS-1$\n" + 
6637
		"			}\n" + 
6638
		"		}\n" + 
6639
		"	}\n" + 
6640
		"}\n";
6641
	formatSource(source,
6642
		"public class X10 {\n" + 
6643
		"	void foo() {\n" + 
6644
		"		if (true) {\n" + 
6645
		"			if (true) {\n" + 
6646
		"				throw new BuildException(\n" + 
6647
		"						InternalAntMessages\n" + 
6648
		"								.getString(\"InternalAntRunner.Could_not_load_the_version_information._10\")); //$NON-NLS-1$\n" + 
6649
		"			}\n" + 
6650
		"		}\n" + 
6651
		"	}\n" + 
6652
		"}\n"
6653
	);
6654
}
6655
public void testBug313524_wksp1_11() throws JavaModelException {
6656
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6657
	String source =
6658
		"public class X11 {\n" + 
6659
		"	private void antFileNotFound() {\n" + 
6660
		"		reportError(AntLaunchConfigurationMessages.getString(\"AntLaunchShortcut.Unable\"), null); //$NON-NLS-1$	\n" + 
6661
		"	}\n" + 
6662
		"}\n";
6663
	formatSource(source,
6664
		"public class X11 {\n" + 
6665
		"	private void antFileNotFound() {\n" + 
6666
		"		reportError(AntLaunchConfigurationMessages\n" + 
6667
		"				.getString(\"AntLaunchShortcut.Unable\"), null); //$NON-NLS-1$	\n" + 
6668
		"	}\n" + 
6669
		"}\n"
6670
	);
6671
}
6672
public void testBug313524_wksp1_12() throws JavaModelException {
6673
	this.formatterPrefs.keep_nested_expression_on_one_line = true;
6674
	String source =
6675
		"public class X12 {\n" + 
6676
		"	void foo() {\n" + 
6677
		"        if (this.fTests.size() == 0) {\n" + 
6678
		"            this.addTest(TestSuite\n" + 
6679
		"                    .warning(\"No tests found in \" + theClass.getName())); //$NON-NLS-1$\n" + 
6680
		"        }\n" + 
6681
		"	}\n" + 
6682
		"}\n";
6683
	formatSource(source,
6684
		"public class X12 {\n" + 
6685
		"	void foo() {\n" + 
6686
		"		if (this.fTests.size() == 0) {\n" + 
6687
		"			this.addTest(TestSuite\n" +
6688
		"					.warning(\"No tests found in \" + theClass.getName())); //$NON-NLS-1$\n" + 
6689
		"		}\n" + 
6690
		"	}\n" + 
6691
		"}\n"
6692
	);
6693
}
6694
6150
}
6695
}
(-)src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java (+44 lines)
Lines 512-517 Link Here
512
		runTest("test026", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
512
		runTest("test026", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
513
	}
513
	}
514
514
515
	public void test026b() {
516
		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
517
		preferences.keep_nested_expression_on_one_line = true;
518
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
519
		runTest(codeFormatter, "test026b", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
520
	}
521
515
	public void test027() {
522
	public void test027() {
516
		runTest("test027", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
523
		runTest("test027", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
517
	}
524
	}
Lines 1779-1784 Link Here
1779
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1786
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1780
		runTest(codeFormatter, "test167", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1787
		runTest(codeFormatter, "test167", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1781
	}
1788
	}
1789
	public void test167b() {
1790
		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
1791
		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
1792
		preferences.keep_nested_expression_on_one_line = true;
1793
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1794
		runTest(codeFormatter, "test167b", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1795
	}
1782
1796
1783
	/**
1797
	/**
1784
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44503
1798
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44503
Lines 1789-1794 Link Here
1789
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1803
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1790
		runTest(codeFormatter, "test169", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1804
		runTest(codeFormatter, "test169", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1791
	}
1805
	}
1806
	public void test169b() {
1807
		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
1808
		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
1809
		preferences.keep_nested_expression_on_one_line = true;
1810
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1811
		runTest(codeFormatter, "test169b", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1812
	}
1792
1813
1793
	/**
1814
	/**
1794
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44503
1815
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44503
Lines 1799-1804 Link Here
1799
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1820
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1800
		runTest(codeFormatter, "test170", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1821
		runTest(codeFormatter, "test170", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1801
	}
1822
	}
1823
	public void test170b() {
1824
		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
1825
		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
1826
		preferences.keep_nested_expression_on_one_line = true;
1827
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
1828
		runTest(codeFormatter, "test170b", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
1829
	}
1802
1830
1803
	/**
1831
	/**
1804
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44576
1832
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44576
Lines 4438-4443 Link Here
4438
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
4466
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
4439
		runTest(codeFormatter, "test337", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
4467
		runTest(codeFormatter, "test337", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
4440
	}
4468
	}
4469
	public void test337b() {
4470
		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
4471
		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
4472
		preferences.number_of_empty_lines_to_preserve = 0;
4473
		preferences.keep_nested_expression_on_one_line = true;
4474
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
4475
		runTest(codeFormatter, "test337b", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
4476
	}
4441
4477
4442
	/**
4478
	/**
4443
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=46686
4479
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=46686
Lines 5980-5985 Link Here
5980
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
6016
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
5981
		runTest(codeFormatter, "test455", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
6017
		runTest(codeFormatter, "test455", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
5982
	}
6018
	}
6019
	public void test455b() {
6020
		Map options = DefaultCodeFormatterConstants.getEclipse21Settings();
6021
		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, "1");//$NON-NLS-1$
6022
		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_NESTED_EXPRESSIONS_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE);
6023
		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
6024
		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
6025
		runTest(codeFormatter, "test455b", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
6026
	}
5983
6027
5984
	/**
6028
	/**
5985
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=50736
6029
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=50736
(-)workspace/Formatter/test026b/A_in.java (+8 lines)
Added Link Here
1
// test026
2
public class A {
3
	public	void foo() {
4
	   this.longReceiver.someQuiteLongMessageSend("aaaaaaaaaaa","bbbbbbbbbbbbb","cccccccc"); 
5
	   this.extremlylongReceiverWillCauseTwoSplitActions.someQuiteLongMessageSend("aaaaaaaaaaa","bbbbbbbbbbbbb","cccccccc"); 
6
      Alignment expressionsAlignment = this.scribe.createAlignment("expressions", Alignment.M_COMPACT_SPLIT + someMessageSend(Alignment.M_COMPACT_SPLIT, Alignment.M_COMPACT_SPLIT, Alignment.M_COMPACT_SPLIT, Alignment.M_COMPACT_SPLIT),expressionsLength - 1, this.scribe.scanner.currentPosition);			
7
	}
8
}
(-)workspace/Formatter/test026b/A_out.java (+17 lines)
Added Link Here
1
// test026
2
public class A {
3
	public void foo() {
4
		this.longReceiver.someQuiteLongMessageSend("aaaaaaaaaaa",
5
				"bbbbbbbbbbbbb", "cccccccc");
6
		this.extremlylongReceiverWillCauseTwoSplitActions
7
				.someQuiteLongMessageSend("aaaaaaaaaaa", "bbbbbbbbbbbbb",
8
						"cccccccc");
9
		Alignment expressionsAlignment = this.scribe.createAlignment(
10
				"expressions", Alignment.M_COMPACT_SPLIT
11
						+ someMessageSend(Alignment.M_COMPACT_SPLIT,
12
								Alignment.M_COMPACT_SPLIT,
13
								Alignment.M_COMPACT_SPLIT,
14
								Alignment.M_COMPACT_SPLIT),
15
				expressionsLength - 1, this.scribe.scanner.currentPosition);
16
	}
17
}
(-)workspace/Formatter/test167b/A_in.java (+14 lines)
Added Link Here
1
public class X {
2
	X(String s) {
3
	}
4
	protected void foo() {
5
		X a = new X(new StringBuffer("this").append("is").append
6
("a").append(
7
				"long")
8
				.append("argument")
9
				.toString()) {
10
			public void run() {
11
			}
12
		};
13
	}
14
}
(-)workspace/Formatter/test167b/A_out.java (+11 lines)
Added Link Here
1
public class X {
2
	X(String s) {
3
	}
4
	protected void foo() {
5
		X a = new X(new StringBuffer("this").append("is").append("a").append(
6
				"long").append("argument").toString()) {
7
			public void run() {
8
			}
9
		};
10
	}
11
}
(-)workspace/Formatter/test169b/A_in.java (+7 lines)
Added Link Here
1
public class X {
2
	X(String s) {
3
	}
4
	protected void foo() {
5
		cmd.createArgument().foo().test().error().setFile(destDir.getAbsoluteFile());
6
	}
7
}
(-)workspace/Formatter/test169b/A_out.java (+8 lines)
Added Link Here
1
public class X {
2
	X(String s) {
3
	}
4
	protected void foo() {
5
		cmd.createArgument().foo().test().error().setFile(
6
				destDir.getAbsoluteFile());
7
	}
8
}
(-)workspace/Formatter/test170b/A_in.java (+7 lines)
Added Link Here
1
public class X {
2
	X(String s) {
3
	}
4
	protected void foo() {
5
		cmd.createArgument().foo().test().error().setFile((Name) (destDir()).getAbsoluteFile());
6
	}
7
}
(-)workspace/Formatter/test170b/A_out.java (+8 lines)
Added Link Here
1
public class X {
2
	X(String s) {
3
	}
4
	protected void foo() {
5
		cmd.createArgument().foo().test().error().setFile(
6
				(Name) (destDir()).getAbsoluteFile());
7
	}
8
}
(-)workspace/Formatter/test337b/A_in.java (+339 lines)
Added Link Here
1
package org.eclipse.update.configurator;
2
3
import java.io.File;
4
import java.io.IOException;
5
import java.net.MalformedURLException;
6
import java.net.URL;
7
import java.util.*;
8
import org.eclipse.core.runtime.*;
9
import org.eclipse.osgi.service.environment.DebugOptions;
10
import org.eclipse.osgi.service.environment.EnvironmentInfo;
11
import org.osgi.framework.*;
12
import org.osgi.service.packageadmin.PackageAdmin;
13
import org.osgi.service.startlevel.StartLevel;
14
import org.osgi.util.tracker.ServiceTracker;
15
16
public class ConfigurationActivator implements BundleActivator {
17
	private final static String DEFAULT_CONVERTER = "org.eclipse.update.configurator.migration.PluginConverter"; //$NON-NLS-1$
18
	
19
	public static String PI_CONFIGURATOR = "org.eclipse.update.configurator";
20
	// debug options
21
	public static String OPTION_DEBUG = PI_CONFIGURATOR + "/debug";
22
	public static String OPTION_DEBUG_CONVERTER = PI_CONFIGURATOR + "/converter/debug";
23
	// debug values
24
	public static boolean DEBUG = false;
25
	public static boolean DEBUG_CONVERTER = false;
26
	
27
	private static BundleContext context;
28
	private ServiceTracker platformTracker;
29
	private ServiceRegistration configurationFactorySR;
30
	private String[] allArgs;
31
32
	// location used to put the generated manfests
33
	private String cacheLocation = (String) System.getProperties().get("osgi.manifest.cache"); //PASCAL Need to set this value somewhere (probably from boot)
34
	private IPluginConverter converter;
35
	private Set ignore;
36
	private BundleListener reconcilerListener;
37
	
38
	public void start(BundleContext ctx) throws Exception {
39
		context = ctx;loadOptions();if (DEBUG)
40
			System.out.println("Starting update configurator...");
41
		computeIgnoredBundles();
42
		loadConverter();
43
		obtainArgs();		
44
		installBundles();
45
	}	
46
	private void computeIgnoredBundles() {
47
		String ignoreList = System.getProperty("eclipse.ignore","org.eclipse.osgi,org.eclipse.core.boot,org.eclipse.core.runtime.adaptor");
48
		ignore = new HashSet();
49
		StringTokenizer tokenizer = new StringTokenizer(ignoreList,",");
50
		while(tokenizer.hasMoreTokens())
51
			ignore.add(tokenizer.nextToken().trim());		
52
	}
53
	private boolean shouldIgnore(String bundleName) {
54
		if (ignore == null)
55
			return false;
56
		StringTokenizer tokenizer = new StringTokenizer(bundleName,"._");
57
		String partialName = "";
58
		while(tokenizer.hasMoreTokens()) {
59
			partialName += tokenizer.nextToken();
60
			if (ignore.contains(partialName))
61
				return true;
62
			partialName +=  ".";
63
		} 
64
		return false;
65
	}
66
	private void loadConverter() {
67
		// TODO look at making this an extension
68
		String converterClassName = System.getProperty("eclipse.manifestconverter", DEFAULT_CONVERTER);
69
		if (converterClassName == null)
70
			return;
71
		Class converterClass;
72
		try {
73
			converterClass = Class.forName(converterClassName);
74
		} catch (ClassNotFoundException e) {
75
			return;
76
		}
77
		try {
78
			converter = (IPluginConverter) converterClass.newInstance();
79
		} catch (InstantiationException e1) {
80
			return;
81
		} catch (IllegalAccessException e1) {
82
			return;
83
		} catch (ClassCastException cce) {
84
			return;
85
		}		
86
	}
87
	private void obtainArgs() {
88
		// all this is only to get the application args		
89
		EnvironmentInfo envInfo = null;
90
		ServiceReference envInfoSR = context.getServiceReference(EnvironmentInfo.class.getName());		
91
		if (envInfoSR != null)
92
			envInfo = (EnvironmentInfo) context.getService(envInfoSR);
93
		if (envInfo == null)
94
			throw new IllegalStateException();
95
		this.allArgs = envInfo.getAllArgs();
96
		// we have what we want - release the service
97
		context.ungetService(envInfoSR);
98
	}
99
100
	public void stop(BundleContext ctx) throws Exception {
101
		releasePlatform();
102
		configurationFactorySR.unregister();
103
	}
104
105
	private void releasePlatform() {
106
		if (platformTracker == null)
107
			return;
108
		platformTracker.close();
109
		platformTracker = null;
110
	}
111
	private IPlatform acquirePlatform() {
112
		if (platformTracker == null) {
113
			platformTracker = new ServiceTracker(context, IPlatform.class.getName(), null);
114
			platformTracker.open();
115
		}
116
		IPlatform result = (IPlatform) platformTracker.getService();
117
		while (result == null) {
118
			try {
119
				platformTracker.waitForService(1000);
120
				result = (IPlatform) platformTracker.getService();
121
			} catch (InterruptedException ie) {
122
			}
123
		}
124
		return result;
125
	}
126
127
	private void installBundles() {
128
		IPlatform platform = acquirePlatform();
129
130
		String metaPath = platform.getLocation().append(".metadata").toOSString();
131
		URL installURL = platform.getInstallURL();
132
		ServiceReference reference = context.getServiceReference(StartLevel.class.getName());
133
		StartLevel start = null;
134
		if (reference != null) 
135
			start = (StartLevel) context.getService(reference);
136
		try {
137
			configurationFactorySR = context.registerService(IPlatformConfigurationFactory.class.getName(), new PlatformConfigurationFactory(), null);
138
			PlatformConfiguration config = getPlatformConfiguration(allArgs, metaPath, installURL);
139
			URL[] plugins = config.getPluginPath();
140
			ArrayList installed = new ArrayList(plugins.length);
141
			for (int i = 0; i < plugins.length; i++) {
142
				try {
143
				String location = plugins[i].toExternalForm();
144
				checkOrGenerateManifest(location);
145
				location = "reference:" + location.substring(0, location.lastIndexOf('/'));
146
				if (!isInstalled(location)) {
147
					try {
148
						Bundle target = context.installBundle(location);
149
						installed.add(target);
150
						if (start != null)
151
							start.setBundleStartLevel(target, 4);
152
					} catch (Exception e) {
153
						System.err.println("Ignoring bundle at: " + location);
154
						System.err.println(e.getMessage());
155
					}
156
				}
157
			} catch (Exception e) {
158
				// TODO Auto-generated catch block
159
				e.printStackTrace();
160
			}
161
			context.ungetService(reference);
162
			refreshPackages((Bundle[]) installed.toArray(new Bundle[installed.size()]));
163
			if (System.getProperty("eclipse.application") == null || System.getProperty("eclipse.application").equals(PlatformConfiguration.RECONCILER_APP))
164
				System.setProperty("eclipse.application", config.getApplicationIdentifier());
165
//			if (config.getApplicationIdentifier().equals(PlatformConfiguration.RECONCILER_APP) ) {
166
//				reconcilerListener = reconcilerListener();
167
//				context.addBundleListener(reconcilerListener);
168
//			}
169
		} catch (Exception e) {
170
			// TODO Auto-generated catch block
171
			e.printStackTrace();
172
		} finally {
173
			releasePlatform();
174
		}
175
	}
176
177
	private BundleListener reconcilerListener() {
178
		return new BundleListener() {
179
			public void bundleChanged(BundleEvent event) {
180
				String buid = event.getBundle().getUniqueId();
181
				if (event.getType() == BundleEvent.STOPPED && buid!=null && buid.equals("org.eclipse.update.core")) 
182
					runPostReconciler();
183
			}
184
		};
185
	}
186
187
	private void runPostReconciler() {
188
		Runnable postReconciler = new Runnable() {
189
			public void run() {
190
				try {
191
					Bundle apprunner = context.getBundle("org.eclipse.core.applicationrunner");
192
					apprunner.stop();
193
					context.removeBundleListener(reconcilerListener);
194
					try {
195
						PlatformConfiguration.shutdown();
196
					} catch (IOException e) {
197
						// TODO Auto-generated catch block
198
						e.printStackTrace();
199
					}
200
					installBundles();
201
					apprunner.start();
202
				} catch (BundleException be) {
203
					be.printStackTrace();
204
				}				
205
			}
206
		};
207
		new Thread(postReconciler, "Post reconciler").start();
208
	}
209
	/**
210
	 * @param location
211
	 */
212
	private void checkOrGenerateManifest(String pluginManifestLocationURL) {		
213
		if (converter == null)			
214
			return;
215
		String pluginManifestLocation = null;
216
		try {
217
			pluginManifestLocation = new URL(pluginManifestLocationURL).getPath();
218
		} catch (MalformedURLException e) {
219
			return;
220
		}
221
		File pluginDir = new File(pluginManifestLocation).getParentFile();
222
		if (shouldIgnore(pluginDir.getName()))
223
			return; 		
224
		File manifest = new File(pluginDir, "META-INF/MANIFEST.MF");
225
		if (manifest.exists())
226
			return;
227
		// bail if the install location is not writable and we don't know where else to write to
228
		if (cacheLocation == null) 
229
			return;
230
		File generationLocation = new File(cacheLocation, computeFileName(pluginDir.getPath()) + ".MF");			
231
		if (generationLocation.exists())
232
			return;			
233
		if (!converter.convertManifest(pluginDir, generationLocation))
234
			System.out.println(pluginDir + " manifest generation failed");
235
	}
236
	/*
237
	 * Derives a file name corresponding to a path:
238
	 * c:\autoexec.bat -> c__autoexec.bat
239
	 */
240
	private String computeFileName(String filePath) {
241
		StringBuffer newName = new StringBuffer(filePath);
242
		for (int i = 0; i < filePath.length(); i++) {
243
			char c = newName.charAt(i);
244
			if (c == ':' || c == '/' || c == '\\')
245
				newName.setCharAt(i,'_');
246
		}
247
		return newName.toString();
248
	}
249
	/**
250
	 * This is a major hack to try to get the reconciler application running. However we should find a way to not run it.
251
	 * @param args
252
	 * @param metaPath
253
	 * @return
254
	 */
255
	private PlatformConfiguration getPlatformConfiguration(String[] args, String metaPath, URL installURL) {
256
		try {
257
			PlatformConfiguration.startup(args, null, null, metaPath, installURL);
258
		} catch (Exception e) {
259
			if (platformTracker != null) {
260
				String message = e.getMessage();
261
				if (message == null)
262
					message = "";
263
				IStatus status = new Status(IStatus.ERROR,IPlatform.PI_RUNTIME,IStatus.OK,message,e);
264
				((IPlatform)platformTracker.getService()).getLog(context.getBundle()).log(status);
265
			}
266
		}
267
		return PlatformConfiguration.getCurrent();
268
269
	}
270
271
	/**
272
	 * Do PackageAdmin.refreshPackages() in a synchronous way.  After installing
273
	 * all the requested bundles we need to do a refresh and want to ensure that 
274
	 * everything is done before returning.
275
	 * @param bundles
276
	 */
277
	private void refreshPackages(Bundle[] bundles) {
278
		if (bundles.length == 0)
279
			return;
280
		ServiceReference packageAdminRef = context.getServiceReference(PackageAdmin.class.getName());
281
		PackageAdmin packageAdmin = null;
282
		if (packageAdminRef != null) {
283
			packageAdmin = (PackageAdmin) context.getService(packageAdminRef);
284
			if (packageAdmin == null)
285
				return;
286
		}
287
		// TODO this is such a hack it is silly.  There are still cases for race conditions etc
288
		// but this should allow for some progress...
289
		final Object semaphore = new Object();
290
		FrameworkListener listener = new FrameworkListener() {
291
			public void frameworkEvent(FrameworkEvent event) {
292
				if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED)
293
					synchronized (semaphore) {
294
						semaphore.notifyAll();
295
					}
296
			}
297
		};
298
		context.addFrameworkListener(listener);
299
		packageAdmin.refreshPackages(bundles);
300
		synchronized (semaphore) {
301
			try {
302
				semaphore.wait();
303
			} catch (InterruptedException e) {
304
			}
305
		}
306
		context.removeFrameworkListener(listener);
307
		context.ungetService(packageAdminRef);
308
	}
309
310
	private boolean isInstalled(String location) {
311
		Bundle[] installed = context.getBundles();
312
		for (int i = 0; i < installed.length; i++) {
313
			Bundle bundle = installed[i];
314
			if (location.equalsIgnoreCase(bundle.getLocation()))
315
				return true;
316
		}
317
		return false;
318
	}
319
320
	private void loadOptions() {
321
		// all this is only to get the application args		
322
		DebugOptions service = null;ServiceReference reference = context.getServiceReference(DebugOptions.class.getName());		
323
		if (reference != null)
324
			service = (DebugOptions) context.getService(reference);
325
		if (service == null)
326
			return;
327
		try {
328
			DEBUG = service.getBooleanOption(OPTION_DEBUG, false);
329
			if (!DEBUG)
330
				return;
331
			DEBUG_CONVERTER = service.getBooleanOption(OPTION_DEBUG_CONVERTER, false);
332
		} finally {
333
			// we have what we want - release the service
334
			context.ungetService(reference);
335
		}
336
	}
337
	public static BundleContext getBundleContext() {return context;
338
	}
339
}
(-)workspace/Formatter/test337b/A_out.java (+346 lines)
Added Link Here
1
package org.eclipse.update.configurator;
2
import java.io.File;
3
import java.io.IOException;
4
import java.net.MalformedURLException;
5
import java.net.URL;
6
import java.util.*;
7
import org.eclipse.core.runtime.*;
8
import org.eclipse.osgi.service.environment.DebugOptions;
9
import org.eclipse.osgi.service.environment.EnvironmentInfo;
10
import org.osgi.framework.*;
11
import org.osgi.service.packageadmin.PackageAdmin;
12
import org.osgi.service.startlevel.StartLevel;
13
import org.osgi.util.tracker.ServiceTracker;
14
public class ConfigurationActivator implements BundleActivator {
15
	private final static String DEFAULT_CONVERTER = "org.eclipse.update.configurator.migration.PluginConverter"; //$NON-NLS-1$
16
	public static String PI_CONFIGURATOR = "org.eclipse.update.configurator";
17
	// debug options
18
	public static String OPTION_DEBUG = PI_CONFIGURATOR + "/debug";
19
	public static String OPTION_DEBUG_CONVERTER = PI_CONFIGURATOR
20
			+ "/converter/debug";
21
	// debug values
22
	public static boolean DEBUG = false;
23
	public static boolean DEBUG_CONVERTER = false;
24
	private static BundleContext context;
25
	private ServiceTracker platformTracker;
26
	private ServiceRegistration configurationFactorySR;
27
	private String[] allArgs;
28
	// location used to put the generated manfests
29
	private String cacheLocation = (String) System.getProperties().get(
30
			"osgi.manifest.cache"); //PASCAL Need to set this value somewhere (probably from boot)
31
	private IPluginConverter converter;
32
	private Set ignore;
33
	private BundleListener reconcilerListener;
34
	public void start(BundleContext ctx) throws Exception {
35
		context = ctx;
36
		loadOptions();
37
		if (DEBUG)
38
			System.out.println("Starting update configurator...");
39
		computeIgnoredBundles();
40
		loadConverter();
41
		obtainArgs();
42
		installBundles();
43
	}
44
	private void computeIgnoredBundles() {
45
		String ignoreList = System
46
				.getProperty("eclipse.ignore",
47
						"org.eclipse.osgi,org.eclipse.core.boot,org.eclipse.core.runtime.adaptor");
48
		ignore = new HashSet();
49
		StringTokenizer tokenizer = new StringTokenizer(ignoreList, ",");
50
		while (tokenizer.hasMoreTokens())
51
			ignore.add(tokenizer.nextToken().trim());
52
	}
53
	private boolean shouldIgnore(String bundleName) {
54
		if (ignore == null)
55
			return false;
56
		StringTokenizer tokenizer = new StringTokenizer(bundleName, "._");
57
		String partialName = "";
58
		while (tokenizer.hasMoreTokens()) {
59
			partialName += tokenizer.nextToken();
60
			if (ignore.contains(partialName))
61
				return true;
62
			partialName += ".";
63
		}
64
		return false;
65
	}
66
	private void loadConverter() {
67
		// TODO look at making this an extension
68
		String converterClassName = System.getProperty(
69
				"eclipse.manifestconverter", DEFAULT_CONVERTER);
70
		if (converterClassName == null)
71
			return;
72
		Class converterClass;
73
		try {
74
			converterClass = Class.forName(converterClassName);
75
		} catch (ClassNotFoundException e) {
76
			return;
77
		}
78
		try {
79
			converter = (IPluginConverter) converterClass.newInstance();
80
		} catch (InstantiationException e1) {
81
			return;
82
		} catch (IllegalAccessException e1) {
83
			return;
84
		} catch (ClassCastException cce) {
85
			return;
86
		}
87
	}
88
	private void obtainArgs() {
89
		// all this is only to get the application args		
90
		EnvironmentInfo envInfo = null;
91
		ServiceReference envInfoSR = context
92
				.getServiceReference(EnvironmentInfo.class.getName());
93
		if (envInfoSR != null)
94
			envInfo = (EnvironmentInfo) context.getService(envInfoSR);
95
		if (envInfo == null)
96
			throw new IllegalStateException();
97
		this.allArgs = envInfo.getAllArgs();
98
		// we have what we want - release the service
99
		context.ungetService(envInfoSR);
100
	}
101
	public void stop(BundleContext ctx) throws Exception {
102
		releasePlatform();
103
		configurationFactorySR.unregister();
104
	}
105
	private void releasePlatform() {
106
		if (platformTracker == null)
107
			return;
108
		platformTracker.close();
109
		platformTracker = null;
110
	}
111
	private IPlatform acquirePlatform() {
112
		if (platformTracker == null) {
113
			platformTracker = new ServiceTracker(context, IPlatform.class
114
					.getName(), null);
115
			platformTracker.open();
116
		}
117
		IPlatform result = (IPlatform) platformTracker.getService();
118
		while (result == null) {
119
			try {
120
				platformTracker.waitForService(1000);
121
				result = (IPlatform) platformTracker.getService();
122
			} catch (InterruptedException ie) {
123
			}
124
		}
125
		return result;
126
	}
127
	private void installBundles() {
128
		IPlatform platform = acquirePlatform();
129
130
		String metaPath = platform.getLocation().append(".metadata").toOSString();
131
		URL installURL = platform.getInstallURL();
132
		ServiceReference reference = context.getServiceReference(StartLevel.class.getName());
133
		StartLevel start = null;
134
		if (reference != null) 
135
			start = (StartLevel) context.getService(reference);
136
		try {
137
			configurationFactorySR = context.registerService(IPlatformConfigurationFactory.class.getName(), new PlatformConfigurationFactory(), null);
138
			PlatformConfiguration config = getPlatformConfiguration(allArgs, metaPath, installURL);
139
			URL[] plugins = config.getPluginPath();
140
			ArrayList installed = new ArrayList(plugins.length);
141
			for (int i = 0; i < plugins.length; i++) {
142
				try {
143
				String location = plugins[i].toExternalForm();
144
				checkOrGenerateManifest(location);
145
				location = "reference:" + location.substring(0, location.lastIndexOf('/'));
146
				if (!isInstalled(location)) {
147
					try {
148
						Bundle target = context.installBundle(location);
149
						installed.add(target);
150
						if (start != null)
151
							start.setBundleStartLevel(target, 4);
152
					} catch (Exception e) {
153
						System.err.println("Ignoring bundle at: " + location);
154
						System.err.println(e.getMessage());
155
					}
156
				}
157
			} catch (Exception e) {
158
				// TODO Auto-generated catch block
159
				e.printStackTrace();
160
			}
161
			context.ungetService(reference);
162
			refreshPackages((Bundle[]) installed.toArray(new Bundle[installed.size()]));
163
			if (System.getProperty("eclipse.application") == null || System.getProperty("eclipse.application").equals(PlatformConfiguration.RECONCILER_APP))
164
				System.setProperty("eclipse.application", config.getApplicationIdentifier());
165
//			if (config.getApplicationIdentifier().equals(PlatformConfiguration.RECONCILER_APP) ) {
166
//				reconcilerListener = reconcilerListener();
167
//				context.addBundleListener(reconcilerListener);
168
//			}
169
		} catch (Exception e) {
170
			// TODO Auto-generated catch block
171
			e.printStackTrace();
172
		} finally {
173
			releasePlatform();
174
		}
175
	}
176
	private BundleListener reconcilerListener() {
177
		return new BundleListener() {
178
			public void bundleChanged(BundleEvent event) {
179
				String buid = event.getBundle().getUniqueId();
180
				if (event.getType() == BundleEvent.STOPPED && buid != null
181
						&& buid.equals("org.eclipse.update.core"))
182
					runPostReconciler();
183
			}
184
		};
185
	}
186
	private void runPostReconciler() {
187
		Runnable postReconciler = new Runnable() {
188
			public void run() {
189
				try {
190
					Bundle apprunner = context
191
							.getBundle("org.eclipse.core.applicationrunner");
192
					apprunner.stop();
193
					context.removeBundleListener(reconcilerListener);
194
					try {
195
						PlatformConfiguration.shutdown();
196
					} catch (IOException e) {
197
						// TODO Auto-generated catch block
198
						e.printStackTrace();
199
					}
200
					installBundles();
201
					apprunner.start();
202
				} catch (BundleException be) {
203
					be.printStackTrace();
204
				}
205
			}
206
		};
207
		new Thread(postReconciler, "Post reconciler").start();
208
	}
209
	/**
210
	 * @param location
211
	 */
212
	private void checkOrGenerateManifest(String pluginManifestLocationURL) {
213
		if (converter == null)
214
			return;
215
		String pluginManifestLocation = null;
216
		try {
217
			pluginManifestLocation = new URL(pluginManifestLocationURL)
218
					.getPath();
219
		} catch (MalformedURLException e) {
220
			return;
221
		}
222
		File pluginDir = new File(pluginManifestLocation).getParentFile();
223
		if (shouldIgnore(pluginDir.getName()))
224
			return;
225
		File manifest = new File(pluginDir, "META-INF/MANIFEST.MF");
226
		if (manifest.exists())
227
			return;
228
		// bail if the install location is not writable and we don't know where else to write to
229
		if (cacheLocation == null)
230
			return;
231
		File generationLocation = new File(cacheLocation,
232
				computeFileName(pluginDir.getPath()) + ".MF");
233
		if (generationLocation.exists())
234
			return;
235
		if (!converter.convertManifest(pluginDir, generationLocation))
236
			System.out.println(pluginDir + " manifest generation failed");
237
	}
238
	/*
239
	 * Derives a file name corresponding to a path:
240
	 * c:\autoexec.bat -> c__autoexec.bat
241
	 */
242
	private String computeFileName(String filePath) {
243
		StringBuffer newName = new StringBuffer(filePath);
244
		for (int i = 0; i < filePath.length(); i++) {
245
			char c = newName.charAt(i);
246
			if (c == ':' || c == '/' || c == '\\')
247
				newName.setCharAt(i, '_');
248
		}
249
		return newName.toString();
250
	}
251
	/**
252
	 * This is a major hack to try to get the reconciler application running. However we should find a way to not run it.
253
	 * @param args
254
	 * @param metaPath
255
	 * @return
256
	 */
257
	private PlatformConfiguration getPlatformConfiguration(String[] args,
258
			String metaPath, URL installURL) {
259
		try {
260
			PlatformConfiguration.startup(args, null, null, metaPath,
261
					installURL);
262
		} catch (Exception e) {
263
			if (platformTracker != null) {
264
				String message = e.getMessage();
265
				if (message == null)
266
					message = "";
267
				IStatus status = new Status(IStatus.ERROR,
268
						IPlatform.PI_RUNTIME, IStatus.OK, message, e);
269
				((IPlatform) platformTracker.getService()).getLog(
270
						context.getBundle()).log(status);
271
			}
272
		}
273
		return PlatformConfiguration.getCurrent();
274
	}
275
	/**
276
	 * Do PackageAdmin.refreshPackages() in a synchronous way.  After installing
277
	 * all the requested bundles we need to do a refresh and want to ensure that 
278
	 * everything is done before returning.
279
	 * @param bundles
280
	 */
281
	private void refreshPackages(Bundle[] bundles) {
282
		if (bundles.length == 0)
283
			return;
284
		ServiceReference packageAdminRef = context
285
				.getServiceReference(PackageAdmin.class.getName());
286
		PackageAdmin packageAdmin = null;
287
		if (packageAdminRef != null) {
288
			packageAdmin = (PackageAdmin) context.getService(packageAdminRef);
289
			if (packageAdmin == null)
290
				return;
291
		}
292
		// TODO this is such a hack it is silly.  There are still cases for race conditions etc
293
		// but this should allow for some progress...
294
		final Object semaphore = new Object();
295
		FrameworkListener listener = new FrameworkListener() {
296
			public void frameworkEvent(FrameworkEvent event) {
297
				if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED)
298
					synchronized (semaphore) {
299
						semaphore.notifyAll();
300
					}
301
			}
302
		};
303
		context.addFrameworkListener(listener);
304
		packageAdmin.refreshPackages(bundles);
305
		synchronized (semaphore) {
306
			try {
307
				semaphore.wait();
308
			} catch (InterruptedException e) {
309
			}
310
		}
311
		context.removeFrameworkListener(listener);
312
		context.ungetService(packageAdminRef);
313
	}
314
	private boolean isInstalled(String location) {
315
		Bundle[] installed = context.getBundles();
316
		for (int i = 0; i < installed.length; i++) {
317
			Bundle bundle = installed[i];
318
			if (location.equalsIgnoreCase(bundle.getLocation()))
319
				return true;
320
		}
321
		return false;
322
	}
323
	private void loadOptions() {
324
		// all this is only to get the application args		
325
		DebugOptions service = null;
326
		ServiceReference reference = context
327
				.getServiceReference(DebugOptions.class.getName());
328
		if (reference != null)
329
			service = (DebugOptions) context.getService(reference);
330
		if (service == null)
331
			return;
332
		try {
333
			DEBUG = service.getBooleanOption(OPTION_DEBUG, false);
334
			if (!DEBUG)
335
				return;
336
			DEBUG_CONVERTER = service.getBooleanOption(OPTION_DEBUG_CONVERTER,
337
					false);
338
		} finally {
339
			// we have what we want - release the service
340
			context.ungetService(reference);
341
		}
342
	}
343
	public static BundleContext getBundleContext() {
344
		return context;
345
	}
346
}
(-)workspace/Formatter/test455b/A_in.java (+49 lines)
Added Link Here
1
public class A {
2
	public void launch(
3
		ILaunchConfiguration configuration,
4
		String mode,
5
		ILaunch launch,
6
		IProgressMonitor monitor)
7
		throws CoreException {
8
		try {
9
			IJavaProject javaProject = getJavaProject(configuration);
10
			if ((javaProject == null) || !javaProject.exists()) {
11
				abort(PDEPlugin.getResourceString("JUnitLaunchConfiguration.error.invalidproject"), null, IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT); //$NON-NLS-1$
12
			}
13
			IType[] testTypes = getTestTypes(configuration, javaProject, new SubProgressMonitor(monitor, 1));
14
			if (testTypes.length == 0) {
15
				abort(PDEPlugin.getResourceString("JUnitLaunchConfiguration.error.notests"), null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); //$NON-NLS-1$
16
			}
17
			monitor.worked(1);
18
			
19
			IVMInstall launcher = LauncherUtils.createLauncher(configuration);
20
			monitor.worked(1);
21
22
			int port = SocketUtil.findFreePort();
23
			VMRunnerConfiguration runnerConfig =
24
				createVMRunner(configuration, testTypes, port, mode);
25
			if (runnerConfig == null) {
26
				monitor.setCanceled(true);
27
				return;
28
			} 
29
			monitor.worked(1);
30
			
31
			launch.setAttribute(
32
				ILauncherSettings.CONFIG_LOCATION,
33
				(configFile == null) ? null : configFile.getParent());
34
			
35
			String workspace = configuration.getAttribute(LOCATION + "0", getDefaultWorkspace(configuration));
36
			LauncherUtils.clearWorkspace(configuration,workspace);
37
38
			setDefaultSourceLocator(launch, configuration);
39
			launch.setAttribute(PORT_ATTR, Integer.toString(port));
40
			launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier());
41
			PDEPlugin.getDefault().getLaunchesListener().manage(launch);
42
			launcher.getVMRunner(mode).run(runnerConfig, launch, monitor);
43
			monitor.worked(1);
44
		} catch (CoreException e) {
45
			monitor.setCanceled(true);
46
			throw e;
47
		}
48
	}
49
}
(-)workspace/Formatter/test455b/A_out.java (+49 lines)
Added Link Here
1
public class A {
2
	public void launch(ILaunchConfiguration configuration, String mode,
3
			ILaunch launch, IProgressMonitor monitor) throws CoreException {
4
		try {
5
			IJavaProject javaProject = getJavaProject(configuration);
6
			if ((javaProject == null) || !javaProject.exists()) {
7
				abort(PDEPlugin
8
						.getResourceString("JUnitLaunchConfiguration.error.invalidproject"), null, IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT); //$NON-NLS-1$
9
			}
10
			IType[] testTypes = getTestTypes(configuration, javaProject,
11
					new SubProgressMonitor(monitor, 1));
12
			if (testTypes.length == 0) {
13
				abort(PDEPlugin
14
						.getResourceString("JUnitLaunchConfiguration.error.notests"), null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE); //$NON-NLS-1$
15
			}
16
			monitor.worked(1);
17
18
			IVMInstall launcher = LauncherUtils.createLauncher(configuration);
19
			monitor.worked(1);
20
21
			int port = SocketUtil.findFreePort();
22
			VMRunnerConfiguration runnerConfig = createVMRunner(configuration,
23
					testTypes, port, mode);
24
			if (runnerConfig == null) {
25
				monitor.setCanceled(true);
26
				return;
27
			}
28
			monitor.worked(1);
29
30
			launch.setAttribute(ILauncherSettings.CONFIG_LOCATION,
31
					(configFile == null) ? null : configFile.getParent());
32
33
			String workspace = configuration.getAttribute(LOCATION + "0",
34
					getDefaultWorkspace(configuration));
35
			LauncherUtils.clearWorkspace(configuration, workspace);
36
37
			setDefaultSourceLocator(launch, configuration);
38
			launch.setAttribute(PORT_ATTR, Integer.toString(port));
39
			launch.setAttribute(TESTTYPE_ATTR, testTypes[0]
40
					.getHandleIdentifier());
41
			PDEPlugin.getDefault().getLaunchesListener().manage(launch);
42
			launcher.getVMRunner(mode).run(runnerConfig, launch, monitor);
43
			monitor.worked(1);
44
		} catch (CoreException e) {
45
			monitor.setCanceled(true);
46
			throw e;
47
		}
48
	}
49
}

Return to bug 313524