Snapshot 568f05589922685b8c8f9a2f2f465043b8128542 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I47fe8cb5d8a3c9876cd4c313dca1a8cc531288ec
diff --git a/java/java-indexing-impl/java-indexing-impl.iml b/java/java-indexing-impl/java-indexing-impl.iml
index 0379d94..bd58ec0 100644
--- a/java/java-indexing-impl/java-indexing-impl.iml
+++ b/java/java-indexing-impl/java-indexing-impl.iml
@@ -11,9 +11,9 @@
<orderEntry type="module" module-name="java-psi-impl" exported="" />
<orderEntry type="module" module-name="indexing-api" exported="" />
<orderEntry type="module" module-name="indexing-impl" exported="" />
- <orderEntry type="module" module-name="projectModel-api" />
+ <orderEntry type="module" module-name="projectModel-api" exported="" />
<orderEntry type="module" module-name="projectModel-impl" />
- <orderEntry type="module" module-name="java-indexing-api" />
+ <orderEntry type="module" module-name="java-indexing-api" exported="" />
</component>
</module>
diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
new file mode 100644
index 0000000..1fec41c
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2000-2013 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.codeInsight;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiMethod;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:johnnyclark@gmail.com">Johnny Clark</a>
+ * Creation Date: 8/3/12
+ */
+@State(
+ name = "ConditionCheckManager",
+ storages = {
+ @Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/checker.xml", scheme = StorageScheme.DIRECTORY_BASED),
+ @Storage(file = StoragePathMacros.PROJECT_FILE)
+ }
+)
+public class ConditionCheckManager implements PersistentStateComponent<ConditionCheckManager.State> {
+ @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private State state;
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheckManager");
+
+ private final List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
+
+ private final List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
+
+ private final List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
+ private final List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
+
+ public static ConditionCheckManager getInstance(Project project) {
+ return ServiceManager.getService(project, ConditionCheckManager.class);
+ }
+
+ public void setIsNullCheckMethods(List<ConditionChecker> methodConditionChecks) {
+ myIsNullCheckMethods.clear();
+ myIsNullCheckMethods.addAll(methodConditionChecks);
+ }
+
+ public void setIsNotNullCheckMethods(List<ConditionChecker> methodConditionChecks) {
+ myIsNotNullCheckMethods.clear();
+ myIsNotNullCheckMethods.addAll(methodConditionChecks);
+ }
+
+ public void setAssertIsNullMethods(List<ConditionChecker> methodConditionChecks) {
+ myAssertIsNullMethods.clear();
+ myAssertIsNullMethods.addAll(methodConditionChecks);
+ }
+
+ public void setAssertIsNotNullMethods(List<ConditionChecker> methodConditionChecks) {
+ myAssertIsNotNullMethods.clear();
+ myAssertIsNotNullMethods.addAll(methodConditionChecks);
+ }
+
+ public void setAssertTrueMethods(List<ConditionChecker> psiMethodWrappers) {
+ myAssertTrueMethods.clear();
+ myAssertTrueMethods.addAll(psiMethodWrappers);
+ }
+
+ public void setAssertFalseMethods(List<ConditionChecker> psiMethodWrappers) {
+ myAssertFalseMethods.clear();
+ myAssertFalseMethods.addAll(psiMethodWrappers);
+ }
+
+ public List<ConditionChecker> getIsNullCheckMethods() {
+ return myIsNullCheckMethods;
+ }
+
+ public List<ConditionChecker> getIsNotNullCheckMethods() {
+ return myIsNotNullCheckMethods;
+ }
+
+ public List<ConditionChecker> getAssertIsNullMethods() {
+ return myAssertIsNullMethods;
+ }
+
+ public List<ConditionChecker> getAssertIsNotNullMethods() {
+ return myAssertIsNotNullMethods;
+ }
+
+ public List<ConditionChecker> getAssertFalseMethods() {
+ return myAssertFalseMethods;
+ }
+
+ public List<ConditionChecker> getAssertTrueMethods() {
+ return myAssertTrueMethods;
+ }
+
+ public static class State {
+ public List<String> myIsNullCheckMethods = new ArrayList<String>();
+ public List<String> myIsNotNullCheckMethods = new ArrayList<String>();
+ public List<String> myAssertIsNullMethods = new ArrayList<String>();
+ public List<String> myAssertIsNotNullMethods = new ArrayList<String>();
+ public List<String> myAssertTrueMethods = new ArrayList<String>();
+ public List<String> myAssertFalseMethods = new ArrayList<String>();
+ }
+
+ @Override
+ public State getState() {
+ State state = new State();
+
+ loadMethodChecksToState(state.myIsNullCheckMethods, myIsNullCheckMethods);
+ loadMethodChecksToState(state.myIsNotNullCheckMethods, myIsNotNullCheckMethods);
+ loadMethodChecksToState(state.myAssertIsNullMethods, myAssertIsNullMethods);
+ loadMethodChecksToState(state.myAssertIsNotNullMethods, myAssertIsNotNullMethods);
+ loadMethodChecksToState(state.myAssertTrueMethods, myAssertTrueMethods);
+ loadMethodChecksToState(state.myAssertFalseMethods, myAssertFalseMethods);
+
+ return state;
+ }
+
+ private static void loadMethodChecksToState(List<String> listToLoadTo, List<ConditionChecker> listToLoadFrom) {
+ for (ConditionChecker checker : listToLoadFrom) {
+ listToLoadTo.add(checker.toString());
+ }
+ }
+
+ @Override
+ public void loadState(State state) {
+ this.state = state;
+ loadMethods(myIsNullCheckMethods, state.myIsNullCheckMethods, ConditionChecker.Type.IS_NULL_METHOD);
+ loadMethods(myIsNotNullCheckMethods, state.myIsNotNullCheckMethods, ConditionChecker.Type.IS_NOT_NULL_METHOD);
+ loadMethods(myAssertIsNullMethods, state.myAssertIsNullMethods, ConditionChecker.Type.ASSERT_IS_NULL_METHOD);
+ loadMethods(myAssertIsNotNullMethods, state.myAssertIsNotNullMethods, ConditionChecker.Type.ASSERT_IS_NOT_NULL_METHOD);
+ loadMethods(myAssertTrueMethods, state.myAssertTrueMethods, ConditionChecker.Type.ASSERT_TRUE_METHOD);
+ loadMethods(myAssertFalseMethods, state.myAssertFalseMethods, ConditionChecker.Type.ASSERT_FALSE_METHOD);
+ }
+
+ private static void loadMethods(List<ConditionChecker> listToLoadTo, List<String> listToLoadFrom, ConditionChecker.Type type){
+ listToLoadTo.clear();
+ for (String setting : listToLoadFrom) {
+ try {
+ listToLoadTo.add(new ConditionChecker.FromConfigBuilder(setting, type).build());
+ } catch (Exception e) {
+ LOG.error("Problem occurred while attempting to load Condition Check from configuration file. " + e.getMessage());
+ }
+ }
+ }
+
+ @Nullable
+ public static ConditionChecker findConditionChecker(@NotNull PsiMethod method) {
+ ConditionCheckManager instance = getInstance(method.getProject());
+ ConditionChecker checker = methodMatches(method, instance.getIsNullCheckMethods());
+ if (checker == null) checker = methodMatches(method, instance.getIsNotNullCheckMethods());
+ if (checker == null) checker = methodMatches(method, instance.getAssertIsNullMethods());
+ if (checker == null) checker = methodMatches(method, instance.getAssertIsNotNullMethods());
+ if (checker == null) checker = methodMatches(method, instance.getAssertTrueMethods());
+ if (checker == null) checker = methodMatches(method, instance.getAssertFalseMethods());
+ return checker;
+ }
+
+ private static ConditionChecker methodMatches(PsiMethod psiMethod, List<ConditionChecker> checkers) {
+ for (ConditionChecker checker : checkers) {
+ if (checker.matchesPsiMethod(psiMethod)) {
+ return checker;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
index 2aad613..600bfc0 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
@@ -1,5 +1,8 @@
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadActionProcessor;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -12,6 +15,7 @@
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.PairProcessor;
import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
/**
* @author max
@@ -19,31 +23,30 @@
public class ConstructorReferencesSearchHelper {
private final PsiManager myManager;
- public ConstructorReferencesSearchHelper(final PsiManager manager) {
+ public ConstructorReferencesSearchHelper(@NotNull PsiManager manager) {
myManager = manager;
}
- public boolean processConstructorReferences(final Processor<PsiReference> processor,
- final PsiMethod constructor,
- final SearchScope searchScope,
+ public boolean processConstructorReferences(@NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull final PsiClass containingClass,
+ @NotNull final SearchScope searchScope,
boolean ignoreAccessScope,
- final boolean isStrictSignatureSearch, SearchRequestCollector collector) {
- PsiClass aClass = constructor.getContainingClass();
- if (aClass == null) {
- return true;
- }
-
- if (aClass.isEnum()) {
- for (PsiField field : aClass.getFields()) {
- if (field instanceof PsiEnumConstant) {
- PsiReference reference = field.getReference();
- if (reference != null && reference.isReferenceTo(constructor)) {
- if (!processor.process(reference)) {
- return false;
- }
- }
- }
+ final boolean isStrictSignatureSearch,
+ @NotNull SearchRequestCollector collector) {
+ final boolean[] constructorCanBeCalledImplicitly = new boolean[1];
+ final boolean[] isEnum = new boolean[1];
+ final boolean[] isUnder18 = new boolean[1];
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0;
+ isEnum[0] = containingClass.isEnum();
+ isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8);
}
+ });
+
+ if (isEnum[0]) {
+ if (!processEnumReferences(processor, constructor, containingClass)) return false;
}
// search usages like "new XXX(..)"
@@ -63,7 +66,7 @@
}
}
else {
- if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) {
+ if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) {
return processor.process(reference);
}
}
@@ -73,30 +76,18 @@
}
};
- ReferencesSearch.searchOptimized(aClass, searchScope, ignoreAccessScope, collector, true, processor1);
- if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8)) {
- ReferencesSearch.search(aClass).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference reference) {
- final PsiElement element = reference.getElement();
- if (element != null) {
- final PsiElement parent = element.getParent();
- if (parent instanceof PsiMethodReferenceExpression &&
- ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
- if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
- processor.process((PsiReference)parent);
- }
- }
- }
- return true;
- }
- });
+ ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1);
+ if (isUnder18[0]) {
+ if (!process18MethodPointers(processor, constructor, containingClass)) return false;
}
- final boolean constructorCanBeCalledImplicitly = constructor.getParameterList().getParametersCount() == 0;
// search usages like "this(..)"
- if (!processSuperOrThis(processor, aClass, constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
- PsiKeyword.THIS)) {
+ if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return processSuperOrThis(containingClass, constructor, constructorCanBeCalledImplicitly[0], searchScope, isStrictSignatureSearch,
+ PsiKeyword.THIS, processor);
+ }
+ })) {
return false;
}
@@ -104,22 +95,69 @@
Processor<PsiClass> processor2 = new Processor<PsiClass>() {
@Override
public boolean process(PsiClass inheritor) {
- return processSuperOrThis(processor, (PsiClass)inheritor.getNavigationElement(), constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
- PsiKeyword.SUPER);
+ final PsiElement navigationElement = inheritor.getNavigationElement();
+ if (navigationElement instanceof PsiClass) {
+ return processSuperOrThis((PsiClass)navigationElement, constructor, constructorCanBeCalledImplicitly[0], searchScope,
+ isStrictSignatureSearch, PsiKeyword.SUPER, processor);
+ }
+ return true;
}
};
- return ClassInheritorsSearch.search(aClass, searchScope, false).forEach(processor2);
+ return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2);
}
- private boolean processSuperOrThis(final Processor<PsiReference> processor,
- final PsiClass inheritor,
- final PsiMethod constructor, final boolean constructorCanBeCalledImplicitly, final SearchScope searchScope,
- final boolean isStrictSignatureSearch,
- final String superOrThisKeyword) {
+ private static boolean processEnumReferences(@NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull final PsiClass aClass) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ for (PsiField field : aClass.getFields()) {
+ if (field instanceof PsiEnumConstant) {
+ PsiReference reference = field.getReference();
+ if (reference != null && reference.isReferenceTo(constructor)) {
+ if (!processor.process(reference)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ private static boolean process18MethodPointers(@NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull PsiClass aClass) {
+ return ReferencesSearch.search(aClass).forEach(new ReadActionProcessor<PsiReference>() {
+ @Override
+ public boolean processInReadAction(PsiReference reference) {
+ final PsiElement element = reference.getElement();
+ if (element != null) {
+ final PsiElement parent = element.getParent();
+ if (parent instanceof PsiMethodReferenceExpression &&
+ ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
+ if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
+ if (!processor.process((PsiReference)parent)) return false;
+ }
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ private boolean processSuperOrThis(@NotNull PsiClass inheritor,
+ @NotNull PsiMethod constructor,
+ final boolean constructorCanBeCalledImplicitly,
+ @NotNull SearchScope searchScope,
+ final boolean isStrictSignatureSearch,
+ @NotNull String superOrThisKeyword,
+ @NotNull Processor<PsiReference> processor) {
PsiMethod[] constructors = inheritor.getConstructors();
if (constructors.length == 0 && constructorCanBeCalledImplicitly) {
- processImplicitConstructorCall(inheritor, processor, constructor, inheritor);
+ if (!processImplicitConstructorCall(inheritor, processor, constructor, inheritor)) return false;
}
for (PsiMethod method : constructors) {
PsiCodeBlock body = method.getBody();
@@ -134,7 +172,7 @@
if (expr instanceof PsiMethodCallExpression) {
PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression();
if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) {
- if (refExpr.getText().equals(superOrThisKeyword)) {
+ if (refExpr.textMatches(superOrThisKeyword)) {
PsiElement referencedElement = refExpr.resolve();
if (referencedElement instanceof PsiMethod) {
PsiMethod constructor1 = (PsiMethod)referencedElement;
@@ -151,43 +189,48 @@
}
}
if (constructorCanBeCalledImplicitly) {
- processImplicitConstructorCall(method, processor, constructor, inheritor);
+ if (!processImplicitConstructorCall(method, processor, constructor, inheritor)) return false;
}
}
return true;
}
- private void processImplicitConstructorCall(final PsiMember usage,
- final Processor<PsiReference> processor,
- final PsiMethod constructor,
- final PsiClass containingClass) {
- if (containingClass instanceof PsiAnonymousClass) return;
- PsiClass superClass = containingClass.getSuperClass();
- if (myManager.areElementsEquivalent(constructor.getContainingClass(), superClass)) {
- processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
- @Override
- public PsiElement getElement() {
- return usage;
- }
-
- @Override
- public TextRange getRangeInElement() {
- if (usage instanceof PsiClass) {
- PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
- if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
- }
- else if (usage instanceof PsiField) {
- PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
- return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
- }
- else if (usage instanceof PsiMethod) {
- PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
- if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
- }
- return super.getRangeInElement();
- }
- });
+ private boolean processImplicitConstructorCall(@NotNull final PsiMember usage,
+ @NotNull final Processor<PsiReference> processor,
+ @NotNull final PsiMethod constructor,
+ @NotNull final PsiClass containingClass) {
+ if (containingClass instanceof PsiAnonymousClass) return true;
+ boolean same = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+ public Boolean compute() {
+ return myManager.areElementsEquivalent(constructor.getContainingClass(), containingClass.getSuperClass());
+ }
+ });
+ if (!same) {
+ return true;
}
+ return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
+ @Override
+ public PsiElement getElement() {
+ return usage;
+ }
+
+ @Override
+ public TextRange getRangeInElement() {
+ if (usage instanceof PsiClass) {
+ PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
+ if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+ }
+ else if (usage instanceof PsiField) {
+ PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
+ return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+ }
+ else if (usage instanceof PsiMethod) {
+ PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
+ if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+ }
+ return super.getRangeInElement();
+ }
+ });
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
index 933a748..5bc07cb 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
@@ -1,9 +1,9 @@
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiReference;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -12,16 +12,26 @@
* @author max
*/
public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
- public ConstructorReferencesSearcher() {
- super(true);
- }
-
@Override
public void processQuery(@NotNull ReferencesSearch.SearchParameters p, @NotNull Processor<PsiReference> consumer) {
final PsiElement element = p.getElementToSearch();
- if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
- new ConstructorReferencesSearchHelper(element.getManager())
- .processConstructorReferences(consumer, (PsiMethod)p.getElementToSearch(), p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
+ if (!(element instanceof PsiMethod)) {
+ return;
}
+ final PsiMethod method = (PsiMethod)element;
+ final PsiManager[] manager = new PsiManager[1];
+ PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ if (!method.isConstructor()) return null;
+ PsiClass aClass = method.getContainingClass();
+ manager[0] = aClass == null ? null : aClass.getManager();
+ return aClass;
+ }
+ });
+ if (aClass == null) {
+ return;
+ }
+ new ConstructorReferencesSearchHelper(manager[0])
+ .processConstructorReferences(consumer, method, aClass, p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
index 49bd3f3..ec298ce 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -1,7 +1,8 @@
package com.intellij.psi.impl.search;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.SearchRequestCollector;
@@ -17,66 +18,77 @@
* @author max
*/
public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters> {
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.MethodUsagesSearcher");
- public MethodUsagesSearcher() {
- super(true);
- }
-
@Override
public void processQuery(@NotNull MethodReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
final PsiMethod method = p.getMethod();
+ final boolean[] isConstructor = new boolean[1];
+ final PsiManager[] psiManager = new PsiManager[1];
+ final String[] methodName = new String[1];
+ final boolean[] isValueAnnotation = new boolean[1];
+ final boolean[] needStrictSignatureSearch = new boolean[1];
+ final boolean strictSignatureSearch = p.isStrictSignatureSearch();
+
+ final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ PsiClass aClass = method.getContainingClass();
+ if (aClass == null) return null;
+ isConstructor[0] = method.isConstructor();
+ psiManager[0] = aClass.getManager();
+ methodName[0] = method.getName();
+ isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) &&
+ PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) &&
+ method.getParameterList().getParametersCount() == 0;
+ needStrictSignatureSearch[0] = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
+ || aClass.hasModifierProperty(PsiModifier.FINAL)
+ || method.hasModifierProperty(PsiModifier.STATIC)
+ || method.hasModifierProperty(PsiModifier.FINAL)
+ || method.hasModifierProperty(PsiModifier.PRIVATE));
+ return aClass;
+ }
+ });
+ if (aClass == null) return;
+
final SearchRequestCollector collector = p.getOptimizer();
final SearchScope searchScope = p.getScope();
- final PsiManager psiManager = method.getManager();
-
- final PsiClass aClass = method.getContainingClass();
- if (aClass == null) return;
-
- final boolean strictSignatureSearch = p.isStrictSignatureSearch();
-
- if (method.isConstructor()) {
- new ConstructorReferencesSearchHelper(psiManager).
- processConstructorReferences(consumer, method, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
+ if (isConstructor[0]) {
+ new ConstructorReferencesSearchHelper(psiManager[0]).
+ processConstructorReferences(consumer, method, aClass, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
}
- if (PsiUtil.isAnnotationMethod(method) &&
- PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) &&
- method.getParameterList().getParametersCount() == 0) {
- ReferencesSearch.search(aClass, p.getScope()).forEach(PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer( consumer));
+ if (isValueAnnotation[0]) {
+ Processor<PsiReference> refProcessor = PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer);
+ ReferencesSearch.search(aClass, searchScope).forEach(refProcessor);
}
- boolean needStrictSignatureSearch = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
- || aClass.hasModifierProperty(PsiModifier.FINAL)
- || method.hasModifierProperty(PsiModifier.STATIC)
- || method.hasModifierProperty(PsiModifier.FINAL)
- || method.hasModifierProperty(PsiModifier.PRIVATE));
- if (needStrictSignatureSearch) {
+ if (needStrictSignatureSearch[0]) {
ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer);
return;
}
- final String textToSearch = method.getName();
- if (StringUtil.isEmpty(textToSearch)) {
+ if (StringUtil.isEmpty(methodName[0])) {
return;
}
- final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(textToSearch, false);
- SearchScope accessScope = methods[0].getUseScope();
- for (int i = 1; i < methods.length; i++) {
- PsiMethod method1 = methods[i];
- accessScope = accessScope.union(method1.getUseScope());
- }
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false);
+ SearchScope accessScope = methods[0].getUseScope();
+ for (int i = 1; i < methods.length; i++) {
+ PsiMethod method1 = methods[i];
+ accessScope = accessScope.union(method1.getUseScope());
+ }
- final SearchScope restrictedByAccess = searchScope.intersectWith(accessScope);
+ SearchScope restrictedByAccessScope = searchScope.intersectWith(accessScope);
- short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
- collector.searchWord(textToSearch, restrictedByAccess, searchContext, true,
- new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
+ short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
+ collector.searchWord(methodName[0], restrictedByAccessScope, searchContext, true,
+ new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
- SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccess, collector);
-
+ SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector);
+ }
+ });
}
}