mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
moreSpecific cleanup
This commit is contained in:
@@ -239,7 +239,16 @@ public class GenericsUtil {
|
||||
supers.add(classToAdd);
|
||||
}
|
||||
|
||||
public static boolean isTypeArgumentsApplicable(PsiTypeParameter[] typeParams, PsiSubstitutor substitutor, final PsiElement context) {
|
||||
public static boolean isTypeArgumentsApplicable(final PsiTypeParameter[] typeParams,
|
||||
final PsiSubstitutor substitutor,
|
||||
final PsiElement context) {
|
||||
return isTypeArgumentsApplicable(typeParams, substitutor, context, true);
|
||||
}
|
||||
|
||||
public static boolean isTypeArgumentsApplicable(final PsiTypeParameter[] typeParams,
|
||||
final PsiSubstitutor substitutor,
|
||||
final PsiElement context,
|
||||
final boolean allowUncheckedConversion) {
|
||||
nextTypeParam:
|
||||
for (PsiTypeParameter typeParameter : typeParams) {
|
||||
PsiType substituted = substitutor.substitute(typeParameter);
|
||||
@@ -266,7 +275,7 @@ public class GenericsUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!TypeConversionUtil.isAssignable(extendsType, substituted)) {
|
||||
if (!TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
@NotNull final PsiSubstitutor substitutorForMethod,
|
||||
@NotNull final PsiType[] args,
|
||||
@NotNull final LanguageLevel languageLevel) {
|
||||
return getApplicabilityLevel(method, substitutorForMethod, args, languageLevel, true);
|
||||
return getApplicabilityLevel(method, substitutorForMethod, args, languageLevel, true, true);
|
||||
}
|
||||
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant
|
||||
@@ -478,7 +478,8 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
@NotNull final PsiSubstitutor substitutorForMethod,
|
||||
@NotNull final PsiType[] args,
|
||||
@NotNull final LanguageLevel languageLevel,
|
||||
boolean allowUncheckedConversion) {
|
||||
final boolean allowUncheckedConversion,
|
||||
final boolean checkVarargs) {
|
||||
final PsiParameter[] parms = method.getParameterList().getParameters();
|
||||
if (args.length < parms.length - 1) return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
|
||||
@@ -502,7 +503,7 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
}
|
||||
}
|
||||
|
||||
if (method.isVarArgs() && languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0) {
|
||||
if (checkVarargs && method.isVarArgs() && languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0) {
|
||||
if (args.length < parms.length) return ApplicabilityLevel.VARARGS;
|
||||
PsiParameter lastParameter = parms[parms.length - 1];
|
||||
if (!lastParameter.isVarArgs()) return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
|
||||
+35
-38
@@ -17,7 +17,6 @@ package com.intellij.psi.scope.conflictResolvers;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
@@ -455,11 +454,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
final int max = Math.max(params1.length, params2.length);
|
||||
PsiType[] types1 = new PsiType[max];
|
||||
PsiType[] types2 = new PsiType[max];
|
||||
final boolean varargsPosition = applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS;
|
||||
for (int i = 0; i < max; i++) {
|
||||
ProgressManager.checkCanceled();
|
||||
PsiType type1 = params1.length > 0 ? params1[Math.min(i, params1.length - 1)].getType() : null;
|
||||
PsiType type2 = params2.length > 0 ? params2[Math.min(i, params2.length - 1)].getType() : null;
|
||||
if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
|
||||
if (varargsPosition) {
|
||||
if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType &&
|
||||
params1.length == params2.length &&
|
||||
(!JavaVersionService.getInstance().isAtLeast(class1, JavaSdkVersion.JDK_1_7) || ((PsiArrayType)type1).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || ((PsiArrayType)type2).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT))) {
|
||||
@@ -503,11 +503,21 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (sameBoxing) {
|
||||
final PsiSubstitutor siteSubstitutor1 = ((MethodCandidateInfo)info1).getSiteSubstitutor();
|
||||
final PsiSubstitutor siteSubstitutor2 = ((MethodCandidateInfo)info2).getSiteSubstitutor();
|
||||
final int level1 = getLevel(applicabilityLevel, languageLevel, method1, typeParameters1, types2, types1, siteSubstitutor2, siteSubstitutor1);
|
||||
final int level2 = getLevel(applicabilityLevel, languageLevel, method2, typeParameters2, types1, types2, siteSubstitutor1, siteSubstitutor2);
|
||||
if (level1 > level2) return Specifics.SECOND;
|
||||
if (level2 > level1) return Specifics.FIRST;
|
||||
if (level1 > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE) {
|
||||
|
||||
final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2);
|
||||
final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1);
|
||||
|
||||
final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel);
|
||||
final PsiSubstitutor methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel);
|
||||
|
||||
final boolean applicable12 = isApplicableTo(types2AtSite, method1, typeParameters1, languageLevel, methodSubstitutor1, varargsPosition);
|
||||
final boolean applicable21 = isApplicableTo(types1AtSite, method2, typeParameters2, languageLevel, methodSubstitutor2, varargsPosition);
|
||||
|
||||
if (applicable12 || applicable21) {
|
||||
|
||||
if (applicable12 && !applicable21) return Specifics.SECOND;
|
||||
if (applicable21 && !applicable12) return Specifics.FIRST;
|
||||
|
||||
final boolean abstract1 = method1.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
final boolean abstract2 = method2.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
if (abstract1 && !abstract2) {
|
||||
@@ -518,7 +528,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
|
||||
else if (varargsPosition) {
|
||||
final PsiType lastParamType1 = classSubstitutor1.substitute(types1[types1.length - 1]);
|
||||
final PsiType lastParamType2 = classSubstitutor2.substitute(types2[types1.length - 1]);
|
||||
final boolean assignable1 = TypeConversionUtil.isAssignable(lastParamType2, lastParamType1);
|
||||
@@ -560,37 +570,24 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return Specifics.NEITHER;
|
||||
}
|
||||
|
||||
private static int getLevel(int applicabilityLevel,
|
||||
LanguageLevel languageLevel,
|
||||
PsiMethod method2,
|
||||
PsiTypeParameter[] typeParameters2,
|
||||
PsiType[] types1,
|
||||
PsiType[] types2,
|
||||
PsiSubstitutor siteSubstitutor1,
|
||||
PsiSubstitutor siteSubstitutor2) {
|
||||
final int argsLength = types1.length;
|
||||
final PsiType[] nTypes1 = new PsiType[argsLength];
|
||||
for (int i = 0; i < argsLength; i++) {
|
||||
nTypes1[i] = siteSubstitutor1.substitute(types1[i]);
|
||||
private boolean isApplicableTo(PsiType[] argTypes,
|
||||
PsiMethod method,
|
||||
PsiTypeParameter[] typeParameters,
|
||||
LanguageLevel languageLevel, PsiSubstitutor methodSubstitutor, boolean checkVarargs) {
|
||||
final int applicabilityLevel = PsiUtil.getApplicabilityLevel(method, methodSubstitutor, argTypes, languageLevel, false, checkVarargs);
|
||||
final boolean applicable = applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
if (applicable && !GenericsUtil.isTypeArgumentsApplicable(typeParameters, methodSubstitutor, myArgumentsList, false)) {
|
||||
return false;
|
||||
}
|
||||
final PsiSubstitutor methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, nTypes1, languageLevel);
|
||||
final int level = Math.min(applicabilityLevel, PsiUtil.getApplicabilityLevel(method2, methodSubstitutor2, nTypes1, languageLevel, false));
|
||||
if (level > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE) {
|
||||
for (PsiTypeParameter typeParameter : typeParameters2) {
|
||||
final PsiType substituted = methodSubstitutor2.substitute(typeParameter);
|
||||
for (PsiClassType extendsType : typeParameter.getExtendsListTypes()) {
|
||||
if (substituted == null || !TypeConversionUtil.isAssignable(methodSubstitutor2.substitute(extendsType), substituted, false)) {
|
||||
return MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (level == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
|
||||
if (!TypeConversionUtil.isAssignable(methodSubstitutor2.substitute(types2[argsLength - 1]), nTypes1[argsLength - 1])) {
|
||||
return MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
}
|
||||
return applicable;
|
||||
}
|
||||
|
||||
private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1) {
|
||||
final PsiType[] types = new PsiType[types1.length];
|
||||
for (int i = 0; i < types1.length; i++) {
|
||||
types[i] = siteSubstitutor1.substitute(types1[i]);
|
||||
}
|
||||
return level;
|
||||
return types;
|
||||
}
|
||||
|
||||
private static PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters,
|
||||
@@ -605,7 +602,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
ProgressManager.checkCanceled();
|
||||
LOG.assertTrue(typeParameter != null);
|
||||
if (!substitutor.getSubstitutionMap().containsKey(typeParameter)) {
|
||||
substitutor = substitutor.put(typeParameter, TypeConversionUtil.erasure(siteSubstitutor.substitute(typeParameter)));
|
||||
substitutor = substitutor.put(typeParameter, siteSubstitutor.substitute(typeParameter));
|
||||
}
|
||||
}
|
||||
return substitutor;
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ abstract class A {
|
||||
abstract void foo(int... x);
|
||||
|
||||
{
|
||||
foo<error descr="Ambiguous method call: both 'A.foo(Object...)' and 'A.foo(int...)' match">(1)</error>;
|
||||
foo(1);
|
||||
}
|
||||
}
|
||||
abstract class A1 {
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class MyTest1 {
|
||||
I i2 = MyTest1 :: m2;
|
||||
i2.m(42,42);
|
||||
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I'">I i3 = MyTest1 :: m3;</error>
|
||||
I i3 = MyTest1 :: m3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user