mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: ignore return type constraints during method reference conflict resolving; work around raw type received from constructor reference given on raw type to be treated as diamond
This commit is contained in:
+7
-2
@@ -1127,13 +1127,18 @@ public class InferenceSession {
|
||||
|
||||
if (parameters.length == functionalMethodParameters.length && !varargs || isStatic && varargs) {//static methods
|
||||
|
||||
if (method.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, qualifierResolveResult.getSubstitutor())) {
|
||||
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
|
||||
if (method.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor)) {
|
||||
//15.13.1 If ClassType is a raw type, but is not a non-static member type of a raw type,
|
||||
//the candidate notional member methods are those specified in §15.9.3 for a
|
||||
//class instance creation expression that uses <> to elide the type arguments to a class
|
||||
initBounds(containingClass.getTypeParameters());
|
||||
psiSubstitutor = PsiSubstitutor.EMPTY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < functionalMethodParameters.length; i++) {
|
||||
final PsiType pType = signature.getParameterTypes()[i];
|
||||
addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, qualifierResolveResult.getSubstitutor(), varargs)),
|
||||
addConstraint(new TypeCompatibilityConstraint(substituteWithInferenceVariables(getParameterType(parameters, i, psiSubstitutor, varargs)),
|
||||
PsiImplUtil.normalizeWildcardTypeByPosition(pType, reference)));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -111,10 +111,10 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) {
|
||||
return inferTypeArguments();
|
||||
return inferTypeArguments(includeReturnConstraint);
|
||||
}
|
||||
|
||||
private PsiSubstitutor inferTypeArguments() {
|
||||
private PsiSubstitutor inferTypeArguments(boolean includeReturnConstraint) {
|
||||
if (interfaceMethod == null) return substitutor;
|
||||
final InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference);
|
||||
session.initThrowsConstraints(method);
|
||||
@@ -127,7 +127,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
if (interfaceMethodReturnType != PsiType.VOID && interfaceMethodReturnType != null) {
|
||||
if (includeReturnConstraint && interfaceMethodReturnType != PsiType.VOID && interfaceMethodReturnType != null) {
|
||||
if (method.isConstructor()) {
|
||||
//todo
|
||||
session.initBounds(reference, method.getContainingClass().getTypeParameters());
|
||||
@@ -230,7 +230,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
if (!(conflict instanceof MethodCandidateInfo)) continue;
|
||||
final PsiMethod psiMethod = ((MethodCandidateInfo)conflict).getElement();
|
||||
|
||||
final PsiSubstitutor substitutor = conflict.getSubstitutor();
|
||||
final PsiSubstitutor substitutor = ((MethodCandidateInfo)conflict).getSubstitutor(false);
|
||||
final PsiType[] parameterTypes = psiMethod.getSignature(substitutor).getParameterTypes();
|
||||
|
||||
final boolean varargs = ((MethodCandidateInfo)conflict).isVarargs();
|
||||
|
||||
+1
-1
@@ -39,6 +39,6 @@ class MyTest1 {
|
||||
static void foo(I3 i) {}
|
||||
|
||||
static {
|
||||
foo<error descr="Cannot resolve method 'foo(<method reference>)'">(Foo::new)</error>;
|
||||
foo<error descr="Ambiguous method call: both 'MyTest1.foo(I1)' and 'MyTest1.foo(I2)' match">(Foo::new)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ class MyTest1 {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
m<error descr="Ambiguous method call: both 'MyTest1.m(I2)' and 'MyTest1.m(I3)' match">(Foo::new)</error>;
|
||||
m<error descr="Ambiguous method call: both 'MyTest1.m(I1)' and 'MyTest1.m(I2)' match">(Foo::new)</error>;
|
||||
}
|
||||
}
|
||||
class MyTest2 {
|
||||
@@ -104,6 +104,6 @@ class MyTest2 {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
m<error descr="Ambiguous method call: both 'MyTest2.m(I2)' and 'MyTest2.m(I3)' match">(Foo::new)</error>;
|
||||
m<error descr="Ambiguous method call: both 'MyTest2.m(I1)' and 'MyTest2.m(I2)' match">(Foo::new)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -29,10 +29,10 @@ class Test {
|
||||
static void meth4(I3 s) { }
|
||||
|
||||
static {
|
||||
meth1(Foo::<error descr="Cannot resolve constructor 'Foo'">new</error>);
|
||||
meth1(<error descr="Inferred type 'java.lang.String' for type parameter 'X' is not within its bound; should extend 'java.lang.Number'">Foo::new</error>);
|
||||
meth2(Foo::new);
|
||||
meth3(Foo::<error descr="Cannot resolve constructor 'Foo'">new</error>);
|
||||
meth4<error descr="Cannot resolve method 'meth4(<method reference>)'">(Foo::new)</error>;
|
||||
meth3(<error descr="Inferred type 'java.lang.Object' for type parameter 'X' is not within its bound; should extend 'java.lang.Number'">Foo::new</error>);
|
||||
meth4<error descr="Ambiguous method call: both 'Test.meth4(I1)' and 'Test.meth4(I2)' match">(Foo::new)</error>;
|
||||
|
||||
meth1(<error descr="Inferred type 'java.lang.String' for type parameter 'X' is not within its bound; should extend 'java.lang.Number'">Test::foo</error>);
|
||||
meth2(Test::foo);
|
||||
|
||||
Reference in New Issue
Block a user