diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/CodeFormatter.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/CodeFormatter.java
index 0ad5f9b5e16..3186172f93a 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/CodeFormatter.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/CodeFormatter.java
@@ -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 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.
+ * Formats 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 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 source
, 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 null
.
+ *
+ * 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 null
, 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
*/
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CCodeFormatter.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CCodeFormatter.java
index 12a08dbb697..bdc678c626a 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CCodeFormatter.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CCodeFormatter.java
@@ -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("", 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;
+ }
}