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

Collapse All | Expand All

(-)formatter/org/eclipse/jdt/internal/formatter/Scribe.java (-16 / +57 lines)
Lines 25-30 Link Here
25
import org.eclipse.jdt.internal.core.util.RecordedParsingInformation;
25
import org.eclipse.jdt.internal.core.util.RecordedParsingInformation;
26
import org.eclipse.jdt.internal.formatter.align.Alignment;
26
import org.eclipse.jdt.internal.formatter.align.Alignment;
27
import org.eclipse.jdt.internal.formatter.align.AlignmentException;
27
import org.eclipse.jdt.internal.formatter.align.AlignmentException;
28
import org.eclipse.jface.text.IRegion;
28
import org.eclipse.text.edits.MultiTextEdit;
29
import org.eclipse.text.edits.MultiTextEdit;
29
import org.eclipse.text.edits.ReplaceEdit;
30
import org.eclipse.text.edits.ReplaceEdit;
30
import org.eclipse.text.edits.TextEdit;
31
import org.eclipse.text.edits.TextEdit;
Lines 66-74 Link Here
66
	public Scanner scanner;
67
	public Scanner scanner;
67
	public int scannerEndPosition;
68
	public int scannerEndPosition;
68
	public int tabLength;	
69
	public int tabLength;	
69
	public int indentationSize;	
70
	public int indentationSize;
70
	private int textRegionEnd;
71
	private IRegion[] regions;
71
	private int textRegionStart;
72
	public int tabChar;
72
	public int tabChar;
73
	public int numberOfIndentations;
73
	public int numberOfIndentations;
74
	private boolean useTabsOnlyForLeadingIndents;
74
	private boolean useTabsOnlyForLeadingIndents;
Lines 79-85 Link Here
79
	private final boolean formatJavadocComment;
79
	private final boolean formatJavadocComment;
80
	private final boolean formatBlockComment;
80
	private final boolean formatBlockComment;
81
	
81
	
82
	Scribe(CodeFormatterVisitor formatter, long sourceLevel, int offset, int length, CodeSnippetParsingUtil codeSnippetParsingUtil) {
82
	Scribe(CodeFormatterVisitor formatter, long sourceLevel, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil) {
83
		this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
83
		this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
84
		this.formatter = formatter;
84
		this.formatter = formatter;
85
		this.pageWidth = formatter.preferences.page_width;
85
		this.pageWidth = formatter.preferences.page_width;
Lines 96-103 Link Here
96
		}
96
		}
97
		this.lineSeparator = formatter.preferences.line_separator;
97
		this.lineSeparator = formatter.preferences.line_separator;
98
		this.indentationLevel = formatter.preferences.initial_indentation_level * this.indentationSize;
98
		this.indentationLevel = formatter.preferences.initial_indentation_level * this.indentationSize;
99
		this.textRegionStart = offset;
99
		this.regions= regions;
100
		this.textRegionEnd = offset + length - 1;
