mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
accept that with different library versions inheritance relation may be intransitive (a fix for IDEA-88527 which doesn't break many web projects)
This commit is contained in:
@@ -19,7 +19,6 @@ import com.intellij.openapi.project.Project;
|
||||
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;
|
||||
@@ -82,7 +81,7 @@ public class ExtendsClassChecker extends DomCustomAnnotationChecker<ExtendClass>
|
||||
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)) {
|
||||
|
||||
+4
@@ -50,6 +50,10 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, O
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod findOverridingMethod(PsiClass inheritor, @NotNull PsiClass parentClass, PsiMethod method) {
|
||||
if (!inheritor.isInheritor(parentClass, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY);
|
||||
MethodSignature signature = method.getSignature(substitutor);
|
||||
PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false);
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
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;
|
||||
@@ -70,8 +71,12 @@ public class InheritanceImplUtil {
|
||||
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()) {
|
||||
@@ -98,16 +103,14 @@ public class InheritanceImplUtil {
|
||||
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;
|
||||
|
||||
@@ -994,12 +994,6 @@ public class PsiClassImplUtil {
|
||||
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);
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -14,14 +14,16 @@
|
||||
* 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
|
||||
*/
|
||||
@@ -72,18 +74,62 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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]) {
|
||||
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 }
|
||||
|
||||
}
|
||||
|
||||
@@ -37,13 +37,13 @@ public abstract class FileIndexFacade {
|
||||
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);
|
||||
|
||||
@@ -63,12 +63,7 @@ public class MockFileIndexFacade extends FileIndexFacade {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInSdkClasses(@NotNull VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLibrarySource(@NotNull VirtualFile file) {
|
||||
public boolean isInLibrarySource(VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
-8
@@ -19,12 +19,9 @@ package com.intellij.openapi.roots.impl;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -59,11 +56,6 @@ public class ProjectFileIndexFacade extends FileIndexFacade {
|
||||
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);
|
||||
|
||||
@@ -56,12 +56,7 @@ public class DefaultFileIndexFacade extends FileIndexFacade {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInSdkClasses(@NotNull VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLibrarySource(@NotNull VirtualFile file) {
|
||||
public boolean isInLibrarySource(VirtualFile file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user