lambda: extract parameters incompatibility check

This commit is contained in:
Anna Kozlova
2014-05-28 09:14:28 +04:00
parent 0fac1ec013
commit a7aa0df7ed
2 changed files with 36 additions and 33 deletions
@@ -315,41 +315,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (interfaceMethod != null) {
final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
final PsiParameter[] lambdaParameters = expression.getParameterList().getParameters();
final String incompatibleTypesMessage = "Incompatible parameter types in lambda expression";
if (lambdaParameters.length != parameters.length) {
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
PsiElement incompatibleElt = LambdaHighlightingUtil
.checkParametersCompatible(expression, parameters, LambdaUtil.getSubstitutor(interfaceMethod, resolveResult));
if (incompatibleElt != null) {
final String incompatibleTypesMessage = "Incompatible parameter types in lambda expression";
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(incompatibleElt)
.descriptionAndTooltip(incompatibleTypesMessage).create();
myHolder.add(result);
}
else {
final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
if (expression.hasFormalParameterTypes()) {
for (int i = 0; i < lambdaParameters.length; i++) {
if (!PsiTypesUtil.compareTypes(lambdaParameters[i].getType(), substitutor.substitute(parameters[i].getType()), true)) {
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.range(lambdaParameters[i])
.descriptionAndTooltip(incompatibleTypesMessage)
.create();
myHolder.add(result);
break;
}
}
} else {
for (int i = 0; i < lambdaParameters.length; i++) {
PsiParameter lambdaParameter = lambdaParameters[i];
if (!TypeConversionUtil.isAssignable(lambdaParameter.getType(), substitutor.substitute(parameters[i].getType()))) {
HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.range(lambdaParameter)
.descriptionAndTooltip(incompatibleTypesMessage)
.create();
myHolder.add(result);
break;
}
}
}
}
if (!myHolder.hasErrorResults()) {
} else {
final PsiClass samClass = resolveResult.getElement();
if (!PsiUtil.isAccessible(myFile.getProject(), samClass, expression, null)) {
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
@@ -17,7 +17,9 @@ package com.intellij.psi;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -45,6 +47,34 @@ public class LambdaHighlightingUtil {
return "Multiple non-overriding abstract methods found";
}
@Nullable
public static PsiElement checkParametersCompatible(PsiLambdaExpression expression,
PsiParameter[] methodParameters,
PsiSubstitutor substitutor) {
final PsiParameter[] lambdaParameters = expression.getParameterList().getParameters();
if (lambdaParameters.length != methodParameters.length) {
return expression;
}
else {
boolean hasFormalParameterTypes = expression.hasFormalParameterTypes();
for (int i = 0; i < lambdaParameters.length; i++) {
PsiParameter lambdaParameter = lambdaParameters[i];
PsiType lambdaParameterType = lambdaParameter.getType();
PsiType substitutedParamType = substitutor.substitute(methodParameters[i].getType());
if (hasFormalParameterTypes) {
if (!PsiTypesUtil.compareTypes(lambdaParameterType, substitutedParamType, true)) {
return lambdaParameter;
}
} else {
if (!TypeConversionUtil.isAssignable(lambdaParameterType, substitutedParamType)) {
return lambdaParameter;
}
}
}
}
return null;
}
public static String checkReturnTypeCompatible(PsiLambdaExpression lambdaExpression, PsiType functionalInterfaceReturnType) {
if (functionalInterfaceReturnType == PsiType.VOID) {
final PsiElement body = lambdaExpression.getBody();