1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Added a method for formatting multiple regions in a single call.

This commit is contained in:
Sergey Prigogin 2011-11-07 10:57:47 -08:00
parent a3dd649914
commit 65673a50e1
2 changed files with 113 additions and 9 deletions

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.core.formatter;
import java.util.Map;
import org.eclipse.jface.text.IRegion;
import org.eclipse.text.edits.TextEdit;
/**
@ -64,15 +65,15 @@ public abstract class CodeFormatter {
public static final int K_MULTI_LINE_COMMENT = 0x20;
/**
* Format <code>source</code>,
* 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.
* Formats <code>source</code>, 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 the offset position is matching a whitespace, the result can include whitespaces.
* It would be up to the caller to get rid of preceding whitespaces.
*
* @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_TRANSLATION_UNIT, K_UNKNOWN
* K_EXPRESSION, K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_TRANSLATION_UNIT, K_UNKNOWN
* @param source the document to format
* @param offset the given offset to start recording the edits (inclusive).
* @param length the given length to stop recording the edits (exclusive).
@ -87,7 +88,36 @@ public abstract class CodeFormatter {
*/
public abstract TextEdit format(int kind, String source, int offset, int length,
int indentationLevel, String lineSeparator);
/**
* Formats one or more regions of <code>source</code>, and returns an array of edits, one edit
* per region. If some of the regions cannot be formatted, the corresponding elements of
* the returned array will be <code>null</code>.
*
* If the offset of a region is matching a whitespace, the result can include whitespaces.
* It would be up to the caller to get rid of preceding whitespaces.
*
* Subclasses may override this method to provide a more efficient implementation.
*
* @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_TRANSLATION_UNIT, K_UNKNOWN.
* @param source the document to format.
* @param regions regions of the source to be formatted.
* @param lineSeparator the line separator to use in formatted source,
* if set to <code>null</code>, then the platform default one will be used.
* @return the text edits, one per region.
* @throws IllegalArgumentException if any of the regions is invalid.
* @since 5.4
*/
public TextEdit[] format(int kind, String source, IRegion[] regions, String lineSeparator) {
TextEdit[] edits = new TextEdit[regions.length];
for (int i = 0; i < regions.length; i++) {
IRegion region = regions[i];
edits[i] = format(kind, source, region.getOffset(), region.getLength(), 0, lineSeparator);
}
return edits;
}
/**
* @param options - general formatter options
*/

View file

@ -7,7 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Sergey Prigogin, Google
* Sergey Prigogin (Google)
* Anton Leherbauer (Wind River Systems)
* IBM Corporation
*******************************************************************************/
@ -34,6 +34,7 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.jface.text.IRegion;
public class CCodeFormatter extends CodeFormatter {
private DefaultCodeFormatterOptions preferences;
@ -117,9 +118,6 @@ public class CCodeFormatter extends CodeFormatter {
}
}
/*
* @see org.eclipse.cdt.core.formatter.CodeFormatter#format(int, java.lang.String, int, int, int, java.lang.String)
*/
@Override
public TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator) {
TextEdit edit= null;
@ -188,4 +186,80 @@ public class CCodeFormatter extends CodeFormatter {
}
return edit;
}
@Override
public TextEdit[] format(int kind, String source, IRegion[] regions, String lineSeparator) {
TextEdit[] edits= new TextEdit[regions.length];
ITranslationUnit tu= (ITranslationUnit) options.get(DefaultCodeFormatterConstants.FORMATTER_TRANSLATION_UNIT);
if (tu == null) {
IFile file= (IFile) options.get(DefaultCodeFormatterConstants.FORMATTER_CURRENT_FILE);
if (file != null) {
tu= (ITranslationUnit) CoreModel.getDefault().create(file);
}
}
if (lineSeparator != null) {
preferences.line_separator = lineSeparator;
} else {
preferences.line_separator = System.getProperty("line.separator"); //$NON-NLS-1$
}
if (tu != null) {
IIndex index;
try {
index = CCorePlugin.getIndexManager().getIndex(tu.getCProject());
index.acquireReadLock();
} catch (CoreException e) {
throw new AbortFormatting(e);
} catch (InterruptedException e) {
return null;
}
IASTTranslationUnit ast;
try {
try {
ast= tu.getAST(index, ITranslationUnit.AST_SKIP_ALL_HEADERS);
} catch (CoreException exc) {
throw new AbortFormatting(exc);
}
for (int i = 0; i < regions.length; i++) {
IRegion region = regions[i];
CodeFormatterVisitor codeFormatter =
new CodeFormatterVisitor(preferences, region.getOffset(), region.getLength());
edits[i] = codeFormatter.format(source, ast);
IStatus status= codeFormatter.getStatus();
if (!status.isOK()) {
CCorePlugin.log(status);
}
}
} finally {
index.releaseReadLock();
}
} else {
IncludeFileContentProvider contentProvider = IncludeFileContentProvider.getSavedFilesProvider();
IScannerInfo scanInfo = new ScannerInfo();
FileContent content = FileContent.create("<text>", source.toCharArray()); //$NON-NLS-1$
ILanguage language= (ILanguage) options.get(DefaultCodeFormatterConstants.FORMATTER_LANGUAGE);
if (language == null) {
language= GPPLanguage.getDefault();
}
IASTTranslationUnit ast;
try {
ast= language.getASTTranslationUnit(content, scanInfo, contentProvider, null, 0,
ParserUtil.getParserLogService());
for (int i = 0; i < regions.length; i++) {
IRegion region = regions[i];
CodeFormatterVisitor codeFormatter =
new CodeFormatterVisitor(preferences, region.getOffset(), region.getLength());
edits[i]= codeFormatter.format(source, ast);
IStatus status= codeFormatter.getStatus();
if (!status.isOK()) {
CCorePlugin.log(status);
}
}
} catch (CoreException e) {
throw new AbortFormatting(e);
}
}
return edits;
}
}