import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ProcessingContext;
final boolean allowEnum,
final DomElementAnnotationHolder holder) {
final Project project = element.getManager().getProject();
- PsiClass extendClass = JavaPsiFacade.getInstance(project).findClass(name, GlobalSearchScope.allScope(project));
+ PsiClass extendClass = JavaPsiFacade.getInstance(project).findClass(name, value.getResolveScope());
final SmartList<DomElementProblemDescriptor> list = new SmartList<DomElementProblemDescriptor>();
if (extendClass != null) {
if (!name.equals(value.getQualifiedName()) && !value.isInheritor(extendClass, true)) {
\r
@Nullable\r
private static PsiMethod findOverridingMethod(PsiClass inheritor, @NotNull PsiClass parentClass, PsiMethod method) {\r
+ if (!inheritor.isInheritor(parentClass, true)) {\r
+ return null;\r
+ }\r
+\r
PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY);\r
MethodSignature signature = method.getSignature(substitutor);\r
PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false);\r
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashSet;
final boolean bInt = baseClass.isInterface();
if (candidateClass instanceof PsiCompiledElement) {
- if (cInt == bInt && checkReferenceListWithQualifiedNames(candidateClass.getExtendsList(), baseClass)) return true;
- return bInt && !cInt && checkReferenceListWithQualifiedNames(candidateClass.getImplementsList(), baseClass);
+ String baseQName = baseClass.getQualifiedName();
+ if (baseQName == null) return false;
+
+ GlobalSearchScope scope = candidateClass.getResolveScope();
+ if (cInt == bInt && checkReferenceListWithQualifiedNames(baseQName, candidateClass.getExtendsList(), manager, scope)) return true;
+ return bInt && !cInt && checkReferenceListWithQualifiedNames(baseQName, candidateClass.getImplementsList(), manager, scope);
}
if (cInt == bInt) {
for (PsiClassType type : candidateClass.getExtendsListTypes()) {
return isInheritorWithoutCaching(candidateClass, baseClass, checkDeep, checkedClasses);
}
- private static boolean checkReferenceListWithQualifiedNames(final PsiReferenceList extList, PsiClass baseClass) {
+ private static boolean checkReferenceListWithQualifiedNames(final String baseQName, final PsiReferenceList extList, final PsiManager manager,
+ final GlobalSearchScope scope) {
if (extList != null) {
- String qname = baseClass.getQualifiedName();
- if (qname != null) {
- for (PsiJavaCodeReferenceElement ref : extList.getReferenceElements()) {
- if (Comparing.equal(PsiNameHelper.getQualifiedClassName(ref.getQualifiedName(), false), qname) &&
- baseClass.isEquivalentTo(ref.resolve())) {
- return true;
- }
- }
+ final PsiJavaCodeReferenceElement[] refs = extList.getReferenceElements();
+ for (PsiJavaCodeReferenceElement ref : refs) {
+ if (Comparing.equal(PsiNameHelper.getQualifiedClassName(ref.getQualifiedName(), false), baseQName) && JavaPsiFacade
+ .getInstance(manager.getProject()).findClass(baseQName, scope) != null)
+ return true;
}
}
return false;
final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile();
boolean lib1 = fileIndex.isInLibraryClasses(vfile1);
boolean lib2 = fileIndex.isInLibraryClasses(vfile2);
- if (aClass instanceof PsiCompiledElement && another instanceof PsiCompiledElement && lib1 && lib2) {
- if (fileIndex.isInSdkClasses(vfile1) && fileIndex.isInSdkClasses(vfile2)) {
- return true;
- }
- return vfile1.equals(vfile2);
- }
return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2);
}
* limitations under the License.
*/
package com.intellij.psi.resolve
-
import com.intellij.openapi.application.ex.PathManagerEx
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.psi.JavaPsiFacade
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiMethod
import com.intellij.psi.search.GlobalSearchScope
+import com.intellij.psi.search.searches.ClassInheritorsSearch
+import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
-
/**
* @author peter
*/
assert intfs.size() == 2
for (i in 0..1) {
+ assert ClassInheritorsSearch.search(intfs[i]).findAll().containsAll([middles[i], bottoms[i]])
+ intfs[i].methods.each {
+ assert OverridingMethodsSearch.search(it).findAll()
+ }
+
assert middles[i].isInheritor(intfs[i], true)
assert bottoms[i].isInheritor(intfs[i], true)
assert bottoms[i].isInheritor(middles[i], true)
}
+ }
+
+ public void "test accept that with different library versions inheritance relation may be intransitive"() {
+ def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/libResolve/inheritance")
+
+ //Foo, Middle implements Foo, Other extends Middle
+ PsiTestUtil.addLibrary(myModule, 'full', lib.path, ["/fullLibrary.jar!/"] as String[], [] as String[])
+
+ //Middle, Bottom extends Middle
+ PsiTestUtil.addLibrary(myModule, 'partial', lib.path, ["/middleBottom.jar!/"] as String[], [] as String[])
+
+ def scope = GlobalSearchScope.allScope(project)
+
+ def i0 = JavaPsiFacade.getInstance(project).findClass('Intf', scope)
+ def other0 = JavaPsiFacade.getInstance(project).findClass('Other', scope)
+ def b1 = JavaPsiFacade.getInstance(project).findClass('Bottom', scope)
+
+ def middles = JavaPsiFacade.getInstance(project).findClasses('Middle', scope)
+ assert middles.size() == 2
+ def m0 = middles[0]
+ def m1 = middles[1]
+
for (deep in [false, true]) {
- for (i in 0..1) {
- assert !middles[i].isInheritor(intfs[1-i], deep)
- assert !bottoms[i].isInheritor(intfs[1-i], deep)
- assert !bottoms[i].isInheritor(middles[1-i], deep)
- }
+ assert m0.isInheritor(i0, deep)
+ assert other0.isInheritor(m0, deep)
+
+ assert !b1.isInheritor(i0, deep)
+
+ assert b1.isInheritor(m0, deep)
+ assert b1.isInheritor(m1, deep)
+
+ assert !m1.isInheritor(i0, deep)
}
+
+ assert other0.isInheritor(i0, true)
+ assert !other0.isInheritor(i0, false)
+
+ assert ClassInheritorsSearch.search(i0).findAll() == [m0, b1, other0]
+ assert ClassInheritorsSearch.search(m0).findAll() == [b1, other0]
+
+ assert fooInheritors(i0) == [fooMethod(m0), fooMethod(other0)] as Set
+ assert fooInheritors(m0) == [fooMethod(other0), fooMethod(b1)] as Set
+ assert fooInheritors(m1) == [fooMethod(other0), fooMethod(b1)] as Set
}
+ private PsiMethod fooMethod(PsiClass c) { c.findMethodsByName('foo', false)[0] }
+ private Set<PsiMethod> fooInheritors(PsiClass c) { OverridingMethodsSearch.search(fooMethod(c)).findAll() as Set }
+
}
return ServiceManager.getService(project, FileIndexFacade.class);
}
- public abstract boolean isInContent(@NotNull VirtualFile file);
- public abstract boolean isInSource(@NotNull VirtualFile file);
- public abstract boolean isInSourceContent(@NotNull VirtualFile file);
- public abstract boolean isInLibraryClasses(@NotNull VirtualFile file);
- public abstract boolean isInSdkClasses(@NotNull VirtualFile file);
- public abstract boolean isInLibrarySource(@NotNull VirtualFile file);
- public abstract boolean isExcludedFile(@NotNull VirtualFile file);
+ public abstract boolean isInContent(VirtualFile file);
+ public abstract boolean isInSource(VirtualFile file);
+ public abstract boolean isInSourceContent(VirtualFile file);
+ public abstract boolean isInLibraryClasses(VirtualFile file);
+
+ public abstract boolean isInLibrarySource(VirtualFile file);
+ public abstract boolean isExcludedFile(VirtualFile file);
@Nullable
public abstract Module getModuleForFile(VirtualFile file);
}
@Override
- public boolean isInSdkClasses(@NotNull VirtualFile file) {
- return false;
- }
-
- @Override
- public boolean isInLibrarySource(@NotNull VirtualFile file) {
+ public boolean isInLibrarySource(VirtualFile file) {
return false;
}
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndexFacade;
-import com.intellij.openapi.roots.JdkOrderEntry;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
return myFileIndex.isInLibraryClasses(file);
}
- @Override
- public boolean isInSdkClasses(@NotNull VirtualFile file) {
- return ContainerUtil.findInstance(myFileIndex.getOrderEntriesForFile(file), JdkOrderEntry.class) != null;
- }
-
@Override
public boolean isInLibrarySource(@NotNull VirtualFile file) {
return myFileIndex.isInLibrarySource(file);
}
@Override
- public boolean isInSdkClasses(@NotNull VirtualFile file) {
- return false;
- }
-
- @Override
- public boolean isInLibrarySource(@NotNull VirtualFile file) {
+ public boolean isInLibrarySource(VirtualFile file) {
return false;
}