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

Collapse All | Expand All

(-)formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java (-8 / +42 lines)
Lines 24-48 Link Here
24
24
25
	/**
25
	/**
26
	 * Unknown kind
26
	 * Unknown kind
27
	 *
27
	 *<p>
28
	 * Note that since 3.4, the {@link #F_INCLUDE_COMMENTS} flag can be added
28
	 * <b>Since 3.6</b>, if the corresponding comment options are set to
29
	 * to this constant in order to get the comments formatted if a compilation unit
29
	 * <code>true</code> then it is also possible to format the comments on the fly
30
	 * is processed.
30
	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
31
	 * </p>
31
	 */
32
	 */
32
	public static final int K_UNKNOWN = 0x00;
33
	public static final int K_UNKNOWN = 0x00;
33
34
34
	/**
35
	/**
35
	 * Kind used to format an expression
36
	 * Kind used to format an expression
37
	 * <p>
38
	 * Note that using this constant, the comments encountered while formatting
39
	 * the expression may be shifted to match the correct indentation but are not
40
	 * formatted.
41
	 * </p><p>
42
	 * <b>Since 3.6</b>, if the corresponding comment options are set to
43
	 * <code>true</code> then it is also possible to format the comments on the fly
44
	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
45
	 * </p>
36
	 */
46
	 */
37
	public static final int K_EXPRESSION = 0x01;
47
	public static final int K_EXPRESSION = 0x01;
38
48
39
	/**
49
	/**
40
	 * Kind used to format a set of statements
50
	 * Kind used to format a set of statements
51
	 * <p>
52
	 * Note that using this constant, the comments encountered while formatting
53
	 * the statements may be shifted to match the correct indentation but are not
54
	 * formatted.
55
	 * </p><p>
56
	 * <b>Since 3.6</b>, if the corresponding comment options are set to
57
	 * <code>true</code> then it is also possible to format the comments on the fly
58
	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
59
	 * </p>
41
	 */
60
	 */
42
	public static final int K_STATEMENTS = 0x02;
61
	public static final int K_STATEMENTS = 0x02;
43
62
44
	/**
63
	/**
45
	 * Kind used to format a set of class body declarations
64
	 * Kind used to format a set of class body declarations
65
	 * <p>
66
	 * Note that using this constant, the comments encountered while formatting
67
	 * the body declarations may be shifted to match the correct indentation but
68
	 * are not formatted.
69
	 * </p><p>
70
	 * <b>Since 3.6</b>, if the corresponding comment options are set to
71
	 * <code>true</code> then it is also possible to format the comments on the fly
72
	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
73
	 * </p>
46
	 */
74
	 */
47
	public static final int K_CLASS_BODY_DECLARATIONS = 0x04;
75
	public static final int K_CLASS_BODY_DECLARATIONS = 0x04;
48
76
Lines 50-60 Link Here
50
	 * Kind used to format a compilation unit
78
	 * Kind used to format a compilation unit
51
	 * <p>
79
	 * <p>
52
	 * Note that using this constant, the comments are only indented while
80
	 * Note that using this constant, the comments are only indented while
53
	 * processing the compilation unit.
81
	 * formatting the compilation unit.
54
	 * </p><p>
82
	 * </p><p>
55
	 * <b>Since 3.4</b>, if the corresponding comment option is set to
83
	 * <b>Since 3.4</b>, if the corresponding comment option is set to
56
	 * <code>true</code> then it is also possible to format the comments on the fly
84
	 * <code>true</code> then it is also possible to format the comments on the fly
57
	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
85
	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
86
	 * </p>
58
	 */
87
	 */
59
	public static final int K_COMPILATION_UNIT = 0x08;
88
	public static final int K_COMPILATION_UNIT = 0x08;
60
89
Lines 81-89 Link Here
81
	 * Flag used to include the comments during the formatting of the code
110
	 * Flag used to include the comments during the formatting of the code
82
	 * snippet.
111
	 * snippet.
83
	 * <p>
112
	 * <p>
84
	 * This flag can only be combined with {@link #K_COMPILATION_UNIT} and
113
	 * This flag can be combined with the following kinds:
85
	 * {@link #K_UNKNOWN} kinds for now but might be extended to other ones
114
	 * <ul>
86
	 * in future versions.
115
	 * 		<li>{@link #K_COMPILATION_UNIT}</li>
116
	 * 		<li>{@link #K_UNKNOWN}</li>
117
	 * 		<li>{@link #K_CLASS_BODY_DECLARATIONS} <i>(since 3.6)</i></li>
118
	 * 		<li>{@link #K_EXPRESSION} <i>(since 3.6)</i></li>
119
	 * 		<li>{@link #K_STATEMENTS} <i>(since 3.6)</i></li>
120
	 * </ul>
87
	 * </p><p>
121
	 * </p><p>
88
	 * Note also that it has an effect only when one or several format comments
122
	 * Note also that it has an effect only when one or several format comments
89
	 * options for
123
	 * options for
(-)formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java (-33 lines)
Lines 118-124 Link Here
118
import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
118
import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
119
import org.eclipse.jdt.internal.formatter.align.Alignment;
119
import org.eclipse.jdt.internal.formatter.align.Alignment;
120
import org.eclipse.jdt.internal.formatter.align.AlignmentException;
120
import org.eclipse.jdt.internal.formatter.align.AlignmentException;
121
import org.eclipse.jdt.internal.formatter.comment.CommentRegion;
122
import org.eclipse.jface.text.IRegion;
121
import org.eclipse.jface.text.IRegion;
123
import org.eclipse.text.edits.TextEdit;
122
import org.eclipse.text.edits.TextEdit;
124
123
Lines 887-924 Link Here
887
	}
886
	}
888
887
889
	/**
888
	/**
890
	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String)
891
	 */
892
	public TextEdit format(String string, CommentRegion region) {
893
		// reset the scribe
894
		this.scribe.reset();
895
896
		if (region == null) {
897
			return failedToFormat();
898
		}
899
900
		long startTime = 0;
901
		if (DEBUG){
902
			startTime = System.currentTimeMillis();
903
		}
904
905
		final char[] compilationUnitSource = string.toCharArray();
906
907
		this.scribe.initializeScanner(compilationUnitSource);
908
909
		TextEdit result = null;
910
		try {
911
			result = region.format(this.preferences.initial_indentation_level, true);
912
		} catch(AbortFormatting e){
913
			return failedToFormat();
914
		}
915
		if (DEBUG){
916
			System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime));  //$NON-NLS-1$
917
		}
918
		return result;
919
	}
920
921
	/**
922
	 * @param source the source of the comment to format
889
	 * @param source the source of the comment to format
923
	 */
890
	 */
924
	public void formatComment(int kind, String source, int start, int end, int indentationLevel) {
891
	public void formatComment(int kind, String source, int start, int end, int indentationLevel) {
(-)formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java (-122 / +22 lines)
Lines 28-42 Link Here
28
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
28
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
29
import org.eclipse.jdt.internal.compiler.util.Util;
29
import org.eclipse.jdt.internal.compiler.util.Util;
30
import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
30
import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
31
import org.eclipse.jdt.internal.formatter.comment.CommentRegion;
32
import org.eclipse.jdt.internal.formatter.comment.JavaDocRegion;
33
import org.eclipse.jdt.internal.formatter.comment.MultiCommentRegion;
34
import org.eclipse.jface.text.Document;
35
import org.eclipse.jface.text.IDocument;
36
import org.eclipse.jface.text.IRegion;
31
import org.eclipse.jface.text.IRegion;
37
import org.eclipse.jface.text.Position;
38
import org.eclipse.jface.text.Region;
32
import org.eclipse.jface.text.Region;
39
import org.eclipse.text.edits.MultiTextEdit;
40
import org.eclipse.text.edits.TextEdit;
33
import org.eclipse.text.edits.TextEdit;
41
34
42
public class DefaultCodeFormatter extends CodeFormatter {
35
public class DefaultCodeFormatter extends CodeFormatter {
Lines 56-95 Link Here
56
		| K_MULTI_LINE_COMMENT
49
		| K_MULTI_LINE_COMMENT
57
		| K_JAVA_DOC;
50
		| K_JAVA_DOC;
58
51
59
	/*
60
	 * Temporary internal statics to enable new comments formatter
61
	 * see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=102780
62
	 * see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=227043
63
	 * TODO (frederic) remove in 3.5
64
	 */
65
	private final static String NEW_COMMENTS_FORMAT = System.getProperty("org.eclipse.jdt.core.formatter.comments.new"); //$NON-NLS-1$
66
	public static boolean ENABLE_NEW_COMMENTS_FORMAT = !JavaCore.DISABLED.equals(NEW_COMMENTS_FORMAT);
67
68
	// Scanner use to probe the kind of the source given to the formatter
52
	// Scanner use to probe the kind of the source given to the formatter
69
	private static Scanner PROBING_SCANNER;
53
	private static Scanner PROBING_SCANNER;
70
54
71
	/**
72
	 * Creates a comment region for a specific document partition type.
73
	 *
74
	 * @param kind the comment snippet kind
75
	 * @param document the document which contains the comment region
76
	 * @param range range of the comment region in the document
77
	 * @return a new comment region for the comment region range in the
78
	 *         document
79
	 * @since 3.1
80
	 */
81
	public static CommentRegion createRegion(int kind, IDocument document, Position range, CodeFormatterVisitor formatter) {
82
		switch (kind & K_MASK) {
83
			case K_SINGLE_LINE_COMMENT:
84
				return new CommentRegion(document, range, formatter);
85
			case K_MULTI_LINE_COMMENT:
86
				return new MultiCommentRegion(document, range, formatter);
87
			case K_JAVA_DOC:
88
				return new JavaDocRegion(document, range, formatter);
89
		}
90
		return null;
91
	}
92
93
	private CodeSnippetParsingUtil codeSnippetParsingUtil;
55
	private CodeSnippetParsingUtil codeSnippetParsingUtil;
94
	private Map defaultCompilerOptions;
56
	private Map defaultCompilerOptions;
95
57
Lines 174-190 Link Here
174
			case K_JAVA_DOC :
136
			case K_JAVA_DOC :
175
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102780
137
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102780
176
				// use the integrated comment formatter to format comment
138
				// use the integrated comment formatter to format comment
177
				if (ENABLE_NEW_COMMENTS_FORMAT) {
139
                return formatComment(kind & K_MASK, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)});
178
	                return formatComment(kind & K_MASK, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)});
179
				}
180
				// $FALL-THROUGH$ - fall through next case when old comment formatter is activated
140
				// $FALL-THROUGH$ - fall through next case when old comment formatter is activated
181
			case K_MULTI_LINE_COMMENT :
141
			case K_MULTI_LINE_COMMENT :
182
			case K_SINGLE_LINE_COMMENT :
142
			case K_SINGLE_LINE_COMMENT :
183
				if (ENABLE_NEW_COMMENTS_FORMAT) {
143
                return formatComment(kind & K_MASK, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)});
184
	                return formatComment(kind & K_MASK, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)});
185
				}
186
				this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
187
				return formatComment(kind, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)}, false);
188
		}
144
		}
189
145
190
		return format(kind, source, new IRegion[] {new Region(offset, length)}, indentationLevel, lineSeparator);
146
		return format(kind, source, new IRegion[] {new Region(offset, length)}, indentationLevel, lineSeparator);
Lines 199-216 Link Here
199
		}
155
		}
200
156
201
		this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
157
		this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
158
		boolean includeComments =  (kind & F_INCLUDE_COMMENTS) != 0;
202
		switch(kind & K_MASK) {
159
		switch(kind & K_MASK) {
203
			case K_CLASS_BODY_DECLARATIONS :
160
			case K_CLASS_BODY_DECLARATIONS :
204
				return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, regions);
161
				return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, regions, includeComments);
205
			case K_COMPILATION_UNIT :
162
			case K_COMPILATION_UNIT :
206
				boolean includeComments =  (kind & F_INCLUDE_COMMENTS) != 0; // || FORCE_NEW_COMMENTS_FORMAT;
207
				return formatCompilationUnit(source, indentationLevel, lineSeparator, regions, includeComments);
163
				return formatCompilationUnit(source, indentationLevel, lineSeparator, regions, includeComments);
208
			case K_EXPRESSION :
164
			case K_EXPRESSION :
209
				return formatExpression(source, indentationLevel, lineSeparator, regions);
165
				return formatExpression(source, indentationLevel, lineSeparator, regions, includeComments);
210
			case K_STATEMENTS :
166
			case K_STATEMENTS :
211
				return formatStatements(source, indentationLevel, lineSeparator, regions);
167
				return formatStatements(source, indentationLevel, lineSeparator, regions, includeComments);
212
			case K_UNKNOWN :
168
			case K_UNKNOWN :
213
				includeComments =  (kind & F_INCLUDE_COMMENTS) != 0; // || FORCE_NEW_COMMENTS_FORMAT;
214
				return probeFormatting(source, indentationLevel, lineSeparator, regions, includeComments);
169
				return probeFormatting(source, indentationLevel, lineSeparator, regions, includeComments);
215
			case K_JAVA_DOC :
170
			case K_JAVA_DOC :
216
			case K_MULTI_LINE_COMMENT :
171
			case K_MULTI_LINE_COMMENT :
Lines 221-234 Link Here
221
		return null;
176
		return null;
222
	}
177
	}
223
178
224
	private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
179
	private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
225
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
180
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
226
181
227
		if (bodyDeclarations == null) {
182
		if (bodyDeclarations == null) {
228
			// a problem occurred while parsing the source
183
			// a problem occurred while parsing the source
229
			return null;
184
			return null;
230
		}
185
		}
231
		return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions);
186
		return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions, includeComments);
232
	}
187
	}
233
188
234
	/*
189
	/*
Lines 271-325 Link Here
271
		return null;
226
		return null;
272
	}
227
	}
273
228
274
	/**
275
	 * Returns the resulting text edit after formatting the given comment.
276
	 *
277
	 * @param kind the given kind
278
	 * @param source the given source
279
	 * @param indentationLevel the given indentation level
280
	 * @param lineSeparator the given line separator
281
	 * @param regions the given regions
282
	 * @param includeComments TODO
283
	 * @return the resulting text edit
284
	 */
285
	private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
286
		Object oldOption = oldCommentFormatOption();
287
		boolean isFormattingComments = false;
288
		if (oldOption == null) {
289
			switch (kind & K_MASK) {
290
				case K_SINGLE_LINE_COMMENT:
291
					isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT));
292
					break;
293
				case K_MULTI_LINE_COMMENT:
294
					isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT));
295
					break;
296
				case K_JAVA_DOC:
297
					isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT));
298
			}
299
		} else {
300
			isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(oldOption);
301
		}
302
		if (isFormattingComments) {
303
			if (lineSeparator != null) {
304
				this.preferences.line_separator = lineSeparator;
305
			} else {
306
				this.preferences.line_separator = Util.LINE_SEPARATOR;
307
			}
308
			this.preferences.initial_indentation_level = indentationLevel;
309
			this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, null, includeComments);
310
311
			IRegion coveredRegion = getCoveredRegion(regions);
312
			int offset = coveredRegion.getOffset();
313
			int length = coveredRegion.getLength();
314
315
			final CommentRegion region = createRegion(kind, new Document(source), new Position(offset, length), this.newCodeFormatter);
316
			if (region != null) {
317
				return this.newCodeFormatter.format(source, region);
318
			}
319
		}
320
		return new MultiTextEdit();
321
	}
322
323
	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
229
	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
324
		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
230
		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
325
231
Lines 335-358 Link Here
335
		return this.newCodeFormatter.format(source, compilationUnitDeclaration);
241
		return this.newCodeFormatter.format(source, compilationUnitDeclaration);
336
	}
242
	}
337
243
338
	private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
244
	private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
339
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
245
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
340
246
341
		if (expression == null) {
247
		if (expression == null) {
342
			// a problem occurred while parsing the source
248
			// a problem occurred while parsing the source
343
			return null;
249
			return null;
344
		}
250
		}
345
		return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions);
251
		return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions, includeComments);
346
	}
252
	}
347
253
348
	private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
254
	private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
349
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
255
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
350
256
351
		if (constructorDeclaration.statements == null) {
257
		if (constructorDeclaration.statements == null) {
352
			// a problem occured while parsing the source
258
			// a problem occured while parsing the source
353
			return null;
259
			return null;
354
		}
260
		}
