From d3b1c245f21180b7bbcb52e987cdb6346ece70c6 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Tue, 11 Sep 2012 16:22:51 +0400 Subject: [PATCH] IDEA-19061 Integrate the Rearranger-plugin into core-IDEA Preserve range markers on arrangement --- .../openapi/editor/impl/DocumentImpl.java | 3 +- .../arrangement/engine/ArrangementEngine.java | 62 ++++++++++--------- .../engine/ArrangementEntryWrapper.java | 15 ----- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index 559d2da1486a..adb7d1980af5 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -372,7 +372,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { assertBounds(srcStart, srcEnd); ProperTextRange srcRange = new ProperTextRange(srcStart, srcEnd); if (dstOffset == srcEnd) return; - assert !srcRange.containsOffset(dstOffset); + assert !srcRange.containsOffset(dstOffset) : + String.format("Can't perform text move from range [%d; %d) to offset %d", srcStart, srcEnd, dstOffset); //CharSequence replacement = getCharsSequence().subSequence(srcStart, srcEnd); String replacement = getCharsSequence().subSequence(srcStart, srcEnd).toString(); diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java index 3023e42590e4..2b6178bb0eca 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java @@ -322,15 +322,12 @@ public class ArrangementEngine { previous = wrapper; } Changer changer; - // TODO den remove - changer = new NormalChanger(); - // TODO den uncomment - //if (document instanceof DocumentEx) { - // changer = new RangeMarkerAwareChanger((DocumentEx)document); - //} - //else { - // changer = new NormalChanger(); - //} + if (document instanceof DocumentEx) { + changer = new RangeMarkerAwareChanger((DocumentEx)document); + } + else { + changer = new DefaultChanger(); + } return new Context(rearranger, wrappers, document, rules, settings, changer); } } @@ -365,7 +362,7 @@ public class ArrangementEngine { @NotNull Context context); } - private static class NormalChanger implements Changer { + private static class DefaultChanger implements Changer { @NotNull private String myParentText; private int myParentShift; @@ -463,7 +460,7 @@ public class ArrangementEngine { private static class RangeMarkerAwareChanger implements Changer { - @NotNull private final Set> myNotMoved = new HashSet>(); + @NotNull private final List> myWrappers = new ArrayList>(); @NotNull private final DocumentEx myDocument; RangeMarkerAwareChanger(@NotNull DocumentEx document) { @@ -472,8 +469,8 @@ public class ArrangementEngine { @Override public void prepare(@NotNull List> toArrange, @NotNull Context context) { - myNotMoved.clear(); - myNotMoved.addAll(toArrange); + myWrappers.clear(); + myWrappers.addAll(toArrange); for (ArrangementEntryWrapper wrapper : toArrange) { wrapper.updateBlankLines(myDocument); } @@ -503,28 +500,32 @@ public class ArrangementEngine { if (oldWrapper.getStartOffset() > newWrapper.getStartOffset()) { insertionOffset -= newWrapper.getEndOffset() - newWrapper.getStartOffset(); } - myDocument.moveText(newWrapper.getStartOffset(), newWrapper.getEndOffset(), oldWrapper.getStartOffset()); - newWrapper.placeBefore(oldWrapper); - myNotMoved.remove(newWrapper); - for (ArrangementEntryWrapper w : myNotMoved) { - if (w.getStartOffset() >= oldWrapper.getStartOffset() && w.getStartOffset() < newWrapper.getStartOffset()) { - w.applyShift(newWrapper.getEndOffset() - newWrapper.getStartOffset()); - } - else if (w.getStartOffset() < oldWrapper.getStartOffset() && w.getStartOffset() > newWrapper.getStartOffset()) { - w.applyShift(newWrapper.getStartOffset() - newWrapper.getEndOffset()); + if (newWrapper.getStartOffset() != oldWrapper.getStartOffset() || !newWrapper.equals(oldWrapper)) { + myDocument.moveText(newWrapper.getStartOffset(), newWrapper.getEndOffset(), oldWrapper.getStartOffset()); + for (int i = myWrappers.size() - 1; i >= 0; i--) { + ArrangementEntryWrapper w = myWrappers.get(i); + if (w == newWrapper) { + continue; + } + if (w.getStartOffset() >= oldWrapper.getStartOffset() && w.getStartOffset() < newWrapper.getStartOffset()) { + w.applyShift(newWrapper.getEndOffset() - newWrapper.getStartOffset()); + } + else if (w.getStartOffset() < oldWrapper.getStartOffset() && w.getStartOffset() > newWrapper.getStartOffset()) { + w.applyShift(newWrapper.getStartOffset() - newWrapper.getEndOffset()); + } } } if (desiredBlankLinesNumber >= 0 && lineFeedsDiff > 0) { myDocument.insertString(insertionOffset, StringUtil.repeat("\n", lineFeedsDiff)); - shiftOffsets(newWrapper, null, lineFeedsDiff); + shiftOffsets(lineFeedsDiff, insertionOffset); } if (desiredBlankLinesNumber >= 0 && lineFeedsDiff < 0) { // Cut exceeding blank lines. int replacementStartOffset = getBlankLineOffset(-lineFeedsDiff, insertionOffset); myDocument.deleteString(replacementStartOffset, insertionOffset); - shiftOffsets(oldWrapper, null, lineFeedsDiff); + shiftOffsets(replacementStartOffset - insertionOffset, insertionOffset); } // Update wrapper ranges. @@ -556,17 +557,18 @@ public class ArrangementEngine { CharSequence text = myDocument.getCharsSequence(); for (int i = myDocument.getLineStartOffset(startLine - 1) - 1; i >= 0; i = CharArrayUtil.lastIndexOf(text, "\n", i - 1)) { if (--blankLinesNumber <= 0) { - return i; + return i + 1; } } return 0; } - private static void shiftOffsets(@Nullable ArrangementEntryWrapper first, @Nullable ArrangementEntryWrapper last, int shift) { - if (first == null) { - return; - } - for (ArrangementEntryWrapper wrapper = first; wrapper != null && wrapper != last; wrapper = wrapper.getNext()) { + private void shiftOffsets(int shift, int changeOffset) { + for (int i = myWrappers.size() - 1; i >= 0; i--) { + ArrangementEntryWrapper wrapper = myWrappers.get(i); + if (wrapper.getStartOffset() < changeOffset) { + break; + } wrapper.applyShift(shift); } } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java index ffa269459054..a801774f5def 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java @@ -113,21 +113,6 @@ public class ArrangementEntryWrapper { return myNext; } - public void placeBefore(@NotNull ArrangementEntryWrapper anchor) { - if (myNext != null) { - myNext.setPrevious(myPrevious); - } - if (myPrevious != null) { - myPrevious.setNext(myNext); - } - setPrevious(anchor.getPrevious()); - if (myPrevious != null) { - myPrevious.setNext(this); - } - setNext(anchor); - anchor.setPrevious(this); - } - public int getBlankLinesBefore() { return myBlankLinesBefore; }