101
		if (codeSnippetParsingUtil != null) {
100
		if (codeSnippetParsingUtil != null) {
102
			final RecordedParsingInformation information = codeSnippetParsingUtil.recordedParsingInformation;
101
			final RecordedParsingInformation information = codeSnippetParsingUtil.recordedParsingInformation;
103
			if (information != null) {
102
			if (information != null) {
Lines 560-574 Link Here
560
	
559
	
561
	public TextEdit getRootEdit() {
560
	public TextEdit getRootEdit() {
562
		MultiTextEdit edit = null;
561
		MultiTextEdit edit = null;
563
		int length = this.textRegionEnd - this.textRegionStart + 1;
562
		int textRegionStart= this.regions[0].getOffset();
564
		if (this.textRegionStart <= 0) {
563
		IRegion lastRegion= this.regions[this.regions.length - 1];
564
		int textRegionEnd= lastRegion.getOffset() + lastRegion.getLength();
565
		
566
		int length = textRegionEnd - textRegionStart + 1;
567
		if (textRegionStart <= 0) {
565
			if (length <= 0) {
568
			if (length <= 0) {
566
				edit = new MultiTextEdit(0, 0);
569
				edit = new MultiTextEdit(0, 0);
567
			} else {
570
			} else {
568
				edit = new MultiTextEdit(0, this.textRegionEnd + 1);
571
				edit = new MultiTextEdit(0, textRegionEnd);
569
			}
572
			}
570
		} else {
573
		} else {
571
			edit = new MultiTextEdit(this.textRegionStart, this.textRegionEnd - this.textRegionStart + 1);
574
			edit = new MultiTextEdit(textRegionStart, length - 1);
572
		}
575
		}
573
		for (int i= 0, max = this.editsIndex; i < max; i++) {
576
		for (int i= 0, max = this.editsIndex; i < max; i++) {
574
			OptimizedReplaceEdit currentEdit = edits[i];
577
			OptimizedReplaceEdit currentEdit = edits[i];
Lines 664-670 Link Here
664
		final int editReplacementLength= edit.replacement.length();
667
		final int editReplacementLength= edit.replacement.length();
665
		final int editOffset= edit.offset;
668
		final int editOffset= edit.offset;
666
		if (editLength != 0) {
669
		if (editLength != 0) {
667
			if (this.textRegionStart <= editOffset && (editOffset + editLength - 1) <= this.textRegionEnd) {
670
			
671
			IRegion covering= getCoveringRegion(editOffset, (editOffset + editLength - 1));
672
			if (covering != null) {
668
				if (editReplacementLength != 0 && editLength == editReplacementLength) {
673
				if (editReplacementLength != 0 && editLength == editReplacementLength) {
669
					for (int i = editOffset, max = editOffset + editLength; i < max; i++) {
674
					for (int i = editOffset, max = editOffset + editLength; i < max; i++) {
670
						if (scanner.source[i] != edit.replacement.charAt(i - editOffset)) {
675
						if (scanner.source[i] != edit.replacement.charAt(i - editOffset)) {
Lines 675-681 Link Here
675
				} else {
680
				} else {
676
					return true;
681
					return true;
677
				}
682
				}
678
			} else if (editOffset + editLength == this.textRegionStart) {
683
			} 
684
			
685
			IRegion starting= getRegionAt(editOffset + editLength);
686
			if (starting != null) {
679
				int i = editOffset;
687
				int i = editOffset;
680
				for (int max = editOffset + editLength; i < max; i++) {
688
				for (int max = editOffset + editLength; i < max; i++) {
681
					int replacementStringIndex = i - editOffset;
689
					int replacementStringIndex = i - editOffset;
Lines 684-703 Link Here
684
					}
692
					}
685
				}
693
				}
686
				if (i - editOffset != editReplacementLength && i != editOffset + editLength - 1) {
694
				if (i - editOffset != editReplacementLength && i != editOffset + editLength - 1) {
687
					edit.offset = textRegionStart;
695
					edit.offset = starting.getOffset();
688
					edit.length = 0;
696
					edit.length = 0;
689
					edit.replacement = edit.replacement.substring(i - editOffset);
697
					edit.replacement = edit.replacement.substring(i - editOffset);
690
					return true;
698
					return true;
691
				}
699
				}
692
			}
700
			}
693
		} else if (this.textRegionStart <= editOffset && editOffset <= this.textRegionEnd) {
701
			
694
			return true;
702
			return false;
695
		} else if (editOffset == this.scannerEndPosition && editOffset == this.textRegionEnd + 1) {
703
		}
704
		
705
		IRegion covering= getCoveringRegion(editOffset, editOffset);
706
		if (covering != null) {
696
			return true;
707
			return true;
697
		}
708
		}
709
710
		if (editOffset == this.scannerEndPosition) {
711
			for (int i= 0; i < this.regions.length; i++) {
712
				IRegion region= this.regions[i];
713
				if (editOffset == getRegionEnd(region) + 1)
714
					return true;
715
			}
716
		}
698
		return false;
717
		return false;
699
	}
718
	}
700
719
720
	private IRegion getRegionAt(int offset) {
721
		for (int i= 0; i < this.regions.length; i++) {
722
			IRegion region= this.regions[i];
723
			if (region.getOffset() == offset)
724
				return region;
725
		}
726
		return null;
727
	}
728
729
	private IRegion getCoveringRegion(int offset, int end) {
730
		for (int i= 0; i < this.regions.length; i++) {
731
			IRegion region= this.regions[i];
732
			if (region.getOffset() <= offset && end <= getRegionEnd(region))
733
				return region;
734
		}
735
		return null;
736
	}
737
738
	private int getRegionEnd(IRegion region) {
739
		return region.getOffset() + region.getLength() - 1;
740
	}
741
701
	private void preserveEmptyLines(int count, int insertPosition) {
742
	private void preserveEmptyLines(int count, int insertPosition) {
702
		if (count > 0) {
743
		if (count > 0) {
703
			if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
744
			if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
(-)formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java (-32 / +89 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.formatter;
11
package org.eclipse.jdt.internal.formatter;
12
12
13
import java.util.Arrays;
14
import java.util.Comparator;
13
import java.util.HashMap;
15
import java.util.HashMap;
14
import java.util.Map;
16
import java.util.Map;
15
17
Lines 32-38 Link Here
32
import org.eclipse.jdt.internal.formatter.comment.MultiCommentRegion;
34
import org.eclipse.jdt.internal.formatter.comment.MultiCommentRegion;
33
import org.eclipse.jface.text.Document;
35
import org.eclipse.jface.text.Document;
34
import org.eclipse.jface.text.IDocument;
36
import org.eclipse.jface.text.IDocument;
37
import org.eclipse.jface.text.IRegion;
35
import org.eclipse.jface.text.Position;
38
import org.eclipse.jface.text.Position;
39
import org.eclipse.jface.text.Region;
36
import org.eclipse.text.edits.MultiTextEdit;
40
import org.eclipse.text.edits.MultiTextEdit;
37
import org.eclipse.text.edits.TextEdit;
41
import org.eclipse.text.edits.TextEdit;
38
42
Lines 144-180 Link Here
144
			int indentationLevel,
148
			int indentationLevel,
145
			String lineSeparator) {
149
			String lineSeparator) {
146
150
151
		return format(kind, source, new IRegion[] {new Region(offset, length)}, indentationLevel, lineSeparator);
152
	}
153
	
154
	/**
155
	 * {@inheritDoc}
156
	 */
157
	public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) {
158
		int regionsLength = regions == null ? 0 : regions.length;
159
		if (regionsLength == 0) {
160
			throw new IllegalArgumentException();
161
		}
162
		
163
		if (regionsLength > 1) {
164
			Arrays.sort(regions, new Comparator() {
165
				public int compare(Object o1, Object o2) {
166
					IRegion r1= (IRegion)o1;
167
					IRegion r2= (IRegion)o2;
168
					if (r1.getOffset() == r2.getOffset())
169
						return 0;
170
					
171
					if (r1.getOffset() < r2.getOffset())
172
						return -1;
173
					
174
					return 1;
175
				}
176
			});
177
		}
178
179
		int offset= regions[0].getOffset();
180
		IRegion lastRegions= regions[regionsLength - 1];
181
		int end= lastRegions.getOffset() + lastRegions.getLength() - 1;
182
		int length = end - offset + 1;
183
		
147
		if (offset < 0 || length < 0 || length > source.length()) {
184
		if (offset < 0 || length < 0 || length > source.length()) {
148
			throw new IllegalArgumentException();
185
			throw new IllegalArgumentException();
149
		}
186
		}
187
		
188
		IRegion last= regions[0];
189
		for (int i= 1; i < regionsLength; i++) {
190
			IRegion current= regions[i];
191
			if (last.getLength() + last.getOffset() - 1 > current.getOffset())
192
				throw new IllegalArgumentException();
193
		}
194
150
		this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
195
		this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
151
		switch(kind) {
196
		switch(kind) {
152
			case K_CLASS_BODY_DECLARATIONS :
197
			case K_CLASS_BODY_DECLARATIONS :
153
				return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, offset, length);
198
				return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, regions);
154
			case K_COMPILATION_UNIT :
199
			case K_COMPILATION_UNIT :
155
				return formatCompilationUnit(source, indentationLevel, lineSeparator, offset, length);
200
				return formatCompilationUnit(source, indentationLevel, lineSeparator, regions);
156
			case K_EXPRESSION :
201
			case K_EXPRESSION :
157
				return formatExpression(source, indentationLevel, lineSeparator, offset, length);
202
				return formatExpression(source, indentationLevel, lineSeparator, regions);
158
			case K_STATEMENTS :
203
			case K_STATEMENTS :
159
				return formatStatements(source, indentationLevel, lineSeparator, offset, length);
204
				return formatStatements(source, indentationLevel, lineSeparator, regions);
160
			case K_UNKNOWN :
205
			case K_UNKNOWN :
161
				return probeFormatting(source, indentationLevel, lineSeparator, offset, length);
206
				return probeFormatting(source, indentationLevel, lineSeparator, regions);
162
			case K_JAVA_DOC :
207
			case K_JAVA_DOC :
163
			case K_MULTI_LINE_COMMENT :
208
			case K_MULTI_LINE_COMMENT :
164
			case K_SINGLE_LINE_COMMENT :
209
			case K_SINGLE_LINE_COMMENT :
165
				return formatComment(kind, source, indentationLevel, lineSeparator, offset, length);
210
				return formatComment(kind, source, indentationLevel, lineSeparator, regions);
166
		}
211
		}
167
		return null;
212
		return null;
168
	}
213
	}
169
214
170
	private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, int offset, int length) {
215
	private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
171
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
216
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
172
		
217
		
173
		if (bodyDeclarations == null) {
218
		if (bodyDeclarations == null) {
174
			// a problem occured while parsing the source
219
			// a problem occured while parsing the source
175
			return null;
220
			return null;
176
		}
221
		}
177
		return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, offset, length);
222
		return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions);
178
	}
223
	}
179
224
180
	/**
225
	/**
Lines 184-195 Link Here
184
	 * @param source the given source
229
	 * @param source the given source
185
	 * @param indentationLevel the given indentation level
230
	 * @param indentationLevel the given indentation level
186
	 * @param lineSeparator the given line separator
231
	 * @param lineSeparator the given line separator
187
	 * @param offset the given offset
232
	 * @param regions the given regions
188
	 * @param length the given length
189
	 * @return the resulting text edit
233
	 * @return the resulting text edit
190
	 * @deprecated
234
	 * @deprecated
191
	 */
235
	 */
192
	private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, int offset, int length) {
236
	private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
193
		Object oldOption = this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT);
237
		Object oldOption = this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT);
194
		boolean isFormattingComments = false;
238
		boolean isFormattingComments = false;
195
		if (oldOption == null) {
239
		if (oldOption == null) {
Lines 213-219 Link Here
213
				this.preferences.line_separator = Util.LINE_SEPARATOR;
257
				this.preferences.line_separator = Util.LINE_SEPARATOR;
214
			}
258
			}
215
			this.preferences.initial_indentation_level = indentationLevel;
259
			this.preferences.initial_indentation_level = indentationLevel;
216
			this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, null);
260
			this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, null);
