Expandable indent storing additional block, which indent is used as min indent marker...
authorYaroslav Lepenkin <yaroslav.lepenkin@jetbrains.com>
Wed, 17 Jun 2015 09:53:37 +0000 (12:53 +0300)
committerYaroslav Lepenkin <yaroslav.lepenkin@jetbrains.com>
Wed, 2 Sep 2015 09:35:07 +0000 (12:35 +0300)
If all blocks corresponding to current expandable indent has no linefeeds in their whitespaces, if one of these blocks has child which has indent less or equal than min marker indent, than indent is expanded.

Total summary:
Indent is expanded, if any of blocks with these indent is located on new line, or when there is some block's children with indent less or equal than min marker indent.

java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
platform/lang-api/src/com/intellij/formatting/Indent.java
platform/lang-api/src/com/intellij/formatting/IndentFactory.java
platform/lang-impl/src/com/intellij/formatting/ExpandableIndent.java
platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java
platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java

index 53c3d3e73ae8e70b0ced50654eccec41dd1518e2..7c32ad77d1dc01cd27f1cd6312dc8eaba6939520 100644 (file)
@@ -867,9 +867,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
     Indent internalIndent = Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS);
 
     if (isInsideMethodCallParenthesis(child)) {
-      Object group = new Object();
-      externalIndent = Indent.getSmartIndentMinOffsetMarker(Indent.Type.NONE, group);
-      internalIndent = Indent.getSmartIndent(Indent.Type.CONTINUATION, group);
+      internalIndent = Indent.getSmartIndent(Indent.Type.CONTINUATION);
     }
 
     AlignmentStrategy alignmentStrategy = AlignmentStrategy.wrap(createAlignment(doAlign, null), JavaTokenType.COMMA);
