move searchers to indexing module

This commit is contained in:
Evgeny Pasynkov
2012-06-22 08:55:07 +02:00
parent 9fcee29903
commit 577ede3fe2
30 changed files with 22 additions and 17 deletions
+1
View File
@@ -32,6 +32,7 @@
<orderEntry type="module" module-name="java-psi-impl" exported="" />
<orderEntry type="module" module-name="RegExpSupport" />
<orderEntry type="module" module-name="java-indexing-impl" exported="" />
<orderEntry type="module" module-name="java-indexing-api" />
</component>
<component name="copyright">
<Base>
@@ -1,52 +0,0 @@
/*
* Copyright 2000-2009 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.navigation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import org.jetbrains.annotations.NotNull;
public class ClassImplementationsSearch implements QueryExecutor<PsiElement, PsiElement> {
public boolean execute(@NotNull final PsiElement sourceElement, @NotNull final Processor<PsiElement> consumer) {
return !(sourceElement instanceof PsiClass) || processImplementations((PsiClass)sourceElement, consumer);
}
public static boolean processImplementations(final PsiClass psiClass, final Processor<? super PsiClass> processor) {
final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces");
return ClassInheritorsSearch.search(psiClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
public SearchScope compute() {
return psiClass.getUseScope();
}
}), true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
public boolean execute(@NotNull PsiClass element) {
if (!showInterfaces && element.isInterface()) {
return true;
}
return processor.process(element);
}
}));
}
}
@@ -1,49 +0,0 @@
/*
* Copyright 2000-2009 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.navigation;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.util.QueryExecutor;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class MethodImplementationsSearch implements QueryExecutor<PsiElement, PsiElement> {
public boolean execute(@NotNull final PsiElement sourceElement, @NotNull final Processor<PsiElement> consumer) {
if (sourceElement instanceof PsiMethod) {
PsiMethod[] implementations = getMethodImplementations((PsiMethod)sourceElement);
return ContainerUtil.process(implementations, consumer);
}
return true;
}
public static void getOverridingMethods(PsiMethod method, ArrayList<PsiMethod> list) {
for (PsiMethod psiMethod : OverridingMethodsSearch.search(method)) {
list.add(psiMethod);
}
}
public static PsiMethod[] getMethodImplementations(final PsiMethod method) {
ArrayList<PsiMethod> result = new ArrayList<PsiMethod>();
getOverridingMethods(method, result);
return result.toArray(new PsiMethod[result.size()]);
}
}
@@ -1,208 +0,0 @@
/*
* Copyright 2000-2009 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.psi.impl.light;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class LightMemberReference extends LightElement implements PsiJavaCodeReferenceElement {
private final PsiMember myRefMember;
private final PsiSubstitutor mySubstitutor;
private LightReferenceParameterList myParameterList;
public LightMemberReference(PsiManager manager, PsiMember refClass, PsiSubstitutor substitutor) {
super(manager, JavaLanguage.INSTANCE);
myRefMember = refClass;
mySubstitutor = substitutor;
}
@Override
public PsiElement resolve() {
return myRefMember;
}
@Override
@NotNull
public JavaResolveResult advancedResolve(boolean incompleteCode){
final PsiElement resolved = resolve();
PsiSubstitutor substitutor = mySubstitutor;
if (substitutor == null) {
substitutor = PsiSubstitutor.EMPTY;
}
return new CandidateInfo(resolved, substitutor);
}
@Override
@NotNull
public JavaResolveResult[] multiResolve(boolean incompleteCode){
final JavaResolveResult result = advancedResolve(incompleteCode);
if(result != JavaResolveResult.EMPTY) return new JavaResolveResult[]{result};
return JavaResolveResult.EMPTY_ARRAY;
}
@Override
public void processVariants(PsiScopeProcessor processor){
throw new RuntimeException("Variants are not available for light references");
}
@Override
public PsiElement getReferenceNameElement() {
return null;
}
@Override
public PsiReferenceParameterList getParameterList() {
if (myParameterList == null) {
myParameterList = new LightReferenceParameterList(myManager, PsiTypeElement.EMPTY_ARRAY);
}
return myParameterList;
}
@Override
public String getQualifiedName() {
final PsiClass containingClass = myRefMember.getContainingClass();
if (containingClass != null) {
final String qualifiedName = containingClass.getQualifiedName();
if (qualifiedName != null) {
return qualifiedName + '.' + myRefMember.getName();
}
}
return myRefMember.getName();
}
@Override
public String getReferenceName() {
return getQualifiedName();
}
@Override
public String getText() {
return myRefMember.getName() + getParameterList().getText();
}
@Override
public PsiReference getReference() {
return this;
}
@Override
@NotNull
public String getCanonicalText() {
String name = getQualifiedName();
if (name == null) return null;
PsiType[] types = getTypeParameters();
if (types.length == 0) return name;
StringBuffer buf = new StringBuffer();
buf.append(name);
buf.append('<');
for (int i = 0; i < types.length; i++) {
if (i > 0) buf.append(',');
buf.append(types[i].getCanonicalText());
}
buf.append('>');
return buf.toString();
}
@Override
public PsiElement copy() {
return new LightMemberReference(myManager, myRefMember, mySubstitutor);
}
@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
//TODO?
throw new IncorrectOperationException();
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
//TODO?
throw new IncorrectOperationException();
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor)visitor).visitReferenceElement(this);
}
else {
visitor.visitElement(this);
}
}
public String toString() {
return "LightClassReference:" + myRefMember.getName();
}
@Override
public boolean isReferenceTo(PsiElement element) {
return element instanceof PsiClass && element.getManager().areElementsEquivalent(resolve(), element);
}
@Override
@NotNull
public Object[] getVariants() {
throw new RuntimeException("Variants are not available for light references");
}
@Override
public boolean isSoft(){
return false;
}
@Override
public TextRange getRangeInElement() {
return new TextRange(0, getTextLength());
}
@Override
public PsiElement getElement() {
return this;
}
@Override
public boolean isValid() {
PsiReferenceParameterList parameterList = getParameterList();
if (parameterList != null && !parameterList.isValid()) return false;
return myRefMember == null || myRefMember.isValid();
}
@Override
@NotNull
public PsiType[] getTypeParameters() {
PsiReferenceParameterList parameterList = getParameterList();
return parameterList == null ? PsiType.EMPTY_ARRAY : parameterList.getTypeArguments();
}
@Override
public PsiElement getQualifier() {
return null;
}
@Override
public boolean isQualified() {
return false;
}
}
@@ -1,173 +0,0 @@
package com.intellij.psi.impl.search;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightMemberReference;
import com.intellij.psi.search.PsiSearchScopeUtil;
import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.PairProcessor;
import com.intellij.util.Processor;
/**
* @author max
*/
public class ConstructorReferencesSearchHelper {
private final PsiManager myManager;
public ConstructorReferencesSearchHelper(final PsiManager manager) {
myManager = manager;
}
public boolean processConstructorReferences(final Processor<PsiReference> processor,
final PsiMethod constructor,
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;
}
}
}
}
}
// search usages like "new XXX(..)"
PairProcessor<PsiReference, SearchRequestCollector> processor1 = new PairProcessor<PsiReference, SearchRequestCollector>() {
@Override
public boolean process(PsiReference reference, SearchRequestCollector collector) {
PsiElement parent = reference.getElement().getParent();
if (parent instanceof PsiAnonymousClass) {
parent = parent.getParent();
}
if (parent instanceof PsiNewExpression) {
PsiMethod constructor1 = ((PsiNewExpression)parent).resolveConstructor();
if (constructor1 != null) {
if (isStrictSignatureSearch) {
if (myManager.areElementsEquivalent(constructor, constructor1)) {
return processor.process(reference);
}
}
else {
if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) {
return processor.process(reference);
}
}
}
}
return true;
}
};
ReferencesSearch.searchOptimized(aClass, searchScope, ignoreAccessScope, collector, true, processor1);
final boolean constructorCanBeCalledImplicitly = constructor.getParameterList().getParametersCount() == 0;
// search usages like "this(..)"
if (!processSuperOrThis(processor, aClass, constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
PsiKeyword.THIS)) {
return false;
}
// search usages like "super(..)"
Processor<PsiClass> processor2 = new Processor<PsiClass>() {
@Override
public boolean process(PsiClass inheritor) {
return processSuperOrThis(processor, (PsiClass)inheritor.getNavigationElement(), constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
PsiKeyword.SUPER);
}
};
return ClassInheritorsSearch.search(aClass, 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) {
PsiMethod[] constructors = inheritor.getConstructors();
if (constructors.length == 0 && constructorCanBeCalledImplicitly) {
processImplicitConstructorCall(inheritor, processor, constructor, inheritor);
}
for (PsiMethod method : constructors) {
PsiCodeBlock body = method.getBody();
if (body == null) {
continue;
}
PsiStatement[] statements = body.getStatements();
if (statements.length != 0) {
PsiStatement statement = statements[0];
if (statement instanceof PsiExpressionStatement) {
PsiExpression expr = ((PsiExpressionStatement)statement).getExpression();
if (expr instanceof PsiMethodCallExpression) {
PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression();
if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) {
if (refExpr.getText().equals(superOrThisKeyword)) {
PsiElement referencedElement = refExpr.resolve();
if (referencedElement instanceof PsiMethod) {
PsiMethod constructor1 = (PsiMethod)referencedElement;
boolean match = isStrictSignatureSearch
? myManager.areElementsEquivalent(constructor1, constructor)
: myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass());
if (match && !processor.process(refExpr)) return false;
}
//as long as we've encountered super/this keyword, no implicit ctr calls are possible here
continue;
}
}
}
}
}
if (constructorCanBeCalledImplicitly) {
processImplicitConstructorCall(method, processor, constructor, inheritor);
}
}
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();
}
});
}
}
}
@@ -1,27 +0,0 @@
package com.intellij.psi.impl.search;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
/**
* @author max
*/
public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
protected 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());
}
}
}
@@ -1,47 +0,0 @@
package com.intellij.psi.impl.search;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import com.intellij.util.Query;
import com.intellij.util.QueryExecutor;
import com.intellij.openapi.application.ReadActionProcessor;
import org.jetbrains.annotations.NotNull;
/**
* @author max
*/
public class PsiAnnotationMethodReferencesSearcher implements QueryExecutor<PsiReference, ReferencesSearch.SearchParameters> {
@Override
public boolean execute(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
final PsiElement refElement = p.getElementToSearch();
if (refElement instanceof PsiAnnotationMethod) {
PsiMethod method = (PsiMethod)refElement;
if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParametersCount() == 0) {
final Query<PsiReference> query = ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope());
return query.forEach(createImplicitDefaultAnnotationMethodConsumer(consumer));
}
}
return true;
}
public static ReadActionProcessor<PsiReference> createImplicitDefaultAnnotationMethodConsumer(final Processor<PsiReference> consumer) {
return new ReadActionProcessor<PsiReference>() {
@Override
public boolean processInReadAction(final PsiReference reference) {
if (reference instanceof PsiJavaCodeReferenceElement) {
PsiJavaCodeReferenceElement javaReference = (PsiJavaCodeReferenceElement)reference;
if (javaReference.getParent() instanceof PsiAnnotation) {
PsiNameValuePair[] members = ((PsiAnnotation)javaReference.getParent()).getParameterList().getAttributes();
if (members.length == 1 && members[0].getNameIdentifier() == null) {
PsiReference t = members[0].getReference();
if (t != null && !consumer.process(t)) return false;
}
}
}
return true;
}
};
}
}
@@ -33,10 +33,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -64,7 +62,6 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,7 +34,6 @@ import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.util.ConflictsUtil;
import com.intellij.refactoring.util.MoveRenameUsageInfo;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;