261
			
262
			int offset= regions[0].getOffset();
263
			IRegion lastRegions= regions[regions.length - 1];
264
			int end= lastRegions.getOffset() + lastRegions.getLength() - 1;
265
			int length= end - offset + 1;
266
			
217
			final CommentRegion region = createRegion(kind, new Document(source), new Position(offset, length), this.newCodeFormatter);
267
			final CommentRegion region = createRegion(kind, new Document(source), new Position(offset, length), this.newCodeFormatter);
218
			if (region != null) {
268
			if (region != null) {
219
				return this.newCodeFormatter.format(source, region);
269
				return this.newCodeFormatter.format(source, region);
Lines 222-228 Link Here
222
		return new MultiTextEdit();
272
		return new MultiTextEdit();
223
	}
273
	}
224
274
225
	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, int offset, int length) {
275
	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
226
		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
276
		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
227
		
277
		
228
		if (lineSeparator != null) {
278
		if (lineSeparator != null) {
Lines 232-260 Link Here
232
		}
282
		}
233
		this.preferences.initial_indentation_level = indentationLevel;
283
		this.preferences.initial_indentation_level = indentationLevel;
234
284
235
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil);
285
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil);
236
		
286
		
237
		return this.newCodeFormatter.format(source, compilationUnitDeclaration);
