From 14259dc0e0d8119a0df9270629f4281dfbb5b929 Mon Sep 17 00:00:00 2001 From: Louis Vignier Date: Mon, 23 Oct 2023 15:56:35 +0200 Subject: [PATCH] [codeInspection.ui] Decouple custom inspection logic from SSR plugin #IDEA-335948 Fixed GitOrigin-RevId: dff86a1b7edb287851590ea5d573362629dd8931 --- .../resources/META-INF/RegExpPlugin.xml | 1 + .../messages/RegExpBundle.properties | 2 + .../custom/CustomRegExpInspection.java | 29 +--- .../custom/RegExpProfileActionProvider.java | 82 +++++++++++ .../messages/InspectionsBundle.properties | 2 + .../ui/CustomInspectionActions.java | 91 +++++++++++++ .../ui/InspectionProfileActionProvider.java | 27 +++- .../ui/SingleInspectionProfilePanel.java | 5 + .../resources/messages/SSRBundle.properties | 6 +- .../inspection/InspectionProfileUtil.java | 26 ---- .../inspection/SSBasedInspection.java | 6 + .../StructuralSearchFakeInspection.java | 9 +- ...StructuralSearchProfileActionProvider.java | 127 +++--------------- 13 files changed, 243 insertions(+), 170 deletions(-) create mode 100644 RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/RegExpProfileActionProvider.java create mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/CustomInspectionActions.java diff --git a/RegExpSupport/resources/META-INF/RegExpPlugin.xml b/RegExpSupport/resources/META-INF/RegExpPlugin.xml index d83b31589c81..2e706f676e6b 100644 --- a/RegExpSupport/resources/META-INF/RegExpPlugin.xml +++ b/RegExpSupport/resources/META-INF/RegExpPlugin.xml @@ -29,6 +29,7 @@ + org.intellij.lang.regexp.intention.CheckRegExpIntentionAction diff --git a/RegExpSupport/resources/messages/RegExpBundle.properties b/RegExpSupport/resources/messages/RegExpBundle.properties index 7fc052ddc68e..c082c68bb47b 100644 --- a/RegExpSupport/resources/messages/RegExpBundle.properties +++ b/RegExpSupport/resources/messages/RegExpBundle.properties @@ -1,6 +1,8 @@ action.add.pattern.text=Add Pattern\u2026 action.add.regexp.replace.template.text=Add RegExp Replace Template\u2026 action.add.regexp.search.template.text=Add RegExp Search Template\u2026 +action.add.regexp.replace.inspection.text=Add RegExp Replace Inspection\u2026 +action.add.regexp.search.inspection.text=Add RegExp Search Inspection\u2026 button.enable.replace=Enable Replace button.search.only=Search Only checker.sample.text=Sample Text diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/CustomRegExpInspection.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/CustomRegExpInspection.java index cdafd63171dd..bda599a0302d 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/CustomRegExpInspection.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/CustomRegExpInspection.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.profile.codeInspection.InspectionProfileManager; +import com.intellij.profile.codeInspection.ui.CustomInspectionActions; import com.intellij.profile.codeInspection.ui.InspectionMetaDataDialog; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -42,32 +43,8 @@ public class CustomRegExpInspection extends LocalInspectionTool implements Dynam public final List myConfigurations = new SmartList<>(); private InspectionProfileImpl mySessionProfile; - public CustomRegExpInspection() { - /* - final FileType javaFileType = FileTypeManager.getInstance().getStdFileType("JAVA"); - final RegExpInspectionConfiguration one = new RegExpInspectionConfiguration("No spaces within parentheses"); - one.patterns.add(new RegExpInspectionConfiguration.InspectionPattern("(\\()\\s+|\\s+(\\))", null, FindModel.SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS, "$1")); - one.suppressId = "NoSpaces"; - one.description = "We don't like spaces within parentheses in our code style"; - myConfigurations.add(one); - - final RegExpInspectionConfiguration two = new RegExpInspectionConfiguration("No more than one empty line in Java"); - two.patterns.add(new RegExpInspectionConfiguration.InspectionPattern("\\n\\n\\n+", javaFileType, FindModel.SearchContext.EXCEPT_STRING_LITERALS, "\n\n")); - two.suppressId = "EmptyLines"; - two.description = "One empty line should be enough for everybody"; - myConfigurations.add(two); - - final RegExpInspectionConfiguration three = new RegExpInspectionConfiguration("Trailing whitespace"); - three.patterns.add(new RegExpInspectionConfiguration.InspectionPattern(" +\\n", PlainTextFileType.INSTANCE, FindModel.SearchContext.ANY, "")); - three.patterns.add(new RegExpInspectionConfiguration.InspectionPattern("\t+\\n", PlainTextFileType.INSTANCE, FindModel.SearchContext.ANY, "")); - three.description = "Trailing whitespace is unnecessary"; - myConfigurations.add(three); - - final RegExpInspectionConfiguration four = new RegExpInspectionConfiguration("Multiple spaces in Java"); - four.patterns.add(new RegExpInspectionConfiguration.InspectionPattern("(?<=\\S) {2,}", javaFileType, FindModel.SearchContext.EXCEPT_COMMENTS, " ")); - four.description = "Double spaced"; - myConfigurations.add(four); - */ + public static CustomRegExpInspection getCustomRegExpInspection(@NotNull InspectionProfile profile) { + return (CustomRegExpInspection)CustomInspectionActions.getInspection(profile, SHORT_NAME); } @Override diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/RegExpProfileActionProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/RegExpProfileActionProvider.java new file mode 100644 index 000000000000..a43d7267c71f --- /dev/null +++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/custom/RegExpProfileActionProvider.java @@ -0,0 +1,82 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.intellij.lang.regexp.inspection.custom; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NlsActions; +import com.intellij.profile.codeInspection.ui.InspectionMetaDataDialog; +import com.intellij.profile.codeInspection.ui.InspectionProfileActionProvider; +import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; +import org.intellij.lang.regexp.RegExpBundle; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class RegExpProfileActionProvider extends InspectionProfileActionProvider { + @Override + public @NotNull List getAddActions(@NotNull SingleInspectionProfilePanel panel) { + return List.of( + new AddCustomRegExpInspectionAction(panel, RegExpBundle.message("action.add.regexp.search.inspection.text"), false), + new AddCustomRegExpInspectionAction(panel, RegExpBundle.message("action.add.regexp.replace.inspection.text"), true) + ); + } + + static final class AddCustomRegExpInspectionAction extends DumbAwareAction { + private final SingleInspectionProfilePanel myPanel; + private final boolean myReplace; + + AddCustomRegExpInspectionAction(@NotNull SingleInspectionProfilePanel panel, @NlsActions.ActionText String text, boolean replace) { + super(text); + myPanel = panel; + myReplace = replace; + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + final RegExpDialog dialog = new RegExpDialog(e.getProject(), true, myReplace ? RegExpInspectionConfiguration.InspectionPattern.EMPTY_REPLACE_PATTERN : null); + if (!dialog.showAndGet()) return; + + final RegExpInspectionConfiguration.InspectionPattern pattern = dialog.getPattern(); + final InspectionProfileModifiableModel profile = myPanel.getProfile(); + final CustomRegExpInspection inspection = CustomRegExpInspection.getCustomRegExpInspection(profile); + final Project project = e.getData(CommonDataKeys.PROJECT); + if (project == null) return; + final InspectionMetaDataDialog metaDataDialog = inspection.createMetaDataDialog(project, null); + if (pattern.replacement() != null) { + metaDataDialog.showCleanupOption(false); + } + if (!metaDataDialog.showAndGet()) return; + + final RegExpInspectionConfiguration configuration = new RegExpInspectionConfiguration(metaDataDialog.getName()); + configuration.addPattern(pattern); + configuration.setDescription(metaDataDialog.getDescription()); + configuration.setSuppressId(metaDataDialog.getSuppressId()); + configuration.setProblemDescriptor(metaDataDialog.getProblemDescriptor()); + configuration.setCleanup(metaDataDialog.isCleanup()); + + configuration.setUuid(null); + inspection.addConfiguration(configuration); + CustomRegExpInspection.addInspectionToProfile(project, profile, configuration); + profile.setModified(true); + profile.getProfileManager().fireProfileChanged(profile); + myPanel.selectInspectionTool(configuration.getUuid()); + } + } + + @Override + public boolean canDeleteInspection(InspectionProfileEntry entry) { + return entry instanceof CustomRegExpInspection; + } + + @Override + public void deleteInspection(InspectionProfileEntry entry, String shortName) { + if (entry instanceof CustomRegExpInspection regExpInspection) { + regExpInspection.removeConfigurationWithUuid(shortName); + } + } +} diff --git a/platform/analysis-api/resources/messages/InspectionsBundle.properties b/platform/analysis-api/resources/messages/InspectionsBundle.properties index b5a732654baf..cd79e8a26e6f 100644 --- a/platform/analysis-api/resources/messages/InspectionsBundle.properties +++ b/platform/analysis-api/resources/messages/InspectionsBundle.properties @@ -334,6 +334,8 @@ label.description=&Description: label.problem.tool.tip=Problem &tool tip (use macro #ref to insert highlighted code): label.suppress.id=&Suppress ID: unnamed.inspection=Unnamed inspection +add.inspection.button=Add Custom Inspection +remove.inspection.button=Remove Custom Inspection long.range.set.presentation.empty=unknown long.range.set.presentation.any=any value diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/CustomInspectionActions.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/CustomInspectionActions.java new file mode 100644 index 000000000000..0f126cf8b659 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/CustomInspectionActions.java @@ -0,0 +1,91 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.profile.codeInspection.ui; + +import com.intellij.codeInspection.InspectionProfile; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; +import com.intellij.codeInspection.ex.InspectionToolWrapper; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class CustomInspectionActions { + @Nullable + public static ActionGroup getAddActionGroup(SingleInspectionProfilePanel panel) { + final DefaultActionGroup actionGroup = new DefaultActionGroup(); + var addActions = ContainerUtil.flatMap( + InspectionProfileActionProvider.EP_NAME.getExtensionList(), + provider -> provider.getAddActions(panel) + ); + if (addActions.isEmpty()) return null; + actionGroup.addAll(addActions); + actionGroup.setPopup(true); + actionGroup.registerCustomShortcutSet(CommonShortcuts.getNew(), panel); + final Presentation presentation = actionGroup.getTemplatePresentation(); + presentation.setIcon(AllIcons.General.Add); + presentation.setText(InspectionsBundle.messagePointer("add.inspection.button")); + return actionGroup; + } + + public static final class RemoveInspectionAction extends DumbAwareAction { + private final SingleInspectionProfilePanel myPanel; + + RemoveInspectionAction(@NotNull SingleInspectionProfilePanel panel) { + super(InspectionsBundle.message("remove.inspection.button"), null, AllIcons.General.Remove); + myPanel = panel; + registerCustomShortcutSet(CommonShortcuts.getDelete(), myPanel); + } + + @Override + public void update(@NotNull AnActionEvent e) { + final InspectionToolWrapper selectedTool = myPanel.getSelectedTool(); + e.getPresentation().setEnabled( + selectedTool != null && + selectedTool.getMainToolId() != null && + ContainerUtil.exists(InspectionProfileActionProvider.EP_NAME.getExtensionList(), + actionProvider -> actionProvider.canDeleteInspection(getInspection(myPanel.getProfile(), + selectedTool.getMainToolId()))) + ); + } + + @Override + public @NotNull ActionUpdateThread getActionUpdateThread() { + return ActionUpdateThread.EDT; + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + final InspectionToolWrapper selectedTool = myPanel.getSelectedTool(); + final String shortName = selectedTool.getShortName(); + final String mainToolId = selectedTool.getMainToolId(); + myPanel.removeSelectedRow(); + final InspectionProfileModifiableModel profile = myPanel.getProfile(); + final InspectionProfileEntry inspection = getInspection(profile, mainToolId); + InspectionProfileActionProvider.EP_NAME.getExtensionList().forEach(actionProvider -> { + if (actionProvider.canDeleteInspection(inspection)) { + actionProvider.deleteInspection(inspection, shortName); + } + }); + profile.removeTool(selectedTool); + profile.setModified(true); + fireProfileChanged(profile); + } + } + + public static InspectionProfileEntry getInspection(@NotNull InspectionProfile profile, @NonNls String shortName) { + final InspectionToolWrapper wrapper = profile.getInspectionTool(shortName, (Project)null); + assert wrapper != null; + return wrapper.getTool(); + } + + public static void fireProfileChanged(@NotNull InspectionProfileImpl profile) { + profile.getProfileManager().fireProfileChanged(profile); + } +} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileActionProvider.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileActionProvider.java index 07d1d7d2f4c8..8d62fd5b98fb 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileActionProvider.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileActionProvider.java @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.profile.codeInspection.ui; +import com.intellij.codeInspection.InspectionProfileEntry; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.extensions.ExtensionPointName; import org.jetbrains.annotations.NotNull; @@ -20,8 +21,30 @@ public abstract class InspectionProfileActionProvider { ExtensionPointName.create("com.intellij.inspectionProfileActionProvider"); /** - * @return additional actions to render in the given inspection profile panel + * @return additional actions to render in the given inspection profile panel. */ @NotNull - public abstract List getActions(@NotNull SingleInspectionProfilePanel panel); + public List getActions(@NotNull SingleInspectionProfilePanel panel) { + return List.of(); + } + + /** + * @return actions to add custom inspections in the given inspection profile panel. + */ + @NotNull + public List getAddActions(@NotNull SingleInspectionProfilePanel panel) { + return List.of(); + } + + /** + * @return true if this extension can delete the inspection corresponding to the given entry. + */ + public boolean canDeleteInspection(InspectionProfileEntry entry) { + return false; + } + + /** + * Called when an inspection entry has been deleted. + */ + public void deleteInspection(InspectionProfileEntry entry, String shortName) {} } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 1b172a6c7114..f811b2754cf2 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -495,6 +495,11 @@ public class SingleInspectionProfilePanel extends JPanel { postProcessModification(); } }); + final var customAdd = CustomInspectionActions.getAddActionGroup(this); + if (customAdd != null) { + actions.add(customAdd); + actions.add(new CustomInspectionActions.RemoveInspectionAction(this)); + } for (InspectionProfileActionProvider provider : InspectionProfileActionProvider.EP_NAME.getExtensionList()) { for (AnAction action : provider.getActions(this)) { actions.add(action); diff --git a/platform/structuralsearch/resources/messages/SSRBundle.properties b/platform/structuralsearch/resources/messages/SSRBundle.properties index d2a60f94f6a9..06cee7d56139 100644 --- a/platform/structuralsearch/resources/messages/SSRBundle.properties +++ b/platform/structuralsearch/resources/messages/SSRBundle.properties @@ -296,8 +296,6 @@ structural.search.group.name=Structural search edit.metadata.button=Edit Metadata\u2026 add.pattern.action=Add Template templates.title=Templates: -add.inspection.button=Add Custom Inspection -remove.inspection.button=Remove Custom Inspection meta.data.dialog.title=Structural Search Inspection inspection.name.label=Inspection name: @@ -338,6 +336,4 @@ replace.configuration.display.text={0} \u21E8 {1} inspection.tree.create.inspection.search.template=Using a Structural Search Template\u2026 inspection.tree.create.inspection.replace.template=Using a Structural Replace Template\u2026 inspection.tree.group.description=Use the + button in the toolbar to create a new Structural Search inspection.
\ -Structural Search inspections highlight code snippets matching the specified search template. A quick-fix can be provided by adding a replace template. -action.add.regexp.replace.inspection.text=Add RegExp Replace Inspection\u2026 -action.add.regexp.search.inspection.text=Add RegExp Search Inspection\u2026 \ No newline at end of file +Structural Search inspections highlight code snippets matching the specified search template. A quick-fix can be provided by adding a replace template. \ No newline at end of file diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/InspectionProfileUtil.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/InspectionProfileUtil.java index 80deb36ba37c..97cde8e6da5a 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/InspectionProfileUtil.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/InspectionProfileUtil.java @@ -1,18 +1,11 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.structuralsearch.inspection; -import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.InspectionProfileEntry; import com.intellij.codeInspection.InspectionsBundle; -import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; -import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.openapi.project.Project; import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; import com.intellij.structuralsearch.SSRBundle; import com.intellij.util.ui.UIUtil; -import org.intellij.lang.regexp.inspection.custom.CustomRegExpInspection; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -24,21 +17,6 @@ public final class InspectionProfileUtil { private InspectionProfileUtil() {} - @NotNull - public static SSBasedInspection getStructuralSearchInspection(@NotNull InspectionProfile profile) { - return (SSBasedInspection)getInspection(profile, SSBasedInspection.SHORT_NAME); - } - - public static CustomRegExpInspection getCustomRegExpInspection(@NotNull InspectionProfile profile) { - return (CustomRegExpInspection)getInspection(profile, CustomRegExpInspection.SHORT_NAME); - } - - public static InspectionProfileEntry getInspection(@NotNull InspectionProfile profile, @NonNls String shortName) { - final InspectionToolWrapper wrapper = profile.getInspectionTool(shortName, (Project)null); - assert wrapper != null; - return wrapper.getTool(); - } - public static InspectionProfileModifiableModel getInspectionProfile(@NotNull Component c) { final SingleInspectionProfilePanel panel = UIUtil.uiParents(c, true).filter(SingleInspectionProfilePanel.class).first(); if (panel == null) return null; @@ -48,8 +26,4 @@ public final class InspectionProfileUtil { public static String[] getGroup() { return new String[] {InspectionsBundle.message("group.names.user.defined"), SSRBundle.message("structural.search.group.name")}; } - - public static void fireProfileChanged(@NotNull InspectionProfileImpl profile) { - profile.getProfileManager().fireProfileChanged(profile); - } } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/SSBasedInspection.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/SSBasedInspection.java index 9363d6114a0f..91a81d4bd487 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/SSBasedInspection.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/SSBasedInspection.java @@ -23,6 +23,7 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.text.NaturalComparator; import com.intellij.openapi.util.text.StringUtil; import com.intellij.profile.codeInspection.InspectionProfileManager; +import com.intellij.profile.codeInspection.ui.CustomInspectionActions; import com.intellij.profile.codeInspection.ui.InspectionMetaDataDialog; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; @@ -77,6 +78,11 @@ public class SSBasedInspection extends LocalInspectionTool implements DynamicGro private final Set myProblemsReported = new HashSet<>(1); private InspectionProfileImpl mySessionProfile; + @NotNull + public static SSBasedInspection getStructuralSearchInspection(@NotNull InspectionProfile profile) { + return (SSBasedInspection)CustomInspectionActions.getInspection(profile, SHORT_NAME); + } + @Override public void writeSettings(@NotNull Element node) throws WriteExternalException { if (myWriteSorted) { diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchFakeInspection.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchFakeInspection.java index c119a3087968..dcd8e6867581 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchFakeInspection.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchFakeInspection.java @@ -13,6 +13,7 @@ import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.profile.codeInspection.ui.CustomInspectionActions; import com.intellij.profile.codeInspection.ui.InspectionMetaDataDialog; import com.intellij.structuralsearch.SSRBundle; import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration; @@ -180,7 +181,7 @@ public class StructuralSearchFakeInspection extends LocalInspectionTool { if (profile == null) { return; } - final SSBasedInspection inspection = InspectionProfileUtil.getStructuralSearchInspection(profile); + final SSBasedInspection inspection = SSBasedInspection.getStructuralSearchInspection(profile); final InspectionMetaDataDialog dialog = inspection.createMetaDataDialog(project, myMainConfiguration); if (isCleanupAllowed()) { dialog.showCleanupOption(myMainConfiguration.isCleanup()); @@ -199,7 +200,7 @@ public class StructuralSearchFakeInspection extends LocalInspectionTool { inspection.removeConfigurationsWithUuid(myMainConfiguration.getUuid()); inspection.addConfigurations(myConfigurations); profile.setModified(true); - InspectionProfileUtil.fireProfileChanged(profile); + CustomInspectionActions.fireProfileChanged(profile); } private void performMove(@NotNull JList list, boolean up) { @@ -293,7 +294,7 @@ public class StructuralSearchFakeInspection extends LocalInspectionTool { private void saveChangesToProfile(@NotNull JList list) { final InspectionProfileModifiableModel profile = InspectionProfileUtil.getInspectionProfile(list); if (profile == null) return; - final SSBasedInspection inspection = InspectionProfileUtil.getStructuralSearchInspection(profile); + final SSBasedInspection inspection = SSBasedInspection.getStructuralSearchInspection(profile); inspection.removeConfigurationsWithUuid(myMainConfiguration.getUuid()); inspection.addConfigurations(myConfigurations); profile.setModified(true); @@ -331,7 +332,7 @@ public class StructuralSearchFakeInspection extends LocalInspectionTool { final InspectionProfileModifiableModel profile = InspectionProfileUtil.getInspectionProfile(myList); if (profile == null) return; - if (InspectionProfileUtil.getStructuralSearchInspection(profile).addConfiguration(configuration)) { + if (SSBasedInspection.getStructuralSearchInspection(profile).addConfiguration(configuration)) { myConfigurations.add(configuration); model.fireContentsChanged(myList); myList.setSelectedIndex(size); diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchProfileActionProvider.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchProfileActionProvider.java index ad629c6ab181..361ac08507da 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchProfileActionProvider.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/StructuralSearchProfileActionProvider.java @@ -7,13 +7,14 @@ import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.ex.ScopeToolState; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsActions; import com.intellij.profile.codeInspection.InspectionProfileManager; +import com.intellij.profile.codeInspection.ui.CustomInspectionActions; import com.intellij.profile.codeInspection.ui.InspectionMetaDataDialog; import com.intellij.profile.codeInspection.ui.InspectionProfileActionProvider; import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; @@ -22,13 +23,8 @@ import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration; import com.intellij.structuralsearch.plugin.ui.Configuration; import com.intellij.structuralsearch.plugin.ui.SearchContext; import com.intellij.structuralsearch.plugin.ui.StructuralSearchDialog; -import org.intellij.lang.regexp.inspection.custom.CustomRegExpInspection; -import org.intellij.lang.regexp.inspection.custom.CustomRegExpInspectionToolWrapper; -import org.intellij.lang.regexp.inspection.custom.RegExpDialog; -import org.intellij.lang.regexp.inspection.custom.RegExpInspectionConfiguration; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -37,24 +33,6 @@ import java.util.List; */ public class StructuralSearchProfileActionProvider extends InspectionProfileActionProvider { - @NotNull - @Override - public List getActions(@NotNull SingleInspectionProfilePanel panel) { - enableSSIfDisabled(panel.getProfile(), panel.getProject()); - final DefaultActionGroup actionGroup = new DefaultActionGroup( - new AddInspectionAction(panel, SSRBundle.message("SSRInspection.add.search.template.button"), false), - new AddInspectionAction(panel, SSRBundle.message("SSRInspection.add.replace.template.button"), true), - new AddCustomRegExpInspectionAction(panel, SSRBundle.message("action.add.regexp.search.inspection.text"), false), - new AddCustomRegExpInspectionAction(panel, SSRBundle.message("action.add.regexp.replace.inspection.text"), true) - ); - actionGroup.setPopup(true); - actionGroup.registerCustomShortcutSet(CommonShortcuts.getNew(), panel); - final Presentation presentation = actionGroup.getTemplatePresentation(); - presentation.setIcon(AllIcons.General.Add); - presentation.setText(SSRBundle.messagePointer("add.inspection.button")); - return Arrays.asList(actionGroup, new RemoveInspectionAction(panel)); - } - private static void enableSSIfDisabled(@NotNull InspectionProfileModifiableModel profile, @NotNull Project project) { if (profile.getToolsOrNull(SSBasedInspection.SHORT_NAME, null) != null && !profile.isToolEnabled(HighlightDisplayKey.find(SSBasedInspection.SHORT_NAME))) { @@ -69,89 +47,24 @@ public class StructuralSearchProfileActionProvider extends InspectionProfileActi } } - private static final class RemoveInspectionAction extends DumbAwareAction { - private final SingleInspectionProfilePanel myPanel; - - private RemoveInspectionAction(@NotNull SingleInspectionProfilePanel panel) { - super(SSRBundle.message("remove.inspection.button"), null, AllIcons.General.Remove); - myPanel = panel; - registerCustomShortcutSet(CommonShortcuts.getDelete(), myPanel); - } - - @Override - public void update(@NotNull AnActionEvent e) { - final InspectionToolWrapper selectedTool = myPanel.getSelectedTool(); - e.getPresentation().setEnabled(selectedTool instanceof CustomRegExpInspectionToolWrapper || - selectedTool instanceof StructuralSearchInspectionToolWrapper); - } - - @Override - public @NotNull ActionUpdateThread getActionUpdateThread() { - return ActionUpdateThread.EDT; - } - - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - final InspectionToolWrapper selectedTool = myPanel.getSelectedTool(); - final String shortName = selectedTool.getShortName(); - final String mainToolId = selectedTool.getMainToolId(); - myPanel.removeSelectedRow(); - final InspectionProfileModifiableModel profile = myPanel.getProfile(); - final InspectionProfileEntry inspection = InspectionProfileUtil.getInspection(profile, mainToolId); - if (inspection instanceof SSBasedInspection ssBasedInspection) { - ssBasedInspection.removeConfigurationsWithUuid(shortName); - } - else if (inspection instanceof CustomRegExpInspection customRegExpInspection) { - customRegExpInspection.removeConfigurationWithUuid(shortName); - } - profile.removeTool(selectedTool); - profile.setModified(true); - InspectionProfileUtil.fireProfileChanged(profile); - } + @Override + public @NotNull List getAddActions(@NotNull SingleInspectionProfilePanel panel) { + enableSSIfDisabled(panel.getProfile(), panel.getProject()); + return List.of( + new AddInspectionAction(panel, SSRBundle.message("SSRInspection.add.search.template.button"), false), + new AddInspectionAction(panel, SSRBundle.message("SSRInspection.add.replace.template.button"), true) + ); } - static final class AddCustomRegExpInspectionAction extends DumbAwareAction { - private final SingleInspectionProfilePanel myPanel; - private final boolean myReplace; + @Override + public boolean canDeleteInspection(InspectionProfileEntry entry) { + return entry instanceof SSBasedInspection; + } - AddCustomRegExpInspectionAction(@NotNull SingleInspectionProfilePanel panel, @NlsActions.ActionText String text, boolean replace) { - super(text); - myPanel = panel; - myReplace = replace; - } - - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - final RegExpDialog dialog = new RegExpDialog(e.getProject(), true, myReplace ? RegExpInspectionConfiguration.InspectionPattern.EMPTY_REPLACE_PATTERN : null); - if (myReplace) { - // do something? - } - if (!dialog.showAndGet()) return; - - final RegExpInspectionConfiguration.InspectionPattern pattern = dialog.getPattern(); - final InspectionProfileModifiableModel profile = myPanel.getProfile(); - final CustomRegExpInspection inspection = InspectionProfileUtil.getCustomRegExpInspection(profile); - final Project project = e.getData(CommonDataKeys.PROJECT); - if (project == null) return; - final InspectionMetaDataDialog metaDataDialog = inspection.createMetaDataDialog(project, null); - if (pattern.replacement() != null) { - metaDataDialog.showCleanupOption(false); - } - if (!metaDataDialog.showAndGet()) return; - - final RegExpInspectionConfiguration configuration = new RegExpInspectionConfiguration(metaDataDialog.getName()); - configuration.addPattern(pattern); - configuration.setDescription(metaDataDialog.getDescription()); - configuration.setSuppressId(metaDataDialog.getSuppressId()); - configuration.setProblemDescriptor(metaDataDialog.getProblemDescriptor()); - configuration.setCleanup(metaDataDialog.isCleanup()); - - configuration.setUuid(null); - inspection.addConfiguration(configuration); - CustomRegExpInspection.addInspectionToProfile(project, profile, configuration); - profile.setModified(true); - InspectionProfileUtil.fireProfileChanged(profile); - myPanel.selectInspectionTool(configuration.getUuid()); + @Override + public void deleteInspection(InspectionProfileEntry entry, String shortName) { + if (entry instanceof SSBasedInspection ssBasedInspection) { + ssBasedInspection.removeConfigurationsWithUuid(shortName); } } @@ -187,7 +100,7 @@ public class StructuralSearchProfileActionProvider extends InspectionProfileActi public static boolean createNewInspection(@NotNull Configuration configuration, @NotNull Project project, @NotNull InspectionProfileImpl profile) { - final SSBasedInspection inspection = InspectionProfileUtil.getStructuralSearchInspection(profile); + final SSBasedInspection inspection = SSBasedInspection.getStructuralSearchInspection(profile); if (!ApplicationManager.getApplication().isUnitTestMode()) { InspectionMetaDataDialog dialog = inspection.createMetaDataDialog(project, null); if (configuration instanceof ReplaceConfiguration) { @@ -206,7 +119,7 @@ public class StructuralSearchProfileActionProvider extends InspectionProfileActi if (profile instanceof InspectionProfileModifiableModel) { ((InspectionProfileModifiableModel)profile).setModified(true); } - InspectionProfileUtil.fireProfileChanged(profile); + CustomInspectionActions.fireProfileChanged(profile); return true; }