diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 2186e43d17f1..c7ebe0f5cdfb 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -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) diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java index 503328ab46c5..440e2e2a625c 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java @@ -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();