@@ -904,11 +902,14 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
           result.add(createJavaBlock(child, mySettings, myJavaSettings, externalIndent, null, bracketAlignment));
         }
         else if (child.getElementType() == to) {
-          result.add(createJavaBlock(child, mySettings, myJavaSettings,
-                                     isAfterIncomplete && !afterAnonymousClass ? internalIndent : externalIndent,
-                                     null,
-                                     isAfterIncomplete ? alignmentStrategy.getAlignment(null) : bracketAlignment)
-          );
+          Block block = createJavaBlock(child, mySettings, myJavaSettings,
+                                        isAfterIncomplete && !afterAnonymousClass ? internalIndent : externalIndent,
+                                        null,
+                                        isAfterIncomplete ? alignmentStrategy.getAlignment(null) : bracketAlignment);
+          result.add(block);
+          if (internalIndent instanceof ExpandableIndent && to == JavaTokenType.RPARENTH) {
+            ((ExpandableIndent)internalIndent).setStrictMinOffsetBlock(block);
+          }
           return child;
         }
         else {
index 3cb9dace7bad4672b18960b6afa36aec92a68aaf..62f80608de9127d835a5801621fe5e3a03a5a977 100644 (file)
@@ -269,12 +269,8 @@ public abstract class Indent {
     return myFactory.getIndent(type, spaces, relativeToDirectParent, enforceIndentToChildren);
   }
 
-  public static Indent getSmartIndent(Type type, Object group) {
-    return myFactory.getSmartIndent(type, group);
-  }
-
-  public static Indent getSmartIndentMinOffsetMarker(Type type, Object group) {
-    return myFactory.getSmartIndentMinOffsetMarker(type, group);
+  public static Indent getSmartIndent(Type type) {
+    return myFactory.getSmartIndent(type);
   }
 
   public static class Type {
index 01afe5f03120c987a1ad15f07cb38141a46d1120..35d2d52d6aa5385f9819358b614bc838ed9e1984 100644 (file)
@@ -34,6 +34,5 @@ interface IndentFactory {
   Indent getSpaceIndent(final int spaces, boolean relativeToDirectParent);
   Indent getIndent(@NotNull Indent.Type type, boolean relativeToDirectParent, boolean enforceIndentToChildren);
   Indent getIndent(@NotNull Indent.Type type, int spaces, boolean relativeToDirectParent, boolean enforceIndentToChildren);
-  Indent getSmartIndent(@NotNull Indent.Type type, @NotNull Object group);
-  Indent getSmartIndentMinOffsetMarker(@NotNull Indent.Type type, @NotNull Object group);
+  Indent getSmartIndent(@NotNull Indent.Type type);
 }
index be049c53e3a59d163e2704b12d80c3b7d345d7a3..f14ac939cd09d6c36a2250eb6a40f13320ddfec7 100644 (file)
 package com.intellij.formatting;
 
 public class ExpandableIndent extends IndentImpl {
-
-  private final Object myGroup;
-  private boolean myMinGroupOffsetMarker;
+  private Block myStrictMinOffsetBlock;
   private boolean myEnforceIndent;
 
-  public ExpandableIndent(Type type, Object group) {
+  public ExpandableIndent(Type type) {
     super(type, false, 0, false, true);
-    myGroup = group;
     myEnforceIndent = false;
   }
 
-  public boolean isMinGroupOffsetMarker() {
-    return myMinGroupOffsetMarker;
-  }
-
-  void setMinGroupOffsetMarker(boolean value) {
-    myMinGroupOffsetMarker = value;
+  public void setStrictMinOffsetBlock(Block block) {
+    myStrictMinOffsetBlock = block;
   }
 
-  public Object getGroup() {
-    return myGroup;
+  Block getStrictMinOffsetBlock() {
+    return myStrictMinOffsetBlock;
   }
 
-
   @Override
   public boolean isEnforceIndentToChildren() {
     return myEnforceIndent;
index 698a1677f5abaf217961f3bc67e2fe5bff934558..8d157038435fb2d8ef56a9e86f390a7b5329dcc0 100644 (file)
@@ -159,7 +159,8 @@ public class FormatProcessor {
 
   @NotNull
   private State myCurrentState;
-  private MultiMap<Object, AbstractBlockWrapper> myExpandableIndents;
+  private MultiMap<ExpandableIndent, AbstractBlockWrapper> myExpandableIndents;
+  private Map<Block, AbstractBlockWrapper> myExpandableIndentsMinOffsetBlocksToWrappers;
 
   public FormatProcessor(final FormattingDocumentModel docModel,
                          Block rootBlock,
@@ -1365,7 +1366,9 @@ public class FormatProcessor {
         root, model, affectedRanges, mySettings, myDefaultIndentOption, interestingOffset, myProgressCallback
       );
       myWrapper.setCollectAlignmentsInsideFormattingRange(myReformatContext);
-      myExpandableIndents = myWrapper.getBlocksWithSmartIndents();
+
+      myExpandableIndents = myWrapper.getExpandableIndentsBlocks();
+      myExpandableIndentsMinOffsetBlocksToWrappers = myWrapper.getMarkerBlocks();
     }
 
     @Override
@@ -1590,9 +1593,8 @@ public class FormatProcessor {
     }
   }
 
-
   private class ExpandChildrenIndent extends State {
-    private Iterator<Object> myIterator;
+    private Iterator<ExpandableIndent> myIterator;
 
     public ExpandChildrenIndent() {
       super(FormattingStateId.EXPANDING_CHILDREN_INDENTS);
@@ -1608,11 +1610,10 @@ public class FormatProcessor {
         return;
       }
 
-      Collection<AbstractBlockWrapper> blocksToExpandIndent = myExpandableIndents.get(myIterator.next());
-
-      if (shouldExpand(blocksToExpandIndent)) {
+      final ExpandableIndent indent = myIterator.next();
+      Collection<AbstractBlockWrapper> blocksToExpandIndent = myExpandableIndents.get(indent);
+      if (shouldExpand(indent, blocksToExpandIndent)) {
         for (AbstractBlockWrapper block : blocksToExpandIndent) {
-          ExpandableIndent indent = (ExpandableIndent)block.getIndent();
           indent.setEnforceIndent(true);
           reindentNewLineChildren(block);
           indent.setEnforceIndent(false);
@@ -1620,28 +1621,20 @@ public class FormatProcessor {
       }
     }
 
-    private boolean shouldExpand(Collection<AbstractBlockWrapper> blocksToExpandIndent) {
-      int minGroupOffset = Integer.MAX_VALUE;
+    private boolean shouldExpand(ExpandableIndent indent, Collection<AbstractBlockWrapper> blocksToExpandIndent) {
       for (AbstractBlockWrapper block : blocksToExpandIndent) {
         if (!block.getWhiteSpace().containsLineFeeds()) continue;
-
-        ExpandableIndent indent = (ExpandableIndent)block.getIndent();
-        if (indent.isMinGroupOffsetMarker()) {
-          minGroupOffset = block.getNumberOfSymbolsBeforeBlock().getTotalSpaces();
-        }
-        else {
-          return true;
-        }
+        return true;
       }
 
-      if (minGroupOffset == Integer.MAX_VALUE) return false;
+      int strictMinOffset = getStrictMinOffset(indent);
+      if (strictMinOffset == Integer.MAX_VALUE) {
+        return false;
+      }
 
       for (AbstractBlockWrapper block : blocksToExpandIndent) {
-        ExpandableIndent indent = (ExpandableIndent)block.getIndent();
-        if (indent.isMinGroupOffsetMarker()) continue;
-
         int minNewLineChildrenOffset = findMinNewLineIndent(block);
-        if (minNewLineChildrenOffset <= minGroupOffset) {
+        if (minNewLineChildrenOffset <= strictMinOffset) {
           return true;
         }
       }
@@ -1649,6 +1642,18 @@ public class FormatProcessor {
       return false;
     }
 
+    private int getStrictMinOffset(ExpandableIndent indent) {
+      final Block minOffsetBlock = indent.getStrictMinOffsetBlock();
+      if (minOffsetBlock == null) return Integer.MAX_VALUE;
+
+      AbstractBlockWrapper wrapper = myExpandableIndentsMinOffsetBlocksToWrappers.get(minOffsetBlock);
+      if (wrapper.getWhiteSpace().containsLineFeeds()) {
+        return wrapper.getNumberOfSymbolsBeforeBlock().getTotalSpaces();
+      }
+
+      return Integer.MAX_VALUE;
+    }
+
     private int findMinNewLineIndent(@NotNull AbstractBlockWrapper block) {
       if (block instanceof LeafBlockWrapper && block.getWhiteSpace().containsLineFeeds()) {
         return block.getNumberOfSymbolsBeforeBlock().getTotalSpaces();
index e7e8cae906500ba1f2f5c3db0f47905a7dcb6741..f8dbc4ed53f9f00dc176dcd45a4272085b9ec2fa 100644 (file)
@@ -819,15 +819,8 @@ public class FormatterImpl extends FormatterEx
   }
 
   @Override
-  public Indent getSmartIndent(@NotNull Indent.Type type, @NotNull Object group) {
-    return new ExpandableIndent(type, group);
-  }
-
-  @Override
-  public Indent getSmartIndentMinOffsetMarker(@NotNull Indent.Type type, @NotNull Object group) {
-    ExpandableIndent indent = new ExpandableIndent(type, group);
-    indent.setMinGroupOffsetMarker(true);
-    return indent;
+  public Indent getSmartIndent(@NotNull Indent.Type type) {
+    return new ExpandableIndent(type);
   }
 
   @Override
index ba74eb8165da1f39e010e28ed6cd7b477c78f048..86a94d27ffccbd5066d1781fb67145579afbcb87 100644 (file)
@@ -76,7 +76,9 @@ class InitialInfoBuilder {
   private Set<Alignment> myAlignmentsInsideRangeToModify = ContainerUtil.newHashSet();
   private boolean myCollectAlignmentsInsideFormattingRange = false;
 
-  private MultiMap<Object, AbstractBlockWrapper> myBlocksToForceChildrenIndent = new LinkedMultiMap<Object, AbstractBlockWrapper>();
+  private Set<Block> myStrictMinOffsetBlocks = ContainerUtil.newHashSet();
+  private MultiMap<ExpandableIndent, AbstractBlockWrapper> myBlocksToForceChildrenIndent = new LinkedMultiMap<ExpandableIndent, AbstractBlockWrapper>();
+  private Map<Block, AbstractBlockWrapper> myMarkerIndentToBlock = ContainerUtil.newHashMap();
 
   private InitialInfoBuilder(final Block rootBlock,
                              final FormattingDocumentModel model,
@@ -289,10 +291,14 @@ class InitialInfoBuilder {
     return wrappedRootBlock;
   }
 
-  public MultiMap<Object, AbstractBlockWrapper> getBlocksWithSmartIndents() {
+  public MultiMap<ExpandableIndent, AbstractBlockWrapper> getExpandableIndentsBlocks() {
     return myBlocksToForceChildrenIndent;
   }
 
+  public Map<Block, AbstractBlockWrapper> getMarkerBlocks() {
+    return myMarkerIndentToBlock;
+  }
+
   private void doIteration(@NotNull State state) {
     List<Block> subBlocks = state.parentBlock.getSubBlocks();
     final int subBlocksCount = subBlocks.size();
@@ -311,11 +317,7 @@ class InitialInfoBuilder {
     final AbstractBlockWrapper wrapper = buildFrom(
       block, childBlockIndex, state.wrappedBlock, state.parentBlockWrap, state.parentBlock, childBlockIsRightBlock
     );
-
-    if (block.getIndent() instanceof ExpandableIndent) {
-      ExpandableIndent expandableIndent = (ExpandableIndent)block.getIndent();
-      myBlocksToForceChildrenIndent.putValue(expandableIndent.getGroup(), wrapper);
-    }
+    registerExpandableIndents(block, wrapper);
 
     if (wrapper.getIndent() == null) {
       wrapper.setIndent((IndentImpl)block.getIndent());
@@ -334,7 +336,22 @@ class InitialInfoBuilder {
       }
     }
   }
-  
+
+  private void registerExpandableIndents(@NotNull Block block, @NotNull AbstractBlockWrapper wrapper) {
+    ExpandableIndent expandableIndent = block.getIndent() instanceof ExpandableIndent ? ((ExpandableIndent)block.getIndent()) : null;
+    if (expandableIndent != null) {
+      myBlocksToForceChildrenIndent.putValue(expandableIndent, wrapper);
+      Block markerBlock = expandableIndent.getStrictMinOffsetBlock();
+      if (markerBlock != null) {
+        myStrictMinOffsetBlocks.add(markerBlock);
+      }
+    }
+
+    if (myStrictMinOffsetBlocks.contains(block)) {
+      myMarkerIndentToBlock.put(block, wrapper);
+    }
+  }
+
   private void setDefaultIndents(final List<AbstractBlockWrapper> list) {
     if (!list.isEmpty()) {
       for (AbstractBlockWrapper wrapper : list) {