diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java index 3f6fea8a1ba1..ac7777c49cd1 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java @@ -23,27 +23,23 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * A range marker that has to be manually updated with {@link #getUpdatedRange(DocumentEvent)} and {@link #applyState(ManualRangeMarker)}. + * A range marker that has to be manually updated with {@link #getUpdatedRange(DocumentEvent)}. * Can hold PSI-based range and be updated when the document is committed. */ public class ManualRangeMarker { - private static int ourCount = 0; - - private ProperTextRange myRange; - private boolean myValid = true; + private final ProperTextRange myRange; private final boolean myGreedyLeft; private final boolean myGreedyRight; - @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") private final int myHash = ourCount++; - private PersistentRangeMarker.LinesCols myLinesCols; + private final PersistentRangeMarker.LinesCols myLinesCols; public ManualRangeMarker(@NotNull FrozenDocument document, @NotNull ProperTextRange range, boolean greedyLeft, boolean greedyRight, boolean surviveOnExternalChange) { this(range, greedyLeft, greedyRight, surviveOnExternalChange ? PersistentRangeMarker.storeLinesAndCols(range, document) : null); } - private ManualRangeMarker(ProperTextRange range, - boolean greedyLeft, - boolean greedyRight, - PersistentRangeMarker.LinesCols linesCols) { + private ManualRangeMarker(@NotNull ProperTextRange range, + boolean greedyLeft, + boolean greedyRight, + @Nullable PersistentRangeMarker.LinesCols linesCols) { myRange = range; myGreedyLeft = greedyLeft; myGreedyRight = greedyRight; @@ -52,67 +48,32 @@ public class ManualRangeMarker { @Nullable public ManualRangeMarker getUpdatedRange(@NotNull DocumentEvent event) { - Pair pair = getUpdatedState(event); - return pair == null ? null : new ManualRangeMarker(pair.first, myGreedyLeft, myGreedyRight, pair.second); - } - - @Nullable - private Pair getUpdatedState(@NotNull DocumentEvent event) { if (event instanceof RetargetRangeMarkers) { int start = ((RetargetRangeMarkers)event).getStartOffset(); if (myRange.getStartOffset() >= start && myRange.getEndOffset() <= ((RetargetRangeMarkers)event).getEndOffset()) { ProperTextRange range = myRange.shiftRight(((RetargetRangeMarkers)event).getMoveDestinationOffset() - start); - return Pair.create(range, myLinesCols == null ? null : PersistentRangeMarker.storeLinesAndCols(range, event.getDocument())); + return new ManualRangeMarker(range, myGreedyLeft, myGreedyRight, myLinesCols == null ? null : PersistentRangeMarker.storeLinesAndCols(range, event.getDocument())); } } if (myLinesCols != null) { - return PersistentRangeMarker + Pair pair = PersistentRangeMarker .applyChange(event, myRange, myRange.getStartOffset(), myRange.getEndOffset(), myGreedyLeft, myGreedyRight, myLinesCols); + return pair == null ? null : new ManualRangeMarker(pair.first, myGreedyLeft, myGreedyRight, pair.second); } ProperTextRange range = RangeMarkerImpl.applyChange(event, myRange.getStartOffset(), myRange.getEndOffset(), myGreedyLeft, myGreedyRight); - return range == null ? null : new Pair(range, null); + return range == null ? null : new ManualRangeMarker(range, myGreedyLeft, myGreedyRight, null); } - public void applyState(@Nullable ManualRangeMarker updated) { - if (updated == null || !updated.myValid) { - myValid = false; - } - if (!myValid) return; - - myRange = updated.myRange; - myLinesCols = updated.myLinesCols; - } - - public boolean isGreedyLeft() { - return myGreedyLeft; - } - - public boolean isGreedyRight() { - return myGreedyRight; - } - - public boolean isSurviveOnExternalChange() { - return myLinesCols != null; - } - - @Nullable + @NotNull public ProperTextRange getRange() { - return myValid ? myRange : null; - } - - public boolean isValid() { - return myValid; + return myRange; } @Override public String toString() { - return "ManualRangeMarker" + (myValid ? myRange.toString() : " invalid"); + return "ManualRangeMarker" + myRange; } - @Override - public int hashCode() { - return myHash; - } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index 4a07a77c486a..889b6e06b12b 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -317,6 +317,12 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen final boolean synchronously) { if (myProject.isDisposed()) return false; assert !(document instanceof DocumentWindow); + + VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); + if (virtualFile != null) { + ((SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject)).fastenBelts(virtualFile); + } + myIsCommitInProgress = true; boolean success = true; try { @@ -635,9 +641,6 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen if (document instanceof DocumentImpl && !myUncommittedInfos.containsKey(document)) { myUncommittedInfos.put(document, new UncommittedInfo((DocumentImpl)document)); - if (isRelevant) { - ((SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject)).fastenBelts(virtualFile); - } } final FileViewProvider viewProvider = getCachedViewProvider(document); @@ -769,7 +772,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen UncommittedInfo info = myUncommittedInfos.remove(document); if (info != null) { ((SmartPointerManagerImpl)SmartPointerManager.getInstance(myProject)).updatePointers(document, info.myFrozen, info.myEvents); - Disposer.dispose(info); + info.removeListener(); } return info; } @@ -845,7 +848,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen @VisibleForTesting public void clearUncommittedDocuments() { for (UncommittedInfo info : myUncommittedInfos.values()) { - Disposer.dispose(info); + info.removeListener(); } myUncommittedInfos.clear(); myUncommittedDocuments.clear(); @@ -892,7 +895,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen return mySynchronizer; } - private static class UncommittedInfo extends DocumentAdapter implements PrioritizedInternalDocumentListener, Disposable { + private static class UncommittedInfo extends DocumentAdapter implements PrioritizedInternalDocumentListener { final DocumentImpl myOriginal; final FrozenDocument myFrozen; final List myEvents = ContainerUtil.newArrayList(); @@ -900,7 +903,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen public UncommittedInfo(DocumentImpl original) { myOriginal = original; myFrozen = original.freeze(); - myOriginal.addDocumentListener(this, this); + myOriginal.addDocumentListener(this); } @Override @@ -918,8 +921,8 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen myEvents.add(new RetargetRangeMarkers(myOriginal, start, end, base)); } - @Override - public void dispose() { + public void removeListener() { + myOriginal.removeDocumentListener(this); } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java index 8dc4ed960ba7..02db4af8a8c6 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java @@ -123,7 +123,8 @@ class AnchorElementInfo extends SelfElementInfo { // switch to tree myStubElementTypeAndId = pack(-1, null); PsiElement anchor = AnchorElementInfoFactory.getAnchor(element); - setRange((anchor == null ? element : anchor).getTextRange(), document); + TextRange range = (anchor == null ? element : anchor).getTextRange(); + setRange(ProperTextRange.create(range)); } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java index 35376b3f18c2..4509f4555633 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java @@ -24,65 +24,39 @@ import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.Trinity; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.WeakHashMap; -import com.intellij.util.containers.WeakValueHashMap; +import gnu.trove.TLongObjectHashMap; +import gnu.trove.TLongObjectProcedure; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; -import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Set; /** * @author peter */ class MarkerCache { - private final Set myMarkerSet = Collections.newSetFromMap(new WeakHashMap()); - private WeakValueHashMap myByRange = new WeakValueHashMap(); - private volatile Trinity, FrozenDocument> myUpdatedRanges; + private final SmartPointerManagerImpl.FilePointersList myPointers; + private volatile Trinity, FrozenDocument> myUpdatedRanges; - @Nullable - private static RangeKey keyOf(@NotNull ManualRangeMarker marker) { - ProperTextRange range = marker.getRange(); - return range == null ? null : new RangeKey(range, marker.isGreedyLeft(), marker.isGreedyRight(), marker.isSurviveOnExternalChange()); + MarkerCache(SmartPointerManagerImpl.FilePointersList pointers) { + myPointers = pointers; } - @NotNull - synchronized ManualRangeMarker obtainMarker(@NotNull ProperTextRange range, @NotNull FrozenDocument frozen, boolean greedyLeft, boolean greedyRight, boolean persistent) { - WeakValueHashMap byRange = getByRangeCache(); - RangeKey key = new RangeKey(range, greedyLeft, greedyRight, persistent); - ManualRangeMarker marker = byRange.get(key); - if (marker == null) { - marker = new ManualRangeMarker(frozen, range, greedyLeft, greedyRight, persistent); - myMarkerSet.add(marker); - byRange.put(key, marker); - myUpdatedRanges = null; - } - return marker; + private static long keyOf(@NotNull ProperTextRange range, boolean forInjected) { + long start = range.getStartOffset(); + assert start >= 0; + assert start < Integer.MAX_VALUE; + + long packed = (start + 1) | ((long)range.getEndOffset() << 32); + assert packed > 0; + return forInjected ? -packed : packed; } - private WeakValueHashMap getByRangeCache() { - if (myByRange == null) { - myByRange = new WeakValueHashMap(); - for (ManualRangeMarker marker : myMarkerSet) { - RangeKey key = keyOf(marker); - if (key != null) { - myByRange.put(key, marker); - } - } - } - return myByRange; - } - - private Map getUpdatedMarkers(@NotNull FrozenDocument frozen, @NotNull List events) { - if (myMarkerSet.isEmpty()) return Collections.emptyMap(); - + private TLongObjectHashMap getUpdatedMarkers(@NotNull FrozenDocument frozen, @NotNull List events) { int eventCount = events.size(); assert eventCount > 0; - Trinity, FrozenDocument> cache = myUpdatedRanges; + Trinity, FrozenDocument> cache = myUpdatedRanges; if (cache != null && cache.first.intValue() == eventCount) return cache.second; //noinspection SynchronizeOnThis @@ -90,17 +64,19 @@ class MarkerCache { cache = myUpdatedRanges; if (cache != null && cache.first.intValue() == eventCount) return cache.second; - Map answer = ContainerUtil.newHashMap(); + TLongObjectHashMap answer; if (cache != null && cache.first < eventCount) { // apply only the new events - answer.putAll(cache.second); + answer = cache.second.clone(); frozen = applyEvents(cache.third, events.subList(cache.first, eventCount), answer); } else { - for (ManualRangeMarker marker : myMarkerSet) { - RangeKey key = keyOf(marker); - if (key != null) { - answer.put(key, marker); + answer = new TLongObjectHashMap(); + for (SelfElementInfo info : getInfos()) { + ProperTextRange range = info.getPsiRange(); + if (range != null) { + boolean forInjected = info.isForInjected(); + answer.put(keyOf(range, forInjected), new ManualRangeMarker(frozen, range, forInjected, forInjected, !forInjected)); } } frozen = applyEvents(frozen, events, answer); @@ -112,10 +88,10 @@ class MarkerCache { } private static FrozenDocument applyEvents(@NotNull FrozenDocument frozen, - @NotNull List events, - Map map) { + @NotNull List events, + final TLongObjectHashMap map) { for (DocumentEvent event : events) { - DocumentEvent corrected; + final DocumentEvent corrected; if ((event instanceof RetargetRangeMarkers)) { RetargetRangeMarkers retarget = (RetargetRangeMarkers)event; corrected = new RetargetRangeMarkers(frozen, retarget.getStartOffset(), retarget.getEndOffset(), retarget.getMoveDestinationOffset()); @@ -126,102 +102,55 @@ class MarkerCache { event.isWholeTextReplaced()); } - for (Map.Entry entry : map.entrySet()) { - ManualRangeMarker currentRange = entry.getValue(); - if (currentRange != null) { - entry.setValue(currentRange.getUpdatedRange(corrected)); + map.forEachEntry(new TLongObjectProcedure() { + @Override + public boolean execute(long key, ManualRangeMarker currentRange) { + if (currentRange != null) { + map.put(key, currentRange.getUpdatedRange(corrected)); + } + return true; } - } + }); } return frozen; } - synchronized void updateMarkers(@NotNull FrozenDocument frozen, @NotNull List events, @NotNull List pointers) { - List infos = ContainerUtil.findAll(ContainerUtil.map(pointers, new NullableFunction() { - @Nullable - @Override - public SmartPointerElementInfo fun(SmartPsiElementPointerImpl pointer) { - return pointer.getElementInfo(); - } - }), SelfElementInfo.class); + synchronized void updateMarkers(@NotNull FrozenDocument frozen, @NotNull List events) { + TLongObjectHashMap updated = getUpdatedMarkers(frozen, events); - Map updated = getUpdatedMarkers(frozen, events); - Map newStates = ContainerUtil.newHashMap(); - for (SelfElementInfo info : infos) { - ManualRangeMarker marker = info.getRangeMarker(); - RangeKey key = marker == null ? null : keyOf(marker); - if (key != null) { - newStates.put(marker, updated.get(key)); + for (SelfElementInfo info : getInfos()) { + ProperTextRange range = info.getPsiRange(); + if (range != null) { + ManualRangeMarker newRange = updated.get(keyOf(range, info.isForInjected())); + info.setRange(newRange == null ? null : newRange.getRange()); } } - myMarkerSet.clear(); - for (Map.Entry entry : newStates.entrySet()) { - ManualRangeMarker marker = entry.getKey(); - marker.applyState(entry.getValue()); - if (marker.isValid()) { - myMarkerSet.add(marker); //re-add only alive markers - } - } - myByRange = null; myUpdatedRanges = null; + } - for (SelfElementInfo info : infos) { - info.updateValidity(); - } + @NotNull + private List getInfos() { + return ContainerUtil.findAll(ContainerUtil.map(myPointers.getAlivePointers(), new NullableFunction() { + @Override + public SmartPointerElementInfo fun(SmartPsiElementPointerImpl pointer) { + return pointer.getElementInfo(); + } + }), SelfElementInfo.class); } @Nullable - ProperTextRange getUpdatedRange(@NotNull ManualRangeMarker marker, @NotNull FrozenDocument frozen, @NotNull List events) { - ManualRangeMarker updated = getUpdatedMarkers(frozen, events).get(keyOf(marker)); + ProperTextRange getUpdatedRange(SelfElementInfo info, @NotNull FrozenDocument frozen, @NotNull List events) { + ProperTextRange range = info.getPsiRange(); + if (range == null) return null; + + ManualRangeMarker updated = getUpdatedMarkers(frozen, events).get(keyOf(range, info.isForInjected())); return updated == null ? null : updated.getRange(); } - @TestOnly - synchronized int getMarkerCount() { - return myMarkerSet.size(); - } - - private static class RangeKey { - final int start; - final int end; - final int flags; - - RangeKey(ProperTextRange range, boolean greedyLeft, boolean greedyRight, boolean persistent) { - start = range.getStartOffset(); - end = range.getEndOffset(); - flags = (persistent ? 4 : 0) + (greedyLeft ? 2 : 0) + (greedyRight ? 1 : 0); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof RangeKey)) return false; - - RangeKey key = (RangeKey)o; - - if (start != key.start) return false; - if (end != key.end) return false; - if (flags != key.flags) return false; - - return true; - } - - @Override - public int hashCode() { - int result = start; - result = 31 * result + end; - result = 31 * result + flags; - return result; - } - - @Override - public String toString() { - return "RangeKey{" + - "start=" + start + - ", end=" + end + - ", flags=" + flags + - '}'; + synchronized void rangeChanged(@NotNull ProperTextRange range, boolean forInjected) { + if (myUpdatedRanges != null && !myUpdatedRanges.second.contains(keyOf(range, forInjected))) { + myUpdatedRanges = null; } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index d0c9efa94d10..2446d6c3e84c 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -17,11 +17,8 @@ package com.intellij.psi.impl.smartPointers; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.editor.impl.FrozenDocument; -import com.intellij.openapi.editor.impl.ManualRangeMarker; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; @@ -37,7 +34,6 @@ import java.util.List; * User: cdr */ public class SelfElementInfo extends SmartPointerElementInfo { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SelfElementInfo"); private static final FileDocumentManager ourFileDocManager = FileDocumentManager.getInstance(); @NotNull private final VirtualFile myVirtualFile; private final Class myType; @@ -45,7 +41,6 @@ public class SelfElementInfo extends SmartPointerElementInfo { private final Language myLanguage; private final MarkerCache myMarkerCache; private final boolean myForInjected; - @Nullable private ManualRangeMarker myRangeMarker; @Nullable private ProperTextRange myPsiRange; private final PsiDocumentManagerBase myPsiDocManager; @@ -65,17 +60,18 @@ public class SelfElementInfo extends SmartPointerElementInfo { myPsiRange = range; myMarkerCache = ((SmartPointerManagerImpl)SmartPointerManager.getInstance(project)).getMarkerCache(myVirtualFile); myPsiDocManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject); + setRange(range); + } - Document document = myPsiDocManager.getCachedDocument(containingFile); - if (document != null) { - setRange(range, document); + void setRange(@Nullable ProperTextRange range) { + myPsiRange = range; + if (range != null) { + myMarkerCache.rangeChanged(range, myForInjected); } } - void setRange(@NotNull TextRange range, @NotNull Document document) { - myPsiRange = null; - FrozenDocument frozenDocument = myPsiDocManager.getLastCommittedDocument(document); - myRangeMarker = myMarkerCache.obtainMarker(ProperTextRange.create(range), frozenDocument, myForInjected, myForInjected, !myForInjected); + boolean isForInjected() { + return myForInjected; } @Override @@ -83,23 +79,6 @@ public class SelfElementInfo extends SmartPointerElementInfo { return ourFileDocManager.getCachedDocument(myVirtualFile); } - // before change - @Override - public void fastenBelt() { - if (myRangeMarker != null) return; // already tracks changes - if (myPsiRange == null) return; // invalid - - Document document = ourFileDocManager.getDocument(myVirtualFile); - if (document == null || !myPsiDocManager.isCommitted(document)) { - // we only have PSI range and now they say the document is uncommitted, so this PSI range is useless - // so, just invalidate - myPsiRange = null; - return; - } - - setRange(myPsiRange, document); - } - @Override public PsiElement restoreElement() { Segment segment = getPsiRange(); @@ -112,8 +91,8 @@ public class SelfElementInfo extends SmartPointerElementInfo { } @Nullable - protected Segment getPsiRange() { - return myRangeMarker != null ? myRangeMarker.getRange() : myPsiRange; + protected ProperTextRange getPsiRange() { + return myPsiRange; } @Override @@ -149,21 +128,9 @@ public class SelfElementInfo extends SmartPointerElementInfo { @Override public void cleanup() { - myRangeMarker = null; myPsiRange = null; } - void updateValidity() { - if (myPsiRange != null) { - LOG.error("Non-fastened smart pointer " + this + " " + myRangeMarker); - myPsiRange = null; - myRangeMarker = null; - } - if (myRangeMarker != null && !myRangeMarker.isValid()) { - myRangeMarker = null; - } - } - @Nullable public static PsiFile restoreFileFromVirtual(@NotNull final VirtualFile virtualFile, @NotNull final Project project, @Nullable final Language language) { return ApplicationManager.getApplication().runReadAction(new NullableComputable() { @@ -252,16 +219,15 @@ public class SelfElementInfo extends SmartPointerElementInfo { @Override @Nullable public Segment getRange() { - if (myRangeMarker != null) { + if (myPsiRange != null) { Document document = getDocumentToSynchronize(); if (document != null) { PsiDocumentManagerBase documentManager = myPsiDocManager; List events = documentManager.getEventsSinceCommit(document); if (!events.isEmpty()) { - return myMarkerCache.getUpdatedRange(myRangeMarker, documentManager.getLastCommittedDocument(document), events); + return myMarkerCache.getUpdatedRange(this, documentManager.getLastCommittedDocument(document), events); } } - return myRangeMarker.getRange(); } return myPsiRange; } @@ -272,8 +238,4 @@ public class SelfElementInfo extends SmartPointerElementInfo { return myProject; } - @Nullable - ManualRangeMarker getRangeMarker() { - return myRangeMarker; - } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index e92c0e32bdcf..d86a61613209 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -230,14 +230,6 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } } - @TestOnly - public int getMarkerCount(@NotNull Document document) { - synchronized (lock) { - VirtualFile file = FileDocumentManager.getInstance().getFile(document); - return file == null ? 0 : getMarkerCache(file).getMarkerCount(); - } - } - @Override public boolean pointToTheSameElement(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2) { return SmartPsiElementPointerImpl.pointsToTheSameElementAs(pointer1, pointer2); @@ -248,7 +240,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { FilePointersList list = file == null ? null : getPointers(file); if (list == null) return; - list.markerCache.updateMarkers(frozen, events, list.getAlivePointers()); + list.markerCache.updateMarkers(frozen, events); } private static class PointerReference extends WeakReference { @@ -265,11 +257,11 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } } - private static class FilePointersList { + static class FilePointersList { private int nextAvailableIndex; private int size; private PointerReference[] references = new PointerReference[10]; - private final MarkerCache markerCache = new MarkerCache(); + private final MarkerCache markerCache = new MarkerCache(this); private void add(@NotNull PointerReference reference) { if (nextAvailableIndex >= references.length || nextAvailableIndex > size*2) { // overflow or too many dead refs @@ -316,7 +308,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } @NotNull - private List getAlivePointers() { + List getAlivePointers() { return ContainerUtil.mapNotNull(references, new Function() { @Override public SmartPsiElementPointerImpl fun(PointerReference reference) {