287
		return this.newCodeFormatter.format(source, compilationUnitDeclaration);
238
	}
288
	}
239
289
240
	private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, int offset, int length) {
290
	private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
241
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
291
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
242
		
292
		
243
		if (expression == null) {
293
		if (expression == null) {
244
			// a problem occured while parsing the source
294
			// a problem occured while parsing the source
245
			return null;
295
			return null;
246
		}
296
		}
247
		return internalFormatExpression(source, indentationLevel, lineSeparator, expression, offset, length);
297
		return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions);
248
	}
298
	}
249
299
250
	private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, int offset, int length) {
300
	private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
251
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
301
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
252
		
302
		
253
		if (constructorDeclaration.statements == null) {
303
		if (constructorDeclaration.statements == null) {
254
			// a problem occured while parsing the source
304
			// a problem occured while parsing the source
255
			return null;
305
			return null;
256
		}
306
		}
257
		return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, offset, length);
307
		return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions);
258
	}
308
	}
259
309
260
	public String getDebugOutput() {
310
	public String getDebugOutput() {
Lines 331-337 Link Here
331
		return this.defaultCompilerOptions;		
381
		return this.defaultCompilerOptions;		
332
	}
382
	}
333
383
334
	private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, int offset, int length) {
384
	private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, IRegion[] regions) {
335
		if (lineSeparator != null) {
385
		if (lineSeparator != null) {
336
			this.preferences.line_separator = lineSeparator;
386
			this.preferences.line_separator = lineSeparator;
337
		} else {
387
		} else {
Lines 339-349 Link Here
339
		}
389
		}
340
		this.preferences.initial_indentation_level = indentationLevel;
390
		this.preferences.initial_indentation_level = indentationLevel;
341
391
342
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil);
392
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil);
343
		return this.newCodeFormatter.format(source, bodyDeclarations);
