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

Collapse All | Expand All

(-)formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java (-2 / +25 lines)
Lines 31-36 Link Here
31
	final static int PARAM_TAG = 0x0020;
31
	final static int PARAM_TAG = 0x0020;
32
	final static int IN_PARAM_TAG = 0x0040;
32
	final static int IN_PARAM_TAG = 0x0040;
33
	final static int IN_DESCRIPTION = 0x0080;
33
	final static int IN_DESCRIPTION = 0x0080;
34
	final static int IMMUTABLE = 0x0100;
34
35
35
	// constants
36
	// constants
36
	final static int MAX_TAG_HIERARCHY = 10;
37
	final static int MAX_TAG_HIERARCHY = 10;
Lines 53-58 Link Here
53
		case TAG_THROWS_VALUE:
54
		case TAG_THROWS_VALUE:
54
		case TAG_EXCEPTION_VALUE:
55
		case TAG_EXCEPTION_VALUE:
55
			this.flags |= PARAM_TAG;
56
			this.flags |= PARAM_TAG;
57
			break;
58
		case TAG_CODE_VALUE:
59
		case TAG_LITERAL_VALUE:
60
			this.flags |= IMMUTABLE;
61
			break;
56
	}
62
	}
57
}
63
}
58
64
Lines 141-146 Link Here
141
		}
147
		}
142
	}
148
	}
143
	addNode(text);
149
	addNode(text);
150
	if (isImmutable()) {
151
		text.immutable = true;
152
	}
144
}
153
}
145
154
146
void clean() {
155
void clean() {
Lines 322-327 Link Here
322
	return (this.flags & PARAM_TAG) == PARAM_TAG;
331
	return (this.flags & PARAM_TAG) == PARAM_TAG;
323
}
332
}
324
333
334
/**
335
 * Returns whether the block is immutable or not.
336
 * <p>
337
 * Currently, only @code inline tag block are considered as immutable.
338
 *
339
 * @return <code>true</code> if the block is immutable,
340
 * 	<code>false</code> otherwise.
341
 */
