diff options
Diffstat (limited to 'platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java')
-rw-r--r-- | platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java | 139 |
1 files changed, 107 insertions, 32 deletions
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java index ab9581f1d7d9..713b545c6247 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -25,16 +25,21 @@ import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.RefManagerImpl; import com.intellij.codeInspection.reference.RefVisitor; import com.intellij.concurrency.JobLauncher; +import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; +import com.intellij.util.containers.SmartHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -78,29 +83,30 @@ public class InspectionEngine { } @NotNull - public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools, + public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionToolWrapper> toolWrappers, @NotNull final PsiFile file, @NotNull final InspectionManager iManager, final boolean isOnTheFly, boolean failFastOnAcquireReadAction, @NotNull final ProgressIndicator indicator) { - final Map<String, List<ProblemDescriptor>> problemDescriptors = inspectEx(tools, file, iManager, isOnTheFly, failFastOnAcquireReadAction, indicator); + final Map<String, List<ProblemDescriptor>> problemDescriptors = inspectEx(toolWrappers, file, iManager, isOnTheFly, failFastOnAcquireReadAction, indicator); final List<ProblemDescriptor> result = new ArrayList<ProblemDescriptor>(); - for (List<ProblemDescriptor> group : problemDescriptors.values()) + for (List<ProblemDescriptor> group : problemDescriptors.values()) { result.addAll(group); + } return result; } // public accessibility for Upsource @NotNull - public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools, + public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionToolWrapper> toolWrappers, @NotNull final PsiFile file, @NotNull final InspectionManager iManager, final boolean isOnTheFly, boolean failFastOnAcquireReadAction, @NotNull final ProgressIndicator indicator) { - if (tools.isEmpty()) return Collections.emptyMap(); + if (toolWrappers.isEmpty()) return Collections.emptyMap(); final Map<String, List<ProblemDescriptor>> resultDescriptors = new ConcurrentHashMap<String, List<ProblemDescriptor>>(); final List<PsiElement> elements = new ArrayList<PsiElement>(); @@ -109,32 +115,32 @@ public class InspectionEngine { Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, new ArrayList<ProperTextRange>(), Collections.<PsiElement>emptyList(), Collections.<ProperTextRange>emptyList(), true, Condition.TRUE); - boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress( - tools, indicator, failFastOnAcquireReadAction, - new Processor<LocalInspectionTool>() { - @Override - public boolean process(final LocalInspectionTool tool) { - ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly); - createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, null); - - tool.inspectionFinished(session, holder); - - if (holder.hasResults()) { - resultDescriptors.put(tool.getShortName(), ContainerUtil.filter(holder.getResults(), new Condition<ProblemDescriptor>() { - @Override - public boolean value(ProblemDescriptor descriptor) { - PsiElement element = descriptor.getPsiElement(); - if (element != null) { - return !SuppressionUtil.inspectionResultSuppressed(element, tool); - } - return true; - } - })); - } + MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = getToolsForElements(toolWrappers, DumbService.isDumb(file.getProject()), elements, Collections.<PsiElement>emptyList()); + List<Map.Entry<LocalInspectionToolWrapper, Collection<String>>> entries = new ArrayList<Map.Entry<LocalInspectionToolWrapper, Collection<String>>>(toolToLanguages.entrySet()); + Processor<Map.Entry<LocalInspectionToolWrapper, Collection<String>>> processor = new Processor<Map.Entry<LocalInspectionToolWrapper, Collection<String>>>() { + @Override + public boolean process(final Map.Entry<LocalInspectionToolWrapper, Collection<String>> entry) { + ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly); + final LocalInspectionTool tool = entry.getKey().getTool(); + Collection<String> languages = entry.getValue(); + createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, languages); - return true; + tool.inspectionFinished(session, holder); + + if (holder.hasResults()) { + resultDescriptors.put(tool.getShortName(), ContainerUtil.filter(holder.getResults(), new Condition<ProblemDescriptor>() { + @Override + public boolean value(ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + return element == null || !SuppressionUtil.inspectionResultSuppressed(element, tool); + } + })); } - }); + + return true; + } + }; + JobLauncher.getInstance().invokeConcurrentlyUnderProgress(entries, indicator, failFastOnAcquireReadAction, processor); return resultDescriptors; } @@ -149,8 +155,7 @@ public class InspectionEngine { refManager.inspectionReadActionStarted(); try { if (toolWrapper instanceof LocalInspectionToolWrapper) { - LocalInspectionTool localTool = ((LocalInspectionToolWrapper)toolWrapper).getTool(); - return inspect(Collections.singletonList(localTool), file, inspectionManager, false, false, new EmptyProgressIndicator()); + return inspect(Collections.singletonList((LocalInspectionToolWrapper)toolWrapper), file, inspectionManager, false, false, new EmptyProgressIndicator()); } if (toolWrapper instanceof GlobalInspectionToolWrapper) { final GlobalInspectionTool globalTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool(); @@ -226,4 +231,74 @@ public class InspectionEngine { } } } + + @NotNull + public static <T extends InspectionToolWrapper> MultiMap<T, String> getToolsForElements(@NotNull List<T> toolWrappers, + boolean checkDumbAwareness, + @NotNull List<PsiElement> inside, + @NotNull List<PsiElement> outside) { + Set<Language> languages = new SmartHashSet<Language>(); + Map<String, Language> langIds = new SmartHashMap<String, Language>(); + Set<String> dialects = new SmartHashSet<String>(); + calculateDialects(inside, languages, langIds, dialects); + calculateDialects(outside, languages, langIds, dialects); + MultiMap<T, String> toolToLanguages = new MultiMap<T, String>() { + @NotNull + @Override + protected Collection<String> createCollection() { + return new SmartHashSet<String>(); + } + + @NotNull + @Override + protected Collection<String> createEmptyCollection() { + return Collections.emptySet(); + } + }; + for (T wrapper : toolWrappers) { + ProgressManager.checkCanceled(); + String language = wrapper.getLanguage(); + if (language == null) { + InspectionProfileEntry tool = wrapper.getTool(); + if (!checkDumbAwareness || tool instanceof DumbAware) { + toolToLanguages.put(wrapper, null); + } + continue; + } + Language lang = langIds.get(language); + if (lang != null) { + InspectionProfileEntry tool = wrapper.getTool(); + if (!checkDumbAwareness || tool instanceof DumbAware) { + toolToLanguages.putValue(wrapper, language); + if (wrapper.applyToDialects()) { + for (Language dialect : lang.getDialects()) { + toolToLanguages.putValue(wrapper, dialect.getID()); + } + } + } + } + else if (wrapper.applyToDialects() && dialects.contains(language)) { + InspectionProfileEntry tool = wrapper.getTool(); + if (!checkDumbAwareness || tool instanceof DumbAware) { + toolToLanguages.putValue(wrapper, language); + } + } + } + return toolToLanguages; + } + + private static void calculateDialects(@NotNull List<PsiElement> inside, + @NotNull Set<Language> languages, + @NotNull Map<String, Language> langIds, + @NotNull Set<String> dialects) { + for (PsiElement element : inside) { + Language language = element.getLanguage(); + if (languages.add(language)) { + langIds.put(language.getID(), language); + for (Language dialect : language.getDialects()) { + dialects.add(dialect.getID()); + } + } + } + } } |