diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java new file mode 100644 index 000000000000..8568dae67d92 --- /dev/null +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java @@ -0,0 +1,71 @@ +package com.intellij.psi.impl.search; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.search.searches.SuperMethodsSearch; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.util.Processor; +import com.intellij.util.QueryExecutor; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author ven + */ +public class MethodSuperSearcher implements QueryExecutor { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.MethodSuperSearcher"); + + @Override + public boolean execute(@NotNull final SuperMethodsSearch.SearchParameters queryParameters, @NotNull final Processor consumer) { + final PsiClass parentClass = queryParameters.getPsiClass(); + final PsiMethod method = queryParameters.getMethod(); + HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); + + final boolean checkBases = queryParameters.isCheckBases(); + final boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); + final List supers = signature.getSuperSignatures(); + for (HierarchicalMethodSignature superSignature : supers) { + if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { + if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) return false; + } + } + + return true; + } + + private static boolean addSuperMethods(final HierarchicalMethodSignature signature, + final PsiMethod method, + final PsiClass parentClass, + final boolean allowStaticMethod, + final boolean checkBases, + final Processor consumer) { + PsiMethod signatureMethod = signature.getMethod(); + PsiClass hisClass = signatureMethod.getContainingClass(); + if (parentClass == null || InheritanceUtil.isInheritorOrSelf(parentClass, hisClass, true)) { + if (isAcceptable(signatureMethod, method, allowStaticMethod)) { + if (parentClass != null && !parentClass.equals(hisClass) && !checkBases) { + return true; + } + LOG.assertTrue(signatureMethod != method, method); // method != method.getsuper() + return consumer.process(signature); //no need to check super classes + } + } + for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) { + if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { + addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer); + } + } + + return true; + } + + private static boolean isAcceptable(final PsiMethod superMethod, final PsiMethod method, final boolean allowStaticMethod) { + boolean hisStatic = superMethod.hasModifierProperty(PsiModifier.STATIC); + return hisStatic == method.hasModifierProperty(PsiModifier.STATIC) && + (allowStaticMethod || !hisStatic) && + JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(superMethod, method, null); + } +} diff --git a/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java b/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java index ffb44dbf30d1..153feb82314a 100644 --- a/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java +++ b/java/java-psi-api/src/com/intellij/psi/search/searches/SuperMethodsSearch.java @@ -1,74 +1,77 @@ -/* - * 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.search.searches; - -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; -import com.intellij.psi.util.MethodSignatureUtil; -import com.intellij.util.Query; -import org.jetbrains.annotations.Nullable; - -/** - * @author max - */ -public class SuperMethodsSearch extends ExtensibleQueryFactory { - public static final SuperMethodsSearch SUPER_METHODS_SEARCH_INSTANCE = new SuperMethodsSearch(); - - public static class SearchParameters { - private final PsiMethod myMethod; - //null means any class would be matched - @Nullable private final PsiClass myClass; - private final boolean myCheckBases; - private final boolean myAllowStaticMethod; - - public SearchParameters(final PsiMethod method, - @Nullable final PsiClass aClass, - final boolean checkBases, - final boolean allowStaticMethod) { - myCheckBases = checkBases; - myClass = aClass; - myMethod = method; - myAllowStaticMethod = allowStaticMethod; - } - - public final boolean isCheckBases() { - return myCheckBases; - } - - public final PsiMethod getMethod() { - return myMethod; - } - - @Nullable - public final PsiClass getPsiClass() { - return myClass; - } - - public final boolean isAllowStaticMethod() { - return myAllowStaticMethod; - } - } - - private SuperMethodsSearch() { - } - - public static Query search(final PsiMethod derivedMethod, @Nullable final PsiClass psiClass, boolean checkBases, boolean allowStaticMethod) { - final SearchParameters parameters = new SearchParameters(derivedMethod, psiClass, checkBases, allowStaticMethod); - return SUPER_METHODS_SEARCH_INSTANCE.createUniqueResultsQuery(parameters, MethodSignatureUtil.METHOD_BASED_HASHING_STRATEGY); - } - -} +/* + * 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.search.searches; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.util.Query; +import com.intellij.util.QueryExecutor; +import org.jetbrains.annotations.Nullable; + +/** + * @author max + */ +public class SuperMethodsSearch extends ExtensibleQueryFactory { + public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.superMethodsSearch"); + public static final SuperMethodsSearch SUPER_METHODS_SEARCH_INSTANCE = new SuperMethodsSearch(); + + public static class SearchParameters { + private final PsiMethod myMethod; + //null means any class would be matched + @Nullable private final PsiClass myClass; + private final boolean myCheckBases; + private final boolean myAllowStaticMethod; + + public SearchParameters(final PsiMethod method, + @Nullable final PsiClass aClass, + final boolean checkBases, + final boolean allowStaticMethod) { + myCheckBases = checkBases; + myClass = aClass; + myMethod = method; + myAllowStaticMethod = allowStaticMethod; + } + + public final boolean isCheckBases() { + return myCheckBases; + } + + public final PsiMethod getMethod() { + return myMethod; + } + + @Nullable + public final PsiClass getPsiClass() { + return myClass; + } + + public final boolean isAllowStaticMethod() { + return myAllowStaticMethod; + } + } + + private SuperMethodsSearch() { + } + + public static Query search(final PsiMethod derivedMethod, @Nullable final PsiClass psiClass, boolean checkBases, boolean allowStaticMethod) { + final SearchParameters parameters = new SearchParameters(derivedMethod, psiClass, checkBases, allowStaticMethod); + return SUPER_METHODS_SEARCH_INSTANCE.createUniqueResultsQuery(parameters, MethodSignatureUtil.METHOD_BASED_HASHING_STRATEGY); + } + +}