From 55bb42dc0c946481ac89547fd6a0621f2dce68ce Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Tue, 22 Nov 2011 19:09:08 +0300 Subject: [PATCH] IDEA-76537 Detected invalid soft wraps recalculation Soft wraps cache is correctly flushed on complete recalculation --- .../impl/softwrap/mapping/CacheEntry.java | 6 ++-- .../mapping/CachingSoftWrapDataMapper.java | 9 +++++- .../mapping/SoftWrapApplianceManager.java | 3 ++ .../SoftWrapAwareDocumentParsingListener.java | 7 ++++- .../SoftWrapAwareVisualSizeManager.java | 6 +++- .../editor/impl/softwrap/mapping/TabData.java | 4 +-- ...apApplianceOnDocumentModificationTest.java | 31 +++++++++++++++++++ 7 files changed, 58 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java index 99adecc7a448..54890f9870aa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CacheEntry.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -228,8 +228,8 @@ class CacheEntry implements Comparable, Cloneable { @Override public String toString() { - return "visual line: " + visualLine + ", offsets: " + startOffset + "-" + endOffset + ", fold regions: " - + Arrays.toString(myFoldingData.getValues()) + ", tab data: " + myTabPositions; + return System.identityHashCode(this) + "=visual line: " + visualLine + ", offsets: " + startOffset + "-" + endOffset + + ", fold regions: " + Arrays.toString(myFoldingData.getValues()) + ", tab data: " + myTabPositions; } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java index 185cc3b330f7..5fd1d61f2769 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/CachingSoftWrapDataMapper.java @@ -482,6 +482,13 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw myBeforeChangeState.cacheShouldBeUpdated = false; } + @Override + public void reset() { + myCache.clear(); + myAffectedByUpdateCacheEntries.clear(); + myNotAffectedByUpdateTailCacheEntries.clear(); + } + @SuppressWarnings({"UseOfSystemOutOrSystemErr", "UnusedDeclaration", "CallToPrintStackTrace"}) private void dumpCache() { Document document = myEditor.getDocument(); @@ -542,7 +549,7 @@ public class CachingSoftWrapDataMapper implements SoftWrapDataMapper, SoftWrapAw int softWrapIndex = myStorage.getSoftWrapIndex(offset); if (softWrapIndex >= 0) { - softWrapIndex++; // We want to process only soft wraps which offsets strictly more than the given one. + softWrapIndex++; // We want to process only soft wraps which offsets are strictly more than the given one. } else { softWrapIndex = -softWrapIndex - 1; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java index d6056d23efc4..147f41506cd9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java @@ -118,6 +118,9 @@ public class SoftWrapApplianceManager implements SoftWrapFoldingListener, Docume public void reset() { myEventsStorage.release(); myEventsStorage.add(myEditor.getDocument(), new IncrementalCacheUpdateEvent(myEditor.getDocument())); + for (SoftWrapAwareDocumentParsingListener listener : myListeners) { + listener.reset(); + } } public void release() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareDocumentParsingListener.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareDocumentParsingListener.java index 32bcf2c183bf..c9f113db9ba2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareDocumentParsingListener.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareDocumentParsingListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,4 +120,9 @@ interface SoftWrapAwareDocumentParsingListener { * should be rolled back if this param value is false */ void onRecalculationEnd(@NotNull IncrementalCacheUpdateEvent event, boolean normal); + + /** + * Callback for asking to drop all cached information (if any). + */ + void reset(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java index c5a12ff59922..78c6579f6140 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapAwareVisualSizeManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,4 +120,8 @@ public class SoftWrapAwareVisualSizeManager implements SoftWrapAwareDocumentPars @Override public void revertToOffset(int offset, int visualLine) { } + + @Override + public void reset() { + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/TabData.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/TabData.java index 12e1fe06d551..f4e6adcabd45 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/TabData.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/TabData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ class TabData implements Cloneable { @Override public String toString() { - return offset + ", width: " + widthInColumns; + return "[" + offset + ", width: " + widthInColumns + "]"; } @Override diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java index 02b5343bf05e..1f6a4865e5c4 100644 --- a/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java +++ b/platform/platform-impl/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java @@ -817,6 +817,37 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP ((EditorImpl)myEditor).setPrefixTextAndAttributes(" ", new TextAttributes()); myEditor.getCaretModel().moveToOffset(text.length()); } + + public void testSoftWrapCacheReset() throws IOException { + // Inspired by IDEA-76537 - the point is to drop cached document info on complete soft wraps recalculation + String text = + "\t first line\n" + + "\t second line\n" + + "\t third line"; + + // Make soft wraps to build a document info cache. + init(300, text); + + // Modify document while soft wraps processing is off. + final EditorSettings settings = getEditor().getSettings(); + settings.setUseSoftWraps(false); + int startOffset = text.indexOf("\t third") - 1; + getEditor().getDocument().deleteString(startOffset, text.length()); + + // Enable soft wraps and ensure that the cache is correctly re-built. + settings.setUseSoftWraps(true); + + getEditor().getCaretModel().moveToOffset(getEditor().getDocument().getTextLength()); + type("\n test"); + + final int offset = getEditor().getDocument().getTextLength() - 1; + final LogicalPosition logicalPosition = getEditor().offsetToLogicalPosition(offset); + assertEquals(offset, getEditor().logicalPositionToOffset(logicalPosition)); + + final VisualPosition visualPosition = getEditor().offsetToVisualPosition(offset); + assertEquals(visualPosition, getEditor().logicalToVisualPosition(logicalPosition)); + assertEquals(logicalPosition, getEditor().visualToLogicalPosition(visualPosition)); + } private void init(final int visibleWidth, @NotNull String fileText) throws IOException { init(visibleWidth, fileText, TestFileType.TEXT);