String (String qualifier, PsiVariable var, @NotNull PsiExpression trueExpression, PsiExpression falseExpression, @Nullable PsiType targetType, boolean useOrElseGet) { PsiExpression stripped = PsiUtil.skipParenthesizedExprDown(trueExpression); PsiType trueType = trueExpression.getType(); boolean trivialMap = ExpressionUtils.isReferenceTo(trueExpression, var) && targetType != null && (trueType instanceof PsiLambdaParameterType || Objects.requireNonNull(trueType).isAssignableFrom(targetType)); if (!trivialMap) { if (stripped instanceof PsiTypeCastExpression castExpression && ExpressionUtils.isNullLiteral(falseExpression)) { PsiTypeElement castType = castExpression.getCastType(); // pull cast outside to avoid the .map() step if (castType != null && ExpressionUtils.isReferenceTo(castExpression.getOperand(), var)) { return "(" + castType.getText() + ")" + qualifier + ".orElse(null)"; } } if (ExpressionUtils.isLiteral(falseExpression, Boolean.FALSE) && PsiTypes.booleanType().equals(trueType)) { if (ExpressionUtils.isLiteral(trueExpression, Boolean.TRUE)) { return qualifier + ".isPresent()"; } return qualifier + ".filter(" + LambdaUtil.createLambda(var, trueExpression) + ").isPresent()"; } if (ExpressionUtils.isLiteral(falseExpression, Boolean.TRUE) && ExpressionUtils.isLiteral(trueExpression, Boolean.FALSE)) { return "!" + qualifier + ".isPresent()"; } if (stripped instanceof PsiConditionalExpression condition) { PsiExpression thenExpression = condition.getThenExpression(); PsiExpression elseExpression = condition.getElseExpression(); if (thenExpression != null && elseExpression != null) { if (PsiEquivalenceUtil.areElementsEquivalent(falseExpression, elseExpression)) { return generateOptionalUnwrap( qualifier + ".filter(" + LambdaUtil.createLambda(var, condition.getCondition()) + ")", var, thenExpression, falseExpression, targetType, useOrElseGet); } if (PsiEquivalenceUtil.areElementsEquivalent(falseExpression, thenExpression)) { return generateOptionalUnwrap( qualifier + ".filter(" + var.getName() + " -> " + BoolUtils.getNegatedExpressionText(condition.getCondition()) + ")", var, elseExpression, falseExpression, targetType, useOrElseGet); } } } String suffix = null; boolean java9 = PsiUtil.isLanguageLevel9OrHigher(trueExpression); if (OptionalUtil.isOptionalEmptyCall(falseExpression)) { suffix = ""; } else if (java9 && InheritanceUtil.isInheritor(falseExpression.getType(), CommonClassNames.JAVA_UTIL_OPTIONAL) && LambdaGenerationUtil.canBeUncheckedLambda(falseExpression)) { suffix = ".or(() -> " + falseExpression.getText() + ")"; } if (suffix != null) { PsiMethodCallExpression mappedOptional = ObjectUtils.tryCast(stripped, PsiMethodCallExpression.class); // simplify "qualifier.map(x -> Optional.of(x)).orElse(Optional.empty())" to "qualifier" if (OptionalUtil.JDK_OPTIONAL_WRAP_METHOD.test(mappedOptional)) { PsiExpression arg = mappedOptional.getArgumentList().getExpressions()[0]; if (ExpressionUtils.isReferenceTo(arg, var)) { return qualifier + suffix; } return qualifier + ".map(" + LambdaUtil.createLambda(var, arg) + ")" + suffix; } if (suffix.isEmpty()) { return qualifier + ".flatMap(" + LambdaUtil.createLambda(var, trueExpression) + ")"; } } if (java9 && StreamApiUtil.isNullOrEmptyStream(falseExpression) && !ExpressionUtils.isNullLiteral(falseExpression)) { PsiType elementType = StreamApiUtil.getStreamElementType(targetType); if (elementType != null) { PsiMethodCallExpression mappedStream = ObjectUtils.tryCast(stripped, PsiMethodCallExpression.class); if (mappedStream != null && "of".equals(mappedStream.getMethodExpression().getReferenceName())) { PsiExpression[] args = mappedStream.getArgumentList().getExpressions(); if (args.length == 1) { PsiMethod method = mappedStream.resolveMethod(); if(method != null && method.getContainingClass() != null) { String className = method.getContainingClass().getQualifiedName(); PsiParameter[] parameters = method.getParameterList().getParameters(); if(className != null && className.startsWith("java.util.stream.") && parameters.length == 1 && !(parameters[0].getType() instanceof PsiArrayType)) { PsiExpression arg = args[0]; if(ExpressionUtils.isReferenceTo(arg, var)) { return qualifier + ".stream()"; } if(arg.getType() != null && elementType.isAssignableFrom(arg.getType())) { return qualifier + ".stream()" + StreamRefactoringUtil.generateMapOperation(var, elementType, arg); } } } } } String flatMapOperationName = StreamRefactoringUtil.getFlatMapOperationName(var.getType(), elementType); if(flatMapOperationName != null && !SideEffectChecker.mayHaveSideEffects(trueExpression)) { return qualifier + ".stream()."+flatMapOperationName+"(" + LambdaUtil.createLambda(var, trueExpression) + ")"; } } } trueExpression = targetType == null ? trueExpression : CommonJavaRefactoringUtil.convertInitializerToNormalExpression(trueExpression, targetType); String typeArg = getMapTypeArgument(trueExpression, targetType, falseExpression); qualifier += "." + typeArg + "map(" + LambdaUtil.createLambda(var, trueExpression) + ")"; } if (useOrElseGet && !ExpressionUtils.isSafelyRecomputableExpression(falseExpression)) { return qualifier + ".orElseGet(() -> " + falseExpression.getText() + ")"; } else { PsiType falseType = falseExpression.getType(); String falseText = falseExpression.getText(); if (falseType instanceof PsiPrimitiveType && targetType instanceof PsiPrimitiveType && !(targetType.equals(falseType))) { Number falseValue = JavaPsiMathUtil.getNumberFromLiteral(falseExpression); if (falseValue != null) { falseText = falseValue.toString(); if (targetType.equals(PsiTypes.floatType())) { falseText += "F"; } else if(targetType.equals(PsiTypes.doubleType()) && !falseText.contains(".")) { falseText += ".0"; } else if(targetType.equals(PsiTypes.longType())) { falseText += "L"; } } } return qualifier + ".orElse(" + falseText + ")"; } }