SSR: cache last compiled pattern in project instead of static field (IDEA-198830)

GitOrigin-RevId: af9d81e4bb454b9b929b0907491be77b05d1e800
This commit is contained in:
Bas Leijdekkers
2019-11-07 17:58:24 +01:00
committed by intellij-monorepo-bot
parent 27091e1241
commit f0a384bd65
2 changed files with 23 additions and 47 deletions

View File

@@ -7,6 +7,7 @@ import com.intellij.dupLocator.util.NodeFilter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
@@ -15,7 +16,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.reference.SoftReference;
import com.intellij.structuralsearch.*;
import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
import com.intellij.structuralsearch.impl.matcher.MatcherImplUtil;
@@ -46,31 +46,31 @@ import java.util.regex.Pattern;
* Compiles the handlers for usability
*/
public class PatternCompiler {
private static final Object LOCK = new Object();
private static SoftReference<CompiledPattern> ourLastCompiledPattern;
private static MatchOptions ourLastMatchOptions;
private static boolean ourLastCompileSuccessful = true;
private static final Key<LastResult> SSR_LAST_COMPILED_PATTERN = new Key<>("SSR_LAST_COMPILED_PATTERN");
private static String ourLastSearchPlan;
public static CompiledPattern compilePattern(Project project, MatchOptions options,
boolean checkForErrors, boolean optimizeScope)
public static CompiledPattern compilePattern(Project project, MatchOptions options, boolean checkForErrors, boolean optimizeScope)
throws MalformedPatternException, NoMatchFoundException {
if (!checkForErrors) {
synchronized (LOCK) {
if (options.equals(ourLastMatchOptions) &&
(!(options.getScope() instanceof GlobalSearchScope) || options.getScope() == ourLastMatchOptions.getScope())) {
if (!ourLastCompileSuccessful) return null;
assert ourLastCompiledPattern != null;
final CompiledPattern lastCompiledPattern = ourLastCompiledPattern.get();
if (lastCompiledPattern != null) {
return lastCompiledPattern;
}
}
final LastResult lastResult = SSR_LAST_COMPILED_PATTERN.get(project);
if (lastResult != null && options.equals(lastResult.options) &&
(!(options.getScope() instanceof GlobalSearchScope) || options.getScope() == lastResult.options.getScope())) {
return lastResult.pattern;
}
}
return !ApplicationManager.getApplication().isDispatchThread()
? ReadAction.compute(() -> doCompilePattern(project, options, checkForErrors, optimizeScope))
: doCompilePattern(project, options, checkForErrors, optimizeScope);
return ReadAction.compute(() -> doCompilePattern(project, options, checkForErrors, optimizeScope));
}
private static class LastResult {
public final MatchOptions options;
public final CompiledPattern pattern;
private LastResult(MatchOptions options, CompiledPattern pattern) {
this.options = options;
this.pattern = pattern;
}
}
@NotNull
@@ -93,17 +93,9 @@ public class PatternCompiler {
try {
checkForUnknownVariables(pattern, elements);
pattern.setNodes(elements);
synchronized (LOCK) {
ourLastMatchOptions = options.copy();
ourLastCompiledPattern = new SoftReference<>(result);
ourLastCompileSuccessful = true;
}
project.putUserData(SSR_LAST_COMPILED_PATTERN, new LastResult(options.copy(), result));
} catch (MalformedPatternException e) {
synchronized (LOCK) {
ourLastMatchOptions = options.copy();
ourLastCompiledPattern = null;
ourLastCompileSuccessful = false;
}
project.putUserData(SSR_LAST_COMPILED_PATTERN, new LastResult(options.copy(), null));
throw e;
}
if (checkForErrors) {
@@ -609,13 +601,4 @@ public class PatternCompiler {
private static void addPredicate(SubstitutionHandler handler, @NotNull MatchPredicate predicate) {
handler.setPredicate(handler.getPredicate() == null ? predicate : new AndPredicate(handler.getPredicate(), predicate));
}
public static void clearStaticCaches() {
synchronized (LOCK) {
ourLastMatchOptions = null;
ourLastCompiledPattern = null;
ourLastSearchPlan = null;
ourLastCompileSuccessful = false;
}
}
}

View File

@@ -1,14 +1,12 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.structuralsearch.plugin;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler;
import org.jetbrains.annotations.NotNull;
public final class StructuralSearchPlugin implements Disposable {
public final class StructuralSearchPlugin {
private boolean searchInProgress;
private DialogWrapper myDialog;
@@ -31,9 +29,4 @@ public final class StructuralSearchPlugin implements Disposable {
public static StructuralSearchPlugin getInstance(@NotNull Project project) {
return ServiceManager.getService(project, StructuralSearchPlugin.class);
}
@Override
public void dispose() {
PatternCompiler.clearStaticCaches();
}
}