From 6431fc6a554f9cc553657683f35835e7e115bae7 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 8 Nov 2017 09:56:28 +0100 Subject: [PATCH] IDEA-181267 Invalid ranges during formatting in Language: FTL> --- .../templateLanguages/BlockUtil.java | 100 ++++++++++++++++-- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/BlockUtil.java b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/BlockUtil.java index f5c3983d69ab..d11b5846fa4b 100644 --- a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/BlockUtil.java +++ b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/BlockUtil.java @@ -15,13 +15,11 @@ */ package com.intellij.formatting.templateLanguages; -import com.intellij.formatting.ASTBlock; -import com.intellij.formatting.Block; -import com.intellij.formatting.Indent; -import com.intellij.formatting.Spacing; +import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -148,8 +146,18 @@ class BlockUtil { } } else { - foreignBlocks.remove(fInd); - foreignBlocks.addAll(fInd, buildChildWrappers(f.getOriginal())); + Block original = f.getOriginal(); + List children = buildChildWrappers(original); + if (!children.isEmpty()) { + foreignBlocks.remove(fInd); + foreignBlocks.addAll(fInd, children); + } else { + result.addAll(splitLeafDataBlock(original, tlBlocks)); + fInd++; + while (vInd < tlBlocks.size() && tlBlocks.get(vInd).getTextRange().getEndOffset() < original.getTextRange().getEndOffset()) { + vInd++; + } + } } } } @@ -162,6 +170,86 @@ class BlockUtil { return result; } + private static List splitLeafDataBlock(Block block, List allTlBlocks) { + TextRange range = block.getTextRange(); + List coveredTlBlocks = ContainerUtil.filter(allTlBlocks, b -> range.contains(b.getTextRange().getStartOffset())); + + List result = new ArrayList<>(); + int dataStart = range.getStartOffset(); + for (TemplateLanguageBlock tlBlock : coveredTlBlocks) { + int dataEnd = tlBlock.getTextRange().getStartOffset(); + if (dataStart < dataEnd) { + result.add(createLeafFragmentBlock(dataStart, dataEnd)); + } + dataStart = tlBlock.getTextRange().getEndOffset(); + if (dataStart < range.getEndOffset()) { + result.add(tlBlock); + } + } + + if (dataStart < range.getEndOffset()) { + result.add(createLeafFragmentBlock(dataStart, range.getEndOffset())); + } + return result; + } + + @NotNull + private static Block createLeafFragmentBlock(int dataStart, int dataEnd) { + return new Block() { + @NotNull + @Override + public TextRange getTextRange() { + return TextRange.create(dataStart, dataEnd); + } + + @NotNull + @Override + public List getSubBlocks() { + return Collections.emptyList(); + } + + @Nullable + @Override + public Wrap getWrap() { + return null; + } + + @Nullable + @Override + public Indent getIndent() { + return null; + } + + @Nullable + @Override + public Alignment getAlignment() { + return null; + } + + @Nullable + @Override + public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { + return null; + } + + @NotNull + @Override + public ChildAttributes getChildAttributes(int newChildIndex) { + return ChildAttributes.DELEGATE_TO_NEXT_CHILD; + } + + @Override + public boolean isIncomplete() { + return true; + } + + @Override + public boolean isLeaf() { + return true; + } + }; + } + @NotNull public static List filterBlocksByRange(@NotNull List list, @NotNull TextRange textRange) { int i = 0;