342
public boolean isImmutable() {
343
	return (this.flags & IMMUTABLE) == IMMUTABLE;
344
}
345
325
void setHeaderLine(int javadocLineStart) {
346
void setHeaderLine(int javadocLineStart) {
326
	if (javadocLineStart == this.lineStart) {
347
	if (javadocLineStart == this.lineStart) {
327
		this.flags |= ON_HEADER_LINE;
348
		this.flags |= ON_HEADER_LINE;
Lines 332-340 Link Here
332
}
353
}
333
354
334
protected void toString(StringBuffer buffer) {
355
protected void toString(StringBuffer buffer) {
335
	if ((this.flags & INLINED) != 0) buffer.append('{');
356
	boolean inlined = (this.flags & INLINED) != 0;
357
	if (inlined) buffer.append("	{"); //$NON-NLS-1$
336
	buffer.append('@');
358
	buffer.append('@');
337
	buffer.append(this.tagValue);
359
	buffer.append(TAG_NAMES[this.tagValue]);
338
	super.toString(buffer);
360
	super.toString(buffer);
339
	if (this.reference == null) {
361
	if (this.reference == null) {
340
		buffer.append('\n');
362
		buffer.append('\n');
Lines 345-350 Link Here
345
	}
367
	}
346
	if (this.nodesPtr > -1) {
368
	if (this.nodesPtr > -1) {
347
		for (int i = 0; i <= this.nodesPtr; i++) {
369
		for (int i = 0; i <= this.nodesPtr; i++) {
370
			if (inlined) buffer.append('\t');
348
			this.nodes[i].toString(buffer);
371
			this.nodes[i].toString(buffer);
349
		}
372
		}
350
	}
373
	}
(-)formatter/org/eclipse/jdt/internal/formatter/FormatJavadocNode.java (+11 lines)
Lines 56-61 Link Here
56
	return false;
56
	return false;
57
}
57
}
58
58
59
/**
60
 * Returns whether the node is immutable or not. If <code>true</code>, then
61
 * the formatter will leave it contents unchanged.
62
 *
63
 * @return <code>true</code> if the node is immutable, <code>false</code>
64
 * 	otherwise.
65
 */
66
public boolean isImmutable() {
67
	return false;
68
}
69
59
public String toString() {
70
public String toString() {
60
	StringBuffer buffer = new StringBuffer();
71
	StringBuffer buffer = new StringBuffer();
61
	toString(buffer);
72
	toString(buffer);
(-)formatter/org/eclipse/jdt/internal/formatter/FormatJavadocText.java (+18 lines)
Lines 31-36 Link Here
31
	long[] separators;
31
	long[] separators;
32
	int separatorsPtr = -1;
32
	int separatorsPtr = -1;
33
	private int htmlTagIndex = -1;
33
	private int htmlTagIndex = -1;
34
	boolean immutable = false;
34
	FormatJavadocNode[] htmlNodes;
35
	FormatJavadocNode[] htmlNodes;
35
	int[] htmlIndexes;
36
	int[] htmlIndexes;
36
	int htmlNodesPtr = -1;
37
	int htmlNodesPtr = -1;
Lines 49-54 Link Here
49
 * child node.
50
 * child node.
50
 */
51
 */
51
void appendText(FormatJavadocText text) {
52
void appendText(FormatJavadocText text) {
53
	this.immutable = text.immutable;
52
	if (this.depth == text.depth) {
54
	if (this.depth == text.depth) {
53
		addSeparator(text);
55
		addSeparator(text);
54
		this.sourceEnd = text.sourceEnd;
56
		this.sourceEnd = text.sourceEnd;
Lines 167-172 Link Here
167
 *
169
 *
168
 * @return <code>true</code> if the node is an immutable tag,
170
 * @return <code>true</code> if the node is an immutable tag,
169
 *		<code>false</code> otherwise.
171
 *		<code>false</code> otherwise.
172
 *@deprecated Use {@link #isImmutable()} instead
170
 */
173
 */
171
public boolean isImmutableHtmlTag() {
174
public boolean isImmutableHtmlTag() {
172
	return this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID;
175
	return this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID;
Lines 174-179 Link Here
174
}
177
}
175
178
176
/**
179
/**
180
 * Returns whether the text is immutable or not.
181
 * <p>
182
 * A text in considered as immutable when it  belongs to an immutable block
183
 * or when it's an immutable html tag.
184
 * </p>
185
 *
186
 * @return <code>true</code> if the node is an immutable tag,
187
 *		<code>false</code> otherwise.
188
 */
189
public boolean isImmutable() {
190
	return this.immutable || (this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID);
191
192
}
193
194
/**
177
 * Returns whether the text at the given separator index position is after a
195
 * Returns whether the text at the given separator index position is after a
178
 * separator tag or not.
196
 * separator tag or not.
179
 *
197
 *
(-)formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java (-2 / +5 lines)
Lines 356-361 Link Here
356
		this.scanner.resetTo(this.index, this.javadocEnd);
356
		this.scanner.resetTo(this.index, this.javadocEnd);
357
		return true;
357
		return true;
358
	}
358
	}
359
	this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
359
	return false;
360
	return false;
360
}
361
}
361
362
Lines 382-387 Link Here
382
			}
383
			}
383
			this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
384
			this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
384
		}
385
		}
386
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
385
	}
387
	}
386
	return valid;
388
	return valid;
387
}
389
}
Lines 394-399 Link Here
394
	if (!valid) {
396
	if (!valid) {
395
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
397
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
396
		this.index = this.tagSourceEnd+1;
398
		this.index = this.tagSourceEnd+1;
399
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
397
	}
400
	}
398
	return valid;
401
	return valid;
399
}
402
}
Lines 506-512 Link Here
506
			if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName)) {
509
			if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName)) {
507
				this.tagValue = TAG_LINK_VALUE;
510
				this.tagValue = TAG_LINK_VALUE;
508
				if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) {
511
				if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) {
509
					valid= parseReference();
512
					valid = parseReference();
510
				} else {
513
				} else {
511
					// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
514
					// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
512
					// Cannot have @link outside inline comment
515
					// Cannot have @link outside inline comment
Lines 605-611 Link Here
605
	} else if (this.invalidTagName) {
608
	} else if (this.invalidTagName) {
606
		this.textStart = previousPosition;
609
		this.textStart = previousPosition;
607
	} else if (this.astPtr == ptr) {
610
	} else if (this.astPtr == ptr) {
608
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
609
		createTag();
611
		createTag();
610
	}
612
	}
611
	return true;
613
	return true;
Lines 620-625 Link Here
620
		// If invalid, restart from the end tag position
622
		// If invalid, restart from the end tag position
621
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
623
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
622
		this.index = this.tagSourceEnd+1;
624
		this.index = this.tagSourceEnd+1;
625
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
623
	}
626
	}
624
	return valid;
627
	return valid;
625
}
628
}
(-)formatter/org/eclipse/jdt/internal/formatter/Scribe.java (-38 / +44 lines)
Lines 2866-2872 Link Here
2866
							if (newLines > 0)  newLines = 1;
2866
							if (newLines > 0)  newLines = 1;
2867
						}
2867
						}
2868
					}
2868
					}
2869
					if (newLines == 0) {
2869
					if (newLines == 0 && (!node.isImmutable() || block.reference != null)) {
2870
						newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
2870
						newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
2871
					}
2871
					}
2872
					printJavadocGapLines(previousEnd+1, nodeStart-1, newLines, clearBlankLines, false, null);
2872
					printJavadocGapLines(previousEnd+1, nodeStart-1, newLines, clearBlankLines, false, null);
Lines 2898-2915 Link Here
2898
			// Print node
2898
			// Print node
2899
			if (node.isText()) {
2899
			if (node.isText()) {
2900
				FormatJavadocText text = (FormatJavadocText) node;
2900
				FormatJavadocText text = (FormatJavadocText) node;
2901
				if (text.isHtmlTag()) {
2901
				if (text.isImmutable()) {
2902
					if (text.isImmutableHtmlTag()) {
2902
					// Indent if new line was added
2903
						// Indent if new line was added
2903
					if (newLines > 0 && this.commentIndentation != null) {
2904
						if (newLines > 0 && this.commentIndentation != null) {
2904
				    	addInsertEdit(node.sourceStart, this.commentIndentation);
2905
					    	addInsertEdit(node.sourceStart, this.commentIndentation);
2905
				    	this.column += this.commentIndentation.length();
2906
					    	this.column += this.commentIndentation.length();
2907
						}
2908
						printJavadocHtmlImmutableTag(text, block, newLines > 0);
2909
						this.column += getTextLength(block, text);
2910
					} else {
2911
						printJavadocHtmlTag(text, block, newLines>0);
2912
					}
2906
					}
2907
					printJavadocImmutableText(text, block, newLines > 0);
2908
					this.column += getTextLength(block, text);
2909
				} else if (text.isHtmlTag()) {
2910
					printJavadocHtmlTag(text, block, newLines>0);
2913
				} else {
2911
				} else {
2914
					printJavadocText(text, block, newLines>0);
2912
					printJavadocText(text, block, newLines>0);
2915
				}
2913
				}
Lines 2934-2948 Link Here
2934
 	    try {
2932
 	    try {
2935
			this.scanner.resetTo(nodeStart , node.sourceEnd);
2933
			this.scanner.resetTo(nodeStart , node.sourceEnd);
2936
	    	int length = 0;
2934
	    	int length = 0;
2937
	    	int newLines = 0;
2938
	    	boolean newLine = false;
2935
	    	boolean newLine = false;
2939
			boolean headerLine = block.isHeaderLine() && this.lastNumberOfNewLines == 0;
2936
			boolean headerLine = block.isHeaderLine() && this.lastNumberOfNewLines == 0;
2940
			int firstColumn = 1 + this.indentationLevel + BLOCK_LINE_PREFIX_LENGTH;
2937
			int firstColumn = 1 + this.indentationLevel + BLOCK_LINE_PREFIX_LENGTH;
2941
			if (this.commentIndentation != null) firstColumn += this.commentIndentation.length();
2938
			if (this.commentIndentation != null) firstColumn += this.commentIndentation.length();
2942
			if (headerLine) maxColumn++;
2939
			if (headerLine) maxColumn++;
2943
	    	if (node.isText()) {
2940
			FormatJavadocText text = null;
2944
	    		FormatJavadocText text = (FormatJavadocText)node;
2941
			boolean isImmutableNode = node.isImmutable();
2945
    			if (text.isImmutableHtmlTag()) {
2942
			boolean nodeIsText = node.isText();
2943
			if (nodeIsText) {
2944
	    		text = (FormatJavadocText)node;
2945
			} else {
2946
				FormatJavadocBlock inlinedBlock = (FormatJavadocBlock)node;
2947
				if (isImmutableNode) {
2948
					text = (FormatJavadocText) inlinedBlock.getLastNode();
2949
		    		length += inlinedBlock.tagEnd - inlinedBlock.sourceStart + 1;  // tag length
2950
					this.scanner.resetTo(text.sourceStart , node.sourceEnd);
2951
				}
2952
			}
2953
	    	if (text != null) {
2954
    			if (isImmutableNode) {
2946
			    	if (nodeStart > (previousEnd+1)) {
2955
			    	if (nodeStart > (previousEnd+1)) {
2947
			    		length++; // include space between nodes
2956
			    		length++; // include space between nodes
2948
			    	}
2957
			    	}
Lines 2952-2959 Link Here
2952
		    				int token = this.scanner.getNextToken();
2961
		    				int token = this.scanner.getNextToken();
2953
		    				switch (token) {
2962
		    				switch (token) {
2954
		    					case TerminalTokens.TokenNameWHITESPACE:
2963
		    					case TerminalTokens.TokenNameWHITESPACE:
2955
		    						if (CharOperation.indexOf('\n', this.scanner.source, this.scanner.startPosition, this.scanner.currentPosition) >= 0) {
2964
		    						if (nodeIsText) {
2956
		    							return newLines;
2965
			    						if (CharOperation.indexOf('\n', this.scanner.source, this.scanner.startPosition, this.scanner.currentPosition) >= 0) {
2966
			    							return 0;
2967
			    						}
2957
		    						}
2968
		    						}
2958
		    						length = 1;
2969
		    						length = 1;
2959
		    						break;
2970
		    						break;
Lines 2975-2989 Link Here
2975
	    				}
2986
	    				}
2976
	    				lastColumn += length;
2987
	    				lastColumn += length;
2977
	    				if (lastColumn > maxColumn) {
2988
	    				if (lastColumn > maxColumn) {
2978
							newLines++;
2989
	    					return 1;
2979
				    		if (headerLine) {
2980
								maxColumn--;
2981
								headerLine = false;
2982
			    			}
2983
							lastColumn = firstColumn;
2984
						}
2990
						}
2985
	    			}
2991
	    			}
2986
	    			return newLines;
2992
	    			return 0;
2987
    			}
2993
    			}
2988
    			if (text.isHtmlTag()) {
2994
    			if (text.isHtmlTag()) {
2989
    				if (text.getHtmlTagID() == JAVADOC_SINGLE_BREAK_TAG_ID) {
2995
    				if (text.getHtmlTagID() == JAVADOC_SINGLE_BREAK_TAG_ID) {
Lines 3146-3152 Link Here
3146
	private int getTextLength(FormatJavadocBlock block, FormatJavadocText text) {
3152
	private int getTextLength(FormatJavadocBlock block, FormatJavadocText text) {
3147
3153
3148
		// Special case for immutable tags
3154
		// Special case for immutable tags
3149
		if (text.isImmutableHtmlTag()) {
3155
		if (text.isImmutable()) {
3150
			this.scanner.resetTo(text.sourceStart , text.sourceEnd);
3156
			this.scanner.resetTo(text.sourceStart , text.sourceEnd);
3151
			int textLength = 0;
3157
			int textLength = 0;
3152
			while (!this.scanner.atEnd()) {
3158
			while (!this.scanner.atEnd()) {
Lines 3468-3490 Link Here
3468
		}
3474
		}
3469
	}
3475
	}
3470
3476
3471
	private void printJavadocHtmlImmutableTag(FormatJavadocText text, FormatJavadocBlock block, boolean textOnNewLine) {
3477
	private void printJavadocImmutableText(FormatJavadocText text, FormatJavadocBlock block, boolean textOnNewLine) {
3472
3478
3473
		try {
3479
		try {
3474
			// Iterate on text line separators
3480
			// Iterate on text line separators
3475
			int lineNumber = text.lineStart;
3481
			int lineNumber = text.lineStart;
3476
			this.scanner.tokenizeWhiteSpace = false;
3482
			this.scanner.tokenizeWhiteSpace = false;
3477
			StringBuffer buffer = null;
3483
			StringBuffer buffer = null;
3478
			for (int idx=1, max=text.separatorsPtr; idx<max ; idx++) {
3484
			for (int idx=0, max=text.separatorsPtr; idx<=max ; idx++) {
3479
				int start = (int) text.separators[idx];
3485
				int start = (int) text.separators[idx];
3480
				int lineStart = Util.getLineNumber(start, this.lineEnds, lineNumber, this.maxLines);
3486
				int lineStart = Util.getLineNumber(start, this.lineEnds, lineNumber-1, this.maxLines);
3481
				if (buffer == null) {
3482
					buffer = new StringBuffer();
3483
					this.column = 1;
3484
					printIndentationIfNecessary(buffer);
3485
					buffer.append(BLOCK_LINE_PREFIX);
3486
					this.column += BLOCK_LINE_PREFIX_LENGTH;
3487
				}
3488
				while (lineNumber < lineStart) {
3487
				while (lineNumber < lineStart) {
3489
					int end = this.lineEnds[lineNumber-1];
3488
					int end = this.lineEnds[lineNumber-1];
3490
					this.scanner.resetTo(end, start);
3489
					this.scanner.resetTo(end, start);
Lines 3499-3504 Link Here
3499
					if (this.scanner.currentCharacter == ' ') {
3498
					if (this.scanner.currentCharacter == ' ') {
3500
						this.scanner.getNextChar();
3499
						this.scanner.getNextChar();
3501
					}
3500
					}
3501
					if (buffer == null) {
3502
						buffer = new StringBuffer();
3503
						this.column = 1;
3504
						printIndentationIfNecessary(buffer);
3505
						buffer.append(BLOCK_LINE_PREFIX);
3506
						this.column += BLOCK_LINE_PREFIX_LENGTH;
3507
					}
3502
					addReplaceEdit(end+1, this.scanner.getCurrentTokenEndPosition(), buffer.toString());
3508
					addReplaceEdit(end+1, this.scanner.getCurrentTokenEndPosition(), buffer.toString());
3503
					lineNumber++;
3509
					lineNumber++;
3504
				}
3510
				}
Lines 3562-3568 Link Here
3562
				if (textStart < previousEnd) {
3568
				if (textStart < previousEnd) {
3563
					addReplaceEdit(textStart, previousEnd, buffer.toString());
3569
					addReplaceEdit(textStart, previousEnd, buffer.toString());
3564
				}
3570
				}
3565
				boolean immutable = htmlTag == null ? false : htmlTag.isImmutableHtmlTag();
3571
				boolean immutable = node.isImmutable();
3566
				if (newLines == 0) {
3572
				if (newLines == 0) {
3567
					newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
3573
					newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
3568
				}
3574
				}
Lines 3579-3585 Link Here
3579
					    	addInsertEdit(node.sourceStart, this.commentIndentation);
3585
					    	addInsertEdit(node.sourceStart, this.commentIndentation);
3580
					    	this.column += this.commentIndentation.length();
3586
					    	this.column += this.commentIndentation.length();
3581
						}
3587
						}
3582
						printJavadocHtmlImmutableTag(htmlTag, block, textOnNewLine);
3588
						printJavadocImmutableText(htmlTag, block, textOnNewLine);
3583
						this.column += getTextLength(block, htmlTag);
3589
						this.column += getTextLength(block, htmlTag);
3584
						linesAfter = 0;
3590
						linesAfter = 0;
3585
					} else {
3591
					} else {
(-)src/org/eclipse/jdt/core/tests/formatter/FormatterCommentsBugsTest.java (-2 / +569 lines)
Lines 4071-4078 Link Here
4071
		"\n" + 
4071
		"\n" + 
4072
		"	/**\n" + 
4072
		"	/**\n" + 
4073
		"	 * Returns the change directly associated with this change element or <code\n" + 
4073
		"	 * Returns the change directly associated with this change element or <code\n" + 
4074
		"	 * null</code>\n" + 
4074
		"	 * null</code> if the element isn\'t associated with a change.\n" + 
4075
		"	 * if the element isn\'t associated with a change.\n" + 
4076
		"	 * \n" + 
4075
		"	 * \n" + 
4077
		"	 * @return the change or <code>null</code>\n" + 
4076
		"	 * @return the change or <code>null</code>\n" + 
4078
		"	 */\n" + 
4077
		"	 */\n" + 
Lines 4398-4403 Link Here
4398
}
4397
}
4399
4398
4400
/**
4399
/**
4400
 * @bug 260381: [formatter] Javadoc formatter breaks {@code ...} tags.
4401
 * @test Ensure that the @code tag is similar to <code> HTML tag
4402
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=260381"
4403
 */
4404
public void testBug260381() throws JavaModelException {
4405
	String source = 
4406
		"/**\n" + 
4407
		" * Comments that can be formated in several lines...\n" + 
4408
		" * \n" + 
4409
		" * @author Myself\n" + 
4410
		" * @version {@code $Revision: 1.2 $ $Date: 2009/01/07 12:27:50 $ $Author:myself $ $Source: /projects/cvs/module/project/src/com/foo/Main.java,v $}\n" + 
4411
		" */\n" + 
4412
		"public class X01 {\n" + 
4413
		"}\n";
4414
	formatSource(source);
4415
}
4416
public void testBug260381b() throws JavaModelException {
4417
	String source = 
4418
		"/**\n" + 
4419
		" * Comments that can be formated in several lines...\n" + 
4420
		" * \n" + 
4421
		" * @author Myself\n" + 
4422
		" * @version <code>$Revision: 1.2 $ $Date: 2009/01/07 12:27:50 $ $Author:myself $ $Source: /projects/cvs/module/project/src/com/foo/Main.java,v $</code>\n" + 
4423
		" */\n" + 
4424
		"public class X01b {\n" + 
4425
		"}\n";
4426
	formatSource(source);
4427
}
4428
public void testBug260381c() throws JavaModelException {
4429
	String source = 
4430
		"/**\n" + 
4431
		" * Comments that can be formated in several lines...\n" + 
4432
		" * \n" + 
4433
		" * @author Myself\n" + 
4434
		" * @version\n" + 
4435
		" *          <code>3.0 xxxxxxxxxxxxxx xwxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code>\n" + 
4436
		" */\n" + 
4437
		"public class X01c {\n" + 
4438
		"}\n";
4439
	formatSource(source,
4440
		"/**\n" + 
4441
		" * Comments that can be formated in several lines...\n" + 
4442
		" * \n" + 
4443
		" * @author Myself\n" + 
4444
		" * @version <code>3.0 xxxxxxxxxxxxxx xwxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code>\n" + 
4445
		" */\n" + 
4446
		"public class X01c {\n" + 
4447
		"}\n"
4448
	);
4449
}
4450
public void testBug260381d() throws JavaModelException {
4451
	String source = 
4452
		"/**\n" + 
4453
		" * Comments that can be formated in several lines...\n" + 
4454
		" * \n" + 
4455
		" * @author Myself\n" + 
4456
		" *  @see Object <code>$Revision: 1.2 $ $Date: 2009/01/07 12:27:50 $ $Author:myself $ $Source: /projects/cvs/module/project/src/com/foo/Main.java,v $</code>\n" + 
4457
		" */\n" + 
4458
		"public class X02 {\n" + 
4459
		"}\n";
4460
	formatSource(source,
4461
		"/**\n" + 
4462
		" * Comments that can be formated in several lines...\n" + 
4463
		" * \n" + 
4464
		" * @author Myself\n" + 
4465
		" * @see Object\n" + 
4466
		" *      <code>$Revision: 1.2 $ $Date: 2009/01/07 12:27:50 $ $Author:myself $ $Source: /projects/cvs/module/project/src/com/foo/Main.java,v $</code>\n" + 
4467
		" */\n" + 
4468
		"public class X02 {\n" + 
4469
		"}\n"
4470
	);
4471
}
4472
public void testBug260381e() throws JavaModelException {
4473
	String source = 
4474
		"/**\n" + 
4475
		" * Comments that can be formated in several lines...\n" + 
4476
		" * \n" + 
4477
		" * {@code $Revision: 1.2 $ $Date: 2009/01/07 12:27:50 $ $Author:myself $\n" + 
4478
		" * $Source: /projects/cvs/module/project/src/com/foo/Main.java,v $}\n" + 
4479
		" */\n" + 
4480
		"public class X03 {\n" + 
4481
		"}\n";
4482
	formatSource(source);
4483
}
4484
public void testBug260381f() throws JavaModelException {
4485
	String source = 
4486
		"/**\n" + 
4487
		" * Literal inline tag should also be untouched by the formatter\n" + 
4488
		" * \n" + 
4489
		" * @version {@literal $Revision: 1.2 $ $Date: 2009/01/07 12:27:50 $ $Author:myself $ $Source: /projects/cvs/module/project/src/com/foo/Main.java,v $}\n" + 
4490
		" */\n" + 
4491
		"public class X04 {\n" + 
4492
		"\n" + 
4493
		"}\n";
4494
	formatSource(source);
4495
}
4496
public void testBug260381_wksp2_01() throws JavaModelException {
4497
	String source = 
4498
		"package wksp2;\n" + 
4499
		"public interface I01 {\n" + 
4500
		"	/**\n" + 
4501
		"	 * Returns the composition of two functions. For {@code f: A->B} and\n" + 
4502
		"	 * {@code g: B->C}, composition is defined as the function h such that\n" + 
4503
		"	 * {@code h(a) == g(f(a))} for each {@code a}.\n" + 
4504
		"	 *\n" + 
4505
		"	 * @see <a href=\"//en.wikipedia.org/wiki/Function_composition\">\n" + 
4506
		"	 * function composition</a>\n" + 
4507
		"	 *\n" + 
4508
		"	 * @param g the second function to apply\n" + 
4509
		"	 * @param f the first function to apply\n" + 
4510
		"	 * @return the composition of {@code f} and {@code g}\n" + 
4511
		"	 */\n" + 
4512
		"	void foo();\n" + 
4513
		"}\n";
4514
	formatSource(source,
4515
		"package wksp2;\n" + 
4516
		"\n" + 
4517
		"public interface I01 {\n" + 
4518
		"	/**\n" + 
4519
		"	 * Returns the composition of two functions. For {@code f: A->B} and\n" + 
4520
		"	 * {@code g: B->C}, composition is defined as the function h such that\n" + 
4521
		"	 * {@code h(a) == g(f(a))} for each {@code a}.\n" + 
4522
		"	 * \n" + 
4523
		"	 * @see <a href=\"//en.wikipedia.org/wiki/Function_composition\"> function\n" + 
4524
		"	 *      composition</a>\n" + 
4525
		"	 * \n" + 
4526
		"	 * @param g\n" + 
4527
		"	 *            the second function to apply\n" + 
4528
		"	 * @param f\n" + 
4529
		"	 *            the first function to apply\n" + 
4530
		"	 * @return the composition of {@code f} and {@code g}\n" + 
4531
		"	 */\n" + 
4532
		"	void foo();\n" + 
4533
		"}\n"
4534
	);
4535
}
4536
public void testBug260381_wksp2_01b() throws JavaModelException {
4537
	String source = 
4538
		"package wksp2;\n" + 
4539
		"public interface I01b {\n" + 
4540
		"  /**\n" + 
4541
		"   * Returns the composition of two functions. For <code> f: A->B</code> and\n" + 
4542
		"   * <code> g: B->C</code>, composition is defined as the function h such that\n" + 
4543
		"   * <code> h(a) == g(f(a))</code> for each <code> a</code>.\n" + 
4544
		"   *\n" + 
4545
		"   * @see <a href=\"//en.wikipedia.org/wiki/Function_composition\">\n" + 
4546
		"   * function composition</a>\n" + 
4547
		"   *\n" + 
4548
		"   * @param g the second function to apply\n" + 
4549
		"   * @param f the first function to apply\n" + 
4550
		"   * @return the composition of <code> f</code> and <code> g</code>\n" + 
4551
		"   */\n" + 
4552
		"  void foo();\n" + 
4553
		"}\n";
4554
	formatSource(source,
4555
		"package wksp2;\n" + 
4556
		"\n" + 
4557
		"public interface I01b {\n" + 
4558
		"	/**\n" + 
4559
		"	 * Returns the composition of two functions. For <code> f: A->B</code> and\n" + 
4560
		"	 * <code> g: B->C</code>, composition is defined as the function h such that\n" + 
4561
		"	 * <code> h(a) == g(f(a))</code> for each <code> a</code>.\n" + 
4562
		"	 * \n" + 
4563
		"	 * @see <a href=\"//en.wikipedia.org/wiki/Function_composition\"> function\n" + 
4564
		"	 *      composition</a>\n" + 
4565
		"	 * \n" + 
4566
		"	 * @param g\n" + 
4567
		"	 *            the second function to apply\n" + 
4568
		"	 * @param f\n" + 
4569
		"	 *            the first function to apply\n" + 
4570
		"	 * @return the composition of <code> f</code> and <code> g</code>\n" + 
4571
		"	 */\n" + 
4572
		"	void foo();\n" + 
4573
		"}\n"
4574
	);
4575
}
4576
public void testBug260381_wksp2_01c() throws JavaModelException {
4577
	String source = 
4578
		"package wksp2;\n" + 
4579
		"public interface I01c {\n" + 
4580
		"  /**\n" + 
4581
		"   * Returns the composition of two functions. For <code> f: A->B</code> and\n" + 
4582
		"   * <code>\n" + 
4583
		"   * g: B->C\n" + 
4584
		"   * </code>,\n" + 
4585
		"   * composition is defined as the function h such that\n" + 
4586
		"   * <code>\n" + 
4587
		"   *  h(a) == g(f(a))\n" + 
4588
		"   *  </code>\n" + 
4589
		"   *  for each\n" + 
4590
		"   *  <code>\n" + 
4591
		"   *  a\n" + 
4592
		"   *  </code>.\n" + 
4593
		"   *\n" + 
4594
		"   * @see <a href=\"//en.wikipedia.org/wiki/Function_composition\">\n" + 
4595
		"   * function composition</a>\n" + 
4596
		"   *\n" + 
4597
		"   * @param g the second function to apply\n" + 
4598
		"   * @param f the first function to apply\n" + 
4599
		"   * @return the composition of <code> f</code> and <code> g</code>\n" + 
4600
		"   */\n" + 
4601
		"  void foo();\n" + 
4602
		"}\n";
4603
	formatSource(source,
4604
		"package wksp2;\n" + 
4605
		"\n" + 
4606
		"public interface I01c {\n" + 
4607
		"	/**\n" + 
4608
		"	 * Returns the composition of two functions. For <code> f: A->B</code> and\n" + 
4609
		"	 * <code>\n" + 
4610
		"	 * g: B->C\n" + 
4611
		"	 * </code>, composition is defined as the function h such that <code>\n" + 
4612
		"	 *  h(a) == g(f(a))\n" + 
4613
		"	 *  </code> for each <code>\n" + 
4614
		"	 *  a\n" + 
4615
		"	 *  </code>.\n" + 
4616
		"	 * \n" + 
4617
		"	 * @see <a href=\"//en.wikipedia.org/wiki/Function_composition\"> function\n" + 
4618
		"	 *      composition</a>\n" + 
4619
		"	 * \n" + 
4620
		"	 * @param g\n" + 
4621
		"	 *            the second function to apply\n" + 
4622
		"	 * @param f\n" + 
4623
		"	 *            the first function to apply\n" + 
4624
		"	 * @return the composition of <code> f</code> and <code> g</code>\n" + 
4625
		"	 */\n" + 
4626
		"	void foo();\n" + 
4627
		"}\n"
4628
	);
4629
}
4630
public void testBug260381_wksp2_02() throws JavaModelException {
4631
	String source = 
4632
		"package wksp2;\n" + 
4633
		"\n" + 
4634
		"public interface I02 {\n" + 
4635
		"\n" + 
4636
		"  /**\n" + 
4637
		"   * Implementations of {@code computeNext} <b>must</b> invoke this method when\n" + 
4638
		"   * there are no elements left in the iteration.\n" + 
4639
		"   *\n" + 
4640
		"   * @return {@code null}; a convenience so your {@link #computeNext}\n" + 
4641
		"   *     implementation can use the simple statement {@code return endOfData();}\n" + 
4642
		"   */\n" + 
4643
		"  void foo();\n" + 
4644
		"}\n";
4645
	formatSource(source,
4646
		"package wksp2;\n" + 
4647
		"\n" + 
4648
		"public interface I02 {\n" + 
4649
		"\n" + 
4650
		"	/**\n" + 
4651
		"	 * Implementations of {@code computeNext} <b>must</b> invoke this method\n" + 
4652
		"	 * when there are no elements left in the iteration.\n" + 
4653
		"	 * \n" + 
4654
		"	 * @return {@code null}; a convenience so your {@link #computeNext}\n" + 
4655
		"	 *         implementation can use the simple statement\n" + 
4656
		"	 *         {@code return endOfData();}\n" + 
4657
		"	 */\n" + 
4658
		"	void foo();\n" + 
4659
		"}\n"
4660
	);
4661
}
4662
public void testBug260381_wksp2_03() throws JavaModelException {
4663
	String source = 
4664
		"package wksp2;\n" + 
4665
		"\n" + 
4666
		"public interface I03 {\n" + 
4667
		"  /**\n" + 
4668
		"   * A builder for creating immutable bimap instances, especially {@code public\n" + 
4669
		"   * static final} bimaps (\"constant bimaps\"). Example: <pre>   {@code\n" + 
4670
		"   *\n" + 
4671
		"   *   static final ImmutableBiMap<String, Integer> WORD_TO_INT =\n" + 
4672
		"   *       new ImmutableBiMap.Builder<String, Integer>()\n" + 
4673
		"   *           .put(\"one\", 1)\n" + 
4674
		"   *           .put(\"two\", 2)\n" + 
4675
		"   *           .put(\"three\", 3)\n" + 
4676
		"   *           .build();}</pre>\n" + 
4677
		"   *\n" + 
4678
		"   * For <i>small</i> immutable bimaps, the {@code ImmutableBiMap.of()} methods\n" + 
4679
		"   * are even more convenient.\n" + 
4680
		"   *\n" + 
4681
		"   * <p>Builder instances can be reused - it is safe to call {@link #build}\n" + 
4682
		"   * multiple times to build multiple bimaps in series. Each bimap is a superset\n" + 
4683
		"   * of the bimaps created before it.\n" + 
4684
		"   */\n" + 
4685
		"  void foo();\n" + 
4686
		"}\n";
4687
	formatSource(source,
4688
		"package wksp2;\n" + 
4689
		"\n" + 
4690
		"public interface I03 {\n" + 
4691
		"	/**\n" + 
4692
		"	 * A builder for creating immutable bimap instances, especially\n" + 
4693
		"	 * {@code public static final} bimaps (\"constant bimaps\"). Example:\n" + 
4694
		"	 * \n" + 
4695
		"	 * <pre>\n" + 
4696
		"	 * {\n" + 
4697
		"	 * 	&#064;code\n" + 
4698
		"	 * 	static final ImmutableBiMap&lt;String, Integer&gt; WORD_TO_INT = new ImmutableBiMap.Builder&lt;String, Integer&gt;()\n" + 
4699
		"	 * 			.put(&quot;one&quot;, 1).put(&quot;two&quot;, 2).put(&quot;three&quot;, 3).build();\n" + 
4700
		"	 * }\n" + 
4701
		"	 * </pre>\n" + 
4702
		"	 * \n" + 
4703
		"	 * For <i>small</i> immutable bimaps, the {@code ImmutableBiMap.of()}\n" + 
4704
		"	 * methods are even more convenient.\n" + 
4705
		"	 * \n" + 
4706
		"	 * <p>\n" + 
4707
		"	 * Builder instances can be reused - it is safe to call {@link #build}\n" + 
4708
		"	 * multiple times to build multiple bimaps in series. Each bimap is a\n" + 
4709
		"	 * superset of the bimaps created before it.\n" + 
4710
		"	 */\n" + 
4711
		"	void foo();\n" + 
4712
		"}\n"
4713
	);
4714
}
4715
public void testBug260381_wksp2_04() throws JavaModelException {
4716
	String source = 
4717
		"package wksp2;\n" + 
4718
		"\n" + 
4719
		"public interface I04 {\n" + 
4720
		"\n" + 
4721
		"  /**\n" + 
4722
		"   * Returns an immutable multiset containing the given elements.\n" + 
4723
		"   * \n" + 
4724
		"   * <p>The multiset is ordered by the first occurrence of each element. For\n" + 
4725
		"   * example, {@code ImmutableMultiset.copyOf(Arrays.asList(2, 3, 1, 3))} yields\n" + 
4726
		"   * a multiset with elements in the order {@code 2, 3, 3, 1}.\n" + 
4727
		"   *\n" + 
4728
		"   * <p>Note that if {@code c} is a {@code Collection<String>}, then {@code\n" + 
4729
		"   * ImmutableMultiset.copyOf(c)} returns an {@code ImmutableMultiset<String>}\n" + 
4730
		"   * containing each of the strings in {@code c}, while\n" + 
4731
		"   * {@code ImmutableMultiset.of(c)} returns an\n" + 
4732
		"   * {@code ImmutableMultiset<Collection<String>>} containing one element (the\n" + 
4733
		"   * given collection itself).\n" + 
4734
		"   *\n" + 
4735
		"   * <p><b>Note:</b> Despite what the method name suggests, if {@code elements}\n" + 
4736
		"   * is an {@code ImmutableMultiset}, no copy will actually be performed, and\n" + 
4737
		"   * the given multiset itself will be returned.\n" + 
4738
		"   *\n" + 
4739
		"   * @throws NullPointerException if any of {@code elements} is null\n" + 
4740
		"   */\n" + 
4741
		"  void foo();\n" + 
4742
		"}\n";
4743
	formatSource(source,
4744
		"package wksp2;\n" + 
4745
		"\n" + 
4746
		"public interface I04 {\n" + 
4747
		"\n" + 
4748
		"	/**\n" + 
4749
		"	 * Returns an immutable multiset containing the given elements.\n" + 
4750
		"	 * \n" + 
4751
		"	 * <p>\n" + 
4752
		"	 * The multiset is ordered by the first occurrence of each element. For\n" + 
4753
		"	 * example, {@code ImmutableMultiset.copyOf(Arrays.asList(2, 3, 1, 3))}\n" + 
4754
		"	 * yields a multiset with elements in the order {@code 2, 3, 3, 1}.\n" + 
4755
		"	 * \n" + 
4756
		"	 * <p>\n" + 
4757
		"	 * Note that if {@code c} is a {@code Collection<String>}, then\n" + 
4758
		"	 * {@code ImmutableMultiset.copyOf(c)} returns an\n" + 
4759
		"	 * {@code ImmutableMultiset<String>} containing each of the strings in\n" + 
4760
		"	 * {@code c}, while {@code ImmutableMultiset.of(c)} returns an\n" + 
4761
		"	 * {@code ImmutableMultiset<Collection<String>>} containing one element (the\n" + 
4762
		"	 * given collection itself).\n" + 
4763
		"	 * \n" + 
4764
		"	 * <p>\n" + 
4765
		"	 * <b>Note:</b> Despite what the method name suggests, if {@code elements}\n" + 
4766
		"	 * is an {@code ImmutableMultiset}, no copy will actually be performed, and\n" + 
4767
		"	 * the given multiset itself will be returned.\n" + 
4768
		"	 * \n" + 
4769
		"	 * @throws NullPointerException\n" + 
4770
		"	 *             if any of {@code elements} is null\n" + 
4771
		"	 */\n" + 
4772
		"	void foo();\n" + 
4773
		"}\n"
4774
	);
4775
}
4776
public void testBug260381_wksp2_05() throws JavaModelException {
4777
	String source = 
4778
		"package wksp2;\n" + 
4779
		"\n" + 
4780
		"public interface I05 {\n" + 
4781
		"\n" + 
4782
		"  /**\n" + 
4783
		"   * Indexes the specified values into a {@code Multimap} by applying a\n" + 
4784
		"   * specified function to each item in an {@code Iterable} of values. Each\n" + 
4785
		"   * value will be stored as a value in the specified multimap. The key used to\n" + 
4786
		"   * store that value in the multimap will be the result of calling the function\n" + 
4787
		"   * on that value. Depending on the multimap implementation, duplicate entries\n" + 
4788
		"   * (equal keys and equal values) may be collapsed.\n" + 
4789
		"   *\n" + 
4790
		"   * <p>For example,\n" + 
4791
		"   *\n" + 
4792
		"   * <pre class=\"code\">\n" + 
4793
		"   * List&lt;String> badGuys =\n" + 
4794
		"   *   Arrays.asList(\"Inky\", \"Blinky\", \"Pinky\", \"Pinky\", \"Clyde\");\n" + 
4795
		"   * Function&lt;String, Integer> stringLengthFunction = ...;\n" + 
4796
		"   * Multimap&lt;Integer, String> index = Multimaps.newHashMultimap();\n" + 
4797
		"   * Multimaps.index(badGuys, stringLengthFunction, index);\n" + 
4798
		"   * System.out.println(index); </pre>\n" + 
4799
		"   *\n" + 
4800
		"   * prints\n" + 
4801
		"   *\n" + 
4802
		"   * <pre class=\"code\">\n" + 
4803
		"   * {4=[Inky], 5=[Pinky, Clyde], 6=[Blinky]} </pre>\n" + 
4804
		"   *\n" + 
4805
		"   * The {@link HashMultimap} collapses the duplicate occurrence of\n" + 
4806
		"   * {@code (5, \"Pinky\")}.\n" + 
4807
		"   *\n" + 
4808
		"   * @param values the values to add to the multimap\n" + 
4809
		"   * @param keyFunction the function used to produce the key for each value\n" + 
4810
		"   * @param multimap the multimap to store the key value pairs\n" + 
4811
		"   */\n" + 
4812
		"  void foo();\n" + 
4813
		"}\n";
4814
	formatSource(source,
4815
		"package wksp2;\n" + 
4816
		"\n" + 
4817
		"public interface I05 {\n" + 
4818
		"\n" + 
4819
		"	/**\n" + 
4820
		"	 * Indexes the specified values into a {@code Multimap} by applying a\n" + 
4821
		"	 * specified function to each item in an {@code Iterable} of values. Each\n" + 
4822
		"	 * value will be stored as a value in the specified multimap. The key used\n" + 
4823
		"	 * to store that value in the multimap will be the result of calling the\n" + 
4824
		"	 * function on that value. Depending on the multimap implementation,\n" + 
4825
		"	 * duplicate entries (equal keys and equal values) may be collapsed.\n" + 
4826
		"	 * \n" + 
4827
		"	 * <p>\n" + 
4828
		"	 * For example,\n" + 
4829
		"	 * \n" + 
4830
		"	 * <pre class=\"code\">\n" + 
4831
		"	 * List&lt;String> badGuys =\n" + 
4832
		"	 *   Arrays.asList(\"Inky\", \"Blinky\", \"Pinky\", \"Pinky\", \"Clyde\");\n" + 
4833
		"	 * Function&lt;String, Integer> stringLengthFunction = ...;\n" + 
4834
		"	 * Multimap&lt;Integer, String> index = Multimaps.newHashMultimap();\n" + 
4835
		"	 * Multimaps.index(badGuys, stringLengthFunction, index);\n" + 
4836
		"	 * System.out.println(index);\n" + 
4837
		"	 * </pre>\n" + 
4838
		"	 * \n" + 
4839
		"	 * prints\n" + 
4840
		"	 * \n" + 
4841
		"	 * <pre class=\"code\">\n" + 
4842
		"	 * {4=[Inky], 5=[Pinky, Clyde], 6=[Blinky]}\n" + 
4843
		"	 * </pre>\n" + 
4844
		"	 * \n" + 
4845
		"	 * The {@link HashMultimap} collapses the duplicate occurrence of\n" + 
4846
		"	 * {@code (5, \"Pinky\")}.\n" + 
4847
		"	 * \n" + 
4848
		"	 * @param values\n" + 
4849
		"	 *            the values to add to the multimap\n" + 
4850
		"	 * @param keyFunction\n" + 
4851
		"	 *            the function used to produce the key for each value\n" + 
4852
		"	 * @param multimap\n" + 
4853
		"	 *            the multimap to store the key value pairs\n" + 
4854
		"	 */\n" + 
4855
		"	void foo();\n" + 
4856
		"}\n"
4857
	);
4858
}
4859
public void testBug260381_wksp2_06() throws JavaModelException {
4860
	String source = 
4861
		"package wksp2;\n" + 
4862
		"\n" + 
4863
		"public interface I06 {\n" + 
4864
		"\n" + 
4865
		"  /**\n" + 
4866
		"   * Adds a number of occurrences of an element to this multiset. Note that if\n" + 
4867
		"   * {@code occurrences == 1}, this method has the identical effect to {@link\n" + 
4868
		"   * #add(Object)}. This method is functionally equivalent (except in the case\n" + 
4869
		"   * of overflow) to the call {@code addAll(Collections.nCopies(element,\n" + 
4870
		"   * occurrences))}, which would presumably perform much more poorly.\n" + 
4871
		"   *\n" + 
4872
		"   * @param element the element to add occurrences of; may be {@code null} only\n" + 
4873
		"   *     if explicitly allowed by the implementation\n" + 
4874
		"   * @param occurrences the number of occurrences of this element to add. May\n" + 
4875
		"   *     be zero, in which case no change will be made.\n" + 
4876
		"   * @return the previous count of this element before the operation; possibly\n" + 
4877
		"   *     zero - TODO: make this the actual behavior!\n" + 
4878
		"   * @throws IllegalArgumentException if {@code occurrences} is negative, or if\n" + 
4879
		"   *     this operation would result in more than {@link Integer#MAX_VALUE}\n" + 
4880
		"   *     occurrences of the element \n" + 
4881
		"   * @throws NullPointerException if {@code element} is null and this\n" + 
4882
		"   *     implementation does not permit null elements. Note that if {@code\n" + 
4883
		"   *     occurrences} is zero, the implementation may opt to return normally.\n" + 
4884
		"   */\n" + 
4885
		"  boolean /*int*/ add(E element, int occurrences);\n" + 
4886
		"}\n";
4887
	formatSource(source,
4888
		"package wksp2;\n" + 
4889
		"\n" + 
4890
		"public interface I06 {\n" + 
4891
		"\n" + 
4892
		"	/**\n" + 
4893
		"	 * Adds a number of occurrences of an element to this multiset. Note that if\n" + 
4894
		"	 * {@code occurrences == 1}, this method has the identical effect to\n" + 
4895
		"	 * {@link #add(Object)}. This method is functionally equivalent (except in\n" + 
4896
		"	 * the case of overflow) to the call\n" + 
4897
		"	 * {@code addAll(Collections.nCopies(element, occurrences))}, which would\n" + 
4898
		"	 * presumably perform much more poorly.\n" + 
4899
		"	 * \n" + 
4900
		"	 * @param element\n" + 
4901
		"	 *            the element to add occurrences of; may be {@code null} only if\n" + 
4902
		"	 *            explicitly allowed by the implementation\n" + 
4903
		"	 * @param occurrences\n" + 
4904
		"	 *            the number of occurrences of this element to add. May be zero,\n" + 
4905
		"	 *            in which case no change will be made.\n" + 
4906
		"	 * @return the previous count of this element before the operation; possibly\n" + 
4907
		"	 *         zero - TODO: make this the actual behavior!\n" + 
4908
		"	 * @throws IllegalArgumentException\n" + 
4909
		"	 *             if {@code occurrences} is negative, or if this operation\n" + 
4910
		"	 *             would result in more than {@link Integer#MAX_VALUE}\n" + 
4911
		"	 *             occurrences of the element\n" + 
4912
		"	 * @throws NullPointerException\n" + 
4913
		"	 *             if {@code element} is null and this implementation does not\n" + 
4914
		"	 *             permit null elements. Note that if {@code occurrences} is\n" + 
4915
		"	 *             zero, the implementation may opt to return normally.\n" + 
4916
		"	 */\n" + 
4917
		"	boolean /* int */add(E element, int occurrences);\n" + 
4918
		"}\n"
4919
	);
4920
}
4921
public void testBug260381_wksp2_07() throws JavaModelException {
4922
	String source = 
4923
		"package wksp2;\n" + 
4924
		"\n" + 
4925
		"public interface I07 {\n" + 
4926
		"\n" + 
4927
		"  /**\n" + 
4928
		"   * Constructs a new, empty multiset, sorted according to the specified\n" + 
4929
		"   * comparator. All elements inserted into the multiset must be <i>mutually\n" + 
4930
		"   * comparable</i> by the specified comparator: {@code comparator.compare(e1,\n" + 
4931
		"   * e2)} must not throw a {@code ClassCastException} for any elements {@code\n" + 
4932
		"   * e1} and {@code e2} in the multiset. If the user attempts to add an element\n" + 
4933
		"   * to the multiset that violates this constraint, the {@code add(Object)} call\n" + 
4934
		"   * will throw a {@code ClassCastException}.\n" + 
4935
		"   *\n" + 
4936
		"   * @param comparator the comparator that will be used to sort this multiset. A\n" + 
4937
		"   *     null value indicates that the elements\' <i>natural ordering</i> should\n" + 
4938
		"   *     be used.\n" + 
4939
		"   */\n" + 
4940
		"  void foo();\n" + 
4941
		"}\n";
4942
	formatSource(source,
4943
		"package wksp2;\n" + 
4944
		"\n" + 
4945
		"public interface I07 {\n" + 
4946
		"\n" + 
4947
		"	/**\n" + 
4948
		"	 * Constructs a new, empty multiset, sorted according to the specified\n" + 
4949
		"	 * comparator. All elements inserted into the multiset must be <i>mutually\n" + 
4950
		"	 * comparable</i> by the specified comparator:\n" + 
4951
		"	 * {@code comparator.compare(e1, e2)} must not throw a\n" + 
4952
		"	 * {@code ClassCastException} for any elements {@code e1} and {@code e2} in\n" + 
4953
		"	 * the multiset. If the user attempts to add an element to the multiset that\n" + 
4954
		"	 * violates this constraint, the {@code add(Object)} call will throw a\n" + 
4955
		"	 * {@code ClassCastException}.\n" + 
4956
		"	 * \n" + 
4957
		"	 * @param comparator\n" + 
4958
		"	 *            the comparator that will be used to sort this multiset. A null\n" + 
4959
		"	 *            value indicates that the elements\' <i>natural ordering</i>\n" + 
4960
		"	 *            should be used.\n" + 
4961
		"	 */\n" + 
4962
		"	void foo();\n" + 
4963
		"}\n"
4964
	);
4965
}
4966
4967
/**
4401
 * @bug 260798: [formatter] Strange behavior of never join lines
4968
 * @bug 260798: [formatter] Strange behavior of never join lines
4402
 * @test Ensure that the formatter indents lines correctly when never join lines pref is activated
4969
 * @test Ensure that the formatter indents lines correctly when never join lines pref is activated
4403
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=260798"
4970
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=260798"

Return to bug 260381