mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
overload resolution: infer most specific agains formal param types substituted against site substitutor, including param bounds (IDEA-150773)
This commit is contained in:
+39
-5
@@ -1493,11 +1493,45 @@ public class InferenceSession {
|
||||
* 18.5.4 More Specific Method Inference
|
||||
*/
|
||||
public static boolean isMoreSpecific(PsiMethod m1,
|
||||
PsiMethod m2,
|
||||
PsiSubstitutor siteSubstitutor1,
|
||||
PsiExpression[] args,
|
||||
PsiElement context,
|
||||
boolean varargs) {
|
||||
final PsiMethod m2,
|
||||
final PsiSubstitutor siteSubstitutor1,
|
||||
final PsiExpression[] args,
|
||||
final PsiElement context,
|
||||
final boolean varargs) {
|
||||
try {
|
||||
//push site substitutor to parameter bounds
|
||||
m1 = JavaPsiFacade.getElementFactory(m1.getProject()).createMethodFromText(m1.getText(), m1);
|
||||
for (PsiTypeParameter parameter : m1.getTypeParameters()) {
|
||||
final PsiClassType[] types = parameter.getExtendsListTypes();
|
||||
if (types.length > 0) {
|
||||
final List<PsiType> conjuncts = ContainerUtil.map(types, new Function<PsiClassType, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(PsiClassType type) {
|
||||
return siteSubstitutor1.substitute(type);
|
||||
}
|
||||
});
|
||||
//don't glb to avoid flattening = Object&Interface would be preserved
|
||||
//otherwise methods with different signatures could get same erasure
|
||||
final PsiType upperBound = PsiIntersectionType.createIntersection(false, conjuncts.toArray(new PsiType[conjuncts.size()]));
|
||||
parameter.putUserData(UPPER_BOUND, upperBound);
|
||||
}
|
||||
}
|
||||
return isMoreSpecificInternal(m1, m2, siteSubstitutor1, args, context, varargs);
|
||||
}
|
||||
finally {
|
||||
for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(m1)) {
|
||||
parameter.putUserData(UPPER_BOUND, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isMoreSpecificInternal(PsiMethod m1,
|
||||
PsiMethod m2,
|
||||
PsiSubstitutor siteSubstitutor1,
|
||||
PsiExpression[] args,
|
||||
PsiElement context,
|
||||
boolean varargs) {
|
||||
|
||||
List<PsiTypeParameter> params = new ArrayList<PsiTypeParameter>();
|
||||
for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) {
|
||||
params.add(param);
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import java.util.List;
|
||||
|
||||
class TestIntelliJ<T, S extends List<T>> extends SubInterface<T, S> {
|
||||
private <H extends SuperInterface<T, S>> H <warning descr="Private method 'test(H)' is never used">test</warning>(H t) {
|
||||
System.out.println("SuperInterface" + t);
|
||||
return t;
|
||||
}
|
||||
|
||||
private <H extends SubInterface<T, S>> H test(H t) {
|
||||
System.out.println("SubInterface" + t);
|
||||
return t;
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
TestIntelliJ<String, List<String>> testIntelliJ = new TestIntelliJ<>();
|
||||
testIntelliJ.test(testIntelliJ);
|
||||
}
|
||||
}
|
||||
|
||||
interface SuperInterface<T, <warning descr="Type parameter 'S' is never used">S</warning> extends List<T>> {
|
||||
}
|
||||
|
||||
abstract class SubInterface<T, S extends List<T>> implements SuperInterface<T, S> {
|
||||
}
|
||||
+4
@@ -192,6 +192,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testCompareFormalParametersWithNotionOfSiteSubstitutorInIsMoreSpecificCheck() throws Exception {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user