diff --git a/java/java-tests/testData/psi/autodetect/XmlContinuationWithoutFirst.xml b/java/java-tests/testData/psi/autodetect/XmlContinuationWithoutFirst.xml
new file mode 100644
index 000000000000..59deea200bf8
--- /dev/null
+++ b/java/java-tests/testData/psi/autodetect/XmlContinuationWithoutFirst.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineInfoBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineInfoBuilderTest.java
index 2c23dcf010e9..9e3a35d9291c 100644
--- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineInfoBuilderTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineInfoBuilderTest.java
@@ -40,17 +40,32 @@ public class FormatterBasedLineInfoBuilderTest extends LightPlatformCodeInsightT
String text = "/**\n" +
" *\n" +
" */";
-
+
+ List infos = getLineInfos(text);
+ assertLinesWithNormalIndent(infos, 0);
+ }
+
+ public void testXmlContinuationWithoutFirst() throws IOException, JDOMException {
+ String text = "\n" +
+ " \n" +
+ " \n" +
+ "";
+
+ List infos = getLineInfos(text);
+ assertLinesWithNormalIndent(infos, 4);
+ }
+
+ private static void assertLinesWithNormalIndent(List infos, int expected) {
+ long linesWithNormalIndent = infos.stream().filter(LineIndentInfo::isLineWithNormalIndent).count();
+ assertEquals(expected, linesWithNormalIndent);
+ }
+
+ private List getLineInfos(String text) throws IOException, JDOMException {
String file = getTestName(false) + ".xml";
-
TestFormattingModel model = new TestFormattingModel(text);
Document document = model.getDocument();
TestBlock block = new FormattingModelXmlReader(model).readTestBlock(getTestDataPath(), file);
-
FormatterBasedLineIndentInfoBuilder builder = new FormatterBasedLineIndentInfoBuilder(document, block);
-
- List infos = builder.build();
- long linesWithNormalIndents = infos.stream().filter(LineIndentInfo::isLineWithNormalIndent).count();
- assertEquals(0, linesWithNormalIndents);
+ return builder.build();
}
}
\ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineIndentInfoBuilder.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineIndentInfoBuilder.java
index 7b1069be480f..c2dcc49b328d 100644
--- a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineIndentInfoBuilder.java
+++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/FormatterBasedLineIndentInfoBuilder.java
@@ -19,6 +19,7 @@ import com.intellij.formatting.ASTBlock;
import com.intellij.formatting.Block;
import com.intellij.formatting.Indent;
import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiComment;
import com.intellij.psi.formatter.common.AbstractBlock;
@@ -58,7 +59,7 @@ public class FormatterBasedLineIndentInfoBuilder {
return LineIndentInfo.LINE_WITH_TABS;
}
- if (hasTotallyNormalOrNoneIndent(newLineBlock)) {
+ if (hasNormalIndent(newLineBlock)) {
return LineIndentInfo.newNormalIndent(blockStartOffset - lineStartOffset);
}
else {
@@ -68,22 +69,50 @@ public class FormatterBasedLineIndentInfoBuilder {
});
}
- private static boolean hasTotallyNormalOrNoneIndent(Block block) {
+ private static boolean hasNormalIndent(Block block) {
final TextRange range = block.getTextRange();
final int startOffset = range.getStartOffset();
-
- boolean startOffsetAlreadyHasNormalIndent = false;
-
- while (block != null && range.getStartOffset() == startOffset) {
- Indent.Type type = block.getIndent() != null ? block.getIndent().getType() : null;
-
- if (type == Indent.Type.NONE || type == Indent.Type.NORMAL && !startOffsetAlreadyHasNormalIndent) {
- startOffsetAlreadyHasNormalIndent = true;
+
+ List allIndents = getIndentOnStartOffset(block, range, startOffset);
+
+ if (hasOnlyNormalOrNoneIndents(allIndents)) {
+ int normalIndents = ContainerUtil.filter(allIndents, new Condition() {
+ @Override
+ public boolean value(Indent.Type type) {
+ return type == Indent.Type.NORMAL;
}
- else {
+ }).size();
+ return normalIndents < 2;
+ }
+
+ return false;
+ }
+
+ private static boolean hasOnlyNormalOrNoneIndents(List indents) {
+ Indent.Type outerMostIndent = indents.get(0);
+ if (outerMostIndent != Indent.Type.NONE && outerMostIndent != Indent.Type.NORMAL) {
+ return false;
+ }
+
+ List innerIndents = indents.subList(1, indents.size());
+ for (Indent.Type indent : innerIndents) {
+ if (indent != Indent.Type.NONE && indent != Indent.Type.NORMAL
+ && indent != Indent.Type.CONTINUATION_WITHOUT_FIRST) {
+ //continuation without first here because it is CONTINUATION only if it's owner is not the first child
return false;
}
+ }
+ return true;
+ }
+
+ private static List getIndentOnStartOffset(Block block, TextRange range, int startOffset) {
+ List indentsOnStartOffset = new ArrayList();
+
+ while (block != null && range.getStartOffset() == startOffset) {
+ Indent.Type type = block.getIndent() != null ? block.getIndent().getType() : Indent.Type.CONTINUATION_WITHOUT_FIRST;
+ indentsOnStartOffset.add(type);
+
if (block instanceof AbstractBlock) {
((AbstractBlock)block).setBuildIndentsOnly(true);
}
@@ -91,7 +120,7 @@ public class FormatterBasedLineIndentInfoBuilder {
block = subBlocks.isEmpty() ? null : subBlocks.get(0);
}
- return true;
+ return indentsOnStartOffset;
}
@NotNull