inspection toolwindow: carefully extract possible calculation scope for "run inspecti...
authorDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Thu, 26 May 2016 17:08:24 +0000 (20:08 +0300)
committerDmitry Batkovich <dmitry.batkovich@jetbrains.com>
Thu, 26 May 2016 17:43:20 +0000 (20:43 +0300)
platform/lang-impl/src/com/intellij/codeInspection/actions/RunInspectionIntention.java
platform/lang-impl/src/com/intellij/codeInspection/ui/actions/KeyAwareInspectionViewAction.java

index 27e1c0a09090d21372ecb08871e43203a2b90b96..4b57ed02b12c06b45dac41e80b3e3ffbd1069899 100644 (file)
@@ -40,6 +40,7 @@ import com.intellij.psi.PsiFile;
 import com.intellij.util.IncorrectOperationException;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.LinkedHashSet;
 
@@ -79,7 +80,6 @@ public class RunInspectionIntention implements IntentionAction, HighPriorityActi
 
   @Override
   public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
-    final InspectionManagerEx managerEx = (InspectionManagerEx)InspectionManager.getInstance(project);
     final Module module = file != null ? ModuleUtilCore.findModuleForPsiElement(file) : null;
     AnalysisScope analysisScope = new AnalysisScope(project);
     if (file != null) {
@@ -89,21 +89,29 @@ public class RunInspectionIntention implements IntentionAction, HighPriorityActi
       }
     }
 
+    selectScopeAndRunInspection(myShortName, analysisScope, module, file, project);
+  }
+
+  public static void selectScopeAndRunInspection(@NotNull String toolShortName,
+                                                 @NotNull AnalysisScope customScope,
+                                                 @Nullable Module module,
+                                                 @Nullable PsiElement context,
+                                                 @NotNull Project project) {
     final BaseAnalysisActionDialog dlg = new BaseAnalysisActionDialog(
       AnalysisScopeBundle.message("specify.analysis.scope", InspectionsBundle.message("inspection.action.title")),
       AnalysisScopeBundle.message("analysis.scope.title", InspectionsBundle.message("inspection.action.noun")),
       project,
-      analysisScope,
+      customScope,
       module != null ? module.getName() : null,
-      true, AnalysisUIOptions.getInstance(project), file);
+      true, AnalysisUIOptions.getInstance(project), context);
     if (!dlg.showAndGet()) {
       return;
     }
     final AnalysisUIOptions uiOptions = AnalysisUIOptions.getInstance(project);
-    analysisScope = dlg.getScope(uiOptions, analysisScope, project, module);
-    final InspectionToolWrapper wrapper = LocalInspectionToolWrapper.findTool2RunInBatch(project, file, myShortName);
-    LOG.assertTrue(wrapper != null, "Can't find tool with name = \"" + myShortName + "\"");
-    rerunInspection(wrapper, managerEx, analysisScope, file);
+    customScope = dlg.getScope(uiOptions, customScope, project, module);
+    final InspectionToolWrapper wrapper = LocalInspectionToolWrapper.findTool2RunInBatch(project, context, toolShortName);
+    LOG.assertTrue(wrapper != null, "Can't find tool with name = \"" + toolShortName + "\"");
+    rerunInspection(wrapper, (InspectionManagerEx)InspectionManager.getInstance(project), customScope, context);
   }
 
   public static void rerunInspection(@NotNull InspectionToolWrapper toolWrapper,
index c5151ecb407879a99acaa81eae88ba49d4853947..685b87989b8e6bdac9de4fcff95e00ed0718e722 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.codeInspection.ui.actions;
 
 import com.intellij.CommonBundle;
+import com.intellij.analysis.AnalysisScope;
 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
 import com.intellij.codeInspection.InspectionProfile;
@@ -29,21 +30,30 @@ import com.intellij.codeInspection.reference.RefElement;
 import com.intellij.codeInspection.reference.RefEntity;
 import com.intellij.codeInspection.ui.InspectionResultsView;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
 import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * @author Dmitry Batkovich
  */
 public abstract class KeyAwareInspectionViewAction extends InspectionViewActionBase {
+  private static final Logger LOG = Logger.getInstance(KeyAwareInspectionViewAction.class);
+
   public KeyAwareInspectionViewAction(String name) {
     super(name);
   }
@@ -122,9 +132,53 @@ public abstract class KeyAwareInspectionViewAction extends InspectionViewActionB
 
     @Override
     protected void actionPerformed(@NotNull InspectionResultsView view, @NotNull HighlightDisplayKey key) {
-      final PsiElement psiElement = getPsiElement(view);
-      assert psiElement != null;
-      new RunInspectionIntention(key).invoke(view.getProject(), null, psiElement.getContainingFile());
+      Set<PsiFile> files = new THashSet<>();
+      for (RefEntity entity : view.getTree().getSelectedElements()) {
+        if (entity instanceof RefElement && entity.isValid()) {
+          final PsiElement element = ((RefElement)entity).getElement();
+          final PsiFile file = element.getContainingFile();
+          files.add(file);
+        }
+      }
+
+      boolean useModule = true;
+      Module module = null;
+      for (PsiFile file : files) {
+        final Module currentFileModule = ModuleUtilCore.findModuleForPsiElement(file);
+        if (currentFileModule != null) {
+          if (module == null) {
+            module = currentFileModule;
+          }
+          else if (currentFileModule != module) {
+            useModule = false;
+            break;
+          }
+        }
+        else {
+          useModule = false;
+          break;
+        }
+      }
+
+      final PsiElement context;
+      final AnalysisScope scope;
+      switch (files.size()) {
+        case 0:
+          context = null;
+          scope = new AnalysisScope(view.getProject());
+          break;
+        case 1:
+          final PsiFile theFile = ContainerUtil.getFirstItem(files);
+          LOG.assertTrue(theFile != null);
+          context = theFile;
+          scope = new AnalysisScope(theFile);
+          break;
+        default:
+          context = null;
+          scope = new AnalysisScope(view.getProject(), files.stream().map(PsiFile::getVirtualFile).collect(Collectors.toList()));
+      }
+
+      RunInspectionIntention.selectScopeAndRunInspection(key.toString(), scope, useModule ? module : null, context, view.getProject());
     }
 
     @Nullable