From 2ee19c4d8a148f582d6726578a617ffcf8a0f7f6 Mon Sep 17 00:00:00 2001 From: Piotr Tomiak Date: Fri, 3 Jan 2020 11:13:47 +0100 Subject: [PATCH] Intentions: fix extension unloading. Intention family name is not guaranteed to be constant by the API. Thus, we need to store the mapping between extension and it's key, so that on extension removal we can remove the extension, event if family name has changed. GitOrigin-RevId: d3e3311418fd56bb6ea67cfcb0b505da07fcc68a --- .../impl/config/IntentionManagerSettings.java | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java index ec87600ee166..74cecd171a64 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java @@ -9,7 +9,10 @@ import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.*; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionNotApplicableException; import com.intellij.openapi.extensions.ExtensionPointListener; @@ -43,6 +46,8 @@ public final class IntentionManagerSettings implements PersistentStateComponent< private final Set myIgnoredActions = Collections.synchronizedSet(new LinkedHashSet<>()); private final Map myMetaData = new LinkedHashMap<>(); // guarded by this + private final Map myExtensionMapping = new HashMap<>(); // guarded by this + @NonNls private static final String IGNORE_ACTION_TAG = "ignoreAction"; @NonNls private static final String NAME_ATT = "name"; private static final Pattern HTML_PATTERN = Pattern.compile("<[^<>]*>"); @@ -59,8 +64,7 @@ public final class IntentionManagerSettings implements PersistentStateComponent< public void extensionRemoved(@NotNull IntentionActionBean extension, @NotNull PluginDescriptor pluginDescriptor) { String[] categories = extension.getCategories(); if (categories == null) return; - String familyName = extension.getInstance().getFamilyName(); - unregisterMetaData(categories, familyName); + unregisterMetaDataForEP(extension); OptionsTopHitProvider.invalidateCachedOptions(IntentionsOptionsTopHitProvider.class); } }, true, this); @@ -82,7 +86,12 @@ public final class IntentionManagerSettings implements PersistentStateComponent< descriptionDirectoryName = instance.getDescriptionDirectoryName(); } try { - registerMetaData(new IntentionActionMetaData(instance, extension.getLoaderForClass(), categories, descriptionDirectoryName)); + //noinspection SynchronizeOnThis + synchronized (this) { + MetaDataKey key = registerMetaData(new IntentionActionMetaData(instance, extension.getLoaderForClass(), + categories, descriptionDirectoryName)); + myExtensionMapping.put(extension, key); + } } catch (ExtensionNotApplicableException ignore) { } @@ -136,7 +145,7 @@ public final class IntentionManagerSettings implements PersistentStateComponent< } private static String getFamilyName(@NotNull IntentionActionMetaData metaData) { - return StringUtil.join(metaData.myCategory, "/") + "/" + metaData.getFamily(); + return StringUtil.join(metaData.myCategory, "/") + "/" + metaData.getAction().getFamilyName(); } private static String getFamilyName(@NotNull IntentionAction action) { @@ -165,12 +174,13 @@ public final class IntentionManagerSettings implements PersistentStateComponent< } } - private synchronized void registerMetaData(@NotNull IntentionActionMetaData metaData) { + private synchronized MetaDataKey registerMetaData(@NotNull IntentionActionMetaData metaData) { MetaDataKey key = new MetaDataKey(metaData.myCategory, metaData.getFamily()); if (!myMetaData.containsKey(key)){ processMetaData(metaData); } myMetaData.put(key, metaData); + return key; } private static void processMetaData(@NotNull IntentionActionMetaData metaData) { @@ -212,7 +222,9 @@ public final class IntentionManagerSettings implements PersistentStateComponent< } } - private synchronized void unregisterMetaData(String[] categories, String familyName) { - myMetaData.remove(new MetaDataKey(categories, familyName)); + private synchronized void unregisterMetaDataForEP(IntentionActionBean extension) { + MetaDataKey key = myExtensionMapping.remove(extension); + assert key != null : extension; + myMetaData.remove(key); } }