mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
generics: do not prefer type with more bounds when additional bounds are just subtypes of the rest (IDEA-67668)
This commit is contained in:
+43
-20
@@ -630,28 +630,31 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
PsiType type2,
|
||||
PsiTypeParameter p1,
|
||||
PsiTypeParameter p2) {
|
||||
Specifics specifics = checkSubtyping(TypeConversionUtil.erasure(PsiSubstitutor.EMPTY.substitute(p1)),
|
||||
TypeConversionUtil.erasure(PsiSubstitutor.EMPTY.substitute(p2)), method1, method2);
|
||||
if (specifics == Specifics.NEITHER) {
|
||||
final Set<PsiElement> resolved1 = new HashSet<PsiElement>();
|
||||
for (PsiJavaCodeReferenceElement referenceElement : p1.getExtendsList().getReferenceElements()) {
|
||||
final PsiElement resolve = referenceElement.resolve();
|
||||
if (resolve != null) {
|
||||
resolved1.add(resolve);
|
||||
}
|
||||
final Set<PsiClass> resolved1 = new HashSet<PsiClass>();
|
||||
for (PsiClassType referenceElement : p1.getExtendsList().getReferencedTypes()) {
|
||||
final PsiClass resolve = referenceElement.resolve();
|
||||
if (resolve != null) {
|
||||
resolved1.add(resolve);
|
||||
}
|
||||
|
||||
final Set<PsiElement> resolved2 = new HashSet<PsiElement>();
|
||||
for (PsiJavaCodeReferenceElement referenceElement : p2.getExtendsList().getReferenceElements()) {
|
||||
final PsiElement resolve = referenceElement.resolve();
|
||||
if (resolve != null) {
|
||||
resolved2.add(resolve);
|
||||
}
|
||||
}
|
||||
|
||||
if (resolved1.size() > resolved2.size() && resolved1.containsAll(resolved2)) return Specifics.FIRST;
|
||||
if (resolved2.size() > resolved1.size() && resolved2.containsAll(resolved1)) return Specifics.SECOND;
|
||||
}
|
||||
|
||||
final Set<PsiClass> resolved2 = new HashSet<PsiClass>();
|
||||
for (PsiClassType referenceElement : p2.getExtendsList().getReferencedTypes()) {
|
||||
final PsiClass resolve = referenceElement.resolve();
|
||||
if (resolve != null) {
|
||||
resolved2.add(resolve);
|
||||
}
|
||||
}
|
||||
|
||||
Specifics specifics = null;
|
||||
if (resolved1.size() > resolved2.size()){
|
||||
specifics = checkExtendsList(resolved1, resolved2, Specifics.FIRST);
|
||||
} else if (resolved2.size() > resolved1.size()) {
|
||||
specifics = checkExtendsList(resolved2, resolved1, Specifics.SECOND);
|
||||
}
|
||||
if (specifics != null) return specifics;
|
||||
specifics = checkSubtyping(TypeConversionUtil.erasure(PsiSubstitutor.EMPTY.substitute(p1)),
|
||||
TypeConversionUtil.erasure(PsiSubstitutor.EMPTY.substitute(p2)), method1, method2);
|
||||
if (specifics != null) {
|
||||
return specifics;
|
||||
} else {
|
||||
@@ -661,6 +664,26 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
|
||||
private static Specifics checkExtendsList(Set<PsiClass> resolved1,
|
||||
Set<PsiClass> resolved2,
|
||||
Specifics preferred) {
|
||||
if (resolved1.containsAll(resolved2)){
|
||||
resolved1.removeAll(resolved2);
|
||||
for (Iterator<PsiClass> iterator = resolved1.iterator(); iterator.hasNext(); ) {
|
||||
PsiClass psiClass = iterator.next();
|
||||
for (PsiClass aClass : resolved2) {
|
||||
if (InheritanceUtil.isInheritorOrSelf(aClass, psiClass, true)) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!resolved1.isEmpty()) return preferred;
|
||||
return Specifics.NEITHER;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters,
|
||||
final PsiType[] types1,
|
||||
final PsiType[] types2,
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
interface A
|
||||
{
|
||||
<S extends Collection<?> & List<?>> void foo(S x);
|
||||
<S extends List<?>> void foo(S x);
|
||||
}
|
||||
|
||||
|
||||
class B
|
||||
{
|
||||
public static void main(String[] args) {
|
||||
A a = null;
|
||||
a.foo<error descr="Ambiguous method call: both 'A.foo(Collection<?>)' and 'A.foo(List<?>)' match">(null)</error>;
|
||||
}
|
||||
}
|
||||
+1
@@ -170,6 +170,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testWrongArgsAndUnknownTypeParams() { doTest(false, false); }
|
||||
public void testAmbiguousMethodCallIDEA97983() { doTest(false, false); }
|
||||
public void testAmbiguousMethodCallIDEA100314() { doTest(false, false); }
|
||||
public void testAmbiguousMethodCallIDEA67668() { doTest(false, false); }
|
||||
public void testInstanceMemberNotAccessibleInStaticContext() { doTest(false, false); }
|
||||
public void testRejectedTypeParamsForConstructor() { doTest(false, false); }
|
||||
public void testAnnotationArgs() throws Exception { doTest(false, false);}
|
||||
|
||||
Reference in New Issue
Block a user