mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[IndentDetector] CONTINUATION_WITHOUT_FIRST indent of the outermost block is treated as CONTINUATION, while the rest are treated as NONE
Every null indent retrieved from Block build by FormattingModelBuilder.buildBlocks is converted to CONTINUATION_WITHOUT_FIRST. Nested blocks starts the same offset and are retrieved as first block of it's parent that's why CONTINUATION_WITHOUT_FIRST works in such a case as NONE (because they are literally first blocks, see CWF javadoc)
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<Block start="0" end="50">
|
||||
<Indent type="NONE"/>
|
||||
<Block start="0" end="13">
|
||||
<Indent type="NONE"/>
|
||||
</Block>
|
||||
<Block start="18" end="35">
|
||||
<Indent type="NONE"/>
|
||||
<Block start="18" end="25">
|
||||
<Indent type="NORMAL"/>
|
||||
<Block start="18" end="25">
|
||||
<Indent type="NONE"/>
|
||||
<Block start="18" end="19"/>
|
||||
<Block start="20" end="25">
|
||||
<Indent type="NONE"/>
|
||||
</Block>
|
||||
</Block>
|
||||
</Block>
|
||||
<Block start="30" end="35">
|
||||
<Indent type="NORMAL"/>
|
||||
<Block start="30" end="35">
|
||||
<Indent type="NONE"/>
|
||||
<Block start="30" end="31"/>
|
||||
<Block start="32" end="35">
|
||||
<Indent type="NONE"/>
|
||||
</Block>
|
||||
</Block>
|
||||
</Block>
|
||||
</Block>
|
||||
<Block start="36" end="50">
|
||||
<Indent type="NONE"/>
|
||||
</Block>
|
||||
</Block>
|
||||
+22
-7
@@ -40,17 +40,32 @@ public class FormatterBasedLineInfoBuilderTest extends LightPlatformCodeInsightT
|
||||
String text = "/**\n" +
|
||||
" *\n" +
|
||||
" */";
|
||||
|
||||
|
||||
List<LineIndentInfo> infos = getLineInfos(text);
|
||||
assertLinesWithNormalIndent(infos, 0);
|
||||
}
|
||||
|
||||
public void testXmlContinuationWithoutFirst() throws IOException, JDOMException {
|
||||
String text = "<idea-plugin>\n" +
|
||||
" <name/>\n" +
|
||||
" <id/>\n" +
|
||||
"</idea-plugin>";
|
||||
|
||||
List<LineIndentInfo> infos = getLineInfos(text);
|
||||
assertLinesWithNormalIndent(infos, 4);
|
||||
}
|
||||
|
||||
private static void assertLinesWithNormalIndent(List<LineIndentInfo> infos, int expected) {
|
||||
long linesWithNormalIndent = infos.stream().filter(LineIndentInfo::isLineWithNormalIndent).count();
|
||||
assertEquals(expected, linesWithNormalIndent);
|
||||
}
|
||||
|
||||
private List<LineIndentInfo> 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<LineIndentInfo> infos = builder.build();
|
||||
long linesWithNormalIndents = infos.stream().filter(LineIndentInfo::isLineWithNormalIndent).count();
|
||||
assertEquals(0, linesWithNormalIndents);
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
+41
-12
@@ -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<Indent.Type> allIndents = getIndentOnStartOffset(block, range, startOffset);
|
||||
|
||||
if (hasOnlyNormalOrNoneIndents(allIndents)) {
|
||||
int normalIndents = ContainerUtil.filter(allIndents, new Condition<Indent.Type>() {
|
||||
@Override
|
||||
public boolean value(Indent.Type type) {
|
||||
return type == Indent.Type.NORMAL;
|
||||
}
|
||||
else {
|
||||
}).size();
|
||||
return normalIndents < 2;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasOnlyNormalOrNoneIndents(List<Indent.Type> indents) {
|
||||
Indent.Type outerMostIndent = indents.get(0);
|
||||
if (outerMostIndent != Indent.Type.NONE && outerMostIndent != Indent.Type.NORMAL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Indent.Type> 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<Indent.Type> getIndentOnStartOffset(Block block, TextRange range, int startOffset) {
|
||||
List<Indent.Type> indentsOnStartOffset = new ArrayList<Indent.Type>();
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user