diff --git a/platform/structuralsearch/source/META-INF/structuralsearch.xml b/platform/structuralsearch/source/META-INF/structuralsearch.xml index 72e24e15ee0f..96611ee2e9dc 100644 --- a/platform/structuralsearch/source/META-INF/structuralsearch.xml +++ b/platform/structuralsearch/source/META-INF/structuralsearch.xml @@ -12,9 +12,6 @@ - - diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java index f95c18c746df..8f92555dd019 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/MatcherImpl.java @@ -38,9 +38,7 @@ import com.intellij.util.indexing.FileBasedIndex; import org.jetbrains.annotations.NotNull; import java.lang.ref.SoftReference; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; /** * This class makes program structure tree matching: @@ -193,10 +191,11 @@ public class MatcherImpl { options.setScope(scope); } - public CompiledOptions precompileOptions(List configurations) { - final List> contexts = new ArrayList>(); - + public void precompileOptions(List configurations, final Map out) { for (final Configuration configuration : configurations) { + if (out.containsKey(configuration)) { + continue; + } final MatchContext matchContext = new MatchContext(); matchContext.setMatcher(visitor); final MatchOptions matchOptions = configuration.getMatchOptions(); @@ -206,16 +205,15 @@ public class MatcherImpl { @Override public void run() { try { - CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, matchOptions); + final CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, matchOptions); matchContext.setPattern(compiledPattern); - contexts.add(Pair.create(matchContext, configuration)); + out.put(configuration, matchContext); } catch (UnsupportedPatternException ignored) {} catch (MalformedPatternException ignored) {} } }); } - return new CompiledOptions(contexts); } Project getProject() { diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java index 10a88a45ca13..8e0d4935bfef 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspection.java @@ -23,9 +23,7 @@ import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.structuralsearch.MatchResult; @@ -41,7 +39,6 @@ import com.intellij.structuralsearch.plugin.replace.impl.Replacer; import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration; import com.intellij.structuralsearch.plugin.ui.Configuration; import com.intellij.structuralsearch.plugin.ui.ConfigurationManager; -import com.intellij.structuralsearch.plugin.ui.SearchContext; import com.intellij.util.PairProcessor; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -59,7 +56,7 @@ public class SSBasedInspection extends LocalInspectionTool { private static final Object LOCK = new Object(); // hack to avoid race conditions in SSR static final String SHORT_NAME = "SSBasedInspection"; - private List myConfigurations = new ArrayList(); + private final List myConfigurations = new ArrayList(); private final Set myProblemsReported = new HashSet(1); @Override @@ -96,13 +93,12 @@ public class SSBasedInspection extends LocalInspectionTool { @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) { - final MatcherImpl.CompiledOptions compiledOptions = - SSBasedInspectionCompiledPatternsCache.getCompiledOptions(holder.getProject()); + final Map compiledOptions = + SSBasedInspectionCompiledPatternsCache.getCompiledOptions(myConfigurations, holder.getProject()); - if (compiledOptions == null) return super.buildVisitor(holder, isOnTheFly); + if (compiledOptions.isEmpty()) return super.buildVisitor(holder, isOnTheFly); return new PsiElementVisitor() { - final List> contexts = compiledOptions.getMatchContexts(); final Matcher matcher = new Matcher(holder.getManager().getProject()); final PairProcessor processor = new PairProcessor() { @Override @@ -122,9 +118,8 @@ public class SSBasedInspection extends LocalInspectionTool { synchronized (LOCK) { if (LexicalNodesFilter.getInstance().accepts(element)) return; final SsrFilteringNodeIterator matchedNodes = new SsrFilteringNodeIterator(element); - for (Pair pair : contexts) { - Configuration configuration = pair.second; - MatchContext context = pair.first; + for (Configuration configuration : myConfigurations) { + final MatchContext context = compiledOptions.get(configuration); if (MatcherImpl.checkIfShouldAttemptToMatch(context, matchedNodes)) { final int nodeCount = context.getPattern().getNodeCount(); @@ -179,23 +174,12 @@ public class SSBasedInspection extends LocalInspectionTool { @Override @Nullable public JComponent createOptionsPanel() { - return new SSBasedInspectionOptions(myConfigurations){ - @Override - public void configurationsChanged(final SearchContext searchContext) { - super.configurationsChanged(searchContext); - SSBasedInspectionCompiledPatternsCache.precompileConfigurations(searchContext.getProject(), SSBasedInspection.this); - InspectionProfileManager.getInstance().fireProfileChanged(null); - } - }.getComponent(); + return new SSBasedInspectionOptions(myConfigurations).getComponent(); } @TestOnly - public void setConfigurations(final List configurations, final Project project) { - myConfigurations = configurations; - SSBasedInspectionCompiledPatternsCache.setCompiledOptions(project, configurations); - } - - public List getConfigurations() { - return myConfigurations; + public void setConfigurations(@NotNull final List configurations, @NotNull final Project project) { + myConfigurations.clear(); + myConfigurations.addAll(configurations); } } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java index 49b55f8be24c..f8add2370037 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionCompiledPatternsCache.java @@ -1,84 +1,50 @@ package com.intellij.structuralsearch.inspection.highlightTemplate; -import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.util.Key; -import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.structuralsearch.Matcher; -import com.intellij.structuralsearch.impl.matcher.MatcherImpl; +import com.intellij.structuralsearch.impl.matcher.MatchContext; import com.intellij.structuralsearch.plugin.ui.Configuration; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; -import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author Eugene.Kudelevsky */ -public class SSBasedInspectionCompiledPatternsCache implements StartupActivity { - private static final Key COMPILED_OPTIONS_KEY = Key.create("SSR_INSPECTION_COMPILED_OPTIONS_KEY"); +public class SSBasedInspectionCompiledPatternsCache { - @Override - public void runActivity(@NotNull final Project project) { - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - @Override - public void run() { - precompileConfigurations(project, null); + private static final Key> COMPILED_OPTIONS_KEY = Key.create("SSR_INSPECTION_COMPILED_OPTIONS_KEY"); + + @NotNull + static Map getCompiledOptions(@NotNull List configurations, @NotNull Project project) { + final Map cache = + ObjectUtils.notNull(project.getUserData(COMPILED_OPTIONS_KEY), new HashMap()); + if (!areConfigurationsInCache(configurations, cache)) { + final Matcher matcher = new Matcher(project); + matcher.precompileOptions(configurations, cache); + project.putUserData(COMPILED_OPTIONS_KEY, cache); + } + return cache; + } + + private static boolean areConfigurationsInCache(@NotNull List configurations, + @NotNull Map cache) { + for (Configuration configuration : configurations) { + if (!(cache.containsKey(configuration))) { + return false; } - }); + } + return true; } - static void precompileConfigurations(final Project project, @Nullable final SSBasedInspection ssBasedInspection) { - if (project.isDisposed()) { - return; + public static void removeFromCache(Configuration configuration, @NotNull Project project) { + final Map cache = project.getUserData(COMPILED_OPTIONS_KEY); + if (cache != null) { + cache.remove(configuration); } - final MatcherImpl.CompiledOptions currentCompiledOptions = getCompiledOptions(project); - - final SSBasedInspection inspection = ssBasedInspection != null ? ssBasedInspection : getInspection(project); - if (inspection == null) { - return; - } - - List configurations = inspection.getConfigurations(); - if (configurations == null) { - configurations = Collections.emptyList(); - } - - if ((currentCompiledOptions == null || currentCompiledOptions.getMatchContexts().isEmpty()) && - configurations.isEmpty()) { - return; - } - - final Matcher matcher = new Matcher(project); - final MatcherImpl.CompiledOptions compiledOptions = matcher.precompileOptions(configurations); - - if (compiledOptions != null) { - project.putUserData(COMPILED_OPTIONS_KEY, compiledOptions); - } - } - - @Nullable - private static SSBasedInspection getInspection(@NotNull Project project) { - final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); - final InspectionToolWrapper entry = profile.getInspectionTool(SSBasedInspection.SHORT_NAME, project); - - return entry == null ? null : (SSBasedInspection)entry.getTool(); - } - - @Nullable - static MatcherImpl.CompiledOptions getCompiledOptions(@NotNull Project project) { - return project.getUserData(COMPILED_OPTIONS_KEY); - } - - @TestOnly - static void setCompiledOptions(@NotNull Project project, @NotNull List configurations) { - final Matcher matcher = new Matcher(project); - project.putUserData(COMPILED_OPTIONS_KEY, - matcher.precompileOptions(configurations)); } } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java index 943d92c65305..53067edf22e1 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/inspection/highlightTemplate/SSBasedInspectionOptions.java @@ -15,6 +15,7 @@ */ package com.intellij.structuralsearch.inspection.highlightTemplate; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.DumbService; @@ -32,7 +33,6 @@ import org.jetbrains.annotations.NonNls; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; -import java.util.Iterator; import java.util.List; /** @@ -100,6 +100,7 @@ public class SSBasedInspectionOptions { public void configurationsChanged(final SearchContext searchContext) { ((MyListModel)myTemplatesList.getModel()).fireContentsChanged(); + DaemonCodeAnalyzer.getInstance(searchContext.getProject()).restart(); } public JPanel getComponent() { @@ -152,18 +153,14 @@ public class SSBasedInspectionOptions { }).setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { - Object[] selected = myTemplatesList.getSelectedValues(); + final SearchContext context = createSearchContext(); + final Object[] selected = myTemplatesList.getSelectedValues(); for (Object o : selected) { - Configuration configuration = (Configuration)o; - Iterator iterator = myConfigurations.iterator(); - while (iterator.hasNext()) { - Configuration configuration1 = iterator.next(); - if (configuration1.getName().equals(configuration.getName())) { - iterator.remove(); - } - } + final Configuration configuration = (Configuration)o; + myConfigurations.remove(configuration); + SSBasedInspectionCompiledPatternsCache.removeFromCache(configuration, context.getProject()); } - configurationsChanged(createSearchContext()); + configurationsChanged(context); } }).setRemoveActionUpdater(new AnActionButtonUpdater() { @Override @@ -225,9 +222,11 @@ public class SSBasedInspectionOptions { if (configuration == null) return; SearchDialog dialog = createDialog(new SearchDialogFactory() { + @Override public SearchDialog createDialog(SearchContext searchContext) { if (configuration instanceof SearchConfiguration) { return new SearchDialog(searchContext, false, false) { + @Override public Configuration createConfiguration() { SearchConfiguration newConfiguration = new SearchConfiguration(); copyConfiguration(configuration, newConfiguration); @@ -237,6 +236,7 @@ public class SSBasedInspectionOptions { } else { return new ReplaceDialog(searchContext, false, false) { + @Override public Configuration createConfiguration() { ReplaceConfiguration newConfiguration = new ReplaceConfiguration(); copyConfiguration(configuration, newConfiguration); @@ -251,16 +251,22 @@ public class SSBasedInspectionOptions { if (!dialog.showAndGet()) { return; } - Configuration newConfiguration = dialog.getConfiguration(); - copyConfiguration(newConfiguration, configuration); - configurationsChanged(dialog.getSearchContext()); + final Configuration newConfiguration = dialog.getConfiguration(); + final int index = myConfigurations.indexOf(configuration); + myConfigurations.remove(index); + myConfigurations.add(index, newConfiguration); + final SearchContext context = dialog.getSearchContext(); + SSBasedInspectionCompiledPatternsCache.removeFromCache(configuration, context.getProject()); + configurationsChanged(context); } private class MyListModel extends AbstractListModel { + @Override public int getSize() { return myConfigurations.size(); } + @Override public Object getElementAt(int index) { return index < myConfigurations.size() ? myConfigurations.get(index) : null; }