355
		return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions);
261
		return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions, includeComments);
356
	}
262
	}
357
263
358
	private IRegion getCoveredRegion(IRegion[] regions) {
264
	private IRegion getCoveredRegion(IRegion[] regions) {
Lines 443-449 Link Here
443
		return this.defaultCompilerOptions;
349
		return this.defaultCompilerOptions;
444
	}
350
	}
445
351
446
	private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, IRegion[] regions) {
352
	private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, IRegion[] regions, boolean includeComments) {
447
		if (lineSeparator != null) {
353
		if (lineSeparator != null) {
448
			this.preferences.line_separator = lineSeparator;
354
			this.preferences.line_separator = lineSeparator;
449
		} else {
355
		} else {
Lines 451-461 Link Here
451
		}
357
		}
452
		this.preferences.initial_indentation_level = indentationLevel;
358
		this.preferences.initial_indentation_level = indentationLevel;
453
359
454
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, false);
360
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
455
		return this.newCodeFormatter.format(source, bodyDeclarations);
361
		return this.newCodeFormatter.format(source, bodyDeclarations);
456
	}
362
	}
457
363
458
	private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, IRegion[] regions) {
364
	private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, IRegion[] regions, boolean includeComments) {
459
		if (lineSeparator != null) {
365
		if (lineSeparator != null) {
460
			this.preferences.line_separator = lineSeparator;
366
			this.preferences.line_separator = lineSeparator;
461
		} else {
367
		} else {
Lines 463-475 Link Here
463
		}
369
		}
464
		this.preferences.initial_indentation_level = indentationLevel;
370
		this.preferences.initial_indentation_level = indentationLevel;
465
371
466
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, false);
372
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
467
373
468
		TextEdit textEdit = this.newCodeFormatter.format(source, expression);
374
		TextEdit textEdit = this.newCodeFormatter.format(source, expression);
469
		return textEdit;
375
		return textEdit;
470
	}
376
	}
471
377
472
	private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, IRegion[] regions) {
378
	private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, IRegion[] regions, boolean includeComments) {
473
		if (lineSeparator != null) {
379
		if (lineSeparator != null) {
474
			this.preferences.line_separator = lineSeparator;
380
			this.preferences.line_separator = lineSeparator;
475
		} else {
381
		} else {
Lines 477-483 Link Here
477
		}
383
		}
478
		this.preferences.initial_indentation_level = indentationLevel;
384
		this.preferences.initial_indentation_level = indentationLevel;
479
385
480
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, false);
386
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
481
387
482
		return this.newCodeFormatter.format(source, constructorDeclaration);
388
		return this.newCodeFormatter.format(source, constructorDeclaration);
483
	}
389
	}
Lines 523-535 Link Here
523
					break;
429
					break;
524
			}
430
			}
525
			if (kind != -1) {
431
			if (kind != -1) {
526
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227043
432
				return formatComment(kind, source, indentationLevel, lineSeparator, regions);
527
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102780
528
				// use the integrated comment formatter to format comment
529
				if (ENABLE_NEW_COMMENTS_FORMAT /*|| FORCE_NEW_COMMENTS_FORMAT*/) {
530
					return formatComment(kind, source, indentationLevel, lineSeparator, regions);
531
				}
532
				return formatComment(kind, source, indentationLevel, lineSeparator, regions, includeComments);
533
			}
433
			}
534
		} catch (InvalidInputException e) {
434
		} catch (InvalidInputException e) {
535
			// ignore
435
			// ignore
Lines 539-557 Link Here
539
		// probe for expression
439
		// probe for expression
540
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
440
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
541
		if (expression != null) {
441
		if (expression != null) {
542
			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions);
442
			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions, includeComments);
543
		}
443
		}
544
444
545
		// probe for body declarations (fields, methods, constructors)
445
		// probe for body declarations (fields, methods, constructors)
546
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
446
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
547
		if (bodyDeclarations != null) {
447
		if (bodyDeclarations != null) {
548
			return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions);
448
			return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions, includeComments);
549
		}
449
		}
550
450
551
		// probe for statements
451
		// probe for statements
552
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
452
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
553
		if (constructorDeclaration.statements != null) {
453
		if (constructorDeclaration.statements != null) {
554
			return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions);
454
			return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions, includeComments);
555
		}
455
		}
556
456
557
		// this has to be a compilation unit
457
		// this has to be a compilation unit
