From 0e63e9b69f366c77dcc87f3f3706bba82206effd Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Mon, 25 Nov 2019 12:36:33 +0300 Subject: [PATCH] clear cached values on plugin load/unload GitOrigin-RevId: aebf935b0ff04c87e10a326d56651aac73b3c9ab --- .../util/CachedValueStabilityChecker.java | 4 +++ .../util/CachedValuesManagerImpl.java | 27 +++++++++++++++++-- .../daemon/impl/DaemonListeners.java | 4 +++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/platform/core-impl/src/com/intellij/util/CachedValueStabilityChecker.java b/platform/core-impl/src/com/intellij/util/CachedValueStabilityChecker.java index 017cfeeaac6e..94c1a2be8f6b 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValueStabilityChecker.java +++ b/platform/core-impl/src/com/intellij/util/CachedValueStabilityChecker.java @@ -173,4 +173,8 @@ class CachedValueStabilityChecker { return "kotlin.jvm.internal.Lambda".equals(superclass.getName()); } + + static void cleanupFieldCache() { + ourFieldCache.clear(); + } } diff --git a/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java b/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java index db124c5cfda6..3a5a3e420f98 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java +++ b/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java @@ -8,13 +8,22 @@ import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.psi.util.*; import com.intellij.serviceContainer.NonInjectable; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + /** * @author ven */ public final class CachedValuesManagerImpl extends CachedValuesManager { + private static final Object NULL = new Object(); + private ConcurrentMap myCacheHolders = ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); + private Set> myKeys = ContainerUtil.newConcurrentSet(); + private final Project myProject; private final CachedValuesFactory myFactory; @@ -64,8 +73,11 @@ public final class CachedValuesManagerImpl extends CachedValuesManager { return value.getValue(); } - private static CachedValue saveInUserData(@NotNull UserDataHolder dataHolder, - @NotNull Key> key, CachedValue value) { + private CachedValue saveInUserData(@NotNull UserDataHolder dataHolder, + @NotNull Key> key, CachedValue value) { + myCacheHolders.put(dataHolder, NULL); + myKeys.add(key); + if (dataHolder instanceof UserDataHolderEx) { return ((UserDataHolderEx)dataHolder).putUserDataIfAbsent(key, value); } @@ -88,4 +100,15 @@ public final class CachedValuesManagerImpl extends CachedValuesManager { return value; } + @ApiStatus.Internal + public void clearCachedValues() { + for (UserDataHolder holder : myCacheHolders.keySet()) { + for (Key key : myKeys) { + holder.putUserData(key, null); + } + } + CachedValueStabilityChecker.cleanupFieldCache(); + myCacheHolders = ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); + myKeys = ContainerUtil.newConcurrentSet(); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index 21aff978103c..0c1a1f363d61 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -71,6 +71,8 @@ import com.intellij.profile.ProfileChangeAdapter; import com.intellij.psi.*; import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.PsiModificationTrackerImpl; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.util.CachedValuesManagerImpl; import com.intellij.util.KeyedLazyInstance; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; @@ -364,12 +366,14 @@ public final class DaemonListeners implements Disposable { connection.subscribe(DynamicPluginListener.TOPIC, new DynamicPluginListener() { @Override public void pluginLoaded(@NotNull IdeaPluginDescriptor pluginDescriptor) { + ((CachedValuesManagerImpl)CachedValuesManager.getManager(myProject)).clearCachedValues(); ((PsiModificationTrackerImpl)PsiManager.getInstance(myProject).getModificationTracker()).incCounter(); stopDaemonAndRestartAllFiles("Plugin installed"); } @Override public void beforePluginUnload(@NotNull IdeaPluginDescriptor pluginDescriptor, boolean isUpdate) { + ((CachedValuesManagerImpl)CachedValuesManager.getManager(myProject)).clearCachedValues(); ((PsiModificationTrackerImpl)PsiManager.getInstance(myProject).getModificationTracker()).incCounter(); stopDaemonAndRestartAllFiles("Plugin will be uninstalled"); removeQuickFixesContributedByPlugin(pluginDescriptor);