ProblemType (@NotNull PsiReferenceExpression optionalRef, @Nullable PsiElement lambdaCandidate, @Nullable PsiExpression falseExpression) { if (lambdaCandidate == null) return ProblemType.NONE; if (lambdaCandidate instanceof PsiReferenceExpression && areElementsEquivalent(lambdaCandidate, optionalRef) && OptionalUtil.isOptionalEmptyCall(falseExpression)) { return ProblemType.WARNING; } if (!LambdaGenerationUtil.canBeUncheckedLambda(lambdaCandidate, optionalRef::isReferenceTo)) return ProblemType.NONE; Ref<Boolean> hasOptionalReference = new Ref<>(Boolean.FALSE); boolean hasNoBadRefs = PsiTreeUtil.processElements(lambdaCandidate, e -> { if (!(e instanceof PsiReferenceExpression)) return true; if (!areElementsEquivalent(e, optionalRef)) return true; // Check that Optional variable is referenced only in context of get() call hasOptionalReference.set(Boolean.TRUE); return isOptionalGetCall(e.getParent().getParent(), optionalRef); }); if (!hasNoBadRefs) return ProblemType.NONE; if (!hasOptionalReference.get() || !(lambdaCandidate instanceof PsiExpression expression)) return ProblemType.INFO; if (falseExpression != null) { // falseExpression == null is "consumer" case (to be replaced with ifPresent()) if (!ExpressionUtils.isNullLiteral(falseExpression) && NullabilityUtil.getExpressionNullability(expression, true) != Nullability.NOT_NULL) { // if falseExpression is null literal, then semantics is preserved return ProblemType.INFO; } PsiType falseType = falseExpression.getType(); PsiType trueType = expression.getType(); if (falseType == null || trueType == null) return ProblemType.NONE; if (falseType instanceof PsiPrimitiveType && trueType instanceof PsiPrimitiveType) { if (falseType.equals(trueType) || JavaPsiMathUtil.getNumberFromLiteral(falseExpression) != null) { // like x ? double_expression : integer_expression; support only if integer_expression is simple literal, // so could be converted explicitly to double return ProblemType.WARNING; } return ProblemType.NONE; } if (!trueType.isAssignableFrom(falseType)) { return ProblemType.NONE; } } return ProblemType.WARNING; }