From bf56d819b13f08c54a3f67143a862d557cd65dd9 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 29 Jan 2019 15:26:05 +0100 Subject: [PATCH] =?UTF-8?q?decouple=20IntentionManagerImpl=20and=20Intenti?= =?UTF-8?q?onManagerSettings=20=E2=80=94=20preloading=20of=20top=20hit=20o?= =?UTF-8?q?ptions=20should=20not=20instantiate=20IntentionManagerImpl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Yes — now we don't listen extension adding, but IDEA itself doesn't support reloading plugins on the fly. And old impl in any case was not fully correct, because "extensionRemoved" was not handled at all. --- .../impl/config/IntentionActionWrapper.java | 27 +++---- .../impl/config/IntentionManagerImpl.java | 75 ++----------------- .../impl/config/IntentionManagerSettings.java | 28 ++++--- .../IntentionsOptionsTopHitProvider.java | 4 - 4 files changed, 37 insertions(+), 97 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java index fbdf2b45f69e..05caca7da63b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java @@ -1,19 +1,4 @@ -/* - * Copyright 2000-2016 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.intention.impl.config; import com.intellij.codeInsight.intention.IntentionAction; @@ -45,6 +30,16 @@ public class IntentionActionWrapper implements IntentionAction, ShortcutProvider myCategories = categories; } + @NotNull + public String getDescriptionDirectoryName() { + return getDescriptionDirectoryName(getImplementationClassName()); + } + + @NotNull + public static String getDescriptionDirectoryName(@NotNull String fqn) { + return fqn.substring(fqn.lastIndexOf('.') + 1).replaceAll("\\$", ""); + } + @Override @NotNull public String getText() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java index e76389b5f74d..e932dfafd95f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java @@ -13,19 +13,13 @@ import com.intellij.codeInspection.actions.CleanupAllIntention; import com.intellij.codeInspection.actions.CleanupInspectionIntention; import com.intellij.codeInspection.actions.RunInspectionIntention; import com.intellij.codeInspection.ex.*; -import com.intellij.openapi.Disposable; -import com.intellij.concurrency.JobScheduler; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.ExtensionPointListener; -import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; @@ -33,7 +27,6 @@ import org.jetbrains.annotations.TestOnly; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -49,77 +42,23 @@ public final class IntentionManagerImpl extends IntentionManager { mySettings = intentionManagerSettings; addAction(new EditInspectionToolsSettingsInSuppressedPlaceIntention()); - - if (ApplicationManager.getApplication().isUnitTestMode()) { - addIntentionExtensionPointListener(); + for (IntentionActionBean extension : IntentionManager.EP_INTENTION_ACTIONS.getExtensionList()) { + addAction(new IntentionActionWrapper(extension, extension.getCategories())); } - else { - //todo temporary hack, need smarter logic: - // * on the first request, wait until all the initialization is finished - // * while waiting, check for ProcessCanceledException - myScheduledFuture.set(JobScheduler.getScheduler().schedule(() -> { - addIntentionExtensionPointListener(); - myScheduledFuture.set(null); - }, 300, TimeUnit.MILLISECONDS)); - } - } - - private void addIntentionExtensionPointListener() { - EP_INTENTION_ACTIONS.getPoint(null).addExtensionPointListener(new ExtensionPointListener() { - @Override - public void extensionAdded(@NotNull final IntentionActionBean extension, @Nullable final PluginDescriptor pluginDescriptor) { - registerIntentionFromBean(extension); - } - }); - } - - private void registerIntentionFromBean(@NotNull final IntentionActionBean extension) { - final String[] categories = extension.getCategories(); - final IntentionAction instance = createIntentionActionWrapper(extension, categories); - if (categories == null) { - addAction(instance); - } - else { - String descriptionDirectoryName = extension.getDescriptionDirectoryName(); - if (descriptionDirectoryName == null) { - registerIntentionAndMetaData(instance, categories); - } - else { - addAction(instance); - mySettings.registerIntentionMetaData(instance, categories, descriptionDirectoryName, extension.getMetadataClassLoader()); - } - } - } - - private static IntentionAction createIntentionActionWrapper(@NotNull IntentionActionBean intentionActionBean, String[] categories) { - return new IntentionActionWrapper(intentionActionBean, categories); } @Override public void registerIntentionAndMetaData(@NotNull IntentionAction action, @NotNull String... category) { - registerIntentionAndMetaData(action, category, getDescriptionDirectoryName(action)); - } + addAction(action); - @NotNull - private static String getDescriptionDirectoryName(final IntentionAction action) { + String descriptionDirectoryName; if (action instanceof IntentionActionWrapper) { - final IntentionActionWrapper wrapper = (IntentionActionWrapper)action; - return getDescriptionDirectoryName(wrapper.getImplementationClassName()); + descriptionDirectoryName = ((IntentionActionWrapper)action).getDescriptionDirectoryName(); } else { - return getDescriptionDirectoryName(action.getClass().getName()); + descriptionDirectoryName = IntentionActionWrapper.getDescriptionDirectoryName(action.getClass().getName()); } - } - - private static String getDescriptionDirectoryName(final String fqn) { - return fqn.substring(fqn.lastIndexOf('.') + 1).replaceAll("\\$", ""); - } - - public void registerIntentionAndMetaData(@NotNull IntentionAction action, - @NotNull String[] categories, - @NotNull @NonNls String descriptionDirectoryName) { - addAction(action); - mySettings.registerIntentionMetaData(action, categories, descriptionDirectoryName); + mySettings.registerIntentionMetaData(action, category, descriptionDirectoryName); } @Override 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 1665567e4d9d..0c86c9c958b6 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 @@ -1,8 +1,8 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - package com.intellij.codeInsight.intention.impl.config; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.IntentionActionBean; import com.intellij.codeInsight.intention.IntentionManager; import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.application.Application; @@ -44,6 +44,23 @@ public final class IntentionManagerSettings implements PersistentStateComponent< @NonNls private static final String NAME_ATT = "name"; private static final Pattern HTML_PATTERN = Pattern.compile("<[^<>]*>"); + public IntentionManagerSettings() { + for (IntentionActionBean extension : IntentionManager.EP_INTENTION_ACTIONS.getExtensionList()) { + String[] categories = extension.getCategories(); + if (categories == null) { + continue; + } + + IntentionActionWrapper instance = new IntentionActionWrapper(extension, categories); + String descriptionDirectoryName = extension.getDescriptionDirectoryName(); + if (descriptionDirectoryName == null) { + descriptionDirectoryName = instance.getDescriptionDirectoryName(); + } + registerMetaData(new IntentionActionMetaData(instance, extension.getMetadataClassLoader(), categories, descriptionDirectoryName)); + } + } + + @NotNull public static IntentionManagerSettings getInstance() { return ServiceManager.getService(IntentionManagerSettings.class); } @@ -60,13 +77,6 @@ public final class IntentionManagerSettings implements PersistentStateComponent< : intentionAction.getClass().getClassLoader(); } - void registerIntentionMetaData(@NotNull IntentionAction intentionAction, - @NotNull String[] category, - @NotNull String descriptionDirectoryName, - final ClassLoader classLoader) { - registerMetaData(new IntentionActionMetaData(intentionAction, classLoader, category, descriptionDirectoryName)); - } - public boolean isShowLightBulb(@NotNull IntentionAction action) { return !myIgnoredActions.contains(action.getFamilyName()); } @@ -90,7 +100,6 @@ public final class IntentionManagerSettings implements PersistentStateComponent< @NotNull public synchronized List getMetaData() { - IntentionManager.getInstance(); // TODO: Hack to make IntentionManager actually register metadata here. Dependencies between IntentionManager and IntentionManagerSettings should be revised. return new ArrayList<>(myMetaData.values()); } @@ -118,6 +127,7 @@ public final class IntentionManagerSettings implements PersistentStateComponent< public boolean isEnabled(@NotNull IntentionAction action) { return !myIgnoredActions.contains(getFamilyName(action)); } + public void setEnabled(@NotNull IntentionAction action, boolean enabled) { if (enabled) { myIgnoredActions.remove(getFamilyName(action)); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionsOptionsTopHitProvider.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionsOptionsTopHitProvider.java index f16a11cb4ec4..60db243f790b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionsOptionsTopHitProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionsOptionsTopHitProvider.java @@ -25,10 +25,6 @@ final class IntentionsOptionsTopHitProvider extends OptionsTopHitProvider { @Override public Collection getOptions(@Nullable Project project) { IntentionManagerSettings settings = IntentionManagerSettings.getInstance(); - if (settings == null) { - return Collections.emptyList(); - } - Collection options = new ArrayList<>(); for (IntentionActionMetaData data : settings.getMetaData()) { options.add(new Option(settings, data));