From 3a3b59467679182d0fc4efc64e24bebfeb644926 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Wed, 29 Jun 2016 15:15:08 +0300 Subject: [PATCH] [java-formatter] extra ranges calculation generified --- .../psi/formatter/java/AbstractJavaBlock.java | 52 +++++++++++++++++-- .../intellij/formatting/FormatTextRanges.java | 1 + 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 60ee49a540a7..6512e3da33cb 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -19,6 +19,8 @@ import com.intellij.formatting.*; import com.intellij.formatting.alignment.AlignmentStrategy; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; @@ -1288,13 +1290,53 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo if (!Registry.is("smart.reformat.vcs.changes")) return null; int startOffset = getTextRange().getStartOffset(); - if (ranges.isOnInsertedLine(startOffset)) { - if (myNode instanceof PsiForStatement || myNode instanceof PsiIfStatement || myNode instanceof PsiWhileStatement) { - return new ExtraReformatRanges(myNode.getTextRange()); - } + if (ranges.isOnInsertedLine(startOffset) && myNode.textContains('\n')) { + List extra = calculateExtraRanges(myNode); + return new ExtraReformatRanges(extra); } return null; } - + + @NotNull + private List calculateExtraRanges(ASTNode node) { + Project project = getProject(node); + Document document = retrieveDocument(node, project); + TextRange range = node.getTextRange(); + if (document != null) { + int startLine = document.getLineNumber(range.getStartOffset()); + int endLine = document.getLineNumber(range.getEndOffset()); + return extractIndentSpaces(document, startLine, endLine); + } + + return ContainerUtil.newArrayList(myNode.getTextRange()); + } + + private static List extractIndentSpaces(Document document, int startLine, int endLine) { + List extra = ContainerUtil.newArrayList(); + + CharSequence chars = document.getCharsSequence(); + + for (int line = startLine + 1; line <= endLine; line++) { + int lineStartOffset = document.getLineStartOffset(line); + int lineEndOffset = document.getLineEndOffset(line); + + int firstNonWsChar = CharArrayUtil.shiftForward(chars, lineStartOffset, lineEndOffset + 1, " \t"); + if (firstNonWsChar <= lineEndOffset + 1) { + extra.add(new TextRange(lineStartOffset, firstNonWsChar)); + } + } + + return extra; + } + + private static Document retrieveDocument(@NotNull ASTNode node, @NotNull Project project) { + PsiFile file = node.getPsi().getContainingFile(); + return PsiDocumentManager.getInstance(project).getDocument(file); + } + + @NotNull + private static Project getProject(@NotNull ASTNode node) { + return node.getPsi().getProject(); + } } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java b/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java index aff4a41f0d18..1cd1501e9205 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java @@ -84,6 +84,7 @@ public class FormatTextRanges { return "FormatTextRanges{" + StringUtil.join(myRanges, StringUtil.createToStringFunction(FormatTextRange.class), ","); } + //todo it should be more tricky public boolean isOnInsertedLine(int offset) { return myHelper != null && myHelper.isOnInsertedLine(offset); }