void (@NotNull PsiLambdaExpression expression) { add(checkFeature(expression, HighlightingFeature.LAMBDA_EXPRESSIONS)); PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); if (toReportFunctionalExpressionProblemOnParent(parent)) return; if (!hasErrorResults() && !LambdaUtil.isValidLambdaContext(parent)) { add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression) .descriptionAndTooltip(JavaErrorBundle.message("lambda.expression.not.expected"))); } if (!hasErrorResults()) add(LambdaHighlightingUtil.checkConsistentParameterDeclaration(expression)); PsiType functionalInterfaceType = null; if (!hasErrorResults()) { functionalInterfaceType = expression.getFunctionalInterfaceType(); if (functionalInterfaceType != null) { add(HighlightClassUtil.checkExtendsSealedClass(expression, functionalInterfaceType)); if (!hasErrorResults()) { String notFunctionalMessage = LambdaHighlightingUtil.checkInterfaceFunctional(functionalInterfaceType); if (notFunctionalMessage != null) { add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression) .descriptionAndTooltip(notFunctionalMessage)); } else { add(LambdaHighlightingUtil.checkFunctionalInterfaceTypeAccessible(myFile.getProject(), expression, functionalInterfaceType)); } } } else if (LambdaUtil.getFunctionalInterfaceType(expression, true) != null) { add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip( JavaErrorBundle.message("cannot.infer.functional.interface.type"))); } } if (!hasErrorResults() && functionalInterfaceType != null) { PsiCallExpression callExpression = parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression ? (PsiCallExpression)parent.getParent() : null; MethodCandidateInfo parentCallResolveResult = callExpression != null ? tryCast(callExpression.resolveMethodGenerics(), MethodCandidateInfo.class) : null; String parentInferenceErrorMessage = parentCallResolveResult != null ? parentCallResolveResult.getInferenceErrorMessage() : null; PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); Map<PsiElement, @Nls String> returnErrors = null; Set<PsiTypeParameter> parentTypeParameters = parentCallResolveResult == null ? Set.of() : Set.of(parentCallResolveResult.getElement().getTypeParameters()); // If return type of the lambda was not fully inferred and lambda parameters don't mention the same type, // it means that lambda is not responsible for inference failure and blaming it would be unreasonable. boolean skipReturnCompatibility = parentCallResolveResult != null && PsiTypesUtil.mentionsTypeParameters(returnType, parentTypeParameters) && !LambdaHighlightingUtil.lambdaParametersMentionTypeParameter(functionalInterfaceType, parentTypeParameters); if (!skipReturnCompatibility) { returnErrors = LambdaUtil.checkReturnTypeCompatible(expression, returnType); } if (parentInferenceErrorMessage != null && (returnErrors == null || !returnErrors.containsValue(parentInferenceErrorMessage))) { if (returnErrors == null) return; HighlightInfo.Builder info = HighlightMethodUtil.createIncompatibleTypeHighlightInfo(callExpression, getResolveHelper(getProject()), parentCallResolveResult, expression); if (info != null) { for (PsiElement errorElement : returnErrors.keySet()) { IntentionAction action = AdjustFunctionContextFix.createFix(errorElement); if (action != null) { info.registerFix(action, null, null, null, null); } } add(info); } } else if (returnErrors != null) { for (Map.Entry<PsiElement, @Nls String> entry : returnErrors.entrySet()) { PsiElement element = entry.getKey(); HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(element) .descriptionAndTooltip(entry.getValue()); IntentionAction action = AdjustFunctionContextFix.createFix(element); if (action != null) { info.registerFix(action, null, null, null, null); } if (element instanceof PsiExpression expr) { HighlightFixUtil.registerLambdaReturnTypeFixes(info, element.getTextRange(), expression, expr); } add(info); } } } if (!hasErrorResults() && functionalInterfaceType != null) { PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); if (interfaceMethod != null) { PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters(); add(LambdaHighlightingUtil.checkParametersCompatible(expression, parameters, LambdaUtil.getSubstitutor(interfaceMethod, resolveResult))); } } if (!hasErrorResults()) { PsiElement body = expression.getBody(); if (body instanceof PsiCodeBlock) { add(HighlightControlFlowUtil.checkUnreachableStatement((PsiCodeBlock)body)); } } }