(-)formatter/org/eclipse/jdt/internal/formatter/comment/CommentLine.java (-315 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
import java.util.LinkedList;
15
16
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
17
18
/**
19
 * General comment line in a comment region.
20
 *
21
 * @since 3.0
22
 */
23
public abstract class CommentLine implements IBorderAttributes {
24
25
	/** Prefix of non-formattable comment lines */
26
	protected static final String NON_FORMAT_START_PREFIX= "/*-"; //$NON-NLS-1$
27
28
	/** The attributes of this line */
29
	private int fAttributes= 0;
30
31
	/** The parent region of this line */
32
	private final CommentRegion fParent;
33
34
	/** The comment ranges in this line */
35
	private final LinkedList fRanges= new LinkedList();
36
37
	/**
38
	 * Creates a new comment line.
39
	 *
40
	 * @param parent comment region to create the comment line for
41
	 */
42
	protected CommentLine(final CommentRegion parent) {
43
		this.fParent= parent;
44
	}
45
46
	/**
47
	 * Adapts the line attributes from the previous line in the comment
48
	 * region.
49
	 *
50
	 * @param previous the previous comment line in the comment region
51
	 */
52
	protected abstract void adapt(final CommentLine previous);
53
54
	/**
55
	 * Appends the specified comment range to this comment line.
56
	 *
57
	 * @param range comment range to append to this line
58
	 */
59
	protected void append(final CommentRange range) {
60
		this.fRanges.add(range);
61
	}
62
63
	/**
64
	 * Formats this comment line as content line.
65
	 *
66
	 * @param predecessor the predecessor comment line in the comment region
67
	 * @param last the most recently processed comment range
68
	 * @param indentation the indentation of the comment region
69
	 * @param line the index of this comment line in the comment region
70
	 * @return the first comment range in this comment line
71
	 */
72
	protected CommentRange formatLine(final CommentLine predecessor, final CommentRange last, final String indentation, final int line) {
73
74
		int offset= 0;
75
		int length= 0;
76
77
		CommentRange next= last;
78
		CommentRange previous= null;
79
80
		final int stop= this.fRanges.size() - 1;
81
		final int end= this.fParent.getSize() - 1;
82
83
		for (int index= stop; index >= 0; index--) {
84
85
			previous= next;
86
			next= (CommentRange)this.fRanges.get(index);
87
88
			if (this.fParent.canFormat(previous, next)) {
89
90
				offset= next.getOffset() + next.getLength();
91
				length= previous.getOffset() - offset;
92
93
				if (index == stop && line != end)
94
					this.fParent.logEdit(this.fParent.getDelimiter(predecessor, this, previous, next, indentation), offset, length);
95
				else
96
					this.fParent.logEdit(this.fParent.getDelimiter(previous, next), offset, length);
97
			}
98
		}
99
		return next;
100
	}
101
102
	/**
103
	 * Formats this comment line as end line having a lower border
104
	 * consisting of content line prefixes.
105
	 *
106
	 * @param range last comment range of the last comment line in the
107
	 *                comment region
108
	 * @param indentation the indentation of the comment region
109
	 * @param length the maximal length of text in this comment region
110
	 *                measured in average character widths
111
	 */
112
	protected void formatLowerBorder(final CommentRange range, final String indentation, final int length) {
113
114
		final int offset= range.getOffset() + range.getLength();
115
116
		final StringBuffer buffer= new StringBuffer(length);
117
		final String end= getEndingPrefix();
118
		final String delimiter= this.fParent.getDelimiter();
119
120
		if (this.fParent.isSingleLine() && this.fParent.getSize() == 1)
121
			buffer.append(end);
122
		else {
123
124
			final String filler= getContentPrefix().trim();
125
126
			buffer.append(delimiter);
127
			buffer.append(indentation);
128
129
			if (this.fParent.hasBorder(BORDER_LOWER)) {
130
131
				buffer.append(' ');
132
				for (int character= 0; character < length; character++)
133
					buffer.append(filler);
134
135
				buffer.append(end.trim());
136
137
			} else
138
				buffer.append(end);
139
		}
140
		this.fParent.logEdit(buffer.toString(), offset, this.fParent.getLength() - offset);
141
	}
142
143
	/**
144
	 * Formats this comment line as start line having an upper border
145
	 * consisting of content line prefixes.
146
	 *
147
	 * @param range the first comment range in the comment region
148
	 * @param indentation the indentation of the comment region
149
	 * @param length the maximal length of text in this comment region
150
	 *                measured in average character widths
151
	 */
152
	protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) {
153
154
		final StringBuffer buffer= new StringBuffer(length);
155
		final String start= getStartingPrefix();
156
		final String content= getContentPrefix();
157
158
		if (this.fParent.isSingleLine() && this.fParent.getSize() == 1)
159
			buffer.append(start);
160
		else {
161
162
			final String trimmed= start.trim();
163
			final String filler= content.trim();
164
165
			buffer.append(trimmed);
166
167
			if (this.fParent.hasBorder(BORDER_UPPER)) {
168
169
				for (int character= 0; character < length - trimmed.length() + start.length(); character++)
170
					buffer.append(filler);
171
			}
172
173
			buffer.append(this.fParent.getDelimiter());
174
			buffer.append(indentation);
175
			buffer.append(content);
176
		}
177
		this.fParent.logEdit(buffer.toString(), 0, range.getOffset());
178
	}
179
180
	/**
181
	 * Returns the line prefix of content lines.
182
	 *
183
	 * @return line prefix of content lines
184
	 */
185
	protected abstract String getContentPrefix();
186
187
	/**
188
	 * Returns the line prefix of end lines.
189
	 *
190
	 * @return line prefix of end lines
191
	 */
192
	protected abstract String getEndingPrefix();
193
194
	/**
195
	 * Returns the first comment range in this comment line.
196
	 *
197
	 * @return the first comment range
198
	 */
199
	protected final CommentRange getFirst() {
200
		return (CommentRange)this.fRanges.getFirst();
201
	}
202
203
	/**
204
	 * Returns the indentation reference string for this line.
205
	 *
206
	 * @return the indentation reference string for this line
207
	 */
208
	protected String getIndentationReference() {
209
		return ""; //$NON-NLS-1$
210
	}
211
212
	/**
213
	 * Returns the last comment range in this comment line.
214
	 *
215
	 * @return the last comment range
216
	 */
217
	protected final CommentRange getLast() {
218
		return (CommentRange)this.fRanges.getLast();
219
	}
220
221
	/**
222
	 * Returns the parent comment region of this comment line.
223
	 *
224
	 * @return the parent comment region
225
	 */
226
	protected final CommentRegion getParent() {
227
		return this.fParent;
228
	}
229
230
	/**
231
	 * Returns the number of comment ranges in this comment line.
232
	 *
233
	 * @return the number of ranges in this line
234
	 */
235
	protected final int getSize() {
236
		return this.fRanges.size();
237
	}
238
239
	/**
240
	 * Returns the line prefix of start lines.
241
	 *
242
	 * @return line prefix of start lines
243
	 */
244
	protected abstract String getStartingPrefix();
245
246
	/**
247
	 * Is the attribute <code>attribute</code> true?
248
	 *
249
	 * @param attribute the attribute to get.
250
	 * @return <code>true</code> iff this attribute is <code>true</code>,
251
	 *         <code>false</code> otherwise.
252
	 */
253
	protected final boolean hasAttribute(final int attribute) {
254
		return (this.fAttributes & attribute) == attribute;
255
	}
256
257
	/**
258
	 * Scans this comment line for comment range boundaries.
259
	 *
260
	 * @param line the index of this line in the comment region
261
	 */
262
	protected abstract void scanLine(final int line);
263
264
	/**
265
	 * Set the attribute <code>attribute</code> to true.
266
	 *
267
	 * @param attribute the attribute to set.
268
	 */
269
	protected final void setAttribute(final int attribute) {
270
		this.fAttributes |= attribute;
271
	}
272
273
	/**
274
	 * Tokenizes this comment line into comment ranges
275
	 *
276
	 * @param line the index of this line in the comment region
277
	 */
278
	protected void tokenizeLine(final int line) {
279
280
		int offset= 0;
281
		int index= offset;
282
283
		final CommentRange range= (CommentRange)this.fRanges.get(0);
284
		final int begin= range.getOffset();
285
286
		final String content= this.fParent.getText(begin, range.getLength());
287
		final int length= content.length();
288
289
		while (offset < length) {
290
291
			while (offset < length && ScannerHelper.isWhitespace(content.charAt(offset)))
292
				offset++;
293
294
			index= offset;
295
296
			while (index < length && !ScannerHelper.isWhitespace(content.charAt(index)))
297
				index++;
298
299
			if (index - offset > 0) {
300
				this.fParent.append(new CommentRange(begin + offset, index - offset));
301
302
				offset= index;
303
			}
304
		}
305
	}
306
307
	public String toString() {
308
		final StringBuffer buffer = new StringBuffer();
309
		final int size = this.fRanges.size();
310
		for (int i = 0; i < size; i++) {
311
			buffer.append(this.fRanges.get(i)).append("\n"); //$NON-NLS-1$
312
		}
313
		return String.valueOf(buffer);
314
	}
315
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/CommentRange.java (-262 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
import java.util.ArrayList;
15
import java.util.Iterator;
16
import java.util.List;
17
18
import org.eclipse.jdt.core.compiler.CharOperation;
19
import org.eclipse.jface.text.Position;
20
21
/**
22
 * Range in a comment region in comment region coordinates.
23
 *
24
 * @since 3.0
25
 */
26
public class CommentRange extends Position implements ICommentAttributes, IHtmlTagDelimiters {
27
28
	/** The attributes of this range */
29
	private int fAttributes= 0;
30
31
	/**
32
	 * Creates a new comment range.
33
	 *
34
	 * @param position offset of the range
35
	 * @param count length of the range
36
	 */
37
	public CommentRange(final int position, final int count) {
38
		super(position, count);
39
	}
40
41
	/**
42
	 * Is the attribute <code>attribute</code> true?
43
	 *
44
	 * @param attribute the attribute to get
45
	 * @return <code>true</code> iff this attribute is <code>true</code>,
46
	 *         <code>false</code> otherwise
47
	 */
48
	protected final boolean hasAttribute(final int attribute) {
49
		return (this.fAttributes & attribute) == attribute;
50
	}
51
52
	/**
53
	 * Does this comment range contain a closing HTML tag?
54
	 *
55
	 * @param token token belonging to the comment range
56
	 * @param tag the HTML tag to check
57
	 * @return <code>true</code> iff this comment range contains a closing
58
	 *         html tag, <code>false</code> otherwise
59
	 */
60
	protected final boolean isClosingTag(final char[] token, final char[] tag) {
61
62
		boolean result= (CharOperation.indexOf(HTML_CLOSE_PREFIX, token, false) == 0)
63
				&& token[token.length - 1] == HTML_TAG_POSTFIX;
64
		if (result) {
65
66
			setAttribute(COMMENT_CLOSE);
67
			result= CharOperation.equals(tag, token, HTML_CLOSE_PREFIX.length, token.length - 1, false);
68
		}
69
		return result;
70
	}
71
72
	/**
73
	 * Does this comment range contain an opening HTML tag?
74
	 *
75
	 * @param token token belonging to the comment range
76
	 * @param tag the HTML tag to check
77
	 * @return <code>true</code> iff this comment range contains an
78
	 *         opening html tag, <code>false</code> otherwise
79
	 */
80
	protected final boolean isOpeningTag(final char[] token, final char[] tag) {
81
82
		boolean result= token.length > 0
83
				&& token[0] == HTML_TAG_PREFIX
84
				&& (CharOperation.indexOf(HTML_CLOSE_PREFIX, token, false) != 0)
85
				&& token[token.length - 1] == HTML_TAG_POSTFIX;
86
		if (result) {
87
88
			setAttribute(COMMENT_OPEN);
89
			result= CharOperation.indexOf(tag, token, false) == 1;
90
		}
91
		return result;
92
	}
93
94
	/**
95
	 * Mark the comment range with the occurred HTML tags.
96
	 *
97
	 * @param tags the HTML tags to test for their occurrence
98
	 * @param token token belonging to the comment range
99
	 * @param attribute attribute to set if a HTML tag is present
100
	 * @param open <code>true</code> iff opening tags should be marked,
101
	 *                <code>false</code> otherwise
102
	 * @param close <code>true</code> iff closing tags should be marked,
103
	 *                <code>false</code> otherwise
104
	 */
105
	protected final void markHtmlTag(final char[][] tags, final char[] token, final int attribute, final boolean open, final boolean close) {
106
		if (token[0] == HTML_TAG_PREFIX && token[token.length - 1] == HTML_TAG_POSTFIX) {
107
108
			char[] tag= null;
109
			boolean isOpen= false;
110
			boolean isClose= false;
111
112
			for (int index= 0; index < tags.length; index++) {
113
114
				tag= tags[index];
115
116
				isOpen= isOpeningTag(token, tag);
117
				isClose= isClosingTag(token, tag);
118
119
				if ((open && isOpen) || (close && isClose)) {
120
121
					setAttribute(attribute);
122
					break;
123
				}
124
			}
125
		}
126
	}
127
128
	/**
129
	 * Mark the comment range with the occurred tags.
130
	 *
131
	 * @param tags the tags to test for their occurrence
132
	 * @param prefix the prefix which is common to all the tags to test
133
	 * @param token the token belonging to the comment range
134
	 * @param attribute attribute to set if a tag is present
135
	 */
136
	protected final void markPrefixTag(final char[][] tags, final char prefix, final char[] token, final int attribute) {
137
138
		if (token[0] == prefix) {
139
140
			char[] tag= null;
141
			for (int index= 0; index < tags.length; index++) {
142
143
				tag= tags[index];
144
				if (CharOperation.equals(token, tag)) {
145
146
					setAttribute(attribute);
147
					break;
148
				}
149
			}
150
		}
151
	}
152
153
	/**
154
	 * Marks the comment range with the HTML range tag.
155
	 *
156
	 * @param token the token belonging to the comment range
157
	 * @param tag the HTML tag which confines the HTML range
158
	 * @param level the nesting level of the current HTML range
159
	 * @param key the key of the attribute to set if the comment range is in
160
	 *                the HTML range
161
	 * @param html <code>true</code> iff the HTML tags in this HTML range
162
	 *                should be marked too, <code>false</code> otherwise
163
	 * @return the new nesting level of the HTML range
164
	 */
165
	protected final int markTagRange(final char[] token, final char[] tag, int level, final int key, final boolean html) {
166
167
		if (isOpeningTag(token, tag)) {
168
			if (level++ > 0)
169
				setAttribute(key);
170
		} else if (isClosingTag(token, tag)) {
171
			if (--level > 0)
172
				setAttribute(key);
173
		} else if (level > 0) {
174
			if (html || !hasAttribute(COMMENT_HTML))
175
				setAttribute(key);
176
		}
177
		return level;
178
	}
179
180
	/**
181
	 * Moves this comment range.
182
	 *
183
	 * @param delta the delta to move the range
184
	 */
185
	public final void move(final int delta) {
186
		this.offset += delta;
187
	}
188
189
	/**
190
	 * Set the attribute <code>attribute</code> to true.
191
	 *
192
	 * @param attribute the attribute to set.
193
	 */
194
	protected final void setAttribute(final int attribute) {
195
		this.fAttributes |= attribute;
196
	}
197
198
	/**
199
	 * Trims this comment range at the beginning.
200
	 *
201
	 * @param delta amount to trim the range
202
	 */
203
	public final void trimBegin(final int delta) {
204
		this.offset += delta;
205
		this.length -= delta;
206
	}
207
208
	/**
209
	 * Trims this comment range at the end.
210
	 *
211
	 * @param delta amount to trim the range
212
	 */
213
	public final void trimEnd(final int delta) {
214
		this.length += delta;
215
	}
216
217
	/*
218
	 * @see java.lang.Object#toString()
219
	 * @since 3.1
220
	 */
221
	public String toString() {
222
		List attributes= new ArrayList();
223
		if (hasAttribute(COMMENT_BLANKLINE))
224
			attributes.add("COMMENT_BLANKLINE"); //$NON-NLS-1$
225
		if (hasAttribute(COMMENT_BREAK))
226
			attributes.add("COMMENT_BREAK"); //$NON-NLS-1$
227
		if (hasAttribute(COMMENT_CLOSE))
228
			attributes.add("COMMENT_CLOSE"); //$NON-NLS-1$
229
		if (hasAttribute(COMMENT_CODE))
230
			attributes.add("COMMENT_CODE"); //$NON-NLS-1$
231
		if (hasAttribute(COMMENT_HTML))
232
			attributes.add("COMMENT_HTML"); //$NON-NLS-1$
233
		if (hasAttribute(COMMENT_IMMUTABLE))
234
			attributes.add("COMMENT_IMMUTABLE"); //$NON-NLS-1$
235
		if (hasAttribute(COMMENT_NEWLINE))
236
			attributes.add("COMMENT_NEWLINE"); //$NON-NLS-1$
237
		if (hasAttribute(COMMENT_OPEN))
238
			attributes.add("COMMENT_OPEN"); //$NON-NLS-1$
239
		if (hasAttribute(COMMENT_PARAGRAPH))
240
			attributes.add("COMMENT_PARAGRAPH"); //$NON-NLS-1$
241
		if (hasAttribute(COMMENT_PARAMETER))
242
			attributes.add("COMMENT_PARAMETER"); //$NON-NLS-1$
243
		if (hasAttribute(COMMENT_ROOT))
244
			attributes.add("COMMENT_ROOT"); //$NON-NLS-1$
245
		if (hasAttribute(COMMENT_SEPARATOR))
246
			attributes.add("COMMENT_SEPARATOR"); //$NON-NLS-1$
247
		if (hasAttribute(COMMENT_FIRST_TOKEN))
248
			attributes.add("COMMENT_FIRST_TOKEN"); //$NON-NLS-1$
249
		if (hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER))
250
			attributes.add("COMMENT_STARTS_WITH_RANGE_DELIMITER"); //$NON-NLS-1$
251
252
		StringBuffer buf= new StringBuffer("CommentRange [" + this.offset + "+" + this.length + "] {"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
253
		for (Iterator it= attributes.iterator(); it.hasNext();) {
254
			String string= (String) it.next();
255
			buf.append(string);
256
			if (it.hasNext())
257
				buf.append(", "); //$NON-NLS-1$
258
		}
259
260
		return buf.toString() + "}"; //$NON-NLS-1$
261
	}
262
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/CommentRegion.java (-576 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
import java.util.Iterator;
15
import java.util.LinkedList;
16
17
import org.eclipse.core.runtime.Assert;
18
19
import org.eclipse.text.edits.MalformedTreeException;
20
import org.eclipse.text.edits.TextEdit;
21
22
import org.eclipse.jface.text.BadLocationException;
23
import org.eclipse.jface.text.DefaultLineTracker;
24
import org.eclipse.jface.text.IDocument;
25
import org.eclipse.jface.text.ILineTracker;
26
import org.eclipse.jface.text.IRegion;
27
import org.eclipse.jface.text.Position;
28
29
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
30
import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
31
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
32
import org.eclipse.jdt.internal.formatter.Scribe;
33
34
/**
35
 * Comment region in a source code document.
36
 *
37
 * @since 3.0
38
 */
39
public class CommentRegion extends Position implements IHtmlTagDelimiters, IBorderAttributes, ICommentAttributes {
40
41
	/** Default comment range delimiter */
42
	protected static final String COMMENT_RANGE_DELIMITER= " "; //$NON-NLS-1$
43
44
	/** Default line prefix length */
45
	private static final int COMMENT_PREFIX_LENGTH= 3;
46
47
	/** The borders of this region */
48
	private int fBorders= 0;
49
50
	/** Should all blank lines be cleared during formatting? */
51
	protected boolean fClear;
52
53
	/** The line delimiter used in this comment region */
54
	private final String fDelimiter;
55
56
	/** The document to format */
57
	private final IDocument fDocument;
58
59
	/** The lines in this comment region */
60
	private final LinkedList fLines= new LinkedList();
61
62
	/** The formatting preferences */
63
	protected final DefaultCodeFormatterOptions preferences;
64
65
	/** The comment ranges in this comment region */
66
	private final LinkedList fRanges= new LinkedList();
67
68
	/** Is this comment region a single line region? */
69
	private final boolean fSingleLine;
70
71
	/** Number of spaces representing tabulator */
72
	private int fTabSize;
73
74
	/** the scribe used to create edits */
75
	protected Scribe scribe;
76
77
	/**
78
	 * Creates a new comment region.
79
	 *
80
	 * @param document the document which contains the comment region
81
	 * @param position the position of this comment region in the document
82
	 * @param formatter the given code formatter
83
	 */
84
	public CommentRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
85
		super(position.getOffset(), position.getLength());
86
87
		this.preferences = formatter.preferences;
88
		this.fDelimiter = this.preferences.line_separator;
89
		this.fDocument= document;
90
91
		this.fTabSize= DefaultCodeFormatterOptions.SPACE == this.preferences.tab_char ? this.preferences.indentation_size : this.preferences.tab_size;
92
93
		this.scribe = formatter.scribe;
94
95
		final ILineTracker tracker= new DefaultLineTracker();
96
97
		IRegion range= null;
98
		CommentLine line= null;
99
100
		tracker.set(getText(0, getLength()));
101
		final int lines= tracker.getNumberOfLines();
102
103
		this.fSingleLine= lines == 1;
104
105
		try {
106
107
			for (int index= 0; index < lines; index++) {
108
109
				range= tracker.getLineInformation(index);
110
				line= createLine();
111
				line.append(new CommentRange(range.getOffset(), range.getLength()));
112
113
				this.fLines.add(line);
114
			}
115
116
		} catch (BadLocationException exception) {
117
			// Should not happen
118
		}
119
	}
120
121
	/**
122
	 * Appends the comment range to this comment region.
123
	 *
124
	 * @param range comment range to append to this comment region
125
	 */
126
	protected final void append(final CommentRange range) {
127
		this.fRanges.addLast(range);
128
	}
129
130
	/**
131
	 * Can the comment range be appended to the comment line?
132
	 *
133
	 * @param line comment line where to append the comment range
134
	 * @param previous comment range which is the predecessor of the current
135
	 *                comment range
136
	 * @param next comment range to test whether it can be appended to the
137
	 *                comment line
138
	 * @param index amount of space in the comment line used by already
139
	 *                inserted comment ranges
140
	 * @param width the maximal width of text in this comment region
141
	 *                measured in average character widths
142
	 * @return <code>true</code> iff the comment range can be added to the
143
	 *         line, <code>false</code> otherwise
144
	 */
145
	protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, final int width) {
146
		return index == 0 || index + next.getLength() <= width;
147
	}
148
149
	/**
150
	 * Can the whitespace between the two comment ranges be formatted?
151
	 *
152
	 * @param previous previous comment range which was already formatted,
153
	 *                can be <code>null</code>
154
	 * @param next next comment range to be formatted
155
	 * @return <code>true</code> iff the next comment range can be
156
	 *         formatted, <code>false</code> otherwise.
157
	 */
158
	protected boolean canFormat(final CommentRange previous, final CommentRange next) {
159
		return previous != null;
160
	}
161
162
	/**
163
	 * Formats the comment region with the given indentation level.
164
	 *
165
	 * @param indentationLevel the indentation level
166
	 * @return the resulting text edit of the formatting process
167
	 * @since 3.1
168
	 */
169
	public final TextEdit format(int indentationLevel, boolean returnEdit) {
170
		final String probe= getText(0, CommentLine.NON_FORMAT_START_PREFIX.length());
171
		if (!probe.startsWith(CommentLine.NON_FORMAT_START_PREFIX)) {
172
173
			int margin= this.preferences.comment_line_length;
174
			String indentation= computeIndentation(indentationLevel);
175
			margin= Math.max(COMMENT_PREFIX_LENGTH + 1, margin - stringToLength(indentation) - COMMENT_PREFIX_LENGTH);
176
177
			tokenizeRegion();
178
			markRegion();
179
			wrapRegion(margin);
180
			formatRegion(indentation, margin);
181
182
		}
183
		if (returnEdit) {
184
			return this.scribe.getRootEdit();
185
		}
186
		return null;
187
	}
188
189
	/**
190
	 * Formats this comment region.
191
	 *
192
	 * @param indentation the indentation of this comment region
193
	 * @param width the maximal width of text in this comment region
194
	 *                measured in average character widths
195
	 */
196
	protected void formatRegion(final String indentation, final int width) {
197
198
		final int last= this.fLines.size() - 1;
199
		if (last >= 0) {
200
201
			CommentLine lastLine= (CommentLine)this.fLines.get(last);
202
			CommentRange lastRange= lastLine.getLast();
203
			lastLine.formatLowerBorder(lastRange, indentation, width);
204
205
			CommentLine previous;
206
			CommentLine next= null;
207
			CommentRange range= null;
208
			for (int line= last; line >= 0; line--) {
209
210
				previous= next;
211
				next= (CommentLine)this.fLines.get(line);
212
213
				range= next.formatLine(previous, range, indentation, line);
214
			}
215
			next.formatUpperBorder(range, indentation, width);
216
		}
217
	}
218
219
	/**
220
	 * Returns the line delimiter used in this comment region.
221
	 *
222
	 * @return the line delimiter for this comment region
223
	 */
224
	protected final String getDelimiter() {
225
		return this.fDelimiter;
226
	}
227
228
	/**
229
	 * Returns the line delimiter used in this comment line break.
230
	 *
231
	 * @param predecessor the predecessor comment line after the line break
232
	 * @param successor the successor comment line before the line break
233
	 * @param previous the comment range after the line break
234
	 * @param next the comment range before the line break
235
	 * @param indentation indentation of the formatted line break
236
	 * @return the line delimiter for this comment line break
237
	 */
238
	protected String getDelimiter(final CommentLine predecessor, final CommentLine successor, final CommentRange previous, final CommentRange next, final String indentation) {
239
		return this.fDelimiter + indentation + successor.getContentPrefix();
240
	}
241
242
	/**
243
	 * Returns the range delimiter for this comment range break.
244
	 *
245
	 * @param previous the previous comment range to the right of the range
246
	 *                delimiter
247
	 * @param next the next comment range to the left of the range delimiter
248
	 * @return the delimiter for this comment range break
249
	 */
250
	protected String getDelimiter(final CommentRange previous, final CommentRange next) {
251
		return COMMENT_RANGE_DELIMITER;
252
	}
253
254
	/**
255
	 * Returns the document of this comment region.
256
	 *
257
	 * @return the document of this region
258
	 */
259
	protected final IDocument getDocument() {
260
		return this.fDocument;
261
	}
262
263
	/**
264
	 * Returns the comment ranges in this comment region
265
	 *
266
	 * @return the comment ranges in this region
267
	 */
268
	protected final LinkedList getRanges() {
269
		return this.fRanges;
270
	}
271
272
	/**
273
	 * Returns the number of comment lines in this comment region.
274
	 *
275
	 * @return the number of lines in this comment region
276
	 */
277
	protected final int getSize() {
278
		return this.fLines.size();
279
	}
280
281
	/**
282
	 * Returns the text of this comment region in the indicated range.
283
	 *
284
	 * @param position the offset of the comment range to retrieve in
285
	 *                comment region coordinates
286
	 * @param count the length of the comment range to retrieve
287
	 * @return the content of this comment region in the indicated range
288
	 */
289
	protected final String getText(final int position, final int count) {
290
291
		String content= ""; //$NON-NLS-1$
292
		try {
293
			content= this.fDocument.get(getOffset() + position, count);
294
		} catch (BadLocationException exception) {
295
			// Should not happen
296
		}
297
		return content;
298
	}
299
300
	/**
301
	 * Does the border <code>border</code> exist?
302
	 *
303
	 * @param border the type of the border, must be a border attribute of
304
	 *                <code>CommentRegion</code>
305
	 * @return <code>true</code> iff this border exists,
306
	 *         <code>false</code> otherwise
307
	 */
308
	protected final boolean hasBorder(final int border) {
309
		return (this.fBorders & border) == border;
310
	}
311
312
	/**
313
	 * Does the comment range consist of letters and digits only?
314
	 *
315
	 * @param range the comment range to text
316
	 * @return <code>true</code> iff the comment range consists of letters
317
	 *         and digits only, <code>false</code> otherwise
318
	 */
319
	protected final boolean isAlphaNumeric(final CommentRange range) {
320
321
		final String token= getText(range.getOffset(), range.getLength());
322
323
		for (int index= 0; index < token.length(); index++) {
324
			if (!ScannerHelper.isLetterOrDigit(token.charAt(index)))
325
				return false;
326
		}
327
		return true;
328
	}
329
330
	/**
331
	 * Does the comment range contain no letters and digits?
332
	 *
333
	 * @param range the comment range to text
334
	 * @return <code>true</code> iff the comment range contains no letters
335
	 *         and digits, <code>false</code> otherwise
336
	 */
337
	protected final boolean isNonAlphaNumeric(final CommentRange range) {
338
339
		final String token= getText(range.getOffset(), range.getLength());
340
341
		for (int index= 0; index < token.length(); index++) {
342
			if (ScannerHelper.isLetterOrDigit(token.charAt(index)))
343
				return false;
344
		}
345
		return true;
346
	}
347
348
	/**
349
	 * Should blank lines be cleared during formatting?
350
	 *
351
	 * @return <code>true</code> iff blank lines should be cleared,
352
	 *         <code>false</code> otherwise
353
	 */
354
	protected final boolean isClearLines() {
355
		return this.fClear;
356
	}
357
358
	/**
359
	 * Is this comment region a single line region?
360
	 *
361
	 * @return <code>true</code> iff this region is single line,
362
	 *         <code>false</code> otherwise
363
	 */
364
	protected final boolean isSingleLine() {
365
		return this.fSingleLine;
366
	}
367
368
	/**
369
	 * Logs a text edit operation occurred during the formatting process
370
	 *
371
	 * @param change the changed text
372
	 * @param position offset measured in comment region coordinates where
373
	 *                to apply the changed text
374
	 * @param count length of the range where to apply the changed text
375
	 */
376
	protected final void logEdit(final String change, final int position, final int count) {
377
		try {
378
			final int base= getOffset() + position;
379
			final String content= this.fDocument.get(base, count);
380
381
			if (!change.equals(content)) {
382
				if (count > 0) {
383
					this.scribe.addReplaceEdit(base, base + count - 1, change);
384
				} else {
385
					this.scribe.addInsertEdit(base, change);
386
				}
387
			}
388
		} catch (BadLocationException exception) {
389
			// Should not happen
390
			CommentFormatterUtil.log(exception);
391
		} catch (MalformedTreeException exception) {
392
			// Do nothing
393
			CommentFormatterUtil.log(exception);
394
		}
395
	}
396
397
	/**
398
	 * Marks the comment ranges in this comment region.
399
	 */
400
	protected void markRegion() {
401
		// Do nothing
402
	}
403
404
	/**
405
	 * Set the border type <code>border</code> to true.
406
	 *
407
	 * @param border the type of the border. Must be a border attribute of
408
	 *                <code>CommentRegion</code>
409
	 */
410
	protected final void setBorder(final int border) {
411
		this.fBorders |= border;
412
	}
413
414
	/**
415
	 * Returns the indentation of the given indentation level.
416
	 *
417
	 * @param indentationLevel the indentation level
418
	 * @return the indentation of the given indentation level
419
	 * @since 3.1
420
	 */
421
	private String computeIndentation(int indentationLevel) {
422
		if (DefaultCodeFormatterOptions.TAB == this.preferences.tab_char)
423
			return replicate("\t", indentationLevel); //$NON-NLS-1$
424
425
		if (DefaultCodeFormatterOptions.SPACE == this.preferences.tab_char)
426
			return replicate(" ", indentationLevel * this.preferences.tab_size); //$NON-NLS-1$
427
428
		if (DefaultCodeFormatterOptions.MIXED == this.preferences.tab_char) {
429
			int tabSize= this.preferences.tab_size;
430
			int indentSize= this.preferences.indentation_size;
431
			int spaceEquivalents= indentationLevel * indentSize;
432
			return replicate("\t", spaceEquivalents / tabSize) + replicate(" ", spaceEquivalents % tabSize); //$NON-NLS-1$ //$NON-NLS-2$
433
		}
434
435
		Assert.isTrue(false);
436
		return null;
437
	}
438
439
	/**
440
	 * Returns the given string n-times replicated.
441
	 *
442
	 * @param string the string
443
	 * @param n n
444
	 * @return the given string n-times replicated
445
	 * @since 3.1
446
	 */
447
	private String replicate(String string, int n) {
448
		StringBuffer buffer= new StringBuffer(n*string.length());
449
		for (int i= 0; i < n; i++)
450
			buffer.append(string);
451
		return buffer.toString();
452
	}
453
454
	/**
455
	 * Computes the equivalent indentation for a string
456
	 *
457
	 * @param reference the string to compute the indentation for
458
	 * @return the indentation string
459
	 */
460
	protected final String stringToIndent(final String reference) {
461
		return replicate(" ", stringToLength(reference)); //$NON-NLS-1$
462
	}
463
464
	/**
465
	 * Returns the length of the string in expanded characters.
466
	 *
467
	 * @param reference the string to get the length for
468
	 * @return the length of the string in expanded characters
469
	 */
470
	protected final int stringToLength(final String reference) {
471
		return expandTabs(reference).length();
472
	}
473
474
	/**
475
	 * Expands the given string's tabs according to the given tab size.
476
	 *
477
	 * @param string the string
478
	 * @return the expanded string
479
	 * @since 3.1
480
	 */
481
	private String expandTabs(String string) {
482
		StringBuffer expanded= new StringBuffer();
483
		for (int i= 0, n= string.length(), chars= 0; i < n; i++) {
484
			char ch= string.charAt(i);
485
			if (ch == '\t') {
486
				for (; chars < this.fTabSize; chars++)
487
					expanded.append(' ');
488
				chars= 0;
489
			} else {
490
				expanded.append(ch);
491
				chars++;
492
				if (chars >= this.fTabSize)
493
					chars= 0;
494
			}
495
496
		}
497
		return expanded.toString();
498
	}
499
500
	/**
501
	 * Tokenizes the comment region.
502
	 */
503
	protected void tokenizeRegion() {
504
505
		int index= 0;
506
		CommentLine line= null;
507
508
		for (final Iterator iterator= this.fLines.iterator(); iterator.hasNext(); index++) {
509
510
			line= (CommentLine)iterator.next();
511
512
			line.scanLine(index);
513
			line.tokenizeLine(index);
514
		}
515
	}
516
517
	/**
518
	 * Wraps the comment ranges in this comment region into comment lines.
519
	 *
520
	 * @param width the maximal width of text in this comment region
521
	 *                measured in average character widths
522
	 */
523
	protected void wrapRegion(final int width) {
524
525
		this.fLines.clear();
526
527
		int index= 0;
528
		boolean adapted= false;
529
530
		CommentLine successor= null;
531
		CommentLine predecessor= null;
532
533
		CommentRange previous= null;
534
		CommentRange next= null;
535
536
		while (!this.fRanges.isEmpty()) {
537
538
			index= 0;
539
			adapted= false;
540
541
			predecessor= successor;
542
			successor= createLine();
543
			this.fLines.add(successor);
544
545
			while (!this.fRanges.isEmpty()) {
546
				next= (CommentRange)this.fRanges.getFirst();
547
548
				if (canAppend(successor, previous, next, index, width)) {
549
550
					if (!adapted && predecessor != null) {
551
552
						successor.adapt(predecessor);
553
						adapted= true;
554
					}
555
556
					this.fRanges.removeFirst();
557
					successor.append(next);
558
559
					index += (next.getLength() + 1);
560
					previous= next;
561
				} else
562
					break;
563
			}
564
		}
565
	}
566
567
	/**
568
	 * Creates a new line for this region.
569
	 *
570
	 * @return a new line for this region
571
	 * @since 3.1
572
	 */
573
	protected CommentLine createLine() {
574
		return new SingleCommentLine(this);
575
	}
576
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/IBorderAttributes.java (-26 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
/**
15
 * Comment region border attributes.
16
 *
17
 * @since 3.0
18
 */
19
public interface IBorderAttributes {
20
21
	/** Region has lower border attribute */
22
	public static final int BORDER_LOWER= 1 << 0;
23
24
	/** Region has upper border attribute */
25
	public static final int BORDER_UPPER= 1 << 1;
26
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/ICommentAttributes.java (-65 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
/**
15
 * General comment range attributes.
16
 *
17
 * @since 3.0
18
 */
19
public interface ICommentAttributes {
20
21
	/** Range has blank line attribute */
22
	public static final int COMMENT_BLANKLINE= 1 << 1;
23
24
	/** Range has line break attribute */
25
	public static final int COMMENT_BREAK= 1 << 2;
26
27
	/** Range has close tag attribute */
28
	public static final int COMMENT_CLOSE= 1 << 3;
29
30
	/** Range has source code attribute */
31
	public static final int COMMENT_CODE= 1 << 4;
32
33
	/** Range has html tag attribute */
34
	public static final int COMMENT_HTML= 1 << 5;
35
36
	/** Range has the immutable region attribute */
37
	public static final int COMMENT_IMMUTABLE= 1 << 6;
38
39
	/** Range has new line attribute */
40
	public static final int COMMENT_NEWLINE= 1 << 7;
41
42
	/** Range has open tag attribute */
43
	public static final int COMMENT_OPEN= 1 << 8;
44
45
	/** Range has paragraph attribute */
46
	public static final int COMMENT_PARAGRAPH= 1 << 9;
47
48
	/** Range has parameter tag attribute */
49
	public static final int COMMENT_PARAMETER= 1 << 10;
50
51
	/** Range has root tag attribute */
52
	public static final int COMMENT_ROOT= 1 << 11;
53
54
	/** Range has paragraph separator attribute */
55
	public static final int COMMENT_SEPARATOR= 1 << 12;
56
57
	/** Range is the first token on the line in the original source */
58
	public static final int COMMENT_FIRST_TOKEN= 1 << 13;
59
60
	/**
61
	 * Range was preceded by whitespace / line delimiters
62
	 * @since 3.1
63
	 */
64
	public static final int COMMENT_STARTS_WITH_RANGE_DELIMITER= 1 << 14;
65
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/IHtmlTagDelimiters.java (-29 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
/**
15
 * Html tag constants.
16
 *
17
 * @since 3.0
18
 */
19
public interface IHtmlTagDelimiters {
20
21
	/** Html tag close prefix */
22
	public static final char[] HTML_CLOSE_PREFIX= "</".toCharArray(); //$NON-NLS-1$
23
24
	/** Html tag postfix */
25
	public static final char HTML_TAG_POSTFIX= '>';
26
27
	/** Html tag prefix */
28
	public static final char HTML_TAG_PREFIX= '<';
29
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocLine.java (-52 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
/**
15
 * Javadoc comment line in a comment region.
16
 *
17
 * @since 3.0
18
 */
19
public class JavaDocLine extends MultiCommentLine {
20
21
	/** Line prefix of javadoc start lines */
22
	public static final String JAVADOC_START_PREFIX= "/**"; //$NON-NLS-1$
23
24
	/**
25
	 * Creates a new javadoc line.
26
	 *
27
	 * @param region comment region to create the line for
28
	 */
29
	protected JavaDocLine(final CommentRegion region) {
30
		super(region);
31
	}
32
33
	/*
34
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#formatUpperBorder(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String, int)
35
	 */
36
	protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) {
37
38
		final CommentRegion parent= getParent();
39
40
		if (parent.isSingleLine() && parent.getSize() == 1) {
41
			parent.logEdit(getStartingPrefix() + CommentRegion.COMMENT_RANGE_DELIMITER, 0, range.getOffset());
42
		} else
43
			super.formatUpperBorder(range, indentation, length);
44
	}
45
46
	/*
47
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getStartingPrefix()
48
	 */
49
	protected String getStartingPrefix() {
50
		return JAVADOC_START_PREFIX;
51
	}
52
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java (-365 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
import java.io.IOException;
15
import java.io.StringReader;
16
import java.util.ArrayList;
17
import java.util.Iterator;
18
19
import org.eclipse.text.edits.TextEdit;
20
21
import org.eclipse.jface.text.BadLocationException;
22
import org.eclipse.jface.text.DefaultLineTracker;
23
import org.eclipse.jface.text.IDocument;
24
import org.eclipse.jface.text.ILineTracker;
25
import org.eclipse.jface.text.Position;
26
import org.eclipse.jface.text.TextUtilities;
27
28
import org.eclipse.jdt.core.formatter.CodeFormatter;
29
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
30
import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
31
32
33
/**
34
 * Javadoc region in a source code document.
35
 *
36
 * @since 3.0
37
 */
38
public class JavaDocRegion extends MultiCommentRegion {
39
40
	/** The positions of code ranges */
41
	private final ArrayList fCodePositions= new ArrayList();
42
43
	/** Should HTML tags be formatted? */
44
	private final boolean fFormatHtml;
45
46
	/** Should source code regions be formatted? */
47
	private final boolean fFormatSource;
48
49
 	/**
50
	 * Creates a new Javadoc region.
51
	 *
52
	 * @param document the document which contains the comment region
53
	 * @param position the position of this comment region in the document
54
	 * @param formatter the given formatter
55
	 */
56
	public JavaDocRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
57
		super(document, position, formatter);
58
59
		this.fFormatSource = this.preferences.comment_format_source;
60
		this.fFormatHtml = this.preferences.comment_format_html;
61
		this.fClear = this.preferences.comment_clear_blank_lines_in_javadoc_comment;
62
	}
63
64
	/*
65
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canFormat(org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange)
66
	 */
67
	protected boolean canFormat(final CommentRange previous, final CommentRange next) {
68
69
		if (previous != null) {
70
71
			final boolean isCurrentCode= next.hasAttribute(COMMENT_CODE);
72
			final boolean isLastCode= previous.hasAttribute(COMMENT_CODE);
73
74
			final int base= getOffset();
75
76
			if (!isLastCode && isCurrentCode)
77
				this.fCodePositions.add(new Position(base + previous.getOffset()));
78
			else if (isLastCode && !isCurrentCode)
79
				this.fCodePositions.add(new Position(base + next.getOffset() + next.getLength()));
80
81
			if (previous.hasAttribute(COMMENT_IMMUTABLE) && next.hasAttribute(COMMENT_IMMUTABLE))
82
				return false;
83
84
			return true;
85
		}
86
		return false;
87
	}
88
89
	/*
90
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#formatRegion(java.lang.String, int)
91
	 */
92
	protected final void formatRegion(final String indentation, final int width) {
93
94
		super.formatRegion(indentation, width);
95
96
		if (this.fFormatSource) {
97
98
			try {
99
100
				if (this.fCodePositions.size() > 0) {
101
102
					int begin= 0;
103
					int end= 0;
104
105
					Position position= null;
106
107
					final IDocument document= getDocument();
108
109
					for (int index= this.fCodePositions.size() - 1; index >= 0;) {
110
111
						position= (Position)this.fCodePositions.get(index--);
112
						begin= position.getOffset();
113
114
						if (index >= 0) {
115
							position= (Position)this.fCodePositions.get(index--);
116
							end= position.getOffset();
117
						} else {
118
							/*
119
							 * Handle missing closing tag
120
							 * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=57011
121
							 */
122
							position= null;
123
							end= getOffset() + getLength() - MultiCommentLine.MULTI_COMMENT_END_PREFIX.trim().length();
124
							while (end > begin && ScannerHelper.isWhitespace(document.getChar(end - 1)))
125
								end--;
126
						}
127
128
						String snippet= document.get(begin, end - begin);
129
						snippet= preprocessCodeSnippet(snippet);
130
						snippet= formatCodeSnippet(snippet);
131
						snippet= postprocessCodeSnippet(snippet, indentation);
132
133
						logEdit(snippet, begin - getOffset(), end - begin);
134
					}
135
				}
136
			} catch (BadLocationException e) {
137
				// Can not happen
138
				CommentFormatterUtil.log(e);
139
			}
140
		}
141
	}
142
143
	/**
144
	 * Preprocess a given code snippet.
145
	 *
146
	 * @param snippet the code snippet
147
	 * @return the preprocessed code snippet
148
	 */
149
	private String preprocessCodeSnippet(String snippet) {
150
		// strip content prefix
151
		StringBuffer buffer= new StringBuffer();
152
		ILineTracker tracker= new DefaultLineTracker();
153
		String contentPrefix= MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX.trim();
154
155
		buffer.setLength(0);
156
		buffer.append(snippet);
157
		tracker.set(snippet);
158
		for (int line= tracker.getNumberOfLines() - 1; line > 0; line--) {
159
			int lineOffset;
160
			try {
161
				lineOffset= tracker.getLineOffset(line);
162
			} catch (BadLocationException e) {
163
				// Can not happen
164
				CommentFormatterUtil.log(e);
165
				return snippet;
166
			}
167
			int prefixOffset= buffer.indexOf(contentPrefix, lineOffset);
168
			if (prefixOffset >= 0 && buffer.substring(lineOffset, prefixOffset).trim().length() == 0)
169
				buffer.delete(lineOffset, prefixOffset + contentPrefix.length() + 1);
170
		}
171
172
		return convertHtml2Java(buffer.toString());
173
	}
174
175
	/**
176
	 * Format the given code snippet
177
	 *
178
	 * @param snippet the code snippet
179
	 * @return the formatted code snippet
180
	 */
181
	private String formatCodeSnippet(String snippet) {
182
		String lineDelimiter= TextUtilities.getDefaultLineDelimiter(getDocument());
183
		TextEdit edit= CommentFormatterUtil.format2(CodeFormatter.K_UNKNOWN, snippet, 0, lineDelimiter, this.preferences.getMap());
184
		if (edit != null)
185
			snippet= CommentFormatterUtil.evaluateFormatterEdit(snippet, edit, null);
186
		return snippet;
187
	}
188
189
	/**
190
	 * Postprocesses the given code snippet with the given indentation.
191
	 *
192
	 * @param snippet the code snippet
193
	 * @param indentation the indentation
194
	 * @return the postprocessed code snippet
195
	 */
196
	private String postprocessCodeSnippet(String snippet, String indentation) {
197
		// patch content prefix
198
		StringBuffer buffer= new StringBuffer();
199
		ILineTracker tracker= new DefaultLineTracker();
200
		String patch= indentation + MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX;
201
202
		// remove trailing spaces
203
		int i= snippet.length();
204
		while (i > 0 && ' ' == snippet.charAt(i-1))
205
			i--;
206
		snippet= snippet.substring(0, i);
207
208
		buffer.setLength(0);
209
		String lineDelimiter= getDelimiter();
210
		if (lineDelimiter != null && snippet.indexOf(lineDelimiter) != 0)
211
			buffer.append(lineDelimiter);
212
		buffer.append(convertJava2Html(snippet));
213
		if (lineDelimiter != null && snippet.lastIndexOf(lineDelimiter) != snippet.length() - lineDelimiter.length())
214
			buffer.append(lineDelimiter);
215
		tracker.set(buffer.toString());
216
217
		for (int line= tracker.getNumberOfLines() - 1; line > 0; line--)
218
			try {
219
				buffer.insert(tracker.getLineOffset(line), patch);
220
			} catch (BadLocationException e) {
221
				// Can not happen
222
				CommentFormatterUtil.log(e);
223
				return snippet;
224
			}
225
226
		return buffer.toString();
227
	}
228
229
	/*
230
	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markHtmlRanges()
231
	 */
232
	protected final void markHtmlRanges() {
233
234
		markTagRanges(JAVADOC_IMMUTABLE_TAGS, COMMENT_IMMUTABLE, true);
235
236
		if (this.fFormatSource)
237
			markTagRanges(JAVADOC_CODE_TAGS, COMMENT_CODE, false);
238
	}
239
240
	/*
241
	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markHtmlTag(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
242
	 */
243
	protected final void markHtmlTag(final CommentRange range, final char[] token) {
244
245
		if (range.hasAttribute(COMMENT_HTML)) {
246
247
			range.markHtmlTag(JAVADOC_IMMUTABLE_TAGS, token, COMMENT_IMMUTABLE, true, true);
248
			if (this.fFormatHtml) {
249
250
				range.markHtmlTag(JAVADOC_SEPARATOR_TAGS, token, COMMENT_SEPARATOR, true, true);
251
				range.markHtmlTag(JAVADOC_BREAK_TAGS, token, COMMENT_BREAK, false, true);
252
				range.markHtmlTag(JAVADOC_SINGLE_BREAK_TAG, token, COMMENT_BREAK, true, false);
253
				range.markHtmlTag(JAVADOC_NEWLINE_TAGS, token, COMMENT_NEWLINE, true, false);
254
255
			} else
256
				range.markHtmlTag(JAVADOC_CODE_TAGS, token, COMMENT_SEPARATOR, true, true);
257
		}
258
	}
259
260
	/*
261
	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markJavadocTag(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
262
	 */
263
	protected final void markJavadocTag(final CommentRange range, final char[] token) {
264
265
		range.markPrefixTag(JAVADOC_PARAM_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_PARAMETER);
266
267
		if (token[0] == JAVADOC_TAG_PREFIX && !range.hasAttribute(COMMENT_PARAMETER))
268
			range.setAttribute(COMMENT_ROOT);
269
	}
270
271
	/**
272
	 * Marks the comment region with the HTML range tag.
273
	 *
274
	 * @param tags the HTML tag which confines the HTML range
275
	 * @param attribute the attribute to set if the comment range is in the
276
	 *                HTML range
277
	 * @param html <code>true</code> iff the HTML tags in this HTML range
278
	 *                should be marked too, <code>false</code> otherwise
279
	 */
280
	protected final void markTagRanges(final char[][] tags, final int attribute, final boolean html) {
281
282
		int level= 0;
283
		int count= 0;
284
		char[] token= null;
285
		CommentRange current= null;
286
287
		for (int index= 0; index < tags.length; index++) {
288
289
			level= 0;
290
			for (final Iterator iterator= getRanges().iterator(); iterator.hasNext();) {
291
292
				current= (CommentRange)iterator.next();
293
				count= current.getLength();
294
295
				if (count > 0 || level > 0) { // PR44035: when inside a tag, mark blank lines as well to get proper snippet formatting
296
297
					token= getText(current.getOffset(), current.getLength()).toCharArray();
298
					level= current.markTagRange(token, tags[index], level, attribute, html);
299
				}
300
			}
301
		}
302
	}
303
304
	/*
305
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canAppend(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, int, int)
306
	 */
307
	protected boolean canAppend(CommentLine line, CommentRange previous, CommentRange next, int index, int count) {
308
		// don't append code sections
309
		if (next.hasAttribute(COMMENT_CODE | COMMENT_FIRST_TOKEN) && line.getSize() != 0)
310
			return false;
311
		return super.canAppend(line, previous, next, index, count);
312
	}
313
314
	/**
315
	 * Converts <code>formatted</code> into valid html code suitable to be
316
	 * put inside &lt;pre&gt;&lt;/pre&gt; tags by replacing any html symbols
317
	 * by the relevant entities.
318
	 *
319
	 * @param formatted the formatted java code
320
	 * @return html version of the formatted code
321
	 */
322
	private String convertJava2Html(String formatted) {
323
		Java2HTMLEntityReader reader= new Java2HTMLEntityReader(new StringReader(formatted));
324
		char[] buf= new char[256];
325
		StringBuffer buffer= new StringBuffer();
326
		int l;
327
		try {
328
			do {
329
				l= reader.read(buf);
330
				if (l != -1)
331
					buffer.append(buf, 0, l);
332
			} while (l > 0);
333
			return buffer.toString();
334
		} catch (IOException e) {
335
			return formatted;
336
		}
337
	}
338
339
	/**
340
	 * Converts <code>html</code> into java code suitable for formatting
341
	 * by replacing any html entities by their plain text representation.
342
	 *
343
	 * @param html html code, may contain html entities
344
	 * @return plain textified version of <code>html</code>
345
	 */
346
	private String convertHtml2Java(String html) {
347
		HTMLEntity2JavaReader reader= new HTMLEntity2JavaReader(new StringReader(html));
348
		char[] buf= new char[html.length()]; // html2text never gets longer, only shorter!
349
350
		try {
351
			int read= reader.read(buf);
352
			return new String(buf, 0, read);
353
		} catch (IOException e) {
354
			return html;
355
		}
356
	}
357
358
	/*
359
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#createLine()
360
	 * @since 3.1
361
	 */
362
	protected CommentLine createLine() {
363
		return new JavaDocLine(this);
364
	}
365
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentLine.java (-409 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
import java.util.HashSet;
15
import java.util.Set;
16
17
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
18
import org.eclipse.jface.text.IRegion;
19
import org.eclipse.jface.text.Region;
20
21
/**
22
 * Multi-line comment line in a comment region.
23
 *
24
 * @since 3.0
25
 */
26
public class MultiCommentLine extends CommentLine implements ICommentAttributes, IHtmlTagDelimiters, IJavaDocTagConstants {
27
28
	/** Line prefix of multi-line comment content lines */
29
	public static final String MULTI_COMMENT_CONTENT_PREFIX= " * "; //$NON-NLS-1$
30
31
	/** Line prefix of multi-line comment end lines */
32
	public static final String MULTI_COMMENT_END_PREFIX= " */"; //$NON-NLS-1$
33
34
	/** Line prefix of multi-line comment content lines */
35
	public static final String MULTI_COMMENT_START_PREFIX= "/* "; //$NON-NLS-1$
36
37
	/** The indentation reference of this line */
38
	private String fReferenceIndentation= ""; //$NON-NLS-1$
39
40
	/** The javadoc tag lookup. */
41
	private static final Set fgTagLookup;
42
43
	static {
44
		fgTagLookup= new HashSet();
45
		for (int i= 0; i < JAVADOC_BREAK_TAGS.length; i++) {
46
			fgTagLookup.add(new String(JAVADOC_BREAK_TAGS[i]));
47
		}
48
		for (int i= 0; i < JAVADOC_SINGLE_BREAK_TAG.length; i++) {
49
			fgTagLookup.add(new String(JAVADOC_SINGLE_BREAK_TAG[i]));
50
		}
51
		for (int i= 0; i < JAVADOC_CODE_TAGS.length; i++) {
52
			fgTagLookup.add(new String(JAVADOC_CODE_TAGS[i]));
53
		}
54
		for (int i= 0; i < JAVADOC_IMMUTABLE_TAGS.length; i++) {
55
			fgTagLookup.add(new String(JAVADOC_IMMUTABLE_TAGS[i]));
56
		}
57
		for (int i= 0; i < JAVADOC_NEWLINE_TAGS.length; i++) {
58
			fgTagLookup.add(new String(JAVADOC_NEWLINE_TAGS[i]));
59
		}
60
		for (int i= 0; i < JAVADOC_SEPARATOR_TAGS.length; i++) {
61
			fgTagLookup.add(new String(JAVADOC_SEPARATOR_TAGS[i]));
62
		}
63
	}
64
65
	/**
66
	 * Creates a new multi-line comment line.
67
	 *
68
	 * @param region comment region to create the line for
69
	 */
70
	protected MultiCommentLine(final CommentRegion region) {
71
		super(region);
72
	}
73
74
	/*
75
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#adapt(org.eclipse.jdt.internal.corext.text.comment.CommentLine)
76
	 */
77
	protected void adapt(final CommentLine previous) {
78
79
		if (!hasAttribute(COMMENT_ROOT) && !hasAttribute(COMMENT_PARAMETER) && !previous.hasAttribute(COMMENT_BLANKLINE))
80
			this.fReferenceIndentation= previous.getIndentationReference();
81
	}
82
83
	/*
84
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#append(org.eclipse.jdt.internal.corext.text.comment.CommentRange)
85
	 */
86
	protected void append(final CommentRange range) {
87
88
		final MultiCommentRegion parent= (MultiCommentRegion)getParent();
89
90
		if (range.hasAttribute(COMMENT_PARAMETER))
91
			setAttribute(COMMENT_PARAMETER);
92
		else if (range.hasAttribute(COMMENT_ROOT))
93
			setAttribute(COMMENT_ROOT);
94
		else if (range.hasAttribute(COMMENT_BLANKLINE))
95
			setAttribute(COMMENT_BLANKLINE);
96
97
		final int ranges= getSize();
98
		if (ranges == 1) {
99
100
			if (parent.isIndentRoots()) {
101
102
				final CommentRange first= getFirst();
103
				final String common= parent.getText(first.getOffset(), first.getLength()) + CommentRegion.COMMENT_RANGE_DELIMITER;
104
105
				if (hasAttribute(COMMENT_ROOT))
106
					this.fReferenceIndentation= common;
107
				else if (hasAttribute(COMMENT_PARAMETER)) {
108
					if (parent.isIndentDescriptions())
109
						this.fReferenceIndentation= "\t" + common; //$NON-NLS-1$
110
					else
111
						this.fReferenceIndentation= common;
112
				}
113
			}
114
		}
115
		super.append(range);
116
	}
117
118
	/*
119
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getContentLinePrefix()
120
	 */
121
	protected String getContentPrefix() {
122
		return MULTI_COMMENT_CONTENT_PREFIX;
123
	}
124
125
	/*
126
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getEndLinePrefix()
127
	 */
128
	protected String getEndingPrefix() {
129
		return MULTI_COMMENT_END_PREFIX;
130
	}
131
132
	/**
133
	 * Returns the reference indentation to use for this line.
134
	 *
135
	 * @return the reference indentation for this line
136
	 */
137
	protected final String getIndentationReference() {
138
		return this.fReferenceIndentation;
139
	}
140
141
	/*
142
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getStartLinePrefix()
143
	 */
144
	protected String getStartingPrefix() {
145
		return MULTI_COMMENT_START_PREFIX;
146
	}
147
148
	/*
149
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#scanLine(int)
150
	 */
151
	protected void scanLine(final int line) {
152
153
		final CommentRegion parent= getParent();
154
		final String start= getStartingPrefix().trim();
155
		final String end= getEndingPrefix().trim();
156
		final String content= getContentPrefix().trim();
157
158
		final int lines= parent.getSize();
159
		final CommentRange range= getFirst();
160
161
		int offset= 0;
162
		int postfix= 0;
163
164
		String text= parent.getText(range.getOffset(), range.getLength());
165
		if (line == 0) {
166
167
			offset= text.indexOf(start);
168
			if (offset >= 0 && text.substring(0, offset).trim().length() != 0)
169
				offset= -1;
170
171
			if (offset >= 0) {
172
173
				offset += start.length();
174
				range.trimBegin(offset);
175
176
				postfix= text.lastIndexOf(end);
177
				if (postfix >= 0 && text.substring(postfix + end.length()).trim().length() != 0)
178
					postfix= -1;
179
180
				if (postfix >= offset)
181
					// comment ends on same line
182
					range.setLength(postfix - offset);
183
				else {
184
					postfix= text.lastIndexOf(content);
185
					if (postfix >= 0 && text.substring(postfix + content.length()).trim().length() != 0)
186
						postfix= -1;
187
188
					if (postfix >= offset) {
189
190
						range.setLength(postfix - offset);
191
						parent.setBorder(BORDER_UPPER);
192
193
						if (postfix > offset) {
194
195
							text= parent.getText(range.getOffset(), range.getLength());
196
							final IRegion region= trimLine(text, content);
197
198
							range.move(region.getOffset());
199
							range.setLength(region.getLength());
200
						}
201
					}
202
				}
203
			}
204
		} else if (line == lines - 1) {
205
206
			offset= text.indexOf(content);
207
			if (offset >= 0 && text.substring(0, offset).trim().length() != 0)
208
				offset= -1;
209
			postfix= text.lastIndexOf(end);
210
			if (postfix >= 0 && text.substring(postfix + end.length()).trim().length() != 0)
211
				postfix= -1;
212
213
			if (offset >= 0 && offset == postfix)
214
				// no content on line, only the comment postfix
215
				range.setLength(0);
216
			else {
217
				if (offset >= 0)
218
					// omit the content prefix
219
					range.trimBegin(offset + content.length());
220
221
				if (postfix >= 0)
222
					// omit the comment postfix
223
					range.trimEnd(-end.length());
224
225
				text= parent.getText(range.getOffset(), range.getLength());
226
				final IRegion region= trimLine(text, content);
227
				if (region.getOffset() != 0 || region.getLength() != text.length()) {
228
229
					range.move(region.getOffset());
230
					range.setLength(region.getLength());
231
232
					parent.setBorder(BORDER_UPPER);
233
					parent.setBorder(BORDER_LOWER);
234
				}
235
			}
236
		} else {
237
238
			offset= text.indexOf(content);
239
			if (offset >= 0 && text.substring(0, offset).trim().length() != 0)
240
				offset= -1;
241
242
			if (offset >= 0) {
243
244
				offset += content.length();
245
				range.trimBegin(offset);
246
			}
247
		}
248
	}
249
250
	/*
251
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#tokenizeLine(int)
252
	 */
253
	protected void tokenizeLine(int line) {
254
255
		int offset= 0;
256
		int index= offset;
257
258
		final CommentRegion parent= getParent();
259
		final CommentRange range= getFirst();
260
		final int begin= range.getOffset();
261
262
		final String content= parent.getText(begin, range.getLength());
263
		final int length= content.length();
264
265
		while (offset < length && ScannerHelper.isWhitespace(content.charAt(offset)))
266
			offset++;
267
268
		CommentRange result= null;
269
		if (offset >= length && !parent.isClearLines() && (line > 0 && line < parent.getSize() - 1)) {
270
271
			result= new CommentRange(begin, 0);
272
			result.setAttribute(COMMENT_BLANKLINE);
273
			result.setAttribute(COMMENT_FIRST_TOKEN);
274
275
			parent.append(result);
276
		}
277
278
		int attribute= COMMENT_FIRST_TOKEN | COMMENT_STARTS_WITH_RANGE_DELIMITER;
279
		while (offset < length) {
280
281
			while (offset < length && ScannerHelper.isWhitespace(content.charAt(offset))) {
282
				offset++;
283
				attribute |= COMMENT_STARTS_WITH_RANGE_DELIMITER;
284
			}
285
286
			index= offset;
287
288
			if (index < length) {
289
290
				if (content.charAt(index) == HTML_TAG_PREFIX) {
291
292
					// in order to avoid recognizing any < in a comment, even those which are part of e.g.
293
					// java source code, we validate the tag content to be one of the recognized
294
					// tags (structural, breaks, pre, code).
295
					int tag= ++index;
296
					while (index < length && content.charAt(index) != HTML_TAG_POSTFIX && content.charAt(index) != HTML_TAG_PREFIX)
297
						index++;
298
299
					if (index < length && content.charAt(index) == HTML_TAG_POSTFIX && isValidTag(content.substring(tag, index))) {
300
						index++;
301
						attribute |= COMMENT_HTML; // only set html attribute if postfix found
302
					} else {
303
						// no tag - do the usual thing from the original offset
304
						index= tag;
305
						while (index < length
306
								&& !ScannerHelper.isWhitespace(content.charAt(index))
307
								&& content.charAt(index) != HTML_TAG_PREFIX
308
								&& !content.startsWith(LINK_TAG_PREFIX_STRING, index))
309
							index++;
310
					}
311
312
313
				} else if (content.startsWith(LINK_TAG_PREFIX_STRING, index)) {
314
315
					while (index < length && content.charAt(index) != LINK_TAG_POSTFIX)
316
						index++;
317
318
					if (index < length && content.charAt(index) == LINK_TAG_POSTFIX)
319
						index++;
320
321
					attribute |= COMMENT_OPEN | COMMENT_CLOSE;
322
323
				} else {
324
325
					while (index < length
326
							&& !ScannerHelper.isWhitespace(content.charAt(index))
327
							&& content.charAt(index) != HTML_TAG_PREFIX
328
							&& !content.startsWith(LINK_TAG_PREFIX_STRING, index))
329
						index++;
330
				}
331
			}
332
333
			if (index - offset > 0) {
334
335
				result= new CommentRange(begin + offset, index - offset);
336
				result.setAttribute(attribute);
337
338
				parent.append(result);
339
				offset= index;
340
			}
341
342
			attribute= 0;
343
		}
344
	}
345
346
	/**
347
	 * Checks whether <code>tag</code> is a valid tag content (text inside
348
	 * the angular brackets &lt;, &gt;).
349
	 * <p>
350
	 * The algorithm is to see if the tag trimmed of whitespace and an
351
	 * optional slash starts with one of our recognized tags.
352
	 *
353
	 * @param tag the tag to check
354
	 * @return <code>true</code> if <code>tag</code> is a valid tag
355
	 *         content
356
	 */
357
	private boolean isValidTag(String tag) {
358
		// strip the slash
359
		if (tag.startsWith("/")) //$NON-NLS-1$
360
			tag= tag.substring(1, tag.length());
361
362
		// strip ws
363
		tag= tag.trim();
364
365
		// extract first token
366
		int i= 0;
367
		while (i < tag.length() && !ScannerHelper.isWhitespace(tag.charAt(i)))
368
			i++;
369
		tag= tag.substring(0, i);
370
371
		// see if it's a tag
372
		return isTagName(tag.toLowerCase());
373
	}
374
375
	/**
376
	 * Checks whether <code>tag</code> is one of the configured tags.
377
	 *
378
	 * @param tag the tag to check
379
	 * @return <code>true</code> if <code>tag</code> is a configured tag
380
	 *         name
381
	 */
382
	private boolean isTagName(String tag) {
383
		return fgTagLookup.contains(tag);
384
	}
385
386
	/**
387
	 * Removes all leading and trailing occurrences from <code>line</code>.
388
	 *
389
	 * @param line the string to remove the occurrences of
390
	 *                <code>trimmable</code>
391
	 * @param trimmable the string to remove from <code>line</code>
392
	 * @return the region of the trimmed substring within <code>line</code>
393
	 */
394
	protected final IRegion trimLine(final String line, final String trimmable) {
395
396
		final int trim= trimmable.length();
397
398
		int offset= 0;
399
		int length= line.length() - trim;
400
401
		while (line.startsWith(trimmable, offset))
402
			offset += trim;
403
404
		while (line.startsWith(trimmable, length))
405
			length -= trim;
406
407
		return new Region(offset, length + trim);
408
	}
409
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentRegion.java (-245 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
import java.util.Iterator;
15
import java.util.ListIterator;
16
17
import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
18
import org.eclipse.jface.text.BadLocationException;
19
import org.eclipse.jface.text.IDocument;
20
import org.eclipse.jface.text.Position;
21
22
/**
23
 * Multi-comment region in a source code document.
24
 *
25
 * @since 3.0
26
 */
27
public class MultiCommentRegion extends CommentRegion implements IJavaDocTagConstants {
28
29
	/** Should root tag parameter descriptions be indented after the tag? */
30
	private final boolean fIndentDescriptions;
31
32
	/** Should root tag parameter descriptions be indented? */
33
	private final boolean fIndentRoots;
34
35
	/** Should description of parameters go to the next line? */
36
	private final boolean fParameterNewLine;
37
38
	/** Should root tags be separated from description? */
39
	private boolean fSeparateRoots;
40
41
 	/**
42
	 * Creates a new multi-comment region.
43
	 *
44
	 * @param document the document which contains the comment region
45
	 * @param position the position of this comment region in the document
46
	 * @param formatter the given formatter
47
	 */
48
	public MultiCommentRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
49
		super(document, position, formatter);
50
51
		this.fIndentRoots= this.preferences.comment_indent_root_tags;
52
		this.fIndentDescriptions= this.preferences.comment_indent_parameter_description;
53
		this.fSeparateRoots= this.preferences.comment_insert_empty_line_before_root_tags;
54
		this.fParameterNewLine= this.preferences.comment_insert_new_line_for_parameter;
55
		this.fClear = this.preferences.comment_clear_blank_lines_in_block_comment;
56
	}
57
58
	/*
59
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canAppend(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, int, int)
60
	 */
61
	protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, int count) {
62
63
		final boolean blank= next.hasAttribute(COMMENT_BLANKLINE);
64
65
		// Avoid wrapping punctuation
66
		if (next.getLength() <= 2 && !blank && isNonAlphaNumeric(next))
67
			return true;
68
69
		if (this.fParameterNewLine && line.hasAttribute(COMMENT_PARAMETER) && line.getSize() > 1)
70
			return false;
71
72
		if (previous != null) {
73
74
			if (index != 0 && (blank || previous.hasAttribute(COMMENT_BLANKLINE) || next.hasAttribute(COMMENT_PARAMETER) || next.hasAttribute(COMMENT_ROOT) || next.hasAttribute(COMMENT_SEPARATOR) || next.hasAttribute(COMMENT_NEWLINE) || previous.hasAttribute(COMMENT_BREAK) || previous.hasAttribute(COMMENT_SEPARATOR)))
75
				return false;
76
77
			if (previous.hasAttribute(COMMENT_ROOT))
78
				return true;
79
80
			if (next.hasAttribute(COMMENT_IMMUTABLE) && previous.hasAttribute(COMMENT_IMMUTABLE))
81
				return true;
82
		}
83
84
		// always append elements that did not have any range separators
85
		if (!next.hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER)) {
86
			return true;
87
		}
88
89
		if (this.fIndentRoots && !line.hasAttribute(COMMENT_ROOT) && !line.hasAttribute(COMMENT_PARAMETER))
90
			count -= stringToLength(line.getIndentationReference());
91
92
		// Avoid appending consecutive immutable ranges, which together exceed the line width
93
		if (next.hasAttribute(COMMENT_IMMUTABLE) && (previous == null || !previous.hasAttribute(COMMENT_IMMUTABLE))) {
94
			// Breaking the abstraction by directly accessing the list of ranges for looking ahead
95
			Iterator iter= getRanges().iterator();
96
			CommentRange current= null;
97
			while (iter.hasNext() && current != next)
98
				current= (CommentRange) iter.next();
99
100
			if (current != null && iter.hasNext()) {
101
				try {
102
					int lineNumber= getDocument().getLineOfOffset(getOffset() + current.getOffset());
103
					CommentRange last= current;
104
					while (iter.hasNext()) {
105
						current= (CommentRange) iter.next();
106
						if (current.hasAttribute(COMMENT_IMMUTABLE) && getDocument().getLineOfOffset(getOffset() + current.getOffset()) == lineNumber)
107
							last= current;
108
						else
109
							break;
110
					}
111
					count -= last.getOffset() + last.getLength() - (next.getOffset() + next.getLength());
112
				} catch (BadLocationException e) {
113
					// Should not happen
114
				}
115
			}
116
		}
117
118
		return super.canAppend(line, previous, next, index, count);
119
	}
120
121
	/*
122
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#getDelimiter(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
123
	 */
124
	protected String getDelimiter(CommentLine predecessor, CommentLine successor, CommentRange previous, CommentRange next, String indentation) {
125
126
		final String delimiter= super.getDelimiter(predecessor, successor, previous, next, indentation);
127
128
		if (previous != null) {
129
130
			// Blank line before <pre> tag
131
			if (previous.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !next.hasAttribute(COMMENT_CODE) && !successor.hasAttribute(COMMENT_BLANKLINE))
132
				return delimiter + delimiter;
133
134
			// Blank line after </pre> tag
135
			else if (next.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
136
				return delimiter + delimiter;
137
138
			// Add blank line before first root/parameter tag, if "Blank line before Javadoc tags"
139
			else if (this.fSeparateRoots && previous.hasAttribute(COMMENT_PARAGRAPH) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
140
				return delimiter + delimiter;
141
142
			else if (this.fIndentRoots && !predecessor.hasAttribute(COMMENT_ROOT) && !predecessor.hasAttribute(COMMENT_PARAMETER) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
143
				return delimiter + stringToIndent(predecessor.getIndentationReference());
144
		}
145
		return delimiter;
146
	}
147
148
	/*
149
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#getDelimiter(org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange)
150
	 */
151
	protected String getDelimiter(final CommentRange previous, final CommentRange next) {
152
		// simply preserve range (~ word) breaks
153
		if (previous != null && !previous.hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER)) {
154
			return ""; //$NON-NLS-1$
155
		} else {
156
			return super.getDelimiter(previous, next);
157
		}
158
	}
159
160
	/**
161
	 * Should root tag parameter descriptions be indented after the tag?
162
	 *
163
	 * @return <code>true</code> iff the descriptions should be indented
164
	 *         after, <code>false</code> otherwise.
165
	 */
166
	protected final boolean isIndentDescriptions() {
167
		return this.fIndentDescriptions;
168
	}
169
170
	/**
171
	 * Should root tag parameter descriptions be indented?
172
	 *
173
	 * @return <code>true</code> iff the root tags should be indented,
174
	 *         <code>false</code> otherwise.
175
	 */
176
	protected final boolean isIndentRoots() {
177
		return this.fIndentRoots;
178
	}
179
180
	/**
181
	 * Marks the comment ranges confined by HTML ranges.
182
	 */
183
	protected void markHtmlRanges() {
184
		// Do nothing
185
	}
186
187
	/**
188
	 * Marks the comment range with its HTML tag attributes.
189
	 *
190
	 * @param range the comment range to mark
191
	 * @param token token associated with the comment range
192
	 */
193
	protected void markHtmlTag(final CommentRange range, final char[] token) {
194
		// Do nothing
195
	}
196
197
	/**
198
	 * Marks the comment range with its javadoc tag attributes.
199
	 *
200
	 * @param range the comment range to mark
201
	 * @param token token associated with the comment range
202
	 */
203
	protected void markJavadocTag(final CommentRange range, final char[] token) {
204
		range.markPrefixTag(COMMENT_ROOT_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_ROOT);
205
	}
206
207
	/*
208
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#markRegion()
209
	 */
210
	protected void markRegion() {
211
212
		int count= 0;
213
		boolean paragraph= false;
214
215
		char[] token= null;
216
		CommentRange range= null;
217
218
		for (final ListIterator iterator= getRanges().listIterator(); iterator.hasNext();) {
219
220
			range= (CommentRange)iterator.next();
221
			count= range.getLength();
222
223
			if (count > 0) {
224
225
				token= getText(range.getOffset(), count).toLowerCase().toCharArray();
226
227
				markJavadocTag(range, token);
228
				if (!paragraph && (range.hasAttribute(COMMENT_ROOT) || range.hasAttribute(COMMENT_PARAMETER))) {
229
					range.setAttribute(COMMENT_PARAGRAPH);
230
					paragraph= true;
231
				}
232
				markHtmlTag(range, token);
233
			}
234
		}
235
		markHtmlRanges();
236
	}
237
238
	/*
239
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#createLine()
240
	 * @since 3.1
241
	 */
242
	protected CommentLine createLine() {
243
		return new MultiCommentLine(this);
244
	}
245
}
(-)formatter/org/eclipse/jdt/internal/formatter/comment/SingleCommentLine.java (-115 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.jdt.internal.formatter.comment;
13
14
/**
15
 * Single-line comment line in a comment region.
16
 *
17
 * @since 3.0
18
 */
19
public class SingleCommentLine extends CommentLine {
20
21
	/** Line prefix for single line comments */
22
	public static final String SINGLE_COMMENT_PREFIX= "// "; //$NON-NLS-1$
23
24
	/** NLS tag prefix */
25
	private static final String NLS_TAG_PREFIX= "//$NON-NLS-"; //$NON-NLS-1$
26
27
	/** Is the comment a NLS locale tag sequence? */
28
	private boolean fLocaleSequence= false;
29
30
	/**
31
	 * Creates a new single-line comment line.
32
	 *
33
	 * @param region comment region to create the line for
34
	 */
35
	protected SingleCommentLine(final CommentRegion region) {
36
		super(region);
37
	}
38
39
	/*
40
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#adapt(org.eclipse.jdt.internal.corext.text.comment.CommentLine)
41
	 */
42
	protected void adapt(final CommentLine previous) {
43
		// Do nothing
44
	}
45
46
	/*
47
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#formatLowerBorder(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String, int)
48
	 */
49
	protected void formatLowerBorder(final CommentRange range, final String indentation, final int length) {
50
51
		final int offset= range.getOffset() + range.getLength();
52
		final CommentRegion parent= getParent();
53
54
		parent.logEdit(parent.getDelimiter(), offset, parent.getLength() - offset);
55
	}
56
57
	/*
58
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#formatUpperBorder(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String, int)
59
	 */
60
	protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) {
61
62
		final CommentRegion parent= getParent();
63
64
		parent.logEdit(getContentPrefix(), 0, range.getOffset());
65
	}
66
67
	/*
68
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getContentPrefix()
69
	 */
70
	protected String getContentPrefix() {
71
		return SINGLE_COMMENT_PREFIX;
72
	}
73
74
	/*
75
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getEndingPrefix()
76
	 */
77
	protected String getEndingPrefix() {
78
		return SINGLE_COMMENT_PREFIX;
79
	}
80
81
	/*
82
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getStartingPrefix()
83
	 */
84
	protected String getStartingPrefix() {
85
		return SINGLE_COMMENT_PREFIX;
86
	}
87
88
	/*
89
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#scanLine(int)
90
	 */
91
	protected void scanLine(final int line) {
92
93
		final CommentRange range= getFirst();
94
		final String content= getParent().getText(range.getOffset(), range.getLength());
95
		final String prefix= getContentPrefix().trim();
96
97
		final int offset= content.indexOf(prefix);
98
		if (offset >= 0) {
99
100
			if (content.startsWith(NLS_TAG_PREFIX))
101
				this.fLocaleSequence= true;
102
103
			range.trimBegin(offset + prefix.length());
104
		}
105
	}
106
107
	/*
108
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#tokenizeLine(int)
109
	 */
110
	protected void tokenizeLine(final int line) {
111
112
		if (!this.fLocaleSequence)
113
			super.tokenizeLine(line);
114
	}
115
}
(-)src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java (-3 / +137 lines)
Lines 2200-2207 Link Here
2200
		"	  return null;\n" +
2200
		"	  return null;\n" +
2201
		"  }\n" +
2201
		"  }\n" +
2202
		"}\n";
2202
		"}\n";
2203
	// TODO (frederic) line comment should be formatted when F_INCLUDE_COMMENTS
2204
	// flag will work for all snippet kinds
2205
	formatSource(source,
2203
	formatSource(source,
2206
		"/**\n" +
2204
		"/**\n" +
2207
		" * Need a javadoc comment before to get the exception.\n" +
2205
		" * Need a javadoc comment before to get the exception.\n" +
Lines 2213-2219 Link Here
2213
		"	 * If there is an authority, it is:\n" +
2211
		"	 * If there is an authority, it is:\n" +
2214
		"	 * \n" +
2212
		"	 * \n" +
2215
		"	 * <pre>\n" +
2213
		"	 * <pre>\n" +
2216
		"	 * //class	body		snippet\n" +
2214
		"	 * // class body snippet\n" + 
2217
		"	 * public class X {\n" +
2215
		"	 * public class X {\n" +
2218
		"	 * }\n" +
2216
		"	 * }\n" +
2219
		"	 * </pre>\n" +
2217
		"	 * </pre>\n" +
Lines 2265-2270 Link Here
2265
}
2263
}
2266
2264
2267
/**
2265
/**
2266
 * @bug 236406: [formatter] Formatting qualified invocations can be broken when the Line Wrapping policy forces element to be on a new line
2267
 * @test Verify that wrapping policies forcing the first element to be on a new line are working again...
2268
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=236406"
2269
 */
2270
public void testBug236406_CDB1() {
2271
	String source = 
2272
		"/**        Javadoc		comment    	    */void foo1() {System.out.println();}\n" +
2273
		"//        Line		comment    	    \n" +
2274
		"void foo2() {System.out.println();}\n" +
2275
		"/*        Block		comment    	    */\n" +
2276
		"void foo3() {\n" +
2277
		"/*        statement Block		comment    	    */\n" +
2278
		"System.out.println();}\n";
2279
	formatSource(source,
2280
		"/**        Javadoc		comment    	    */\n" + 
2281
		"void foo1() {\n" + 
2282
		"	System.out.println();\n" + 
2283
		"}\n" + 
2284
		"\n" + 
2285
		"//        Line		comment    	    \n" + 
2286
		"void foo2() {\n" + 
2287
		"	System.out.println();\n" + 
2288
		"}\n" + 
2289
		"\n" + 
2290
		"/*        Block		comment    	    */\n" +
2291
		"void foo3() {\n" +
2292
		"	/*        statement Block		comment    	    */\n" + 
2293
		"	System.out.println();\n" + 
2294
		"}",
2295
		CodeFormatter.K_CLASS_BODY_DECLARATIONS
2296
	);
2297
}
2298
public void testBug236406_CDB2() {
2299
	String source = 
2300
		"/**        Javadoc		comment    	    */void foo1() {System.out.println();}\n" +
2301
		"//        Line		comment    	    \n" +
2302
		"void foo2() {System.out.println();}\n" +
2303
		"/*        Block		comment    	    */\n" +
2304
		"void foo3() {\n" +
2305
		"/*        statement Block		comment    	    */\n" +
2306
		"System.out.println();}\n";
2307
	formatSource(source,
2308
		"/** Javadoc comment */\n" + 
2309
		"void foo1() {\n" + 
2310
		"	System.out.println();\n" + 
2311
		"}\n" + 
2312
		"\n" + 
2313
		"// Line comment\n" + 
2314
		"void foo2() {\n" + 
2315
		"	System.out.println();\n" + 
2316
		"}\n" + 
2317
		"\n" + 
2318
		"/* Block comment */\n" +
2319
		"void foo3() {\n" + 
2320
		"	/* statement Block comment */\n" + 
2321
		"	System.out.println();\n" + 
2322
		"}",
2323
		CodeFormatter.K_CLASS_BODY_DECLARATIONS | CodeFormatter.F_INCLUDE_COMMENTS
2324
	);
2325
}
2326
public void testBug236406_EX1() {
2327
	String source = 
2328
		"//        Line		comment    	    \n" +
2329
		"i = \n" +
2330
		"/**        Javadoc		comment    	    */\n" +
2331
		"1     +     (/*      Block		comment*/++a)\n";
2332
	formatSource(source,
2333
		"//        Line		comment    	    \n" + 
2334
		"i =\n" + 
2335
		"/**        Javadoc		comment    	    */\n" + 
2336
		"1 + (/*      Block		comment*/++a)",
2337
		CodeFormatter.K_EXPRESSION
2338
	);
2339
}
2340
public void testBug236406_EX2() {
2341
	String source = 
2342
		"//        Line		comment    	    \n" +
2343
		"i = \n" +
2344
		"/**        Javadoc		comment    	    */\n" +
2345
		"1     +     (/*      Block		comment*/++a)\n";
2346
	formatSource(source,
2347
		"// Line comment\n" + 
2348
		"i =\n" + 
2349
		"/** Javadoc comment */\n" + 
2350
		"1 + (/* Block comment */++a)",
2351
		CodeFormatter.K_EXPRESSION | CodeFormatter.F_INCLUDE_COMMENTS
2352
	);
2353
}
2354
public void testBug236406_ST1() {
2355
	String source = 
2356
		"/**        Javadoc		comment    	    */foo1();\n" +
2357
		"//        Line		comment    	    \n" +
2358
		"foo2();\n" +
2359
		"/*        Block		comment    	    */\n" +
2360
		"foo3(); {\n" +
2361
		"/*        indented Block		comment    	    */\n" +
2362
		"System.out.println();}\n";
2363
	formatSource(source,
2364
		"/**        Javadoc		comment    	    */\n" + 
2365
		"foo1();\n" + 
2366
		"//        Line		comment    	    \n" + 
2367
		"foo2();\n" + 
2368
		"/*        Block		comment    	    */\n" + 
2369
		"foo3();\n" + 
2370
		"{\n" + 
2371
		"	/*        indented Block		comment    	    */\n" + 
2372
		"	System.out.println();\n" + 
2373
		"}",
2374
		CodeFormatter.K_STATEMENTS
2375
	);
2376
}
2377
public void testBug236406_ST2() {
2378
	String source = 
2379
		"/**        Javadoc		comment    	    */foo1();\n" +
2380
		"//        Line		comment    	    \n" +
2381
		"foo2();\n" +
2382
		"/*        Block		comment    	    */\n" +
2383
		"foo3(); {\n" +
2384
		"/*        indented Block		comment    	    */\n" +
2385
		"System.out.println();}\n";
2386
	formatSource(source,
2387
		"/** Javadoc comment */\n" + 
2388
		"foo1();\n" + 
2389
		"// Line comment\n" + 
2390
		"foo2();\n" + 
2391
		"/* Block comment */\n" + 
2392
		"foo3();\n" + 
2393
		"{\n" + 
2394
		"	/* indented Block comment */\n" + 
2395
		"	System.out.println();\n" + 
2396
		"}",
2397
		CodeFormatter.K_STATEMENTS | CodeFormatter.F_INCLUDE_COMMENTS
2398
	);
2399
}
2400
2401
/**
2268
 * @bug 237051: [formatter] Formatter insert blank lines after javadoc if javadoc contains Commons Attributes @@ annotations
2402
 * @bug 237051: [formatter] Formatter insert blank lines after javadoc if javadoc contains Commons Attributes @@ annotations
2269
 * @test Ensure that Commons Attributes @@ annotations do not screw up the comment formatter
2403
 * @test Ensure that Commons Attributes @@ annotations do not screw up the comment formatter
2270
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=237051"
2404
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=237051"
(-)src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java (+4 lines)
Lines 240-245 Link Here
240
	void formatSource(String source, String formattedOutput) {
240
	void formatSource(String source, String formattedOutput) {
241
		formatSource(source, formattedOutput, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, true /*repeat formatting twice*/);
241
		formatSource(source, formattedOutput, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, true /*repeat formatting twice*/);
242
	}
242
	}
243
244
	void formatSource(String source, String formattedOutput, int kind) {
245
		formatSource(source, formattedOutput, kind, 0, true /*repeat formatting twice*/);
246
	}
243
	
247
	
244
	void formatSource(String source, String formattedOutput, boolean repeat) {
248
	void formatSource(String source, String formattedOutput, boolean repeat) {
245
		formatSource(source, formattedOutput, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, repeat);
249
		formatSource(source, formattedOutput, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, repeat);
(-)src/org/eclipse/jdt/core/tests/formatter/comment/CommentTestCase.java (+1 lines)
Lines 24-29 Link Here
24
import org.eclipse.jdt.core.tests.model.SuiteOfTestCases;
24
import org.eclipse.jdt.core.tests.model.SuiteOfTestCases;
25
25
26
public abstract class CommentTestCase extends SuiteOfTestCases {
26
public abstract class CommentTestCase extends SuiteOfTestCases {
27
27
	public static Test buildTestSuite(Class evaluationTestClass) {
28
	public static Test buildTestSuite(Class evaluationTestClass) {
28
		return buildTestSuite(evaluationTestClass, null); //$NON-NLS-1$
29
		return buildTestSuite(evaluationTestClass, null); //$NON-NLS-1$
29
	}
30
	}
(-)src/org/eclipse/jdt/core/tests/formatter/comment/JavaDocTestCase.java (-57 / +31 lines)
Lines 19-41 Link Here
19
import org.eclipse.jdt.core.formatter.CodeFormatter;
19
import org.eclipse.jdt.core.formatter.CodeFormatter;
20
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
20
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
21
21
22
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
23
import org.eclipse.jdt.internal.formatter.comment.JavaDocLine;
24
import org.eclipse.jdt.internal.formatter.comment.MultiCommentLine;
25
import org.eclipse.text.edits.TextEdit;
22
import org.eclipse.text.edits.TextEdit;
26
23
27
public class JavaDocTestCase extends CommentTestCase {
24
public class JavaDocTestCase extends MultiLineTestCase {
28
25
29
	static {
26
	static {
30
//		TESTS_NAMES = new String[] { "test109636_2" } ;
27
//		TESTS_NAMES = new String[] { "test109636_2" } ;
31
	}
28
	}
32
29
33
	protected static final String INFIX= MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX;
34
35
	protected static final String POSTFIX= MultiCommentLine.MULTI_COMMENT_END_PREFIX;
36
37
	protected static final String PREFIX= JavaDocLine.JAVADOC_START_PREFIX;
38
39
	public static Test suite() {
30
	public static Test suite() {
40
		return buildTestSuite(JavaDocTestCase.class);
31
		return buildTestSuite(JavaDocTestCase.class);
41
	}
32
	}
Lines 698-704 Link Here
698
689
699
		String expected = "/**" + DELIMITER +
690
		String expected = "/**" + DELIMITER +
700
				" * <pre>" + DELIMITER +
691
				" * <pre>" + DELIMITER +
701
				(DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT ? " * " +  DELIMITER : "") +
692
				" * " +  DELIMITER +
702
				" * </pre>" + DELIMITER +
693
				" * </pre>" + DELIMITER +
703
				" * " +  DELIMITER +
694
				" * " +  DELIMITER +
704
				" * " + DELIMITER +
695
				" * " + DELIMITER +
Lines 876-898 Link Here
876
				" * </code>" + DELIMITER +
867
				" * </code>" + DELIMITER +
877
				" */";
868
				" */";
878
869
879
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
880
			? input // do not change as <code> is an immutable tag
881
			:	"/**" + DELIMITER +
882
				" * <code>" + DELIMITER +
883
				" * <pre>" + DELIMITER +
884
				" * setLeadingComment(&quot;/* traditional comment &#42;/&quot;); // correct" + DELIMITER +
885
				" * setLeadingComment(&quot;missing comment delimiters&quot;); // wrong" + DELIMITER +
886
				" * setLeadingComment(&quot;/* unterminated traditional comment &quot;); // wrong" + DELIMITER +
887
				" * setLeadingComment(&quot;/* broken\\n traditional comment &#42;/&quot;); // correct" + DELIMITER +
888
				" * setLeadingComment(&quot;// end-of-line comment\\n&quot;); // correct" + DELIMITER +
889
				" * setLeadingComment(&quot;// end-of-line comment without line terminator&quot;); // correct" + DELIMITER +
890
				" * setLeadingComment(&quot;// broken\\n end-of-line comment\\n&quot;); // wrong" + DELIMITER +
891
				" * </pre>" + DELIMITER +
892
				" * </code>" + DELIMITER +
893
				" */";
894
		String result=testFormat(input, options);
870
		String result=testFormat(input, options);
895
		assertEquals(expected, result);
871
		assertEquals(input, result);
896
	}
872
	}
897
873
898
	public void test109636_2() {
874
	public void test109636_2() {
Lines 940-976 Link Here
940
	}
916
	}
941
917
942
	public void test109636_4() {
918
	public void test109636_4() {
943
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) {
919
		Map options = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
944
			Map options = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
945
920
946
			String input =
921
		String input =
947
					"/**" + DELIMITER +
922
				"/**" + DELIMITER +
948
					" * <pre>" + DELIMITER +
923
				" * <pre>" + DELIMITER +
949
					" * setLeadingComment(\"/&#42; traditional comment &#42;/\");  // correct" + DELIMITER +
924
				" * setLeadingComment(\"/&#42; traditional comment &#42;/\");  // correct" + DELIMITER +
950
					" * setLeadingComment(\"missing comment delimiters\");  // wrong" + DELIMITER +
925
				" * setLeadingComment(\"missing comment delimiters\");  // wrong" + DELIMITER +
951
					" * setLeadingComment(\"/&#42; unterminated traditional comment \");  // wrong" + DELIMITER +
926
				" * setLeadingComment(\"/&#42; unterminated traditional comment \");  // wrong" + DELIMITER +
952
					" * setLeadingComment(\"/&#42; broken\\n traditional comment &#42;/\");  // correct" + DELIMITER +
927
				" * setLeadingComment(\"/&#42; broken\\n traditional comment &#42;/\");  // correct" + DELIMITER +
953
					" * setLeadingComment(\"// end-of-line comment\\n\");  // correct" + DELIMITER +
928
				" * setLeadingComment(\"// end-of-line comment\\n\");  // correct" + DELIMITER +
954
					" * setLeadingComment(\"// end-of-line comment without line terminator\");  // correct" + DELIMITER +
929
				" * setLeadingComment(\"// end-of-line comment without line terminator\");  // correct" + DELIMITER +
955
					" * setLeadingComment(\"// broken\\n end-of-line comment\\n\");  // wrong" + DELIMITER +
930
				" * setLeadingComment(\"// broken\\n end-of-line comment\\n\");  // wrong" + DELIMITER +
956
					" * </pre>" + DELIMITER +
931
				" * </pre>" + DELIMITER +
957
					" */";
932
				" */";
958
933
959
			String expected =
934
		String expected =
960
					"/**" + DELIMITER +
935
				"/**" + DELIMITER +
961
					" * <pre>" + DELIMITER +
936
				" * <pre>" + DELIMITER +
962
					" * setLeadingComment(&quot;/* traditional comment &#42;/&quot;); // correct" + DELIMITER +
937
				" * setLeadingComment(&quot;/* traditional comment &#42;/&quot;); // correct" + DELIMITER +
963
					" * setLeadingComment(&quot;missing comment delimiters&quot;); // wrong" + DELIMITER +
938
				" * setLeadingComment(&quot;missing comment delimiters&quot;); // wrong" + DELIMITER +
964
					" * setLeadingComment(&quot;/* unterminated traditional comment &quot;); // wrong" + DELIMITER +
939
				" * setLeadingComment(&quot;/* unterminated traditional comment &quot;); // wrong" + DELIMITER +
965
					" * setLeadingComment(&quot;/* broken\\n traditional comment &#42;/&quot;); // correct" + DELIMITER +
940
				" * setLeadingComment(&quot;/* broken\\n traditional comment &#42;/&quot;); // correct" + DELIMITER +
966
					" * setLeadingComment(&quot;// end-of-line comment\\n&quot;); // correct" + DELIMITER +
941
				" * setLeadingComment(&quot;// end-of-line comment\\n&quot;); // correct" + DELIMITER +
967
					" * setLeadingComment(&quot;// end-of-line comment without line terminator&quot;); // correct" + DELIMITER +
942
				" * setLeadingComment(&quot;// end-of-line comment without line terminator&quot;); // correct" + DELIMITER +
968
					" * setLeadingComment(&quot;// broken\\n end-of-line comment\\n&quot;); // wrong" + DELIMITER +
943
				" * setLeadingComment(&quot;// broken\\n end-of-line comment\\n&quot;); // wrong" + DELIMITER +
969
					" * </pre>" + DELIMITER +
944
				" * </pre>" + DELIMITER +
970
					" */";
945
				" */";
971
			String result=testFormat(input, options);
946
		String result=testFormat(input, options);
972
			assertEquals(expected, result);
947
		assertEquals(expected, result);
973
		}
974
	}
948
	}
975
949
976
	/**
950
	/**
(-)src/org/eclipse/jdt/core/tests/formatter/comment/MultiLineTestCase.java (-14 / +6 lines)
Lines 17-34 Link Here
17
17
18
import junit.framework.Test;
18
import junit.framework.Test;
19
19
20
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
21
import org.eclipse.jdt.internal.formatter.comment.MultiCommentLine;
22
23
public class MultiLineTestCase extends CommentTestCase {
20
public class MultiLineTestCase extends CommentTestCase {
24
	static {
21
	static {
25
//		TESTS_NAMES = new String[] { "test170580" } ;
22
//		TESTS_NAMES = new String[] { "test170580" } ;
26
	}
23
	}
27
	protected static final String INFIX= MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX;
28
29
	protected static final String POSTFIX= MultiCommentLine.MULTI_COMMENT_END_PREFIX;
30
24
31
	protected static final String PREFIX= MultiCommentLine.MULTI_COMMENT_START_PREFIX;
25
	protected static final String INFIX= " * "; //$NON-NLS-1$
26
	protected static final String POSTFIX= " */"; //$NON-NLS-1$
27
	protected static final String PREFIX= "/* "; //$NON-NLS-1$
32
28
33
	public static Test suite() {
29
	public static Test suite() {
34
		return buildTestSuite(MultiLineTestCase.class);
30
		return buildTestSuite(MultiLineTestCase.class);
Lines 116-128 Link Here
116
				" * Member comment\n" +//$NON-NLS-1$
112
				" * Member comment\n" +//$NON-NLS-1$
117
				" */";//$NON-NLS-1$
113
				" */";//$NON-NLS-1$
118
		String result= testFormat(input, 0, input.length(), CodeFormatter.K_MULTI_LINE_COMMENT , 2);
114
		String result= testFormat(input, 0, input.length(), CodeFormatter.K_MULTI_LINE_COMMENT , 2);
119
		String expectedOutput = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
115
		String expectedOutput = "/**\n" +
120
			?	"/**\n" +
116
			" * Member comment\n" +
121
				" * Member comment\n" +
117
			" */";
122
				" */"
123
			:	"/***********************************************************************\n" +
124
				"	 * Member comment\n" +
125
				"	 */";
126
		assertEquals("Different output", expectedOutput, result);
118
		assertEquals("Different output", expectedOutput, result);
127
	}
119
	}
128
120
(-)src/org/eclipse/jdt/core/tests/formatter/comment/SingleLineTestCase.java (-62 / +26 lines)
Lines 16-26 Link Here
16
import org.eclipse.jdt.core.formatter.CodeFormatter;
16
import org.eclipse.jdt.core.formatter.CodeFormatter;
17
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
17
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
18
18
19
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
20
import org.eclipse.jdt.internal.formatter.comment.SingleCommentLine;
21
22
public class SingleLineTestCase extends CommentTestCase {
19
public class SingleLineTestCase extends CommentTestCase {
23
	protected static final String PREFIX= SingleCommentLine.SINGLE_COMMENT_PREFIX;
20
21
	protected static final String PREFIX= "// "; //$NON-NLS-1$
24
22
25
	static {
23
	static {
26
//		TESTS_NAMES = new String[] { "test109581" } ;
24
//		TESTS_NAMES = new String[] { "test109581" } ;
Lines 42-50 Link Here
42
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
40
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
43
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE);
41
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE);
44
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE);
42
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE);
45
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
43
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + "//"+ DELIMITER + PREFIX + "test";
46
			? PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + "//"+ DELIMITER + PREFIX + "test"
47
			: PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
48
		assertEquals(expected, testFormat("//test\ttest" + DELIMITER + "//" + DELIMITER + "//\t\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
44
		assertEquals(expected, testFormat("//test\ttest" + DELIMITER + "//" + DELIMITER + "//\t\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
49
	}
45
	}
50
46
Lines 52-60 Link Here
52
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
48
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
53
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE);
49
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE);
54
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE);
50
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE);
55
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
51
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + DELIMITER + PREFIX + "test";
56
			? PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + DELIMITER + PREFIX + "test"
57
			: PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
58
		assertEquals(expected, testFormat("//test\t\ttest" + DELIMITER + PREFIX + DELIMITER + "//\t\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
52
		assertEquals(expected, testFormat("//test\t\ttest" + DELIMITER + PREFIX + DELIMITER + "//\t\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
59
	}
53
	}
60
54
Lines 62-84 Link Here
62
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
56
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
63
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE);
57
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, DefaultCodeFormatterConstants.FALSE);
64
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE);
58
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, DefaultCodeFormatterConstants.FALSE);
65
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
59
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + "//"+ DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test";
66
			? PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + "//"+ DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test"
67
			: PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
68
		assertEquals(expected, testFormat("//test\ttest" + DELIMITER + "//" + DELIMITER + PREFIX + "test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
60
		assertEquals(expected, testFormat("//test\ttest" + DELIMITER + "//" + DELIMITER + PREFIX + "test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
69
	}
61
	}
70
62
71
	public void testCommentBegin1() {
63
	public void testCommentBegin1() {
72
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
64
		String expected = PREFIX + "test";
73
			? PREFIX + "test"
74
			: PREFIX + "test" + DELIMITER;
75
		assertEquals(expected, testFormat("//test")); //$NON-NLS-1$ //$NON-NLS-2$
65
		assertEquals(expected, testFormat("//test")); //$NON-NLS-1$ //$NON-NLS-2$
76
	}
66
	}
77
67
78
	public void testCommentBegin2() {
68
	public void testCommentBegin2() {
79
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
69
		String expected = PREFIX + "test";
80
			? PREFIX + "test"
81
			: PREFIX + "test" + DELIMITER;
82
		assertEquals(expected, testFormat(PREFIX + "test")); //$NON-NLS-1$ //$NON-NLS-2$
70
		assertEquals(expected, testFormat(PREFIX + "test")); //$NON-NLS-1$ //$NON-NLS-2$
83
	}
71
	}
84
72
Lines 87-100 Link Here
87
	}
75
	}
88
76
89
	public void testCommentDelimiter1() {
77
	public void testCommentDelimiter1() {
90
		String expected = PREFIX + "test" + DELIMITER;
78
		String expected = PREFIX + "test" + DELIMITER + DELIMITER;
91
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) expected += DELIMITER;
92
		assertEquals(expected, testFormat("//\t\ttest " + DELIMITER + DELIMITER)); //$NON-NLS-1$ //$NON-NLS-2$
79
		assertEquals(expected, testFormat("//\t\ttest " + DELIMITER + DELIMITER)); //$NON-NLS-1$ //$NON-NLS-2$
93
	}
80
	}
94
81
95
	public void testCommentDelimiter2() {
82
	public void testCommentDelimiter2() {
96
		String expected = PREFIX + "test" + DELIMITER;
83
		String expected = PREFIX + "test" + DELIMITER + DELIMITER ;
97
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) expected += DELIMITER ;
98
		assertEquals(expected, testFormat(PREFIX + "test " + DELIMITER + DELIMITER + DELIMITER)); //$NON-NLS-1$ //$NON-NLS-2$
84
		assertEquals(expected, testFormat(PREFIX + "test " + DELIMITER + DELIMITER + DELIMITER)); //$NON-NLS-1$ //$NON-NLS-2$
99
	}
85
	}
100
86
Lines 123-169 Link Here
123
	}
109
	}
124
110
125
	public void testCommentSpace1() {
111
	public void testCommentSpace1() {
126
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
112
		String expected = PREFIX + "test test";
127
			? PREFIX + "test test"
128
			: PREFIX + "test test" + DELIMITER;
129
		assertEquals(expected, testFormat("//test\t \t test")); //$NON-NLS-1$ //$NON-NLS-2$
113
		assertEquals(expected, testFormat("//test\t \t test")); //$NON-NLS-1$ //$NON-NLS-2$
130
	}
114
	}
131
115
132
	public void testCommentSpace2() {
116
	public void testCommentSpace2() {
133
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
117
		String expected = PREFIX + "test test";
134
			? PREFIX + "test test"
135
			: PREFIX + "test test" + DELIMITER;
136
		assertEquals(expected, testFormat("//test test")); //$NON-NLS-1$ //$NON-NLS-2$
118
		assertEquals(expected, testFormat("//test test")); //$NON-NLS-1$ //$NON-NLS-2$
137
	}
119
	}
138
120
139
	public void testCommentSpace3() {
121
	public void testCommentSpace3() {
140
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
122
		String expected = PREFIX + "test test";
141
			? PREFIX + "test test"
142
			: PREFIX + "test test" + DELIMITER;
143
		assertEquals(expected, testFormat(PREFIX + "test \t    \t test")); //$NON-NLS-1$ //$NON-NLS-2$
123
		assertEquals(expected, testFormat(PREFIX + "test \t    \t test")); //$NON-NLS-1$ //$NON-NLS-2$
144
	}
124
	}
145
125
146
	public void testCommentWrapping1() {
126
	public void testCommentWrapping1() {
147
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
127
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
148
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
128
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test";
149
			? PREFIX + "test" + DELIMITER + PREFIX + "test"
150
			: PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
151
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
129
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
152
	}
130
	}
153
131
154
	public void testCommentWrapping2() {
132
	public void testCommentWrapping2() {
155
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "1"); //$NON-NLS-1$
133
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "1"); //$NON-NLS-1$
156
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
134
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test";
157
			? PREFIX + "test" + DELIMITER + PREFIX + "test"
158
			: PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
159
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
135
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
160
	}
136
	}
161
137
162
	public void testCommentWrapping3() {
138
	public void testCommentWrapping3() {
163
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "32"); //$NON-NLS-1$
139
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "32"); //$NON-NLS-1$
164
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
140
		String expected = PREFIX + "test test";
165
			? PREFIX + "test test"
166
			: PREFIX + "test test" + DELIMITER;
167
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
141
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
168
	}
142
	}
169
143
Lines 186-243 Link Here
186
	public void testHeaderComment1() {
160
	public void testHeaderComment1() {
187
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, DefaultCodeFormatterConstants.FALSE);
161
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, DefaultCodeFormatterConstants.FALSE);
188
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "12"); //$NON-NLS-1$
162
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "12"); //$NON-NLS-1$
189
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
163
		String expected = PREFIX + "test test" + DELIMITER + PREFIX + "test test" + DELIMITER + PREFIX + "test test";