393
		return this.newCodeFormatter.format(source, bodyDeclarations);
344
	}
394
	}
345
	
395
	
346
	private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, int offset, int length) {
396
	private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, IRegion[] regions) {
347
		if (lineSeparator != null) {
397
		if (lineSeparator != null) {
348
			this.preferences.line_separator = lineSeparator;
398
			this.preferences.line_separator = lineSeparator;
349
		} else {
399
		} else {
Lines 351-363 Link Here
351
		}
401
		}
352
		this.preferences.initial_indentation_level = indentationLevel;
402
		this.preferences.initial_indentation_level = indentationLevel;
353
403
354
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil);
404
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil);
355
		
405
		
356
		TextEdit textEdit = this.newCodeFormatter.format(source, expression);
406
		TextEdit textEdit = this.newCodeFormatter.format(source, expression);
357
		return textEdit;
407
		return textEdit;
358
	}
408
	}
359
409
360
	private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, int offset, int length) {
410
	private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, IRegion[] regions) {
361
		if (lineSeparator != null) {
411
		if (lineSeparator != null) {
362
			this.preferences.line_separator = lineSeparator;
412
			this.preferences.line_separator = lineSeparator;
363
		} else {
413
		} else {
Lines 365-397 Link Here
365
		}
415
		}
366
		this.preferences.initial_indentation_level = indentationLevel;
416
		this.preferences.initial_indentation_level = indentationLevel;
367
417
368
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil);
418
		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil);
369
		
419
		
370
		return this.newCodeFormatter.format(source, constructorDeclaration);
420
		return this.newCodeFormatter.format(source, constructorDeclaration);
371
	}
421
	}
