mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
introduce DumbAwareSearchParameters and delay reference search executors until smart mode by default
This commit is contained in:
+2
-1
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.search.searches;
|
||||
|
||||
import com.intellij.openapi.application.DumbAwareSearchParameters;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
@@ -33,7 +34,7 @@ public class MethodReferencesSearch extends ExtensibleQueryFactory<PsiReference,
|
||||
public static final ExtensionPointName<QueryExecutor> EP_NAME = ExtensionPointName.create("com.intellij.methodReferencesSearch");
|
||||
public static final MethodReferencesSearch INSTANCE = new MethodReferencesSearch();
|
||||
|
||||
public static class SearchParameters {
|
||||
public static class SearchParameters implements DumbAwareSearchParameters {
|
||||
private final PsiMethod myMethod;
|
||||
private final Project myProject;
|
||||
private final SearchScope myScope;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.application;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A marker interface for {@link QueryExecutorBase} parameters which indicates that searches should only be executed when indexing is complete.
|
||||
* The query executors that are not {@link com.intellij.openapi.project.DumbAware} are delayed in processing until index is ready.
|
||||
*
|
||||
* @author peter
|
||||
*/
|
||||
public interface DumbAwareSearchParameters {
|
||||
@NotNull
|
||||
Project getProject();
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.intellij.openapi.application;
|
||||
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -7,15 +10,31 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* An adapter for {@link QueryExecutor} interface which makes it easier to write implementations. It provides a possibility to
|
||||
* automatically wrap the implementation code into a read action. During indexing, query executors that don't implement {@link com.intellij.openapi.project.DumbAware}
|
||||
* (but need to be run in a read action), are delayed until indexing is complete, given that search parameters implement {@link DumbAwareSearchParameters}.
|
||||
* <p/>
|
||||
* Besides, {@link #processQuery(Object, Processor)} doesn't require to return a boolean value and thus it's harder to cancel the whole search
|
||||
* by accidentally returning false.
|
||||
*
|
||||
* @see Application#runReadAction(Computable)
|
||||
* @see DumbService
|
||||
*
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class QueryExecutorBase<Result, Params> implements QueryExecutor<Result, Params> {
|
||||
private final boolean myRequireReadAction;
|
||||
|
||||
/**
|
||||
* @param requireReadAction whether {@link #processQuery(Object, Processor)} should be wrapped into a read action.
|
||||
*/
|
||||
protected QueryExecutorBase(boolean requireReadAction) {
|
||||
myRequireReadAction = requireReadAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance that executes {@link #processQuery(Object, Processor)} as is, without wrapping into a read action.
|
||||
*/
|
||||
protected QueryExecutorBase() {
|
||||
this(false);
|
||||
}
|
||||
@@ -39,11 +58,22 @@ public abstract class QueryExecutorBase<Result, Params> implements QueryExecutor
|
||||
};
|
||||
|
||||
if (myRequireReadAction) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
processQuery(queryParameters, wrapper);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (!DumbService.isDumbAware(this)) {
|
||||
Project project = queryParameters instanceof DumbAwareSearchParameters ? ((DumbAwareSearchParameters)queryParameters).getProject()
|
||||
: null;
|
||||
if (project != null) {
|
||||
DumbService.getInstance(project).runReadActionInSmartMode(runnable);
|
||||
return toContinue.get();
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
}
|
||||
else {
|
||||
processQuery(queryParameters, wrapper);
|
||||
@@ -52,5 +82,8 @@ public abstract class QueryExecutorBase<Result, Params> implements QueryExecutor
|
||||
return toContinue.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find some results according to queryParameters and feed them to consumer. If consumer returns false, stop.
|
||||
*/
|
||||
public abstract void processQuery(@NotNull Params queryParameters, @NotNull Processor<Result> consumer);
|
||||
}
|
||||
|
||||
@@ -18,10 +18,17 @@ package com.intellij.util;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A generic extension to enable plugging into various searches.<p/>
|
||||
*
|
||||
* Consider extending {@link com.intellij.openapi.application.QueryExecutorBase} instead unless you know what you're doing.
|
||||
*
|
||||
* @author max
|
||||
*/
|
||||
public interface QueryExecutor<Result, Param> {
|
||||
|
||||
/**
|
||||
* Find some results according to queryParameters and feed them to consumer. If consumer returns false, stop.
|
||||
* @return false if the searching should be stopped immediately. This should happen only when consumer has returned false.
|
||||
*/
|
||||
boolean execute(@NotNull Param queryParameters, @NotNull Processor<Result> consumer);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.search.searches;
|
||||
|
||||
import com.intellij.openapi.application.DumbAwareSearchParameters;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -39,7 +40,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
|
||||
private ReferencesSearch() {
|
||||
}
|
||||
|
||||
public static class SearchParameters {
|
||||
public static class SearchParameters implements DumbAwareSearchParameters {
|
||||
private final PsiElement myElementToSearch;
|
||||
private final SearchScope myScope;
|
||||
private final boolean myIgnoreAccessScope;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.theoryinpractice.testng;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.openapi.application.QueryExecutorBase;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.UsageSearchContext;
|
||||
@@ -27,23 +26,21 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.testng.annotations.DataProvider;
|
||||
|
||||
public class DataProviderSearcher extends QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters> {
|
||||
public DataProviderSearcher() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processQuery(@NotNull final MethodReferencesSearch.SearchParameters queryParameters, @NotNull Processor<PsiReference> consumer) {
|
||||
DumbService.getInstance(queryParameters.getProject()).runReadActionInSmartMode(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PsiMethod method = queryParameters.getMethod();
|
||||
public void processQuery(@NotNull MethodReferencesSearch.SearchParameters queryParameters, @NotNull Processor<PsiReference> consumer) {
|
||||
final PsiMethod method = queryParameters.getMethod();
|
||||
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
|
||||
if (annotation == null) return;
|
||||
final PsiAnnotationMemberValue dataProviderMethodName = annotation.findDeclaredAttributeValue("name");
|
||||
if (dataProviderMethodName != null) {
|
||||
final String providerName = StringUtil.unquoteString(dataProviderMethodName.getText());
|
||||
queryParameters.getOptimizer().searchWord(providerName, queryParameters.getEffectiveSearchScope(), UsageSearchContext.IN_STRINGS, true, method);
|
||||
}
|
||||
}
|
||||
});
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName());
|
||||
if (annotation == null) return;
|
||||
final PsiAnnotationMemberValue dataProviderMethodName = annotation.findDeclaredAttributeValue("name");
|
||||
if (dataProviderMethodName != null) {
|
||||
final String providerName = StringUtil.unquoteString(dataProviderMethodName.getText());
|
||||
queryParameters.getOptimizer().searchWord(providerName, queryParameters.getEffectiveSearchScope(), UsageSearchContext.IN_STRINGS, true, method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user