190
			? PREFIX + "test test" + DELIMITER + PREFIX + "test test" + DELIMITER + PREFIX + "test test"
191
			: PREFIX + "test test" + DELIMITER + PREFIX + "test test" + DELIMITER + PREFIX + "test test" + DELIMITER;
192
		assertEquals(expected, testFormat("//test\t\t\t\ttest" + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
164
		assertEquals(expected, testFormat("//test\t\t\t\ttest" + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
193
	}
165
	}
194
166
195
	public void testHeaderComment2() {
167
	public void testHeaderComment2() {
196
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, DefaultCodeFormatterConstants.FALSE);
168
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, DefaultCodeFormatterConstants.FALSE);
197
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "24"); //$NON-NLS-1$
169
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "24"); //$NON-NLS-1$
198
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
170
		String expected = "// test" + DELIMITER + PREFIX + "test test test test" + DELIMITER;
199
			? "// test" + DELIMITER + PREFIX + "test test test test" + DELIMITER
200
			: PREFIX + "test test test test" + DELIMITER + PREFIX + "test" + DELIMITER;
201
		assertEquals(expected, testFormat("//test\t\t\t" + DELIMITER + PREFIX + "test test test test" + DELIMITER)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
171
		assertEquals(expected, testFormat("//test\t\t\t" + DELIMITER + PREFIX + "test test test test" + DELIMITER)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
202
	}
172
	}
