PsiElementVisitor (@NotNull ProblemsHolder holder, boolean isOnTheFly) { if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) { return PsiElementVisitor.EMPTY_VISITOR; } return new JavaElementVisitor() { @Override public void visitConditionalExpression(@NotNull PsiConditionalExpression ternary) { TernaryNullCheck ternaryNullCheck = TernaryNullCheck.from(ternary); if (ternaryNullCheck == null) return; PsiVariable variable = ternaryNullCheck.myVariable; PsiExpression nullBranch = ternaryNullCheck.myNullBranch; PsiExpression notNullBranch = ternaryNullCheck.myNotNullBranch; if (!ExpressionUtils.isSafelyRecomputableExpression(nullBranch) && !LambdaGenerationUtil.canBeUncheckedLambda(nullBranch, variable::equals)) { return; } List<PsiReferenceExpression> references = VariableAccessUtils.getVariableReferences(variable, notNullBranch); if (references.isEmpty() || variable instanceof PsiField && !ContainerUtil.exists(references, ExpressionUtil::isEffectivelyUnqualified)) { return; } if (!LambdaGenerationUtil.canBeUncheckedLambda(notNullBranch, variable::equals)) { return; } if (!areTypesCompatible(nullBranch, notNullBranch)) return; boolean mayChangeSemantics = !ExpressionUtils.isNullLiteral(nullBranch) && NullabilityUtil.getExpressionNullability(notNullBranch, true) != Nullability.NOT_NULL; if (!isOnTheFly && mayChangeSemantics) return; holder.registerProblem(ternary.getCondition(), JavaBundle.message("inspection.message.can.be.replaced.with.optional.of.nullable"), mayChangeSemantics ? ProblemHighlightType.INFORMATION : ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceConditionWithOptionalFix(mayChangeSemantics)); } private static boolean areTypesCompatible(PsiExpression nullBranch, PsiExpression notNullBranch) { PsiType notNullType = ((PsiExpression)notNullBranch.copy()).getType(); PsiType nullType = ((PsiExpression)nullBranch.copy()).getType(); if (nullType == null || notNullType == null) return false; if (nullType.isAssignableFrom(notNullType)) return true; if (nullType.equals(PsiTypes.nullType())) return true; if (OptionalUtil.isOptionalEmptyCall(nullBranch) && TypeUtils.isOptional(notNullType)) return true; return false; } }; }