372
422
373
	private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, int offset, int length) {
423
	private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
374
		if (ProbingScanner == null) {
424
		if (ProbingScanner == null) {
375
			// scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT 
425
			// scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT 
376
			ProbingScanner = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_3, ClassFileConstants.JDK1_3, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
426
			ProbingScanner = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_3, ClassFileConstants.JDK1_3, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
377
		}
427
		}
378
		ProbingScanner.setSource(source.toCharArray());
428
		ProbingScanner.setSource(source.toCharArray());
429
		
430
		int offset= regions[0].getOffset();
431
		IRegion lastRegions= regions[regions.length - 1];
432
		int end= lastRegions.getOffset() + lastRegions.getLength() - 1;
433
		int length= end - offset + 1;
434
		
379
		ProbingScanner.resetTo(offset, offset + length);
435
		ProbingScanner.resetTo(offset, offset + length);
380
		try {
436
		try {
381
			switch(ProbingScanner.getNextToken()) {
437
			switch(ProbingScanner.getNextToken()) {
382
				case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
438
				case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
383
					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
439
					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
384
						return formatComment(K_MULTI_LINE_COMMENT, source, indentationLevel, lineSeparator, offset, length);
440
						return formatComment(K_MULTI_LINE_COMMENT, source, indentationLevel, lineSeparator, regions);
385
					}
441
					}
386
					break;
442
					break;
387
				case ITerminalSymbols.TokenNameCOMMENT_LINE :
443
				case ITerminalSymbols.TokenNameCOMMENT_LINE :
388
					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
444
					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
389
						return formatComment(K_SINGLE_LINE_COMMENT, source, indentationLevel, lineSeparator, offset, length);
445
						return formatComment(K_SINGLE_LINE_COMMENT, source, indentationLevel, lineSeparator, regions);
390
					}
446
					}
391
					break;
447
					break;
392
				case ITerminalSymbols.TokenNameCOMMENT_JAVADOC :
448
				case ITerminalSymbols.TokenNameCOMMENT_JAVADOC :
393
					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
449
					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
394
						return formatComment(K_JAVA_DOC, source, indentationLevel, lineSeparator, offset, length);
450
						return formatComment(K_JAVA_DOC, source, indentationLevel, lineSeparator, regions);
395
					}
451
					}
396
			}
452
			}
397
		} catch (InvalidInputException e) {
453
		} catch (InvalidInputException e) {
Lines 402-423 Link Here
402
		// probe for expression
458
		// probe for expression
403
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
459
		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
404
		if (expression != null) {
460
		if (expression != null) {
405
			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, offset, length);
461
			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions);
406
		}
462
		}
407
463
408
		// probe for body declarations (fields, methods, constructors)
464
		// probe for body declarations (fields, methods, constructors)
409
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
465
		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
410
		if (bodyDeclarations != null) {
466
		if (bodyDeclarations != null) {
411
			return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, offset, length);
467
			return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions);
412
		}
468
		}
413
469
414
		// probe for statements
470
		// probe for statements
415
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
471
		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
416
		if (constructorDeclaration.statements != null) {
472
		if (constructorDeclaration.statements != null) {
417
			return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, offset, length);
473
			return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions);
418
		}
474
		}
419
475
420
		// this has to be a compilation unit
476
		// this has to be a compilation unit
421
		return formatCompilationUnit(source, indentationLevel, lineSeparator, offset, length);
477
		return formatCompilationUnit(source, indentationLevel, lineSeparator, regions);
422
	}
478
	}
