mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: postpone argument types calculation
This commit is contained in:
@@ -82,9 +82,11 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
@ApplicabilityLevelConstant
|
||||
private int getApplicabilityLevelInner() {
|
||||
if (myArgumentTypes == null) return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
final PsiType[] argumentTypes = getArgumentTypes();
|
||||
|
||||
int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), myArgumentTypes, myLanguageLevel);
|
||||
if (argumentTypes == null) return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
|
||||
int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), argumentTypes, myLanguageLevel);
|
||||
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE;
|
||||
return level;
|
||||
}
|
||||
@@ -104,18 +106,17 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return getApplicabilityLevel();
|
||||
}
|
||||
|
||||
if (myArgumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
@ApplicabilityLevelConstant int level;
|
||||
Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
|
||||
@Override
|
||||
public Integer compute() {
|
||||
|
||||
final PsiMethod method = getElement();
|
||||
if (method != null && method.hasTypeParameters() || myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
|
||||
return PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(false), myArgumentTypes, myLanguageLevel);
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
|
||||
final PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
return PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(false), argumentTypes, myLanguageLevel);
|
||||
}
|
||||
return getApplicabilityLevelInner();
|
||||
}
|
||||
@@ -127,7 +128,17 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
}
|
||||
|
||||
public PsiSubstitutor getSiteSubstitutor() {
|
||||
return super.getSubstitutor();
|
||||
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
|
||||
if (myTypeArguments != null) {
|
||||
PsiMethod method = getElement();
|
||||
if (method != null) {
|
||||
PsiTypeParameter[] typeParams = method.getTypeParameters();
|
||||
for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) {
|
||||
incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return incompleteSubstitutor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -206,22 +217,10 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return inferTypeArguments(policy, arguments, true);
|
||||
}
|
||||
else {
|
||||
return typeArgumentsSubstitutor();
|
||||
return getSiteSubstitutor();
|
||||
}
|
||||
}
|
||||
|
||||
public PsiSubstitutor typeArgumentsSubstitutor() {
|
||||
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
|
||||
PsiMethod method = getElement();
|
||||
if (method != null) {
|
||||
PsiTypeParameter[] typeParams = method.getTypeParameters();
|
||||
for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) {
|
||||
incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]);
|
||||
}
|
||||
}
|
||||
return incompleteSubstitutor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy,
|
||||
@NotNull PsiExpression[] arguments,
|
||||
@@ -283,6 +282,10 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
}
|
||||
}
|
||||
|
||||
public PsiType[] getArgumentTypes() {
|
||||
return myArgumentTypes;
|
||||
}
|
||||
|
||||
public static class ApplicabilityLevel {
|
||||
public static final int NOT_APPLICABLE = 1;
|
||||
public static final int VARARGS = 2;
|
||||
|
||||
+29
-12
@@ -72,7 +72,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (conflicts.isEmpty()) return null;
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParameterTypes().length, true);
|
||||
boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParametersLength(), true);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkSameSignatures(conflicts);
|
||||
@@ -81,7 +81,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
checkAccessStaticLevels(conflicts, true);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkParametersNumber(conflicts, getActualParameterTypes().length, false);
|
||||
checkParametersNumber(conflicts, getActualParametersLength(), false);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
final int applicabilityLevel = checkApplicability(conflicts);
|
||||
@@ -97,7 +97,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkPrimitiveVarargs(conflicts, getActualParameterTypes().length);
|
||||
checkPrimitiveVarargs(conflicts, getActualParametersLength());
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkAccessStaticLevels(conflicts, false);
|
||||
@@ -110,10 +110,19 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
private void checkLambdaApplicable(@NotNull List<CandidateInfo> conflicts, @NotNull LanguageLevel languageLevel) {
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return;
|
||||
for (int i = 0; i < getActualParameterTypes().length; i++) {
|
||||
PsiType parameterType = getActualParameterTypes()[i];
|
||||
if (parameterType instanceof PsiLambdaExpressionType) {
|
||||
final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression();
|
||||
for (int i = 0; i < getActualParametersLength(); i++) {
|
||||
|
||||
PsiExpression expression;
|
||||
if (myArgumentsList instanceof PsiExpressionList) {
|
||||
expression = ((PsiExpressionList)myArgumentsList).getExpressions()[i];
|
||||
}
|
||||
else {
|
||||
final PsiType argType = getActualParameterTypes()[i];
|
||||
expression = argType instanceof PsiLambdaExpressionType ? ((PsiLambdaExpressionType)argType).getExpression() : null;
|
||||
}
|
||||
|
||||
if (expression instanceof PsiLambdaExpression) {
|
||||
final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression;
|
||||
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
|
||||
ProgressManager.checkCanceled();
|
||||
final CandidateInfo conflict = iterator.next();
|
||||
@@ -411,6 +420,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return myActualParameterTypes;
|
||||
}
|
||||
|
||||
private int getActualParametersLength() {
|
||||
if (myActualParameterTypes == null) {
|
||||
LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
|
||||
return ((PsiExpressionList)myArgumentsList).getExpressions().length;
|
||||
}
|
||||
return myActualParameterTypes.length;
|
||||
}
|
||||
|
||||
protected PsiType[] getArgumentTypes() {
|
||||
return ((PsiExpressionList)myArgumentsList).getExpressionTypes();
|
||||
}
|
||||
@@ -500,8 +517,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
final PsiSubstitutor siteSubstitutor1 = info1.getSiteSubstitutor();
|
||||
final PsiSubstitutor siteSubstitutor2 = info2.getSiteSubstitutor();
|
||||
|
||||
final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2, typeParameters2);
|
||||
final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1, typeParameters1);
|
||||
final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2);
|
||||
final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1);
|
||||
|
||||
final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite,
|
||||
languageLevel);
|
||||
@@ -538,7 +555,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && myArgumentsList instanceof PsiExpressionList && (typeParameters1.length == 0 || typeParameters2.length == 0)) {
|
||||
boolean toCompareFunctional = false;
|
||||
for (int i = 0; i < myActualParameterTypes.length; i++) {
|
||||
for (int i = 0; i < getActualParametersLength(); i++) {
|
||||
if (types1.length > 0 && LambdaUtil.isFunctionalType(types1[Math.min(i, types1.length - 1)]) &&
|
||||
types2.length > 0 && LambdaUtil.isFunctionalType(types2[Math.min(i, types2.length - 1)])) {
|
||||
types1AtSite[Math.min(i, types1.length - 1)] = PsiType.NULL;
|
||||
@@ -555,7 +572,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
if (applicable12ignoreFunctionalType || applicable21ignoreFunctionalType) {
|
||||
Specifics specifics = null;
|
||||
for (int i = 0; i < myActualParameterTypes.length; i++) {
|
||||
for (int i = 0; i < getActualParametersLength(); i++) {
|
||||
if (types1.length > 0 && types1AtSite[Math.min(i, types1.length - 1)] == PsiType.NULL &&
|
||||
types2.length > 0 && types2AtSite[Math.min(i, types2.length - 1)] == PsiType.NULL) {
|
||||
Specifics specific = isFunctionalTypeMoreSpecific(info1, info2, ((PsiExpressionList)myArgumentsList).getExpressions()[i], i);
|
||||
@@ -642,7 +659,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1, PsiTypeParameter[] typeParameters1) {
|
||||
private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1) {
|
||||
final PsiType[] types = PsiType.createArray(types1.length);
|
||||
for (int i = 0; i < types1.length; i++) {
|
||||
types[i] = siteSubstitutor1.substitute(types1[i]);
|
||||
|
||||
+6
-1
@@ -63,7 +63,12 @@ public class MethodCandidatesProcessor extends MethodsProcessor{
|
||||
final boolean staticProblem, final boolean accessible) {
|
||||
final PsiExpressionList argumentList = getArgumentList();
|
||||
return new MethodCandidateInfo(method, substitutor, !accessible, staticProblem, argumentList, myCurrentFileContext,
|
||||
getExpressionTypes(argumentList), getTypeArguments(), getLanguageLevel());
|
||||
null, getTypeArguments(), getLanguageLevel()) {
|
||||
@Override
|
||||
public PsiType[] getArgumentTypes() {
|
||||
return getExpressionTypes(argumentList);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) {
|
||||
|
||||
Reference in New Issue
Block a user