mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-09 08:09:39 +07:00
overload resolution: ensure type parameters of containing class are fixed during most specific inference (IDEA-205886)
GitOrigin-RevId: 01b3a6f25c68e27475a053c74a7765e84147beca
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e530259307
commit
b540bb262e
@@ -1637,14 +1637,7 @@ public class InferenceSession {
|
||||
PsiElement context,
|
||||
boolean varargs) {
|
||||
|
||||
List<PsiTypeParameter> params = new ArrayList<>();
|
||||
for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) {
|
||||
params.add(param);
|
||||
}
|
||||
|
||||
siteSubstitutor1 = getSiteSubstitutor(siteSubstitutor1, params);
|
||||
|
||||
final InferenceSession session = new InferenceSession(params.toArray(PsiTypeParameter.EMPTY_ARRAY), siteSubstitutor1, m2.getManager(), context);
|
||||
final InferenceSession session = new InferenceSession(m2.getTypeParameters(), siteSubstitutor1, m2.getManager(), context);
|
||||
|
||||
final PsiParameter[] parameters1 = m1.getParameterList().getParameters();
|
||||
final PsiParameter[] parameters2 = m2.getParameterList().getParameters();
|
||||
@@ -1684,14 +1677,6 @@ public class InferenceSession {
|
||||
return session.repeatInferencePhases();
|
||||
}
|
||||
|
||||
private static PsiSubstitutor getSiteSubstitutor(PsiSubstitutor siteSubstitutor1, List<PsiTypeParameter> params) {
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
for (PsiTypeParameter param : params) {
|
||||
subst = subst.put(param, siteSubstitutor1.substitute(param));
|
||||
}
|
||||
return subst;
|
||||
}
|
||||
|
||||
/**
|
||||
* 15.12.2.5 Choosing the Most Specific Method
|
||||
* "a functional interface type S is more specific than a functional interface type T for an expression exp" part
|
||||
|
||||
@@ -516,10 +516,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite,
|
||||
myLanguageLevel);
|
||||
boolean applicable12 = isApplicableTo(types2AtSite, method1, myLanguageLevel, varargsPosition, methodSubstitutor1, method2, siteSubstitutor2);
|
||||
boolean applicable12 = isApplicableTo(types2AtSite, method1, myLanguageLevel, varargsPosition, methodSubstitutor1, method2, siteSubstitutor2.putAll(siteSubstitutor1));
|
||||
|
||||
final PsiSubstitutor methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, myLanguageLevel);
|
||||
boolean applicable21 = isApplicableTo(types1AtSite, method2, myLanguageLevel, varargsPosition, methodSubstitutor2, method1, siteSubstitutor1);
|
||||
boolean applicable21 = isApplicableTo(types1AtSite, method2, myLanguageLevel, varargsPosition, methodSubstitutor2, method1, siteSubstitutor1.putAll(siteSubstitutor2));
|
||||
|
||||
if (!myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
final boolean typeArgsApplicable12 = GenericsUtil.isTypeArgumentsApplicable(typeParameters1, methodSubstitutor1, myArgumentsList, !applicable21);
|
||||
@@ -616,24 +616,27 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return parameterType instanceof PsiPrimitiveType ^ isExpressionTypePrimitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param siteSubstitutor should contain mapping for both candidates sites to align types in hierarchy
|
||||
*/
|
||||
private boolean isApplicableTo(@NotNull PsiType[] types2AtSite,
|
||||
@NotNull PsiMethod method1,
|
||||
@NotNull final LanguageLevel languageLevel,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
boolean varargsPosition,
|
||||
@NotNull PsiSubstitutor methodSubstitutor1,
|
||||
@NotNull PsiMethod method2,
|
||||
final PsiSubstitutor siteSubstitutor1) {
|
||||
PsiSubstitutor siteSubstitutor) {
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && method1.getTypeParameters().length > 0 && myArgumentsList instanceof PsiExpressionList) {
|
||||
final PsiElement parent = myArgumentsList.getParent();
|
||||
if (parent instanceof PsiCallExpression) {
|
||||
return InferenceSession.isMoreSpecific(method2, method1, siteSubstitutor1, ((PsiExpressionList)myArgumentsList).getExpressions(), myArgumentsList, varargsPosition);
|
||||
return InferenceSession.isMoreSpecific(method2, method1, siteSubstitutor, ((PsiExpressionList)myArgumentsList).getExpressions(), myArgumentsList, varargsPosition);
|
||||
}
|
||||
}
|
||||
final PsiUtil.ApplicabilityChecker applicabilityChecker = (left, right, allowUncheckedConversion, argId) -> {
|
||||
if (right instanceof PsiClassType) {
|
||||
final PsiClass rightClass = ((PsiClassType)right).resolve();
|
||||
if (rightClass instanceof PsiTypeParameter) {
|
||||
right = new PsiImmediateClassType(rightClass, siteSubstitutor1);
|
||||
right = new PsiImmediateClassType(rightClass, siteSubstitutor);
|
||||
}
|
||||
}
|
||||
return languageLevel.isAtLeast(LanguageLevel.JDK_1_8) ? isTypeMoreSpecific(left, right, argId) : TypeConversionUtil.isAssignable(left, right, allowUncheckedConversion);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class MyTest {
|
||||
|
||||
static class Foo<X> {
|
||||
<T> void test(X x) { }
|
||||
}
|
||||
static class Bar extends Foo<Integer> {
|
||||
void test(Double x) { }
|
||||
|
||||
void call() {
|
||||
test<error descr="Ambiguous method call: both 'Bar.test(Double)' and 'Foo.test(Integer)' match">(null)</error>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,6 +276,7 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testUnqualifiedStaticInterfaceMethodCallsOnInnerClasses() { doTest(false);}
|
||||
|
||||
public void testStaticMethodInSuperInterfaceConflictWithCurrentStatic() { doTest(false);}
|
||||
public void testFixedContainingClassTypeArguments() { doTest(false);}
|
||||
public void testPotentialCompatibilityWithArrayCreation() { doTest(false);}
|
||||
public void testOverloadsWithOneNonCompatible() { doTest(false);}
|
||||
public void testSecondSearchOverloadsBoxing() {
|
||||
|
||||
Reference in New Issue
Block a user