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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java (+360 lines)
Lines 38-43 Link Here
38
}
38
}
39
39
40
/**
40
/**
41
 * @bug 198963: [formatter] 3.3 Code Formatter repeatedly indents block comment
42
 * @test Ensure that no the formatter indents the block comment only once
43
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=198963"
44
 */
45
public void testBug198963_Tabs01() {
46
	this.formatterPrefs.comment_format_block_comment = false;
47
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
48
	String source =
49
		"public class Test {\n" + 
50
		"\n" + 
51
		"    int x = 0; /*\n" + 
52
		"    * XXXX\n" + 
53
		"    */\n" + 
54
		"}";
55
	formatSource(source,
56
		"public class Test {\n" + 
57
		"\n" + 
58
		"	int x = 0; /*\n" + 
59
		"				* XXXX\n" + 
60
		"				*/\n" + 
61
		"}"
62
	);
63
}
64
public void testBug198963_Tabs02() {
65
	this.formatterPrefs.comment_format_block_comment = false;
66
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
67
	String source =
68
		"public class Test {\n" + 
69
		"\n" + 
70
		"    int x = 10; /*\n" + 
71
		"    * XXXX\n" + 
72
		"    */\n" + 
73
		"}";
74
	formatSource(source,
75
		"public class Test {\n" + 
76
		"\n" + 
77
		"	int x = 10; /*\n" + 
78
		"				* XXXX\n" + 
79
		"				*/\n" + 
80
		"}"
81
	);
82
}
83
public void testBug198963_Tabs03() {
84
	this.formatterPrefs.comment_format_block_comment = false;
85
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
86
	String source =
87
		"public class Test {\n" + 
88
		"\n" + 
89
		"    int x = 100; /*\n" + 
90
		"    * XXXX\n" + 
91
		"    */\n" + 
92
		"}";
93
	formatSource(source,
94
		"public class Test {\n" + 
95
		"\n" + 
96
		"	int x = 100; /*\n" + 
97
		"					* XXXX\n" + 
98
		"					*/\n" + 
99
		"}"
100
	);
101
}
102
public void testBug198963_Tabs04() {
103
	this.formatterPrefs.comment_format_block_comment = false;
104
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
105
	String source =
106
		"public class Test {\n" + 
107
		"\n" + 
108
		"    int x = 0; /*\n" + 
109
		"                      * XXXX\n" + 
110
		"                        */\n" + 
111
		"}";
112
	formatSource(source,
113
		"public class Test {\n" + 
114
		"\n" + 
115
		"	int x = 0; /*\n" + 
116
		"				       * XXXX\n" + 
117
		"				         */\n" + 
118
		"}"
119
	);
120
}
121
public void testBug198963_Tabs05() {
122
	this.formatterPrefs.comment_format_block_comment = false;
123
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
124
	String source =
125
		"public class Test {\n" + 
126
		"\n" + 
127
		"        /*\n" + 
128
		"             * XXXX\n" + 
129
		"               */\n" + 
130
		"    int x = 0;\n" + 
131
		"}";
132
	formatSource(source,
133
		"public class Test {\n" + 
134
		"\n" + 
135
		"	/*\n" + 
136
		"	     * XXXX\n" + 
137
		"	       */\n" + 
138
		"	int x = 0;\n" + 
139
		"}"
140
	);
141
}
142
public void testBug198963_Tabs06() {
143
	this.formatterPrefs.comment_format_block_comment = false;
144
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.TAB;
145
	String source =
146
		"public class Test {\n" + 
147
		"\n" + 
148
		"            /*\n" + 
149
		"         * XXXX\n" + 
150
		"       */\n" + 
151
		"    int x = 0;\n" + 
152
		"}";
153
	formatSource(source,
154
		"public class Test {\n" + 
155
		"\n" + 
156
		"	/*\n" + 
157
		"	* XXXX\n" + 
158
		"	*/\n" + 
159
		"	int x = 0;\n" + 
160
		"}"
161
	);
162
}
163
public void testBug198963_Spaces01() {
164
	this.formatterPrefs.comment_format_block_comment = false;
165
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
166
	String source =
167
		"public class Test {\n" + 
168
		"\n" + 
169
		"    int x = 0; /*\n" + 
170
		"    * XXXX\n" + 
171
		"    */\n" + 
172
		"}";
173
	formatSource(source,
174
		"public class Test {\n" + 
175
		"\n" + 
176
		"    int x = 0; /*\n" + 
177
		"               * XXXX\n" + 
178
		"               */\n" + 
179
		"}"
180
	);
181
}
182
public void testBug198963_Spaces02() {
183
	this.formatterPrefs.comment_format_block_comment = false;
184
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
185
	String source =
186
		"public class Test {\n" + 
187
		"\n" + 
188
		"    int x = 10; /*\n" + 
189
		"    * XXXX\n" + 
190
		"    */\n" + 
191
		"}";
192
	formatSource(source,
193
		"public class Test {\n" + 
194
		"\n" + 
195
		"    int x = 10; /*\n" + 
196
		"                * XXXX\n" + 
197
		"                */\n" + 
198
		"}"
199
	);
200
}
201
public void testBug198963_Spaces03() {
202
	this.formatterPrefs.comment_format_block_comment = false;
203
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
204
	String source =
205
		"public class Test {\n" + 
206
		"\n" + 
207
		"    int x = 100; /*\n" + 
208
		"    * XXXX\n" + 
209
		"    */\n" + 
210
		"}";
211
	formatSource(source,
212
		"public class Test {\n" + 
213
		"\n" + 
214
		"    int x = 100; /*\n" + 
215
		"                 * XXXX\n" + 
216
		"                 */\n" + 
217
		"}"
218
	);
219
}
220
public void testBug198963_Spaces04() {
221
	this.formatterPrefs.comment_format_block_comment = false;
222
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
223
	String source =
224
		"public class Test {\n" + 
225
		"\n" + 
226
		"    int x = 0; /*\n" + 
227
		"                      * XXXX\n" + 
228
		"                        */\n" + 
229
		"}";
230
	formatSource(source,
231
		"public class Test {\n" + 
232
		"\n" + 
233
		"    int x = 0; /*\n" + 
234
		"                      * XXXX\n" + 
235
		"                        */\n" + 
236
		"}"
237
	);
238
}
239
public void testBug198963_Spaces05() {
240
	this.formatterPrefs.comment_format_block_comment = false;
241
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
242
	String source =
243
		"public class Test {\n" + 
244
		"\n" + 
245
		"        /*\n" + 
246
		"             * XXXX\n" + 
247
		"               */\n" + 
248
		"    int x = 0;\n" + 
249
		"}";
250
	formatSource(source,
251
		"public class Test {\n" + 
252
		"\n" + 
253
		"    /*\n" + 
254
		"         * XXXX\n" + 
255
		"           */\n" + 
256
		"    int x = 0;\n" + 
257
		"}"
258
	);
259
}
260
public void testBug198963_Spaces06() {
261
	this.formatterPrefs.comment_format_block_comment = false;
262
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.SPACE;
263
	String source =
264
		"public class Test {\n" + 
265
		"\n" + 
266
		"            /*\n" + 
267
		"         * XXXX\n" + 
268
		"       */\n" + 
269
		"    int x = 0;\n" + 
270
		"}";
271
	formatSource(source,
272
		"public class Test {\n" + 
273
		"\n" + 
274
		"    /*\n" + 
275
		"    * XXXX\n" + 
276
		"    */\n" + 
277
		"    int x = 0;\n" + 
278
		"}"
279
	);
280
}
281
public void testBug198963_Mixed01() {
282
	this.formatterPrefs.comment_format_block_comment = false;
283
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
284
	String source =
285
		"public class Test {\n" + 
286
		"\n" + 
287
		"    int x = 0; /*\n" + 
288
		"    * XXXX\n" + 
289
		"    */\n" + 
290
		"}";
291
	formatSource(source,
292
		"public class Test {\n" + 
293
		"\n" + 
294
		"	int x = 0; /*\n" + 
295
		"			   * XXXX\n" + 
296
		"			   */\n" + 
297
		"}"
298
	);
299
}
300
public void testBug198963_Mixed02() {
301
	this.formatterPrefs.comment_format_block_comment = false;
302
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
303
	String source =
304
		"public class Test {\n" + 
305
		"\n" + 
306
		"    int x = 10; /*\n" + 
307
		"    * XXXX\n" + 
308
		"    */\n" + 
309
		"}";
310
	formatSource(source,
311
		"public class Test {\n" + 
312
		"\n" + 
313
		"	int x = 10; /*\n" + 
314
		"				* XXXX\n" + 
315
		"				*/\n" + 
316
		"}"
317
	);
318
}
319
public void testBug198963_Mixed03() {
320
	this.formatterPrefs.comment_format_block_comment = false;
321
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
322
	String source =
323
		"public class Test {\n" + 
324
		"\n" + 
325
		"    int x = 100; /*\n" + 
326
		"    * XXXX\n" + 
327
		"    */\n" + 
328
		"}";
329
	formatSource(source,
330
		"public class Test {\n" + 
331
		"\n" + 
332
		"	int x = 100; /*\n" + 
333
		"				 * XXXX\n" + 
334
		"				 */\n" + 
335
		"}"
336
	);
337
}
338
public void testBug198963_Mixed04() {
339
	this.formatterPrefs.comment_format_block_comment = false;
340
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
341
	String source =
342
		"public class Test {\n" + 
343
		"\n" + 
344
		"    int x = 0; /*\n" + 
345
		"                      * XXXX\n" + 
346
		"                        */\n" + 
347
		"}";
348
	formatSource(source,
349
		"public class Test {\n" + 
350
		"\n" + 
351
		"	int x = 0; /*\n" + 
352
		"			          * XXXX\n" + 
353
		"			            */\n" + 
354
		"}"
355
	);
356
}
357
public void testBug198963_Mixed05() {
358
	this.formatterPrefs.comment_format_block_comment = false;
359
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
360
	String source =
361
		"public class Test {\n" + 
362
		"\n" + 
363
		"        /*\n" + 
364
		"             * XXXX\n" + 
365
		"               */\n" + 
366
		"    int x = 0;\n" + 
367
		"}";
368
	formatSource(source,
369
		"public class Test {\n" + 
370
		"\n" + 
371
		"	/*\n" + 
372
		"	     * XXXX\n" + 
373
		"	       */\n" + 
374
		"	int x = 0;\n" + 
375
		"}"
376
	);
377
}
378
public void testBug198963_Mixed06() {
379
	this.formatterPrefs.comment_format_block_comment = false;
380
	this.formatterPrefs.tab_char = DefaultCodeFormatterOptions.MIXED;
381
	String source =
382
		"public class Test {\n" + 
383
		"\n" + 
384
		"            /*\n" + 
385
		"         * XXXX\n" + 
386
		"       */\n" + 
387
		"    int x = 0;\n" + 
388
		"}";
389
	formatSource(source,
390
		"public class Test {\n" + 
391
		"\n" + 
392
		"	/*\n" + 
393
		"	* XXXX\n" + 
394
		"	*/\n" + 
395
		"	int x = 0;\n" + 
396
		"}"
397
	);
398
}
399
400
/**
41
 * @bug 204091: [formatter] format region in comment introduces comment start/end tokens
401
 * @bug 204091: [formatter] format region in comment introduces comment start/end tokens
42
 * @test Ensure that a region inside a javadoc comment is well formatted
402
 * @test Ensure that a region inside a javadoc comment is well formatted
43
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=204091"
403
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=204091"
(-)formatter/org/eclipse/jdt/internal/formatter/Scribe.java (-85 / +91 lines)
Lines 797-810 Link Here
797
				case '\t' :
797
				case '\t' :
798
					offset += this.tabLength;
798
					offset += this.tabLength;
799
					break;
799
					break;
800
				case ' ' :
801
					offset++;
802
					break;
803
				case '\r' :
800
				case '\r' :
804
				case '\n' :
801
				case '\n' :
805
					break;
802
					break;
806
				default:
803
				default:
807
					return offset;
804
					offset++;
805
					break;
808
			}
806
			}
809
		}
807
		}
810
		return offset;
808
		return offset;
Lines 1250-1300 Link Here
1250
		this.needSpace = false;
1248
		this.needSpace = false;
1251
		this.pendingSpace = false;
1249
		this.pendingSpace = false;
1252
1250
1251
		int commentColumn = this.column;
1253
		if (includesBlockComments) {
1252
		if (includesBlockComments) {
1254
			if (printBlockComment(currentTokenStartPosition, currentTokenEndPosition)) {
1253
			if (printBlockComment(currentTokenStartPosition, currentTokenEndPosition)) {
1255
				return;
1254
				return;
1256
			}
1255
			}
1257
		}
1256
		}
1258
1257
1258
		int currentIndentationLevel = this.indentationLevel;
1259
		if ((commentColumn-1) > this.indentationLevel) {
1260
			this.indentationLevel = commentColumn-1;
1261
		}
1259
		int currentCommentOffset = onFirstColumn ? 0 : getCurrentCommentOffset(start);
1262
		int currentCommentOffset = onFirstColumn ? 0 : getCurrentCommentOffset(start);
1260
		boolean formatComment = (isJavadoc && (this.formatComments & CodeFormatter.K_JAVA_DOC) != 0) || (!isJavadoc && (this.formatComments & CodeFormatter.K_MULTI_LINE_COMMENT) != 0);
1263
		boolean formatComment = (isJavadoc && (this.formatComments & CodeFormatter.K_JAVA_DOC) != 0) || (!isJavadoc && (this.formatComments & CodeFormatter.K_MULTI_LINE_COMMENT) != 0);
1261
1264
1262
		while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter = this.scanner.getNextChar()) != -1) {
1265
		try {
1263
			nextCharacterStart = this.scanner.currentPosition;
1266
			while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter = this.scanner.getNextChar()) != -1) {
1264
1267
				nextCharacterStart = this.scanner.currentPosition;
1265
			switch(currentCharacter) {
1268
	
1266
				case '\r' :
1269
				switch(currentCharacter) {
1267
					start = previousStart;
1270
					case '\r' :
1268
					isNewLine = true;
1271
						start = previousStart;
1269
					if (this.scanner.getNextChar('\n')) {
1272
						isNewLine = true;
1270
						currentCharacter = '\n';
1273
						if (this.scanner.getNextChar('\n')) {
1274
							currentCharacter = '\n';
1275
							nextCharacterStart = this.scanner.currentPosition;
1276
						}
1277
						break;
1278
					case '\n' :
1279
						start = previousStart;
1280
						isNewLine = true;
1271
						nextCharacterStart = this.scanner.currentPosition;
1281
						nextCharacterStart = this.scanner.currentPosition;
1272
					}
1282
						break;
1273
					break;
1283
					default:
1274
				case '\n' :
1284
						if (isNewLine) {
1275
					start = previousStart;
1285
							this.column = 1;
1276
					isNewLine = true;
1286
							this.line++;
1277
					nextCharacterStart = this.scanner.currentPosition;
1287
							isNewLine = false;
1278
					break;
1288
	
1279
				default:
1289
							StringBuffer buffer = new StringBuffer();
1280
					if (isNewLine) {
1290
							if (onFirstColumn) {
1281
						this.column = 1;
1291
								// simply insert indentation if necessary
1282
						this.line++;
1292
								buffer.append(this.lineSeparator);
1283
						isNewLine = false;
1293
								if (indentComment) {
1284
1294
									printIndentationIfNecessary(buffer);
1285
						StringBuffer buffer = new StringBuffer();
1295
								}
1286
						if (onFirstColumn) {
1296
								if (formatComment) {
1287
							// simply insert indentation if necessary
1297
									if (ScannerHelper.isWhitespace((char) currentCharacter)) {
1288
							buffer.append(this.lineSeparator);
1298
										int previousStartPosition = this.scanner.currentPosition;
1289
							if (indentComment) {
1299
										while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
1290
								printIndentationIfNecessary(buffer);
1300
											previousStart = nextCharacterStart;
1291
							}
1301
											previousStartPosition = this.scanner.currentPosition;
1292
							if (formatComment) {
1302
											currentCharacter = this.scanner.getNextChar();
1303
											nextCharacterStart = this.scanner.currentPosition;
1304
										}
1305
										if (currentCharacter == '\r' || currentCharacter == '\n') {
1306
											nextCharacterStart = previousStartPosition;
1307
										}
1308
									}
1309
									if (currentCharacter != '\r' && currentCharacter != '\n') {
1310
										buffer.append(' ');
1311
									}
1312
								}
1313
							} else {
1293
								if (ScannerHelper.isWhitespace((char) currentCharacter)) {
1314
								if (ScannerHelper.isWhitespace((char) currentCharacter)) {
1294
									int previousStartPosition = this.scanner.currentPosition;
1315
									int previousStartPosition = this.scanner.currentPosition;
1295
									while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
1316
									int count = 0;
1317
									loop: while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
1318
										if (count >= currentCommentOffset) {
1319
											break loop;
1320
										}
1296
										previousStart = nextCharacterStart;
1321
										previousStart = nextCharacterStart;
1297
										previousStartPosition = this.scanner.currentPosition;
1322
										previousStartPosition = this.scanner.currentPosition;
1323
										switch(currentCharacter) {
1324
											case '\t' :
1325
												count += this.tabLength;
1326
												break;
1327
											default :
1328
												count ++;
1329
										}
1298
										currentCharacter = this.scanner.getNextChar();
1330
										currentCharacter = this.scanner.getNextChar();
1299
										nextCharacterStart = this.scanner.currentPosition;
1331
										nextCharacterStart = this.scanner.currentPosition;
1300
									}
1332
									}
Lines 1302-1363 Link Here
1302
										nextCharacterStart = previousStartPosition;
1334
										nextCharacterStart = previousStartPosition;
1303
									}
1335
									}
1304
								}
1336
								}
1305
								if (currentCharacter != '\r' && currentCharacter != '\n') {
1337
								buffer.append(this.lineSeparator);
1306
									buffer.append(' ');
1338
								if (indentComment) {
1339
									printIndentationIfNecessary(buffer);
1307
								}
1340
								}
1308
							}
1341
								if (formatComment) {
1309
						} else {
1342
									int previousStartTemp = previousStart;
1310
							if (ScannerHelper.isWhitespace((char) currentCharacter)) {
1343
									int nextCharacterStartTemp = nextCharacterStart;
1311
								int previousStartPosition = this.scanner.currentPosition;
1344
									while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
1312
								int count = 0;
1345
										previousStart = nextCharacterStart;
1313
								loop: while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
1346
										currentCharacter = this.scanner.getNextChar();
1314
									if (count >= currentCommentOffset) {
1347
										nextCharacterStart = this.scanner.currentPosition;
1315
										break loop;
1316
									}
1348
									}
1317
									previousStart = nextCharacterStart;
1349
									if (currentCharacter == '*') {
1318
									previousStartPosition = this.scanner.currentPosition;
1350
										buffer.append(' ');
1319
									switch(currentCharacter) {
1351
									} else {
1320
										case '\t' :
1352
										previousStart = previousStartTemp;
1321
											count += this.tabLength;
1353
										nextCharacterStart = nextCharacterStartTemp;
1322
											break;
1323
										default :
1324
											count ++;
1325
									}
1354
									}
1326
									currentCharacter = this.scanner.getNextChar();
1355
									this.scanner.currentPosition = nextCharacterStart;
1327
									nextCharacterStart = this.scanner.currentPosition;
1328
								}
1329
								if (currentCharacter == '\r' || currentCharacter == '\n') {
1330
									nextCharacterStart = previousStartPosition;
1331
								}
1332
							}
1333
							buffer.append(this.lineSeparator);
1334
							if (indentComment) {
1335
								printIndentationIfNecessary(buffer);
1336
							}
1337
							if (formatComment) {
1338
								int previousStartTemp = previousStart;
1339
								int nextCharacterStartTemp = nextCharacterStart;
1340
								while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
1341
									previousStart = nextCharacterStart;
1342
									currentCharacter = this.scanner.getNextChar();
1343
									nextCharacterStart = this.scanner.currentPosition;
1344
								}
1345
								if (currentCharacter == '*') {
1346
									buffer.append(' ');
1347
								} else {
1348
									previousStart = previousStartTemp;
1349
									nextCharacterStart = nextCharacterStartTemp;
1350
								}
1356
								}
1351
								this.scanner.currentPosition = nextCharacterStart;
1352
							}
1357
							}
1358
							addReplaceEdit(start, previousStart - 1, String.valueOf(buffer));
1359
						} else {
1360
							this.column += (nextCharacterStart - previousStart);
1353
						}
1361
						}
1354
						addReplaceEdit(start, previousStart - 1, String.valueOf(buffer));
1362
				}
1355
					} else {
1363
				previousStart = nextCharacterStart;
1356
						this.column += (nextCharacterStart - previousStart);
1364
				this.scanner.currentPosition = nextCharacterStart;
1357
					}
1358
			}
1365
			}
1359
			previousStart = nextCharacterStart;
1366
		} finally {
1360
			this.scanner.currentPosition = nextCharacterStart;
1367
			this.indentationLevel = currentIndentationLevel;
1361
		}
1368
		}
1362
		this.lastNumberOfNewLines = 0;
1369
		this.lastNumberOfNewLines = 0;
1363
		this.needSpace = false;
1370
		this.needSpace = false;
Lines 1366-1372 Link Here
1366
1373
1367
	private boolean printBlockComment(int currentTokenStartPosition, int currentTokenEndPosition) {
1374
	private boolean printBlockComment(int currentTokenStartPosition, int currentTokenEndPosition) {
1368
1375
1369
1370
		// Compute indentation
1376
		// Compute indentation
1371
		int maxColumn = this.formatter.preferences.comment_line_length + 1;
1377
		int maxColumn = this.formatter.preferences.comment_line_length + 1;
1372
		int indentLevel = this.indentationLevel;
1378
		int indentLevel = this.indentationLevel;

Return to bug 198963