Implemented simple check for alignment infinite recusrsion - we limit amount of backward block rollbacks (when we switch myCurrentBlock to some previously located block) to the number of total blocks with alignments.

This commit is contained in:
Yaroslav Lepenkin
2015-10-28 12:31:10 +03:00
parent b5c2a67327
commit c30e7b54e0
3 changed files with 24 additions and 2 deletions
@@ -135,7 +135,7 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP
*/
protected abstract int getAlignmentIndentDiff(@NotNull IndentData alignmentAnchorIndent, @NotNull Context context);
private static void reportAlignmentProcessingError(Context context) {
protected static void reportAlignmentProcessingError(Context context) {
ASTNode node = context.targetBlock.getNode();
Language language = node != null ? node.getPsi().getLanguage() : null;
LogMessageEx.error(LOG,
@@ -42,6 +42,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.intellij.formatting.AbstractBlockAlignmentProcessor.*;
public class FormatProcessor {
private static final Map<Alignment.Anchor, BlockAlignmentProcessor> ALIGNMENT_PROCESSORS =
@@ -160,6 +162,8 @@ public class FormatProcessor {
@NotNull
private State myCurrentState;
private MultiMap<ExpandableIndent, AbstractBlockWrapper> myExpandableIndents;
private int myTotalBlocksWithAlignments;
private int myBlockRollbacks;
public FormatProcessor(final FormattingDocumentModel docModel,
Block rootBlock,
@@ -752,7 +756,15 @@ public class FormatProcessor {
myBackwardShiftedAlignedBlocks.put(offsetResponsibleBlock, blocksCausedRealignment);
blocksCausedRealignment.add(myCurrentBlock);
storeAlignmentMapping(myCurrentBlock, offsetResponsibleBlock);
myCurrentBlock = offsetResponsibleBlock.getNextBlock();
if (myBlockRollbacks > myTotalBlocksWithAlignments) {
reportAlignmentProcessingError(context);
return true;
}
else {
myCurrentBlock = offsetResponsibleBlock.getNextBlock();
myBlockRollbacks++;
}
onCurrentLineChanged();
return false;
case RECURSION_DETECTED:
@@ -1398,6 +1410,7 @@ public class FormatProcessor {
myLastWhiteSpace = new WhiteSpace(lastBlockOffset, false);
myLastWhiteSpace.append(Math.max(lastBlockOffset, myWrapper.getEndOffset()), myModel, myDefaultIndentOption);
myAlignmentsInsideRangesToModify = myWrapper.getAlignmentsInsideRangeToModify();
myTotalBlocksWithAlignments = myWrapper.getBlocksToAlign().values().size();
}
}
@@ -77,6 +77,7 @@ class InitialInfoBuilder {
private boolean myCollectAlignmentsInsideFormattingRange = false;
private MultiMap<ExpandableIndent, AbstractBlockWrapper> myBlocksToForceChildrenIndent = new LinkedMultiMap<ExpandableIndent, AbstractBlockWrapper>();
private MultiMap<Alignment, Block> myBlocksToAlign = new MultiMap<Alignment, Block>();
private InitialInfoBuilder(final Block rootBlock,
final FormattingDocumentModel model,
@@ -205,6 +206,10 @@ class InitialInfoBuilder {
myAlignmentsInsideRangeToModify.add(rootBlock.getAlignment());
}
if (rootBlock.getAlignment() != null) {
myBlocksToAlign.putValue(rootBlock.getAlignment(), rootBlock);
}
ReadOnlyBlockInformationProvider previousProvider = myReadOnlyBlockInformationProvider;
try {
if (rootBlock instanceof ReadOnlyBlockInformationProvider) {
@@ -293,6 +298,10 @@ class InitialInfoBuilder {
return myBlocksToForceChildrenIndent;
}
public MultiMap<Alignment, Block> getBlocksToAlign() {
return myBlocksToAlign;
}
private void doIteration(@NotNull State state) {
List<Block> subBlocks = state.parentBlock.getSubBlocks();
final int subBlocksCount = subBlocks.size();