From 6a3984e3c7e833cd5d729d2df8ecb18dca7141e7 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 4 Oct 2011 10:40:17 +0400 Subject: [PATCH] language-aware inspections --- .../EmptyIntentionInspectionQuickFixTest.java | 2 +- .../codeInspection/LocalInspectionEP.java | 3 ++ .../daemon/impl/LocalInspectionsPass.java | 32 ++++++++++++++----- .../impl/LocalInspectionsPassFactory.java | 16 ++++++---- .../WholeFileLocalInspectionsPassFactory.java | 10 +++--- .../ex/InspectionProfileWrapper.java | 11 +++---- .../ex/InspectionToolWrapper.java | 5 +++ .../ex/LocalInspectionToolWrapper.java | 4 +++ .../src/META-INF/XmlPlugin.xml | 2 +- .../InspectionGadgets/src/META-INF/plugin.xml | 18 +++++------ .../generate-tostring/src/META-INF/plugin.xml | 2 +- .../ui/SpellCheckingEditorCustomization.java | 15 +++++---- resources/src/META-INF/IdeaPlugin.xml | 2 +- 13 files changed, 76 insertions(+), 46 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java index f1d7457625e9..c4e1abca2b20 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/EmptyIntentionInspectionQuickFixTest.java @@ -73,7 +73,7 @@ public class EmptyIntentionInspectionQuickFixTest extends LightQuickFixTestCase{ IntentionAction action = emptyActions.get(i); if (!(action instanceof EmptyIntentionAction)) emptyActions.remove(i); } - assertEquals(1, emptyActions.size()); + assertEquals(emptyActions.toString(), 1, emptyActions.size()); } public void testLowPriority() throws Exception { diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java b/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java index b0139b82c038..6517d048972a 100644 --- a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java +++ b/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java @@ -31,4 +31,7 @@ public class LocalInspectionEP extends InspectionEP { @Attribute("alternativeId") public String alternativeId; + + @Attribute("runForWholeFile") + public boolean runForWholeFile; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index 1182317ef41f..74e0059f0f86 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -128,8 +128,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass if (!HighlightLevelUtil.shouldInspect(myFile)) return; final InspectionManagerEx iManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); final InspectionProfileWrapper profile = myProfileWrapper; - final List tools = DumbService.getInstance(myProject).filterByDumbAwareness(getInspectionTools(profile)); - inspect(tools, iManager, true, true, progress); + inspect(getInspectionTools(profile), iManager, true, true, DumbService.isDumb(myProject), progress); } finally { disposeDescriptors(); @@ -145,10 +144,9 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass for (InspectionProfileEntry toolWrapper : toolWrappers) { tool2Wrapper.put(((LocalInspectionToolWrapper)toolWrapper).getTool(), (LocalInspectionToolWrapper)toolWrapper); } - List tools = new ArrayList(tool2Wrapper.keySet()); ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); - inspect(tools, iManager, false, false, progress); + inspect(new ArrayList(tool2Wrapper.values()), iManager, false, false, false, progress); addDescriptorsFromInjectedResults(tool2Wrapper, iManager); List resultList = result.get(myFile); if (resultList == null) return; @@ -206,25 +204,43 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } } - private void inspect(@NotNull final List tools, + private void inspect(@NotNull final List toolWrappers, @NotNull final InspectionManagerEx iManager, final boolean isOnTheFly, boolean failFastOnAcquireReadAction, + boolean checkDumbAwareness, @NotNull final ProgressIndicator indicator) { myFailFastOnAcquireReadAction = failFastOnAcquireReadAction; - if (tools.isEmpty()) return; + if (toolWrappers.isEmpty()) return; List inside = new ArrayList(); List outside = new ArrayList(); Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, outside, HighlightLevelUtil.AnalysisLevel.HIGHLIGHT_AND_INSPECT,true); + Set languages = new HashSet(); + for (PsiElement element : inside) { + languages.add(element.getLanguage().getID()); + } + for (PsiElement element : outside) { + languages.add(element.getLanguage().getID()); + } + List tools = new ArrayList(); + for (LocalInspectionToolWrapper wrapper : toolWrappers) { + if (wrapper.getLanguage() == null || languages.contains(wrapper.getLanguage())) { + LocalInspectionTool tool = wrapper.getTool(); + if (!checkDumbAwareness || tool instanceof DumbAware) { + tools.add(tool); + } + } + } + setProgressLimit(1L * tools.size() * 2); final LocalInspectionToolSession session = new LocalInspectionToolSession(myFile, myStartOffset, myEndOffset); List> init = new ArrayList>(); visitPriorityElementsAndInit(tools, iManager, isOnTheFly, indicator, inside, session, init); - visitRestElementsAndCleanup(tools,iManager,isOnTheFly, indicator, outside, session, init); + visitRestElementsAndCleanup(tools, iManager, isOnTheFly, indicator, outside, session, init); indicator.checkCanceled(); @@ -640,7 +656,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass return new ArrayList(result); } - List getInspectionTools(InspectionProfileWrapper profile) { + List getInspectionTools(InspectionProfileWrapper profile) { return profile.getHighlightingLocalInspectionTools(myFile); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java index 53f040a77f57..4919a01e04f2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPassFactory.java @@ -16,9 +16,12 @@ package com.intellij.codeInsight.daemon.impl; -import com.intellij.codeHighlighting.*; -import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeHighlighting.MainHighlightingPassFactory; +import com.intellij.codeHighlighting.Pass; +import com.intellij.codeHighlighting.TextEditorHighlightingPass; +import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar; import com.intellij.codeInspection.ex.InspectionProfileWrapper; +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -26,7 +29,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.PsiFile; -import com.intellij.util.PlatformUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -74,10 +76,10 @@ public class LocalInspectionsPassFactory extends AbstractProjectComponent implem super(file, document, textRange.getStartOffset(), textRange.getEndOffset(), visibleRange, true); } - List getInspectionTools(InspectionProfileWrapper profile) { - List tools = super.getInspectionTools(profile); - List result = new ArrayList(tools.size()); - for (LocalInspectionTool tool : tools) { + List getInspectionTools(InspectionProfileWrapper profile) { + List tools = super.getInspectionTools(profile); + List result = new ArrayList(tools.size()); + for (LocalInspectionToolWrapper tool : tools) { if (!tool.runForWholeFile()) result.add(tool); } return result; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java index 0c3555b409ef..85ddd9622960 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java @@ -23,6 +23,7 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar; import com.intellij.codeInsight.daemon.DaemonBundle; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.ex.InspectionProfileWrapper; +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.editor.Editor; @@ -94,11 +95,12 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone myFileTools.containsKey(file) && !myFileTools.get(file)) { return null; } + return new LocalInspectionsPass(file, editor.getDocument(), 0, file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true) { - List getInspectionTools(InspectionProfileWrapper profile) { - List tools = super.getInspectionTools(profile); - List result = new ArrayList(); - for (LocalInspectionTool tool : tools) { + List getInspectionTools(InspectionProfileWrapper profile) { + List tools = super.getInspectionTools(profile); + List result = new ArrayList(tools.size()); + for (LocalInspectionToolWrapper tool : tools) { if (tool.runForWholeFile()) result.add(tool); } myFileTools.put(file, !result.isEmpty()); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java index 729f62de1aa1..3af0ac3509af 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileWrapper.java @@ -18,7 +18,6 @@ package com.intellij.codeInspection.ex; import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; @@ -55,15 +54,13 @@ public class InspectionProfileWrapper { return (InspectionTool[])myProfile.getInspectionTools(element); } - public List getHighlightingLocalInspectionTools(PsiElement element) { - List enabled = new ArrayList(); + public List getHighlightingLocalInspectionTools(PsiElement element) { + List enabled = new ArrayList(); final InspectionTool[] tools = getInspectionTools(element); checkInspectionsDuplicates(tools); for (InspectionTool tool : tools) { - if (tool instanceof LocalInspectionToolWrapper) { - if (myProfile.isToolEnabled(HighlightDisplayKey.find(tool.getShortName()), element)) { - enabled.add(((LocalInspectionToolWrapper)tool).getTool()); - } + if (tool instanceof LocalInspectionToolWrapper && myProfile.isToolEnabled(HighlightDisplayKey.find(tool.getShortName()), element)) { + enabled.add((LocalInspectionToolWrapper)tool); } } return enabled; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java index 2f4bfcfc60bc..778c359c79a3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java @@ -60,6 +60,11 @@ public abstract class InspectionToolWrapper - diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java b/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java index b6f214fb4b4c..4a68d569c2df 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/ui/SpellCheckingEditorCustomization.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.intention.IntentionManager; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionProfileWrapper; +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; @@ -46,7 +47,7 @@ import java.util.Map; */ public class SpellCheckingEditorCustomization extends AbstractEditorCustomization { - private static final Map SPELL_CHECK_TOOLS = new HashMap(); + private static final Map SPELL_CHECK_TOOLS = new HashMap(); private static final boolean READY = init(); @SuppressWarnings({"unchecked"}) @@ -58,7 +59,7 @@ public class SpellCheckingEditorCustomization extends AbstractEditorCustomizatio for (Class inspectionClass : inspectionClasses) { try { LocalInspectionTool tool = inspectionClass.newInstance(); - SPELL_CHECK_TOOLS.put(tool.getID(), tool); + SPELL_CHECK_TOOLS.put(tool.getID(), new LocalInspectionToolWrapper(tool)); } catch (Throwable e) { return false; @@ -144,19 +145,19 @@ public class SpellCheckingEditorCustomization extends AbstractEditorCustomizatio } @Override - public List getHighlightingLocalInspectionTools(PsiElement element) { - List result = new ArrayList(myDelegate.getHighlightingLocalInspectionTools(element)); + public List getHighlightingLocalInspectionTools(PsiElement element) { + List result = new ArrayList(myDelegate.getHighlightingLocalInspectionTools(element)); if (myUseSpellCheck) { - Map spellingTools = new HashMap(SPELL_CHECK_TOOLS); - for (LocalInspectionTool tool : result) { + Map spellingTools = new HashMap(SPELL_CHECK_TOOLS); + for (LocalInspectionToolWrapper tool : result) { spellingTools.remove(tool.getID()); } result.addAll(spellingTools.values()); } else { for (int i = result.size() - 1; i >= 0; i--) { - LocalInspectionTool tool = result.get(i); + LocalInspectionToolWrapper tool = result.get(i); if (SPELL_CHECK_TOOLS.containsKey(tool.getID())) { result.remove(i); } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 83c6945c0a07..47141ea45cf0 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -422,7 +422,7 @@