mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
new inference: exclude return constraints/non pertinent to applicability argument constraints from overload resolution process
This commit is contained in:
@@ -111,7 +111,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
else {
|
||||
final PsiSubstitutor substitutor = getSubstitutor();
|
||||
final PsiSubstitutor substitutor = getSubstitutor(false);
|
||||
Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
|
||||
@Override
|
||||
public Integer compute() {
|
||||
@@ -120,7 +120,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
});
|
||||
level = boxedLevel != null ? boxedLevel : getApplicabilityLevel();
|
||||
}
|
||||
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE;
|
||||
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(false)) level = ApplicabilityLevel.NOT_APPLICABLE;
|
||||
return level;
|
||||
}
|
||||
Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
|
||||
@@ -145,7 +145,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
@NotNull
|
||||
public PsiSubstitutor getSubstitutor(boolean includeReturnConstraint) {
|
||||
PsiSubstitutor substitutor = myCalcedSubstitutor;
|
||||
if (substitutor == null || !includeReturnConstraint) {
|
||||
if (substitutor == null || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
|
||||
PsiMethod method = getElement();
|
||||
if (myTypeArguments == null) {
|
||||
@@ -153,7 +153,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
|
||||
if (!stackStamp.mayCacheNow() || !includeReturnConstraint) {
|
||||
if (!stackStamp.mayCacheNow() || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
return inferredSubstitutor;
|
||||
}
|
||||
|
||||
@@ -173,12 +173,16 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
|
||||
public boolean isTypeArgumentsApplicable() {
|
||||
return isTypeArgumentsApplicable(false);
|
||||
}
|
||||
|
||||
public boolean isTypeArgumentsApplicable(boolean includeReturnConstraint) {
|
||||
final PsiMethod psiMethod = getElement();
|
||||
PsiTypeParameter[] typeParams = psiMethod.getTypeParameters();
|
||||
if (myTypeArguments != null && typeParams.length != myTypeArguments.length && !PsiUtil.isLanguageLevel7OrHigher(psiMethod)){
|
||||
return typeParams.length == 0 && JavaVersionService.getInstance().isAtLeast(psiMethod, JavaSdkVersion.JDK_1_7);
|
||||
}
|
||||
PsiSubstitutor substitutor = getSubstitutor();
|
||||
PsiSubstitutor substitutor = getSubstitutor(includeReturnConstraint);
|
||||
return GenericsUtil.isTypeArgumentsApplicable(typeParams, substitutor, getParent());
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -199,10 +199,19 @@ public class InferenceSession {
|
||||
@Nullable PsiExpression[] args,
|
||||
@Nullable PsiElement parent,
|
||||
ParameterTypeInferencePolicy policy) {
|
||||
boolean doesNotContainFalseBound = repeatInferencePhases(parameters == null);
|
||||
return infer(parameters, args, parent, false, policy);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiSubstitutor infer(@Nullable PsiParameter[] parameters,
|
||||
@Nullable PsiExpression[] args,
|
||||
@Nullable PsiElement parent,
|
||||
boolean acceptNonPertinentArgs,
|
||||
ParameterTypeInferencePolicy policy) {
|
||||
boolean doesNotContainFalseBound = repeatInferencePhases(parameters == null || !policy.allowPostponeInference());
|
||||
// if (!doesNotContainFalseBound) return prepareSubstitution();
|
||||
|
||||
resolveBounds(myInferenceVariables.values(), mySiteSubstitutor, false);
|
||||
resolveBounds(myInferenceVariables.values(), mySiteSubstitutor, !policy.allowPostponeInference());
|
||||
|
||||
final Pair<PsiMethod, PsiCallExpression> pair = getPair(parent);
|
||||
if (pair != null) {
|
||||
@@ -220,7 +229,7 @@ public class InferenceSession {
|
||||
MethodCandidateInfo.updateSubstitutor(argumentList, substitutor);
|
||||
}
|
||||
|
||||
if (parameters != null && args != null) {
|
||||
if (parameters != null && args != null && (acceptNonPertinentArgs || pair != null)) {
|
||||
final Set<ConstraintFormula> additionalConstraints = new HashSet<ConstraintFormula>();
|
||||
if (parameters.length > 0) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
callSession.initExpressionConstraints(parameters, args, myExpression, method);
|
||||
substitutor = callSession.infer(parameters, args, myExpression, LiftParameterTypeInferencePolicy.INSTANCE);
|
||||
substitutor = callSession.infer(parameters, args, myExpression, true, LiftParameterTypeInferencePolicy.INSTANCE);
|
||||
}
|
||||
} else {
|
||||
substitutor = pair.second;
|
||||
|
||||
+15
-14
@@ -123,7 +123,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (methodParameters.length == 0) continue;
|
||||
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
|
||||
final PsiType paramType = param.getType();
|
||||
if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
|
||||
if (!LambdaUtil.isAcceptable(lambdaExpression, ((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType),
|
||||
lambdaExpression.hasFormalParameterTypes())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
@@ -147,7 +148,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
ProgressManager.checkCanceled();
|
||||
final CandidateInfo conflict = newConflictsArray[j];
|
||||
if (nonComparable(method, conflict)) continue;
|
||||
switch (isMoreSpecific(method, conflict, applicabilityLevel, languageLevel)) {
|
||||
switch (isMoreSpecific((MethodCandidateInfo)method, (MethodCandidateInfo)conflict, applicabilityLevel, languageLevel)) {
|
||||
case FIRST:
|
||||
conflicts.remove(conflict);
|
||||
break;
|
||||
@@ -217,7 +218,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
|
||||
PsiClass class1 = method.getContainingClass();
|
||||
PsiSubstitutor infoSubstitutor = info.getSubstitutor();
|
||||
PsiSubstitutor infoSubstitutor = ((MethodCandidateInfo)info).getSubstitutor(false);
|
||||
MethodSignature signature = method.getSignature(infoSubstitutor);
|
||||
CandidateInfo existing = signatures.get(signature);
|
||||
|
||||
@@ -276,7 +277,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
PsiType returnType2 = existingMethod.getReturnType();
|
||||
if (returnType1 != null && returnType2 != null) {
|
||||
returnType1 = infoSubstitutor.substitute(returnType1);
|
||||
returnType2 = existing.getSubstitutor().substitute(returnType2);
|
||||
returnType2 = ((MethodCandidateInfo)existing).getSubstitutor(false).substitute(returnType2);
|
||||
if (!returnType1.equals(returnType2) && returnType1.isAssignableFrom(returnType2)) {
|
||||
conflicts.remove(i);
|
||||
i--;
|
||||
@@ -437,12 +438,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return TypeConversionUtil.boxingConversionApplicable(parameterType, argType);
|
||||
}
|
||||
|
||||
private Specifics isMoreSpecific(final CandidateInfo info1,
|
||||
final CandidateInfo info2,
|
||||
private Specifics isMoreSpecific(final MethodCandidateInfo info1,
|
||||
final MethodCandidateInfo info2,
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
PsiMethod method1 = (PsiMethod)info1.getElement();
|
||||
PsiMethod method2 = (PsiMethod)info2.getElement();
|
||||
PsiMethod method1 = info1.getElement();
|
||||
PsiMethod method2 = info2.getElement();
|
||||
final PsiClass class1 = method1.getContainingClass();
|
||||
final PsiClass class2 = method2.getContainingClass();
|
||||
|
||||
@@ -451,8 +452,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
final PsiTypeParameter[] typeParameters1 = method1.getTypeParameters();
|
||||
final PsiTypeParameter[] typeParameters2 = method2.getTypeParameters();
|
||||
final PsiSubstitutor classSubstitutor1 = info1.getSubstitutor(); //substitutions for method type parameters will be ignored
|
||||
final PsiSubstitutor classSubstitutor2 = info2.getSubstitutor();
|
||||
final PsiSubstitutor classSubstitutor1 = info1.getSubstitutor(false); //substitutions for method type parameters will be ignored
|
||||
final PsiSubstitutor classSubstitutor2 = info2.getSubstitutor(false);
|
||||
|
||||
final int max = Math.max(params1.length, params2.length);
|
||||
PsiType[] types1 = PsiType.createArray(max);
|
||||
@@ -504,8 +505,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (boxingHappened[0] > 0 && boxingHappened[1] == 0) return Specifics.SECOND;
|
||||
|
||||
if (sameBoxing) {
|
||||
final PsiSubstitutor siteSubstitutor1 = ((MethodCandidateInfo)info1).getSiteSubstitutor();
|
||||
final PsiSubstitutor siteSubstitutor2 = ((MethodCandidateInfo)info2).getSiteSubstitutor();
|
||||
final PsiSubstitutor siteSubstitutor1 = info1.getSiteSubstitutor();
|
||||
final PsiSubstitutor siteSubstitutor2 = info2.getSiteSubstitutor();
|
||||
|
||||
final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2, typeParameters2);
|
||||
final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1, typeParameters1);
|
||||
@@ -607,7 +608,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
if (class1 != class2) {
|
||||
if (class2.isInheritor(class1, true) || class1.isInterface() && !class2.isInterface()) {
|
||||
if (MethodSignatureUtil.isSubsignature(method1.getSignature(info1.getSubstitutor()), method2.getSignature(info2.getSubstitutor()))) {
|
||||
if (MethodSignatureUtil.isSubsignature(method1.getSignature(info1.getSubstitutor(false)), method2.getSignature(info2.getSubstitutor(false)))) {
|
||||
return Specifics.SECOND;
|
||||
}
|
||||
else if (method1.hasModifierProperty(PsiModifier.STATIC) && method2.hasModifierProperty(PsiModifier.STATIC) && boxingHappened[0] == 0) {
|
||||
@@ -616,7 +617,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
else if (class1.isInheritor(class2, true) || class2.isInterface()) {
|
||||
if (MethodSignatureUtil.areErasedParametersEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY)) &&
|
||||
MethodSignatureUtil.isSubsignature(method2.getSignature(info2.getSubstitutor()), method1.getSignature(info1.getSubstitutor()))) {
|
||||
MethodSignatureUtil.isSubsignature(method2.getSignature(info2.getSubstitutor(false)), method1.getSignature(info1.getSubstitutor(false)))) {
|
||||
return Specifics.FIRST;
|
||||
}
|
||||
else if (method1.hasModifierProperty(PsiModifier.STATIC) && method2.hasModifierProperty(PsiModifier.STATIC) && boxingHappened[0] == 0) {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ class ReturnTypeIncompatibility {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I3<Object>)' match">(i-> {return i;})</error>;
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I2<Integer>)' match">(i-> {return i;})</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user