479
423
}
480
}
(-)formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java (-7 / +8 lines)
Lines 19-24 Link Here
19
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
19
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
20
import org.eclipse.jdt.internal.compiler.ASTVisitor;
20
import org.eclipse.jdt.internal.compiler.ASTVisitor;
21
import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
21
import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
22
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
22
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
23
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
23
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
24
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
24
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
25
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
Lines 31-37 Link Here
31
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
32
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
32
import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
33
import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
33
import org.eclipse.jdt.internal.compiler.ast.Assignment;
34
import org.eclipse.jdt.internal.compiler.ast.Assignment;
34
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
35
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
35
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
36
import org.eclipse.jdt.internal.compiler.ast.Block;
36
import org.eclipse.jdt.internal.compiler.ast.Block;
37
import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
37
import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
Lines 71-83 Link Here
71
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
71
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
72
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
72
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
73
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
73
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
74
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
75
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
76
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
77
import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
78
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
74
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
79
import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
75
import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
80
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
76
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
77
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
78
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
81
import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
79
import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
82
import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
80
import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
83
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
81
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
Lines 86-95 Link Here
86
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
84
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
87
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
85
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
88
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
86
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
87
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
89
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
88
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
90
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
89
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
91
import org.eclipse.jdt.internal.compiler.ast.Statement;
90
import org.eclipse.jdt.internal.compiler.ast.Statement;
92
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
91
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
92
import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
93
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
93
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
94
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
94
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
95
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
95
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
Lines 117-122 Link Here
117
import org.eclipse.jdt.internal.formatter.align.Alignment;
117
import org.eclipse.jdt.internal.formatter.align.Alignment;
118
import org.eclipse.jdt.internal.formatter.align.AlignmentException;
118
import org.eclipse.jdt.internal.formatter.align.AlignmentException;
119
import org.eclipse.jdt.internal.formatter.comment.CommentRegion;
119
import org.eclipse.jdt.internal.formatter.comment.CommentRegion;
120
import org.eclipse.jface.text.IRegion;
120
import org.eclipse.text.edits.TextEdit;
121
import org.eclipse.text.edits.TextEdit;
121
122
122
/**
123
/**
Lines 174-187 Link Here
174
	public DefaultCodeFormatterOptions preferences;
175
	public DefaultCodeFormatterOptions preferences;
175
	public Scribe scribe;
176
	public Scribe scribe;
176
177
177
	public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, int offset, int length, CodeSnippetParsingUtil codeSnippetParsingUtil) {
178
	public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil) {
178
		long sourceLevel = settings == null
179
		long sourceLevel = settings == null
179
			? ClassFileConstants.JDK1_3
180
			? ClassFileConstants.JDK1_3
180
			: CompilerOptions.versionToJdkLevel(settings.get(JavaCore.COMPILER_SOURCE));
181
			: CompilerOptions.versionToJdkLevel(settings.get(JavaCore.COMPILER_SOURCE));
181
		this.localScanner = new Scanner(true, false, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
182
		this.localScanner = new Scanner(true, false, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
182
		
183
		
183
		this.preferences = preferences;
184
		this.preferences = preferences;
184
		this.scribe = new Scribe(this, sourceLevel, offset, length, codeSnippetParsingUtil);
185
		this.scribe = new Scribe(this, sourceLevel, regions, codeSnippetParsingUtil);
185
	}
186
	}
186
	
187
	
187
	/**
188
	/**
(-)formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java (+28 lines)
Lines 11-16 Link Here
11
package org.eclipse.jdt.core.formatter;
11
package org.eclipse.jdt.core.formatter;
12
12
13
import org.eclipse.jdt.internal.compiler.util.Util;
13
import org.eclipse.jdt.internal.compiler.util.Util;
14
import org.eclipse.jface.text.IRegion;
14
import org.eclipse.text.edits.TextEdit;
15
import org.eclipse.text.edits.TextEdit;
15
16
16
/**
17
/**
Lines 86-91 Link Here
86
	 */
87
	 */
87
	public abstract TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator);
88
	public abstract TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator);
88
	
89
	
90
	
91
	/** 
92
	 * Format <code>source</code>,
93
	 * and returns a text edit that correspond to the difference between the given string and the formatted string.
94
	 * <p>It returns null if the given string cannot be formatted.</p>
95
	 * 
96
	 * <p>If an offset position is matching a whitespace, the result can include whitespaces. It would be up to the
97
	 * caller to get rid of preceeding whitespaces.</p>
98
	 * 
99
	 * <p>No region in <code>regions</code> must overlap with any other region in <code>regions</code></p>
100
	 * 
101
	 * @param kind Use to specify the kind of the code snippet to format. It can be any of these:
102
	 *        K_EXPRESSION, K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_COMPILATION_UNIT, K_UNKNOWN,
103
	 *        K_SINGLE_LINE_COMMENT, K_MULTI_LINE_COMMENT, K_JAVA_DOC
104
	 * @param source the source to format
105
	 * @param regions a set of regions in source to format
106
	 * @param indentationLevel the initial indentation level, used 
107
	 *      to shift left/right the entire source fragment. An initial indentation
108
	 *      level of zero or below has no effect.
109
	 * @param lineSeparator the line separator to use in formatted source,
110
	 *     if set to <code>null</code>, then the platform default one will be used.
111
	 * @return the text edit
112
	 * @throws IllegalArgumentException if offset is lower than 0, length is lower than 0 or
113
	 * length is greater than source length.
114
	 */
115
	public abstract TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator);
116
	
89
	/**
117
	/**
90
	 * Answers the string that corresponds to the indentation to the given indentation level or an empty string
118
	 * Answers the string that corresponds to the indentation to the given indentation level or an empty string
91
	 * if the indentation cannot be computed.
119
	 * if the indentation cannot be computed.

Return to bug 203304