203
173
204
	public void testIllegalLineLength1() {
174
	public void testIllegalLineLength1() {
205
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "1"); //$NON-NLS-1$
175
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "1"); //$NON-NLS-1$
206
		String expected =PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
176
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test";
207
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) expected = expected.substring(0, expected.length()-DELIMITER.length());
208
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
177
		assertEquals(expected, testFormat("//test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
209
	}
178
	}
210
179
211
	public void testIllegalLineLength2() {
180
	public void testIllegalLineLength2() {
212
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "-16"); //$NON-NLS-1$
181
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "-16"); //$NON-NLS-1$
213
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
182
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test";
214
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) expected = expected.substring(0, expected.length()-DELIMITER.length());
215
		assertEquals(expected, testFormat(PREFIX + "\t\t test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
183
		assertEquals(expected, testFormat(PREFIX + "\t\t test\ttest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
216
	}
184
	}
217
185
218
	public void testMultipleComments1() {
186
	public void testMultipleComments1() {
219
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
187
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "5"); //$NON-NLS-1$
220
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
188
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test";
221
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) expected = expected.substring(0, expected.length()-DELIMITER.length());
222
		assertEquals(expected, testFormat("//test test" + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
189
		assertEquals(expected, testFormat("//test test" + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
223
	}
190
	}
224
191
225
	public void testMultipleComments2() {
192
	public void testMultipleComments2() {
226
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "12"); //$NON-NLS-1$
193
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "12"); //$NON-NLS-1$
227
		String expected = DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT
194
		String expected = "// test test" + DELIMITER +
228
			? "// test test" + DELIMITER +
195
			"// test" + DELIMITER +
229
				"// test" + DELIMITER +
196
			"// " + DELIMITER +
230
				"// " + DELIMITER +
197
			"// test test" + DELIMITER +
231
				"// test test" + DELIMITER +
198
			"// test test";
232
				"// test test"
233
			: PREFIX + "test test" + DELIMITER + PREFIX + "test test" + DELIMITER + PREFIX + "test test" + DELIMITER + PREFIX + "test" + DELIMITER;
234
		assertEquals(expected, testFormat("//test test\ttest" + DELIMITER + PREFIX + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
199
		assertEquals(expected, testFormat("//test test\ttest" + DELIMITER + PREFIX + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
235
	}
200
	}
236
201
237
	public void testMultipleComments3() {
202
	public void testMultipleComments3() {
238
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "11"); //$NON-NLS-1$
203
		setUserOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, "11"); //$NON-NLS-1$
239
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER;
204
		String expected = PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test" + DELIMITER + PREFIX + "test";
240
		if (DefaultCodeFormatter.ENABLE_NEW_COMMENTS_FORMAT) expected = expected.substring(0, expected.length()-DELIMITER.length());
241
		assertEquals(expected, testFormat("//   test\t\t\ttest\ttest" + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
205
		assertEquals(expected, testFormat("//   test\t\t\ttest\ttest" + DELIMITER + PREFIX + "test test test test")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
242
	}
206
	}
243
207

Return to bug 236406