mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
goto implementations: use type parameter bounds to detect overriding methods (IDEA-165282)
This commit is contained in:
@@ -292,7 +292,8 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
|
||||
}
|
||||
else if (expression != null) {
|
||||
psiClass = PsiUtil.resolveClassInType(expression.getType());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (element instanceof PsiClass) {
|
||||
psiClass = (PsiClass)element;
|
||||
final PsiElement resolve = ((PsiReferenceExpression)reference).advancedResolve(true).getElement();
|
||||
@@ -306,15 +307,31 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
|
||||
|
||||
if (containingClass == null && psiClass == null) return PsiClass.EMPTY_ARRAY;
|
||||
if (containingClass != null) {
|
||||
PsiElementFindProcessor<PsiClass> processor1 = new PsiElementFindProcessor<>(containingClass);
|
||||
while (psiClass != null) {
|
||||
if (!processor1.process(psiClass) ||
|
||||
!ClassInheritorsSearch.search(containingClass).forEach(new PsiElementFindProcessor<>(psiClass)) ||
|
||||
!ClassInheritorsSearch.search(psiClass).forEach(processor1)) {
|
||||
return new PsiClass[] {psiClass};
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
List<PsiClass> result = new ArrayList<>();
|
||||
for (PsiClassType classType : psiClass.getExtendsListTypes()) {
|
||||
ContainerUtil.addIfNotNull(result, getInheritor(containingClass, classType.resolve()));
|
||||
}
|
||||
psiClass = psiClass.getContainingClass();
|
||||
return result.isEmpty() ? null : result.toArray(PsiClass.EMPTY_ARRAY);
|
||||
}
|
||||
else {
|
||||
PsiClass aClass = getInheritor(containingClass, psiClass);
|
||||
if (aClass != null) return new PsiClass[] {aClass};
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PsiClass getInheritor(PsiClass containingClass, PsiClass psiClass) {
|
||||
PsiElementFindProcessor<PsiClass> processor1 = new PsiElementFindProcessor<>(containingClass);
|
||||
while (psiClass != null) {
|
||||
if (!processor1.process(psiClass) ||
|
||||
!ClassInheritorsSearch.search(containingClass).forEach(new PsiElementFindProcessor<>(psiClass)) ||
|
||||
!ClassInheritorsSearch.search(psiClass).forEach(processor1)) {
|
||||
return psiClass;
|
||||
}
|
||||
psiClass = psiClass.getContainingClass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -249,6 +249,27 @@ public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCas
|
||||
assertEquals("A", aClass.getName());
|
||||
}
|
||||
|
||||
public void testMethodImplementationsOnTypeVariable() throws Exception {
|
||||
PsiFile file = myFixture.addFileToProject("Foo.java", "interface I {}\n" +
|
||||
"interface Im {\n" +
|
||||
" void m();\n" +
|
||||
"}\n" +
|
||||
"class Im1 implements Im {\n" +
|
||||
" public void m() {}\n" +
|
||||
"}\n" +
|
||||
"class Im2 implements Im {\n" +
|
||||
" public void m() {}\n" +
|
||||
"}\n" +
|
||||
"class JavaClass<T extends I & Im> {\n" +
|
||||
" void a(T t){\n" +
|
||||
" t.<caret>m();\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
|
||||
PsiElement[] targets = getTargets(file);
|
||||
assertSize(2, targets);
|
||||
}
|
||||
|
||||
public void testStaticMethodReference() {
|
||||
PsiFile file = myFixture.addFileToProject("Foo.java",
|
||||
"class C {\n" +
|
||||
|
||||
Reference in New Issue
Block a user