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 6512e3da33cb..fe6dcf2536f7 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 @@ -1281,16 +1281,13 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo public SyntheticCodeBlock createCodeBlockBlock(final List localResult, final Indent indent, final int childrenIndent) { final SyntheticCodeBlock result = new SyntheticCodeBlock(localResult, null, getSettings(), myJavaSettings, indent, null); result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(childrenIndent), null)); - return result; + return result; } @Nullable @Override public ExtraReformatRanges getExtraRangesToFormat(FormatTextRanges ranges) { - if (!Registry.is("smart.reformat.vcs.changes")) return null; - - int startOffset = getTextRange().getStartOffset(); - if (ranges.isOnInsertedLine(startOffset) && myNode.textContains('\n')) { + if (Registry.is("smart.reformat.vcs.changes") && ranges.isInsertedBlock(this) && myNode.textContains('\n')) { List extra = calculateExtraRanges(myNode); return new ExtraReformatRanges(extra); } @@ -1299,36 +1296,16 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo } @NotNull - private List calculateExtraRanges(ASTNode node) { - Project project = getProject(node); - Document document = retrieveDocument(node, project); - TextRange range = node.getTextRange(); + private List calculateExtraRanges(@NotNull ASTNode node) { + Document document = retrieveDocument(node, getProject(node)); if (document != null) { - int startLine = document.getLineNumber(range.getStartOffset()); - int endLine = document.getLineNumber(range.getEndOffset()); - return extractIndentSpaces(document, startLine, endLine); + TextRange ranges = node.getTextRange(); + return new IndentRangesCalculator(document, ranges).calcIndentRanges(); } 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(); diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/IndentRangesCalculator.kt b/java/java-impl/src/com/intellij/psi/formatter/java/IndentRangesCalculator.kt new file mode 100644 index 000000000000..7d0268db0804 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/formatter/java/IndentRangesCalculator.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java + +import com.intellij.openapi.editor.Document +import com.intellij.openapi.util.TextRange +import com.intellij.util.text.CharArrayUtil + +class IndentRangesCalculator(private val document: Document, + private val textRange: TextRange) +{ + private val startOffset = textRange.startOffset + private val endOffset = textRange.endOffset + + fun calcIndentRanges(): List { + val startLine = document.getLineNumber(startOffset) + val endLine = document.getLineNumber(endOffset) + val chars = document.charsSequence + + val indentRanges = mutableListOf() + + for (line in startLine..endLine) { + val lineStartOffset = document.getLineStartOffset(line) + val lineEndOffset = document.getLineEndOffset(line) + val firstNonWsChar = CharArrayUtil.shiftForward(chars, lineStartOffset, lineEndOffset + 1, " \t") + indentRanges.add(TextRange(lineStartOffset, firstNonWsChar)) + } + + return indentRanges + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentRangesCalculatorTest.kt b/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentRangesCalculatorTest.kt new file mode 100644 index 000000000000..50eed0444926 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentRangesCalculatorTest.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java + +import com.intellij.openapi.util.TextRange +import com.intellij.testFramework.LightPlatformCodeInsightTestCase +import org.assertj.core.api.Assertions.assertThat + +class IndentRangesCalculatorTest: LightPlatformCodeInsightTestCase() { + + fun `test simple ranges calculation`() { + configureFromFileText( + "test.txt", +"""class Test { + void foo() { + if (1 > 2) { + int a = 3; + } + } +} +""") + + val document = myEditor.document + val calculator = IndentRangesCalculator(document, TextRange(32, 67)) + val ranges = calculator.calcIndentRanges() + + assertThat(ranges).hasSize(3) + assertThat(ranges[0]).isEqualTo(TextRange(28, 32)) + assertThat(ranges[1]).isEqualTo(TextRange(45, 51)) + assertThat(ranges[2]).isEqualTo(TextRange(62, 66)) + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java b/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java index 1cd1501e9205..19027c1bb121 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatTextRanges.java @@ -84,8 +84,8 @@ public class FormatTextRanges { return "FormatTextRanges{" + StringUtil.join(myRanges, StringUtil.createToStringFunction(FormatTextRange.class), ","); } - //todo it should be more tricky - public boolean isOnInsertedLine(int offset) { + public boolean isInsertedBlock(Block block) { + int offset = block.getTextRange().getStartOffset(); return myHelper != null && myHelper.isOnInsertedLine(offset); }