### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java,v retrieving revision 1.62 diff -u -r1.62 DefaultCodeFormatter.java --- formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java 6 Mar 2007 02:38:50 -0000 1.62 +++ formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java 14 Sep 2007 08:50:41 -0000 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.jdt.internal.formatter; +import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; @@ -32,7 +34,9 @@ import org.eclipse.jdt.internal.formatter.comment.MultiCommentRegion; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.TextEdit; @@ -144,37 +148,78 @@ int indentationLevel, String lineSeparator) { + return format(kind, source, new IRegion[] {new Region(offset, length)}, indentationLevel, lineSeparator); + } + + /** + * {@inheritDoc} + */ + public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) { + int regionsLength = regions == null ? 0 : regions.length; + if (regionsLength == 0) { + throw new IllegalArgumentException(); + } + + if (regionsLength > 1) { + Arrays.sort(regions, new Comparator() { + public int compare(Object o1, Object o2) { + IRegion r1= (IRegion)o1; + IRegion r2= (IRegion)o2; + if (r1.getOffset() == r2.getOffset()) + return 0; + + if (r1.getOffset() < r2.getOffset()) + return -1; + + return 1; + } + }); + } + + int offset= regions[0].getOffset(); + IRegion lastRegions= regions[regionsLength - 1]; + int end= lastRegions.getOffset() + lastRegions.getLength() - 1; + int length = end - offset + 1; + if (offset < 0 || length < 0 || length > source.length()) { throw new IllegalArgumentException(); } + + IRegion last= regions[0]; + for (int i= 1; i < regionsLength; i++) { + IRegion current= regions[i]; + if (last.getLength() + last.getOffset() - 1 > current.getOffset()) + throw new IllegalArgumentException(); + } + this.codeSnippetParsingUtil = new CodeSnippetParsingUtil(); switch(kind) { case K_CLASS_BODY_DECLARATIONS : - return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, offset, length); + return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, regions); case K_COMPILATION_UNIT : - return formatCompilationUnit(source, indentationLevel, lineSeparator, offset, length); + return formatCompilationUnit(source, indentationLevel, lineSeparator, regions); case K_EXPRESSION : - return formatExpression(source, indentationLevel, lineSeparator, offset, length); + return formatExpression(source, indentationLevel, lineSeparator, regions); case K_STATEMENTS : - return formatStatements(source, indentationLevel, lineSeparator, offset, length); + return formatStatements(source, indentationLevel, lineSeparator, regions); case K_UNKNOWN : - return probeFormatting(source, indentationLevel, lineSeparator, offset, length); + return probeFormatting(source, indentationLevel, lineSeparator, regions); case K_JAVA_DOC : case K_MULTI_LINE_COMMENT : case K_SINGLE_LINE_COMMENT : - return formatComment(kind, source, indentationLevel, lineSeparator, offset, length); + return formatComment(kind, source, indentationLevel, lineSeparator, regions); } return null; } - private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, int offset, int length) { + private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, IRegion[] regions) { ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true); if (bodyDeclarations == null) { // a problem occured while parsing the source return null; } - return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, offset, length); + return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions); } /** @@ -184,12 +229,11 @@ * @param source the given source * @param indentationLevel the given indentation level * @param lineSeparator the given line separator - * @param offset the given offset - * @param length the given length + * @param regions the given regions * @return the resulting text edit * @deprecated */ - private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, int offset, int length) { + private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, IRegion[] regions) { Object oldOption = this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT); boolean isFormattingComments = false; if (oldOption == null) { @@ -213,7 +257,13 @@ this.preferences.line_separator = Util.LINE_SEPARATOR; } this.preferences.initial_indentation_level = indentationLevel; - this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, null); + this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, null); + + int offset= regions[0].getOffset(); + IRegion lastRegions= regions[regions.length - 1]; + int end= lastRegions.getOffset() + lastRegions.getLength() - 1; + int length= end - offset + 1; + final CommentRegion region = createRegion(kind, new Document(source), new Position(offset, length), this.newCodeFormatter); if (region != null) { return this.newCodeFormatter.format(source, region); @@ -222,7 +272,7 @@ return new MultiTextEdit(); } - private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, int offset, int length) { + private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, IRegion[] regions) { CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true); if (lineSeparator != null) { @@ -232,29 +282,29 @@ } this.preferences.initial_indentation_level = indentationLevel; - this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil); + this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil); return this.newCodeFormatter.format(source, compilationUnitDeclaration); } - private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, int offset, int length) { + private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, IRegion[] regions) { Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true); if (expression == null) { // a problem occured while parsing the source return null; } - return internalFormatExpression(source, indentationLevel, lineSeparator, expression, offset, length); + return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions); } - private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, int offset, int length) { + private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, IRegion[] regions) { ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false); if (constructorDeclaration.statements == null) { // a problem occured while parsing the source return null; } - return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, offset, length); + return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions); } public String getDebugOutput() { @@ -331,7 +381,7 @@ return this.defaultCompilerOptions; } - private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, int offset, int length) { + private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, IRegion[] regions) { if (lineSeparator != null) { this.preferences.line_separator = lineSeparator; } else { @@ -339,11 +389,11 @@ } this.preferences.initial_indentation_level = indentationLevel; - this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil); + this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil); return this.newCodeFormatter.format(source, bodyDeclarations); } - private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, int offset, int length) { + private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, IRegion[] regions) { if (lineSeparator != null) { this.preferences.line_separator = lineSeparator; } else { @@ -351,13 +401,13 @@ } this.preferences.initial_indentation_level = indentationLevel; - this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil); + this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil); TextEdit textEdit = this.newCodeFormatter.format(source, expression); return textEdit; } - private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, int offset, int length) { + private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, IRegion[] regions) { if (lineSeparator != null) { this.preferences.line_separator = lineSeparator; } else { @@ -365,33 +415,39 @@ } this.preferences.initial_indentation_level = indentationLevel; - this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil); + this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil); return this.newCodeFormatter.format(source, constructorDeclaration); } - private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, int offset, int length) { + private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, IRegion[] regions) { if (ProbingScanner == null) { // scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT ProbingScanner = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_3, ClassFileConstants.JDK1_3, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); } ProbingScanner.setSource(source.toCharArray()); + + int offset= regions[0].getOffset(); + IRegion lastRegions= regions[regions.length - 1]; + int end= lastRegions.getOffset() + lastRegions.getLength() - 1; + int length= end - offset + 1; + ProbingScanner.resetTo(offset, offset + length); try { switch(ProbingScanner.getNextToken()) { case ITerminalSymbols.TokenNameCOMMENT_BLOCK : if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) { - return formatComment(K_MULTI_LINE_COMMENT, source, indentationLevel, lineSeparator, offset, length); + return formatComment(K_MULTI_LINE_COMMENT, source, indentationLevel, lineSeparator, regions); } break; case ITerminalSymbols.TokenNameCOMMENT_LINE : if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) { - return formatComment(K_SINGLE_LINE_COMMENT, source, indentationLevel, lineSeparator, offset, length); + return formatComment(K_SINGLE_LINE_COMMENT, source, indentationLevel, lineSeparator, regions); } break; case ITerminalSymbols.TokenNameCOMMENT_JAVADOC : if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) { - return formatComment(K_JAVA_DOC, source, indentationLevel, lineSeparator, offset, length); + return formatComment(K_JAVA_DOC, source, indentationLevel, lineSeparator, regions); } } } catch (InvalidInputException e) { @@ -402,22 +458,23 @@ // probe for expression Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true); if (expression != null) { - return internalFormatExpression(source, indentationLevel, lineSeparator, expression, offset, length); + return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions); } // probe for body declarations (fields, methods, constructors) ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true); if (bodyDeclarations != null) { - return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, offset, length); + return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions); } // probe for statements ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false); if (constructorDeclaration.statements != null) { - return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, offset, length); + return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions); } // this has to be a compilation unit - return formatCompilationUnit(source, indentationLevel, lineSeparator, offset, length); + return formatCompilationUnit(source, indentationLevel, lineSeparator, regions); } + } Index: formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java,v retrieving revision 1.201 diff -u -r1.201 CodeFormatterVisitor.java --- formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java 12 Sep 2007 14:09:06 -0000 1.201 +++ formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java 14 Sep 2007 08:50:41 -0000 @@ -19,6 +19,7 @@ import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.internal.compiler.ASTVisitor; import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression; +import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; @@ -31,7 +32,6 @@ import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference; import org.eclipse.jdt.internal.compiler.ast.AssertStatement; import org.eclipse.jdt.internal.compiler.ast.Assignment; -import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; import org.eclipse.jdt.internal.compiler.ast.Block; import org.eclipse.jdt.internal.compiler.ast.BreakStatement; @@ -71,13 +71,11 @@ import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; -import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; -import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; -import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; -import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; +import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.PostfixExpression; import org.eclipse.jdt.internal.compiler.ast.PrefixExpression; import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; @@ -86,10 +84,12 @@ import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; +import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.StringLiteral; +import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation; import org.eclipse.jdt.internal.compiler.ast.SuperReference; import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; @@ -117,6 +117,7 @@ import org.eclipse.jdt.internal.formatter.align.Alignment; import org.eclipse.jdt.internal.formatter.align.AlignmentException; import org.eclipse.jdt.internal.formatter.comment.CommentRegion; +import org.eclipse.jface.text.IRegion; import org.eclipse.text.edits.TextEdit; /** @@ -174,14 +175,14 @@ public DefaultCodeFormatterOptions preferences; public Scribe scribe; - public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, int offset, int length, CodeSnippetParsingUtil codeSnippetParsingUtil) { + public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil) { long sourceLevel = settings == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(settings.get(JavaCore.COMPILER_SOURCE)); this.localScanner = new Scanner(true, false, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); this.preferences = preferences; - this.scribe = new Scribe(this, sourceLevel, offset, length, codeSnippetParsingUtil); + this.scribe = new Scribe(this, sourceLevel, regions, codeSnippetParsingUtil); } /** Index: formatter/org/eclipse/jdt/internal/formatter/Scribe.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java,v retrieving revision 1.107 diff -u -r1.107 Scribe.java --- formatter/org/eclipse/jdt/internal/formatter/Scribe.java 29 May 2007 15:12:40 -0000 1.107 +++ formatter/org/eclipse/jdt/internal/formatter/Scribe.java 14 Sep 2007 08:50:42 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.internal.formatter; import java.util.Arrays; +import java.util.Comparator; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.InvalidInputException; @@ -25,6 +26,8 @@ import org.eclipse.jdt.internal.core.util.RecordedParsingInformation; import org.eclipse.jdt.internal.formatter.align.Alignment; import org.eclipse.jdt.internal.formatter.align.AlignmentException; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; @@ -66,9 +69,8 @@ public Scanner scanner; public int scannerEndPosition; public int tabLength; - public int indentationSize; - private int textRegionEnd; - private int textRegionStart; + public int indentationSize; + private IRegion[] regions; public int tabChar; public int numberOfIndentations; private boolean useTabsOnlyForLeadingIndents; @@ -79,7 +81,7 @@ private final boolean formatJavadocComment; private final boolean formatBlockComment; - Scribe(CodeFormatterVisitor formatter, long sourceLevel, int offset, int length, CodeSnippetParsingUtil codeSnippetParsingUtil) { + Scribe(CodeFormatterVisitor formatter, long sourceLevel, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil) { this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); this.formatter = formatter; this.pageWidth = formatter.preferences.page_width; @@ -96,8 +98,7 @@ } this.lineSeparator = formatter.preferences.line_separator; this.indentationLevel = formatter.preferences.initial_indentation_level * this.indentationSize; - this.textRegionStart = offset; - this.textRegionEnd = offset + length - 1; + this.regions= regions; if (codeSnippetParsingUtil != null) { final RecordedParsingInformation information = codeSnippetParsingUtil.recordedParsingInformation; if (information != null) { @@ -560,15 +561,19 @@ public TextEdit getRootEdit() { MultiTextEdit edit = null; - int length = this.textRegionEnd - this.textRegionStart + 1; - if (this.textRegionStart <= 0) { + int textRegionStart= this.regions[0].getOffset(); + IRegion lastRegion= this.regions[this.regions.length - 1]; + int textRegionEnd= lastRegion.getOffset() + lastRegion.getLength(); + + int length = textRegionEnd - textRegionStart + 1; + if (textRegionStart <= 0) { if (length <= 0) { edit = new MultiTextEdit(0, 0); } else { - edit = new MultiTextEdit(0, this.textRegionEnd + 1); + edit = new MultiTextEdit(0, textRegionEnd); } } else { - edit = new MultiTextEdit(this.textRegionStart, this.textRegionEnd - this.textRegionStart + 1); + edit = new MultiTextEdit(textRegionStart, length - 1); } for (int i= 0, max = this.editsIndex; i < max; i++) { OptimizedReplaceEdit currentEdit = edits[i]; @@ -664,7 +669,9 @@ final int editReplacementLength= edit.replacement.length(); final int editOffset= edit.offset; if (editLength != 0) { - if (this.textRegionStart <= editOffset && (editOffset + editLength - 1) <= this.textRegionEnd) { + + IRegion covering= getCoveringRegion(editOffset, (editOffset + editLength - 1)); + if (covering != null) { if (editReplacementLength != 0 && editLength == editReplacementLength) { for (int i = editOffset, max = editOffset + editLength; i < max; i++) { if (scanner.source[i] != edit.replacement.charAt(i - editOffset)) { @@ -675,7 +682,10 @@ } else { return true; } - } else if (editOffset + editLength == this.textRegionStart) { + } + + IRegion starting= getRegionAt(editOffset + editLength); + if (starting != null) { int i = editOffset; for (int max = editOffset + editLength; i < max; i++) { int replacementStringIndex = i - editOffset; @@ -684,20 +694,92 @@ } } if (i - editOffset != editReplacementLength && i != editOffset + editLength - 1) { - edit.offset = textRegionStart; + edit.offset = starting.getOffset(); edit.length = 0; edit.replacement = edit.replacement.substring(i - editOffset); return true; } } - } else if (this.textRegionStart <= editOffset && editOffset <= this.textRegionEnd) { + + return false; + } + + IRegion covering= getCoveringRegion(editOffset, editOffset); + if (covering != null) { return true; - } else if (editOffset == this.scannerEndPosition && editOffset == this.textRegionEnd + 1) { + } + + if (editOffset == this.scannerEndPosition) { + int index= Arrays.binarySearch(this.regions, new Region(editOffset, 0), new Comparator() { + public int compare(Object o1, Object o2) { + IRegion r1= (IRegion)o1; + IRegion r2= (IRegion)o2; + + int r1End= r1.getOffset() + r1.getLength(); + int r2End= r2.getOffset() + r2.getLength(); + + if (r1End == r2End) + return 0; + + if (r1End < r2End) + return -1; + + return 1; + } + }); + if (index < 0) + return false; + + //Assert.isTrue(editOffset == getRegionEnd(this.regions[index]) + 1); return true; } return false; } + private IRegion getRegionAt(int offset) { + int index= getIndexOfRegionAt(offset); + if (index < 0) + return null; + + return this.regions[index]; + } + + private IRegion getCoveringRegion(int offset, int end) { + int index= getIndexOfRegionAt(offset); + + if (index < 0) { + index= -(index + 1); + //Assert.isTrue(index == this.regions.length || this.regions[index].getOffset() > offset); + index--; + if (index < 0) + return null; + } + //Assert.isTrue(this.regions[index].getOffset() <= offset); + + IRegion region= this.regions[index]; + if (end <= region.getOffset() + region.getLength() - 1) + return region; + + return null; + } + + private int getIndexOfRegionAt(int offset) { + return Arrays.binarySearch(this.regions, new Region(offset, 0), new Comparator() { + public int compare(Object o1, Object o2) { + int r1Offset= ((IRegion)o1).getOffset(); + int r2Offset= ((IRegion)o2).getOffset(); + + if (r1Offset == r2Offset) + return 0; + + if (r1Offset < r2Offset) + return -1; + + return 1; + } + }); + } + private void preserveEmptyLines(int count, int insertPosition) { if (count > 0) { if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) { Index: formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java,v retrieving revision 1.16 diff -u -r1.16 CodeFormatter.java --- formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java 24 Nov 2006 01:32:06 -0000 1.16 +++ formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java 14 Sep 2007 08:50:38 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.core.formatter; import org.eclipse.jdt.internal.compiler.util.Util; +import org.eclipse.jface.text.IRegion; import org.eclipse.text.edits.TextEdit; /** @@ -86,6 +87,34 @@ */ public abstract TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator); + + /** + * Format source, + * and returns a text edit that correspond to the difference between the given string and the formatted string. + *

It returns null if the given string cannot be formatted.

+ * + *

If an offset position is matching a whitespace, the result can include whitespaces. It would be up to the + * caller to get rid of preceeding whitespaces.

+ * + *

No region in regions must overlap with any other region in regions. + * Each region must be within source. There must be at least on region.

+ * + * @param kind Use to specify the kind of the code snippet to format. It can be any of these: + * K_EXPRESSION, K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_COMPILATION_UNIT, K_UNKNOWN, + * K_SINGLE_LINE_COMMENT, K_MULTI_LINE_COMMENT, K_JAVA_DOC + * @param source the source to format + * @param regions a set of regions in source to format + * @param indentationLevel the initial indentation level, used + * to shift left/right the entire source fragment. An initial indentation + * level of zero or below has no effect. + * @param lineSeparator the line separator to use in formatted source, + * if set to null, then the platform default one will be used. + * @return the text edit + * @throws IllegalArgumentException if offset is lower than 0, length is lower than 0 or + * length is greater than source length. + */ + public abstract TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator); + /** * Answers the string that corresponds to the indentation to the given indentation level or an empty string * if the indentation cannot be computed.