### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.ui Index: core extension/org/eclipse/jdt/internal/corext/util/CodeFormatterUtil.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/CodeFormatterUtil.java,v retrieving revision 1.64 diff -u -r1.64 CodeFormatterUtil.java --- core extension/org/eclipse/jdt/internal/corext/util/CodeFormatterUtil.java 11 Jul 2007 12:47:17 -0000 1.64 +++ core extension/org/eclipse/jdt/internal/corext/util/CodeFormatterUtil.java 13 Sep 2007 15:37:22 -0000 @@ -18,6 +18,8 @@ import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; @@ -284,7 +286,7 @@ if (offset < 0 || length < 0 || offset + length > source.length()) { throw new IllegalArgumentException("offset or length outside of string. offset: " + offset + ", length: " + length + ", string size: " + source.length()); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } - return ToolFactory.createCodeFormatter(options, ToolFactory.M_FORMAT_EXISTING).format(kind, source, offset, length, indentationLevel, lineSeparator); + return reformat(kind, source, new IRegion[] {new Region(offset, length)}, indentationLevel, lineSeparator, options); } /** @@ -314,6 +316,14 @@ public static TextEdit reformat(int kind, String source, int indentationLevel, String lineSeparator, Map options) { return reformat(kind, source, 0, source.length(), indentationLevel, lineSeparator, options); } + + + public static TextEdit reformat(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeperator, Map options) { + if (regions.length == 0) + return null; + + return ToolFactory.createCodeFormatter(options, ToolFactory.M_FORMAT_EXISTING).format(kind, source, regions, indentationLevel, lineSeperator); + } /** * Creates edits that describe how to format the given string. #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 13 Sep 2007 15:37:24 -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,75 @@ 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) { + if (regions == null || regions.length == 0) { + throw new IllegalArgumentException(); + } + + 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[regions.length - 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 < regions.length; 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); } /** @@ -189,7 +231,7 @@ * @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 +255,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 +270,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 +280,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 +379,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 +387,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 +399,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 +413,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 +456,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 13 Sep 2007 15:37:24 -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 13 Sep 2007 15:37:24 -0000 @@ -25,6 +25,7 @@ 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.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; @@ -66,9 +67,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 +79,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 +96,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 +559,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 + 1); } } else { - edit = new MultiTextEdit(this.textRegionStart, this.textRegionEnd - this.textRegionStart + 1); + edit = new MultiTextEdit(textRegionStart, length); } for (int i= 0, max = this.editsIndex; i < max; i++) { OptimizedReplaceEdit currentEdit = edits[i]; @@ -664,7 +667,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 +680,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 +692,54 @@ } } 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 true; - } else if (editOffset == this.scannerEndPosition && editOffset == this.textRegionEnd + 1) { + + return false; + } + + IRegion covering= getCoveringRegion(editOffset, editOffset); + if (covering != null) { return true; + } + + + if (editOffset == this.scannerEndPosition) { + for (int i= 0; i < this.regions.length; i++) { + IRegion region= this.regions[i]; + if (editOffset == getRegionEnd(region) + 1) + return true; + } } return false; } + private IRegion getRegionAt(int offset) { + for (int i= 0; i < this.regions.length; i++) { + IRegion region= this.regions[i]; + if (region.getOffset() == offset) + return region; + } + return null; + } + + private IRegion getCoveringRegion(int offset, int end) { + for (int i= 0; i < this.regions.length; i++) { + IRegion region= this.regions[i]; + if (region.getOffset() <= offset && end <= getRegionEnd(region)) + return region; + } + return null; + } + + private int getRegionEnd(IRegion region) { + return region.getOffset() + region.getLength() - 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 13 Sep 2007 15:37:23 -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,33 @@ */ 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

+ * + * @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.