IDEA-163627 Simplify optional.isPresent() inspection could better handle some specific cases

IDEA-163462 Simplify Optional.isPresent() ? Optional.get() : ...
This commit is contained in:
Tagir Valeev
2016-11-07 17:20:46 +07:00
parent 0000a95ba2
commit 21564bba7b
49 changed files with 628 additions and 236 deletions

View File

@@ -19,6 +19,7 @@ import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
import com.intellij.codeInspection.util.LambdaGenerationUtil;
import com.intellij.codeInspection.util.OptionalUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -47,7 +48,8 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
private static final OptionalIfPresentCase[] CASES = {
new ReturnCase(),
new AssignmentCase(),
new ConsumerCase()
new ConsumerCase(),
new TernaryCase()
};
@NotNull
@@ -58,25 +60,46 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
}
return new JavaElementVisitor() {
@Override
public void visitIfStatement(PsiIfStatement statement) {
super.visitIfStatement(statement);
PsiExpression condition = PsiUtil.skipParenthesizedExprDown(statement.getCondition());
if(condition == null) return;
public void visitConditionalExpression(PsiConditionalExpression expression) {
super.visitConditionalExpression(expression);
PsiExpression condition = PsiUtil.skipParenthesizedExprDown(expression.getCondition());
if (condition == null) return;
boolean invert = false;
PsiExpression strippedCondition = condition;
if(BoolUtils.isNegation(condition)) {
if (BoolUtils.isNegation(condition)) {
strippedCondition = BoolUtils.getNegated(condition);
invert = true;
}
PsiVariable optionalVariable = extractOptionalFromIfPresentCheck(strippedCondition);
if(optionalVariable == null) return;
if (optionalVariable == null) return;
PsiExpression thenExpression = invert ? expression.getElseExpression() : expression.getThenExpression();
PsiExpression elseExpression = invert ? expression.getThenExpression() : expression.getElseExpression();
check(condition, optionalVariable, thenExpression, elseExpression);
}
@Override
public void visitIfStatement(PsiIfStatement statement) {
super.visitIfStatement(statement);
PsiExpression condition = PsiUtil.skipParenthesizedExprDown(statement.getCondition());
if (condition == null) return;
boolean invert = false;
PsiExpression strippedCondition = condition;
if (BoolUtils.isNegation(condition)) {
strippedCondition = BoolUtils.getNegated(condition);
invert = true;
}
PsiVariable optionalVariable = extractOptionalFromIfPresentCheck(strippedCondition);
if (optionalVariable == null) return;
PsiStatement thenStatement = extractThenStatement(statement, invert);
PsiStatement elseStatement = extractElseStatement(statement, invert);
for(OptionalIfPresentCase scenario : CASES) {
String replacementName = scenario.getReplacementName(optionalVariable, thenStatement, elseStatement);
if(replacementName != null) {
holder.registerProblem(condition, "Can be replaced with "+replacementName,
new OptionalIfPresentFix(scenario, replacementName));
check(condition, optionalVariable, thenStatement, elseStatement);
}
void check(PsiExpression condition, PsiVariable optionalVariable, PsiElement thenElement, PsiElement elseElement) {
for (OptionalIfPresentCase scenario : CASES) {
if (scenario.isApplicable(optionalVariable, thenElement, elseElement)) {
holder.registerProblem(condition, "Can be replaced with single expression in functional style",
new OptionalIfPresentFix(scenario));
}
}
}
@@ -90,18 +113,18 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
@Nullable
private static PsiStatement extractThenStatement(PsiIfStatement ifStatement, boolean invert) {
if(invert) return extractElseStatement(ifStatement, false);
if (invert) return extractElseStatement(ifStatement, false);
return ControlFlowUtils.stripBraces(ifStatement.getThenBranch());
}
private static PsiStatement extractElseStatement(PsiIfStatement ifStatement, boolean invert) {
if(invert) return extractThenStatement(ifStatement, false);
if (invert) return extractThenStatement(ifStatement, false);
PsiStatement statement = ControlFlowUtils.stripBraces(ifStatement.getElseBranch());
if(statement == null) {
if (statement == null) {
PsiStatement thenStatement = extractThenStatement(ifStatement, false);
if(thenStatement instanceof PsiReturnStatement) {
if (thenStatement instanceof PsiReturnStatement) {
PsiElement nextElement = PsiTreeUtil.skipSiblingsForward(ifStatement, PsiComment.class, PsiWhiteSpace.class);
if(nextElement instanceof PsiStatement) {
if (nextElement instanceof PsiStatement) {
statement = ControlFlowUtils.stripBraces((PsiStatement)nextElement);
}
}
@@ -111,16 +134,16 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
@Contract("null -> null")
static PsiVariable extractOptionalFromIfPresentCheck(PsiExpression expression) {
if(!(expression instanceof PsiMethodCallExpression)) return null;
if (!(expression instanceof PsiMethodCallExpression)) return null;
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
if(call.getArgumentList().getExpressions().length != 0) return null;
if(!"isPresent".equals(call.getMethodExpression().getReferenceName())) return null;
if (call.getArgumentList().getExpressions().length != 0) return null;
if (!"isPresent".equals(call.getMethodExpression().getReferenceName())) return null;
PsiMethod method = call.resolveMethod();
if(method == null) return null;
if (method == null) return null;
PsiClass containingClass = method.getContainingClass();
if (containingClass == null || !CommonClassNames.JAVA_UTIL_OPTIONAL.equals(containingClass.getQualifiedName())) return null;
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
if(!(qualifier instanceof PsiReferenceExpression)) return null;
if (!(qualifier instanceof PsiReferenceExpression)) return null;
PsiElement element = ((PsiReferenceExpression)qualifier).resolve();
if (!(element instanceof PsiVariable) || isRaw((PsiVariable)element)) return null;
return (PsiVariable)element;
@@ -128,23 +151,23 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
@Contract("null, _ -> false")
static boolean isOptionalGetCall(PsiElement element, PsiVariable variable) {
if(!(element instanceof PsiMethodCallExpression)) return false;
if (!(element instanceof PsiMethodCallExpression)) return false;
PsiMethodCallExpression call = (PsiMethodCallExpression)element;
if(call.getArgumentList().getExpressions().length != 0) return false;
if(!"get".equals(call.getMethodExpression().getReferenceName())) return false;
if (call.getArgumentList().getExpressions().length != 0) return false;
if (!"get".equals(call.getMethodExpression().getReferenceName())) return false;
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
if(!(qualifier instanceof PsiReferenceExpression)) return false;
if (!(qualifier instanceof PsiReferenceExpression)) return false;
return ((PsiReferenceExpression)qualifier).isReferenceTo(variable);
}
@Contract("null, _ -> false")
static boolean isOptionalLambdaCandidate(PsiExpression lambdaCandidate, PsiVariable optionalVariable) {
if(lambdaCandidate == null) return false;
if(!ExceptionUtil.getThrownCheckedExceptions(lambdaCandidate).isEmpty()) return false;
if (lambdaCandidate == null) return false;
if (!ExceptionUtil.getThrownCheckedExceptions(lambdaCandidate).isEmpty()) return false;
return PsiTreeUtil.processElements(lambdaCandidate, e -> {
if (!(e instanceof PsiReferenceExpression)) return true;
PsiElement element = ((PsiReferenceExpression)e).resolve();
if(!(element instanceof PsiVariable)) return true;
if (!(element instanceof PsiVariable)) return true;
// Check that Optional variable is referenced only in context of get() call and other variables are effectively final
return element == optionalVariable
? isOptionalGetCall(e.getParent().getParent(), optionalVariable)
@@ -152,48 +175,41 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
});
}
@NotNull
static String generateMapIfNeeded(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiExpression trueValue) {
String name = optionalVariable.getName();
LOG.assertTrue(name != null);
if(isOptionalGetCall(trueValue, optionalVariable)) {
return name;
} else {
return name + ".map(" + generateOptionalLambda(factory, optionalVariable, trueValue) + ")";
}
}
@NotNull
static String generateOptionalLambda(PsiElementFactory factory, PsiVariable optionalVariable, PsiExpression trueValue) {
PsiType type = optionalVariable.getType();
JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(trueValue.getProject());
SuggestedNameInfo info = javaCodeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type);
if(info.names.length == 0)
if (info.names.length == 0) {
info = javaCodeStyleManager.suggestVariableName(VariableKind.PARAMETER, "value", null, type);
}
String paramName = javaCodeStyleManager.suggestUniqueVariableName(info, trueValue, true).names[0];
PsiElement copy = trueValue.copy();
for (PsiElement getCall : PsiTreeUtil.collectElements(copy, e -> isOptionalGetCall(e, optionalVariable))) {
getCall.replace(factory.createIdentifier(paramName));
PsiElement result = getCall.replace(factory.createIdentifier(paramName));
if (copy == getCall) copy = result;
}
return paramName + "->" + copy.getText();
}
static String generateOptionalUnwrap(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiExpression trueValue,
PsiExpression falseValue) {
String lambdaText = generateOptionalLambda(factory, optionalVariable, trueValue);
PsiLambdaExpression lambda = (PsiLambdaExpression)factory.createExpressionFromText(lambdaText, trueValue);
if(falseValue instanceof PsiReferenceExpression && ((PsiReferenceExpression)falseValue).isReferenceTo(optionalVariable)) {
falseValue = factory.createExpressionFromText(CommonClassNames.JAVA_UTIL_OPTIONAL+".empty()", falseValue);
}
return OptionalUtil.generateOptionalUnwrap(optionalVariable.getName(), lambda.getParameterList().getParameters()[0],
(PsiExpression)lambda.getBody(), falseValue, falseValue.getType(), true);
}
static class OptionalIfPresentFix implements LocalQuickFix {
private final OptionalIfPresentCase myScenario;
private final String myReplacementName;
public OptionalIfPresentFix(OptionalIfPresentCase scenario, String replacementName) {
public OptionalIfPresentFix(OptionalIfPresentCase scenario) {
myScenario = scenario;
myReplacementName = replacementName;
}
@Nls
@NotNull
@Override
public String getName() {
return "Replace Optional.isPresent() condition with "+myReplacementName;
}
@Nls
@@ -206,141 +222,149 @@ public class OptionalIsPresentInspection extends BaseJavaBatchLocalInspectionToo
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getStartElement();
if(!(element instanceof PsiExpression)) return;
PsiIfStatement statement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class);
if(statement == null) return;
if (!(element instanceof PsiExpression)) return;
PsiExpression condition = (PsiExpression)element;
boolean invert = false;
if(BoolUtils.isNegation(condition)) {
if (BoolUtils.isNegation(condition)) {
condition = BoolUtils.getNegated(condition);
invert = true;
}
PsiVariable optionalVariable = extractOptionalFromIfPresentCheck(condition);
if(optionalVariable == null) return;
PsiStatement thenStatement = extractThenStatement(statement, invert);
PsiStatement elseStatement = extractElseStatement(statement, invert);
if (!myScenario.isApplicable(optionalVariable, thenStatement, elseStatement)) return;
if (optionalVariable == null) return;
PsiElement cond = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class, PsiConditionalExpression.class);
PsiElement thenElement;
PsiElement elseElement;
if(cond instanceof PsiIfStatement) {
thenElement = extractThenStatement((PsiIfStatement)cond, invert);
elseElement = extractElseStatement((PsiIfStatement)cond, invert);
} else if(cond instanceof PsiConditionalExpression) {
thenElement = invert ? ((PsiConditionalExpression)cond).getElseExpression() : ((PsiConditionalExpression)cond).getThenExpression();
elseElement = invert ? ((PsiConditionalExpression)cond).getThenExpression() : ((PsiConditionalExpression)cond).getElseExpression();
} else return;
if (!myScenario.isApplicable(optionalVariable, thenElement, elseElement)) return;
if (!FileModificationService.getInstance().preparePsiElementForWrite(element.getContainingFile())) return;
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiElement parent = statement.getParent();
StreamEx.of(statement, thenStatement, elseStatement).nonNull()
PsiElement parent = cond.getParent();
StreamEx.of(cond, thenElement, elseElement).nonNull()
.flatCollection(st -> PsiTreeUtil.findChildrenOfType(st, PsiComment.class))
.distinct()
.forEach(comment -> {
parent.addBefore(comment, statement);
parent.addBefore(comment, cond);
comment.delete();
});
String replacement = myScenario.generateReplacement(factory, optionalVariable, thenStatement, elseStatement);
if(thenStatement != null && !PsiTreeUtil.isAncestor(statement, thenStatement, true)) thenStatement.delete();
if(elseStatement != null && !PsiTreeUtil.isAncestor(statement, elseStatement, true)) elseStatement.delete();
PsiElement result = statement.replace(factory.createStatementFromText(replacement, statement));
String replacementText = myScenario.generateReplacement(factory, optionalVariable, thenElement, elseElement);
if (thenElement != null && !PsiTreeUtil.isAncestor(cond, thenElement, true)) thenElement.delete();
if (elseElement != null && !PsiTreeUtil.isAncestor(cond, elseElement, true)) elseElement.delete();
PsiElement replacement = cond instanceof PsiExpression ?
factory.createExpressionFromText(replacementText, cond) :
factory.createStatementFromText(replacementText, cond);
PsiElement result = cond.replace(replacement);
LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
CodeStyleManager.getInstance(project).reformat(result);
}
}
interface OptionalIfPresentCase {
String getReplacementName(PsiVariable optionalVariable, PsiStatement trueStatement, PsiStatement falseStatement);
default boolean isApplicable(PsiVariable optionalVariable, PsiStatement trueStatement, PsiStatement falseStatement) {
return getReplacementName(optionalVariable, trueStatement, falseStatement) != null;
}
boolean isApplicable(PsiVariable optionalVariable, PsiElement trueElement, PsiElement falseElement);
String generateReplacement(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiStatement trueStatement,
PsiStatement falseStatement);
PsiElement trueElement,
PsiElement falseElement);
}
static class ReturnCase implements OptionalIfPresentCase {
@Override
public String getReplacementName(PsiVariable optionalVariable, PsiStatement trueStatement, PsiStatement falseStatement) {
if (!(trueStatement instanceof PsiReturnStatement) || !(falseStatement instanceof PsiReturnStatement)) return null;
PsiExpression falseValue = ((PsiReturnStatement)falseStatement).getReturnValue();
if(!ExpressionUtils.isSimpleExpression(falseValue)) return null;
PsiExpression trueValue = ((PsiReturnStatement)trueStatement).getReturnValue();
if(!isOptionalLambdaCandidate(trueValue, optionalVariable)) return null;
return isOptionalGetCall(trueValue, optionalVariable) ? "orElse()" : "map().orElse()";
public boolean isApplicable(PsiVariable optionalVariable, PsiElement trueElement, PsiElement falseElement) {
if (!(trueElement instanceof PsiReturnStatement) || !(falseElement instanceof PsiReturnStatement)) return false;
PsiExpression falseValue = ((PsiReturnStatement)falseElement).getReturnValue();
if (!ExpressionUtils.isSimpleExpression(falseValue) &&
!LambdaGenerationUtil.canBeUncheckedLambda(falseValue)) return false;
PsiExpression trueValue = ((PsiReturnStatement)trueElement).getReturnValue();
return isOptionalLambdaCandidate(trueValue, optionalVariable);
}
@Override
public String generateReplacement(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiStatement trueStatement,
PsiStatement falseStatement) {
PsiExpression trueValue = ((PsiReturnStatement)trueStatement).getReturnValue();
PsiExpression falseValue = ((PsiReturnStatement)falseStatement).getReturnValue();
PsiElement trueElement,
PsiElement falseElement) {
PsiExpression trueValue = ((PsiReturnStatement)trueElement).getReturnValue();
PsiExpression falseValue = ((PsiReturnStatement)falseElement).getReturnValue();
LOG.assertTrue(trueValue != null);
LOG.assertTrue(falseValue != null);
String trueBranch = generateMapIfNeeded(factory, optionalVariable, trueValue);
return "return " + trueBranch + ".orElse(" + falseValue.getText() + ");";
return "return " + generateOptionalUnwrap(factory, optionalVariable, trueValue, falseValue) + ";";
}
}
static class AssignmentCase implements OptionalIfPresentCase {
@Override
public String getReplacementName(PsiVariable optionalVariable, PsiStatement trueStatement, PsiStatement falseStatement) {
PsiAssignmentExpression trueAssignment = ExpressionUtils.getAssignment(trueStatement);
PsiAssignmentExpression falseAssignment = ExpressionUtils.getAssignment(falseStatement);
public boolean isApplicable(PsiVariable optionalVariable, PsiElement trueElement, PsiElement falseElement) {
PsiAssignmentExpression trueAssignment = ExpressionUtils.getAssignment(trueElement);
PsiAssignmentExpression falseAssignment = ExpressionUtils.getAssignment(falseElement);
if (trueAssignment == null ||
falseAssignment == null ||
!EquivalenceChecker.getCanonicalPsiEquivalence()
.expressionsAreEquivalent(trueAssignment.getLExpression(), falseAssignment.getLExpression()) ||
!isOptionalLambdaCandidate(trueAssignment.getRExpression(), optionalVariable)) {
return null;
return false;
}
String mapPart = isOptionalGetCall(trueAssignment.getRExpression(), optionalVariable) ? "" : "map().";
if(ExpressionUtils.isSimpleExpression(falseAssignment.getRExpression())) {
return mapPart + "orElse()";
}
if(LambdaGenerationUtil.canBeUncheckedLambda(falseAssignment.getRExpression())) {
return mapPart + "orElseGet()";
}
return null;
return ExpressionUtils.isSimpleExpression(falseAssignment.getRExpression()) ||
LambdaGenerationUtil.canBeUncheckedLambda(falseAssignment.getRExpression());
}
@Override
public String generateReplacement(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiStatement trueStatement,
PsiStatement falseStatement) {
PsiAssignmentExpression trueAssignment = ExpressionUtils.getAssignment(trueStatement);
PsiAssignmentExpression falseAssignment = ExpressionUtils.getAssignment(falseStatement);
PsiElement trueElement,
PsiElement falseElement) {
PsiAssignmentExpression trueAssignment = ExpressionUtils.getAssignment(trueElement);
PsiAssignmentExpression falseAssignment = ExpressionUtils.getAssignment(falseElement);
LOG.assertTrue(trueAssignment != null);
LOG.assertTrue(falseAssignment != null);
PsiExpression lValue = trueAssignment.getLExpression();
PsiExpression trueValue = trueAssignment.getRExpression();
PsiExpression falseValue = falseAssignment.getRExpression();
LOG.assertTrue(falseValue != null);
String trueBranch = generateMapIfNeeded(factory, optionalVariable, trueValue);
String falseBranch;
if(ExpressionUtils.isSimpleExpression(falseValue)) {
falseBranch = "orElse(" + falseValue.getText() + ")";
} else {
falseBranch = "orElseGet(" + "() -> " + falseValue.getText() + ")";
}
return lValue.getText() + " = " + trueBranch + "." + falseBranch + ";";
return lValue.getText() + " = " + generateOptionalUnwrap(factory, optionalVariable, trueValue, falseValue) + ";";
}
}
static class ConsumerCase implements OptionalIfPresentCase {
static class TernaryCase implements OptionalIfPresentCase {
@Override
public String getReplacementName(PsiVariable optionalVariable, PsiStatement trueStatement, PsiStatement falseStatement) {
if(falseStatement != null && !(falseStatement instanceof PsiEmptyStatement)) return null;
if(!(trueStatement instanceof PsiExpressionStatement)) return null;
PsiExpression expression = ((PsiExpressionStatement)trueStatement).getExpression();
if(!isOptionalLambdaCandidate(expression, optionalVariable)) return null;
return "ifPresent()";
public boolean isApplicable(PsiVariable optionalVariable, PsiElement trueElement, PsiElement falseElement) {
if(!(trueElement instanceof PsiExpression) || !(falseElement instanceof PsiExpression)) return false;
return isOptionalLambdaCandidate((PsiExpression)trueElement, optionalVariable) &&
(ExpressionUtils.isSimpleExpression((PsiExpression)falseElement) ||
LambdaGenerationUtil.canBeUncheckedLambda((PsiExpression)falseElement));
}
@Override
public String generateReplacement(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiStatement trueStatement,
PsiStatement falseStatement) {
PsiExpression expression = ((PsiExpressionStatement)trueStatement).getExpression();
PsiElement trueElement,
PsiElement falseElement) {
PsiExpression trueExpression = (PsiExpression)trueElement;
PsiExpression falseExpression = (PsiExpression)falseElement;
return generateOptionalUnwrap(factory, optionalVariable, trueExpression, falseExpression);
}
}
static class ConsumerCase implements OptionalIfPresentCase {
@Override
public boolean isApplicable(PsiVariable optionalVariable, PsiElement trueElement, PsiElement falseElement) {
if (falseElement != null && !(falseElement instanceof PsiEmptyStatement)) return false;
if (!(trueElement instanceof PsiExpressionStatement)) return false;
PsiExpression expression = ((PsiExpressionStatement)trueElement).getExpression();
return isOptionalLambdaCandidate(expression, optionalVariable);
}
@Override
public String generateReplacement(PsiElementFactory factory,
PsiVariable optionalVariable,
PsiElement trueElement,
PsiElement falseElement) {
PsiExpression expression = ((PsiExpressionStatement)trueElement).getExpression();
return optionalVariable.getName() + ".ifPresent(" + generateOptionalLambda(factory, optionalVariable, expression) + ");";
}
}

View File

@@ -15,12 +15,11 @@
*/
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.util.OptionalUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.NotNull;
@@ -103,35 +102,9 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
}
}
private static String generateOptionalUnwrap(String stream, @NotNull StreamApiMigrationInspection.TerminalBlock tb,
PsiExpression trueExpression, PsiExpression falseExpression, PsiType targetType) {
PsiVariable var = tb.getVariable();
if (!StreamApiMigrationInspection.isIdentityMapping(var, trueExpression)) {
if(trueExpression instanceof PsiTypeCastExpression && ExpressionUtils.isNullLiteral(falseExpression)) {
PsiTypeCastExpression castExpression = (PsiTypeCastExpression)trueExpression;
PsiTypeElement castType = castExpression.getCastType();
// pull cast outside to avoid the .map() step
if(castType != null && StreamApiMigrationInspection.isIdentityMapping(var, castExpression.getOperand())) {
return "(" + castType.getText() + ")" + stream + ".orElse(null)";
}
}
if(ExpressionUtils.isLiteral(falseExpression, Boolean.FALSE) && PsiType.BOOLEAN.equals(trueExpression.getType())) {
return stream + ".filter(" + LambdaUtil.createLambda(var, trueExpression) + ").isPresent()";
}
if(trueExpression instanceof PsiConditionalExpression) {
PsiConditionalExpression condition = (PsiConditionalExpression)trueExpression;
PsiExpression elseExpression = condition.getElseExpression();
if(elseExpression != null && PsiEquivalenceUtil.areElementsEquivalent(falseExpression, elseExpression)) {
return generateOptionalUnwrap(
stream + ".filter(" + LambdaUtil.createLambda(var, condition.getCondition()) + ")", tb,
condition.getThenExpression(), falseExpression, targetType);
}
}
trueExpression =
targetType == null ? trueExpression : RefactoringUtil.convertInitializerToNormalExpression(trueExpression, targetType);
stream += ".map(" + LambdaUtil.createLambda(var, trueExpression) + ")";
}
stream += ".orElse(" + falseExpression.getText() + ")";
return stream;
private static String generateOptionalUnwrap(String qualifier, StreamApiMigrationInspection.TerminalBlock tb,
PsiExpression trueExpression, PsiExpression falseExpression,
PsiType targetType) {
return OptionalUtil.generateOptionalUnwrap(qualifier, tb.getVariable(), trueExpression, falseExpression, targetType, false);
}
}

View File

@@ -259,7 +259,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
final PsiVariable variable = tb.getVariable();
final PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall();
LOG.assertTrue(methodCallExpression != null);
if (!isIdentityMapping(variable, methodCallExpression.getArgumentList().getExpressions()[0])) return false;
if (!ExpressionUtils.isIdentityMapping(variable, methodCallExpression.getArgumentList().getExpressions()[0])) return false;
PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
if(qualifierExpression == null || qualifierExpression instanceof PsiThisExpression) {
PsiMethod method = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethod.class);
@@ -384,11 +384,6 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return ContainerUtil.find(method.getThrowsList().getReferencedTypes(), type -> !ExceptionUtil.isUncheckedException(type)) != null;
}
@Contract("_, null -> false")
static boolean isIdentityMapping(PsiVariable variable, PsiExpression mapperCall) {
return mapperCall instanceof PsiReferenceExpression && ((PsiReferenceExpression)mapperCall).isReferenceTo(variable);
}
@Nullable
private static PsiClassType createDefaultConsumerType(Project project, PsiVariable variable) {
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
@@ -671,7 +666,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if(!(var instanceof PsiVariable) || !nonFinalVariables.contains(var)) return;
PsiExpression rValue = assignment.getRExpression();
if(rValue == null || isVariableReferenced((PsiVariable)var, rValue)) return;
if(tb.getVariable().getType() instanceof PsiPrimitiveType && !isIdentityMapping(tb.getVariable(), rValue)) return;
if(tb.getVariable().getType() instanceof PsiPrimitiveType && !ExpressionUtils.isIdentityMapping(tb.getVariable(), rValue)) return;
registerProblem(statement, "findFirst", new ReplaceWithFindFirstFix());
}
}
@@ -718,7 +713,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
registerProblem(statement, "anyMatch", new ReplaceWithMatchFix("anyMatch"));
}
if(nextReturnStatement != null && ExpressionUtils.isSimpleExpression(nextReturnStatement.getReturnValue())
&& (!(tb.getVariable().getType() instanceof PsiPrimitiveType) || isIdentityMapping(tb.getVariable(), value))) {
&& (!(tb.getVariable().getType() instanceof PsiPrimitiveType) || ExpressionUtils.isIdentityMapping(tb.getVariable(), value))) {
registerProblem(statement, "findFirst", new ReplaceWithFindFirstFix());
}
}
@@ -973,7 +968,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
@Override
public String createReplacement() {
if (isIdentityMapping(myVariable, myExpression)) {
if (ExpressionUtils.isIdentityMapping(myVariable, myExpression)) {
if (!(myType instanceof PsiPrimitiveType)) {
return myVariable.getType() instanceof PsiPrimitiveType ? ".boxed()" : "";
}

View File

@@ -16,11 +16,11 @@
package com.intellij.codeInspection.streamToLoop;
import com.intellij.codeInspection.streamToLoop.StreamToLoopInspection.StreamToLoopReplacementContext;
import com.intellij.codeInspection.util.OptionalUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.TypeConversionUtil;
import com.siyeh.ig.psiutils.BoolUtils;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,21 +47,6 @@ abstract class TerminalOperation extends Operation {
abstract String generate(StreamVariable inVar, StreamToLoopReplacementContext context);
@NotNull
@Contract(pure = true)
private static String getOptionalClass(String type) {
switch (type) {
case "int":
return "java.util.OptionalInt";
case "long":
return "java.util.OptionalLong";
case "double":
return "java.util.OptionalDouble";
default:
return "java.util.Optional";
}
}
@Nullable
static TerminalOperation createTerminal(@NotNull String name, @NotNull PsiExpression[] args,
@NotNull PsiType elementType, @NotNull PsiType resultType, boolean isVoid) {
@@ -105,7 +90,7 @@ abstract class TerminalOperation extends Operation {
}
}
if(args.length == 1) {
PsiType optionalElementType = getOptionalElementType(resultType);
PsiType optionalElementType = OptionalUtil.getOptionalElementType(resultType);
FunctionHelper fn = FunctionHelper.create(args[0], 2);
if(fn != null && optionalElementType != null) {
return new ReduceToOptionalTerminalOperation(fn, optionalElementType.getCanonicalText());
@@ -169,7 +154,7 @@ abstract class TerminalOperation extends Operation {
}
}
if(collector.getName().equals("reducing") && collectorArgs.length == 1) {
PsiType optionalElementType = getOptionalElementType(resultType);
PsiType optionalElementType = OptionalUtil.getOptionalElementType(resultType);
FunctionHelper fn = FunctionHelper.create(collectorArgs[0], 2);
if(fn != null && optionalElementType != null) {
return new ReduceToOptionalTerminalOperation(fn, optionalElementType.getCanonicalText());
@@ -193,30 +178,6 @@ abstract class TerminalOperation extends Operation {
return null;
}
@Contract("null -> null")
static PsiType getOptionalElementType(PsiType type) {
if(!(type instanceof PsiClassType)) return null;
PsiClass aClass = ((PsiClassType)type).resolve();
if(aClass == null) return null;
if("java.util.OptionalInt".equals(aClass.getQualifiedName())) {
return PsiType.INT;
}
if("java.util.OptionalLong".equals(aClass.getQualifiedName())) {
return PsiType.LONG;
}
if("java.util.OptionalDouble".equals(aClass.getQualifiedName())) {
return PsiType.DOUBLE;
}
if(!CommonClassNames.JAVA_UTIL_OPTIONAL.equals(aClass.getQualifiedName())) return null;
PsiType[] parameters = ((PsiClassType)type).getParameters();
if(parameters.length != 1) return null;
PsiType streamType = parameters[0];
if(streamType instanceof PsiCapturedWildcardType) {
streamType = ((PsiCapturedWildcardType)streamType).getUpperBound();
}
return streamType;
}
static class ReduceTerminalOperation extends TerminalOperation {
private PsiExpression myIdentity;
private String myType;
@@ -261,7 +222,7 @@ abstract class TerminalOperation extends Operation {
String seen = context.declare("seen", "boolean", "false");
String accumulator = context.declareResult("acc", myType, TypeConversionUtil.isPrimitive(myType) ? "0" : "null");
myUpdater.transform(context, accumulator, inVar.getName());
String optionalClass = getOptionalClass(myType);
String optionalClass = OptionalUtil.getOptionalClass(myType);
context.setFinisher("(" + seen + "?" + optionalClass + ".of(" + accumulator + "):" + optionalClass + ".empty())");
return "if(!" + seen + ") {\n" +
seen + "=true;\n" +

View File

@@ -0,0 +1,159 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInspection.util;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
/**
* @author Tagir Valeev
*/
public class OptionalUtil {
@NotNull
@Contract(pure = true)
public static String getOptionalClass(String type) {
switch (type) {
case "int":
return "java.util.OptionalInt";
case "long":
return "java.util.OptionalLong";
case "double":
return "java.util.OptionalDouble";
default:
return CommonClassNames.JAVA_UTIL_OPTIONAL;
}
}
@Contract("null -> null")
public static PsiType getOptionalElementType(PsiType type) {
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
if(aClass == null) return null;
String className = aClass.getQualifiedName();
if(className == null) return null;
switch (className) {
case "java.util.OptionalInt":
return PsiType.INT;
case "java.util.OptionalLong":
return PsiType.LONG;
case "java.util.OptionalDouble":
return PsiType.DOUBLE;
case CommonClassNames.JAVA_UTIL_OPTIONAL:
PsiType[] parameters = ((PsiClassType)type).getParameters();
if (parameters.length != 1) return null;
PsiType streamType = parameters[0];
if (streamType instanceof PsiCapturedWildcardType) {
streamType = ((PsiCapturedWildcardType)streamType).getUpperBound();
}
return streamType;
default:
return null;
}
}
static boolean isOptionalEmptyCall(PsiMethodCallExpression call) {
if ("empty".equals(call.getMethodExpression().getReferenceName())) {
PsiExpression[] args = call.getArgumentList().getExpressions();
if(args.length == 0) {
PsiMethod method = call.resolveMethod();
if (method != null && method.getParameterList().getParametersCount() == 0) {
PsiClass aClass = method.getContainingClass();
if(aClass != null && CommonClassNames.JAVA_UTIL_OPTIONAL.equals(aClass.getQualifiedName())) {
return true;
}
}
}
}
return false;
}
static boolean isOptionalOfCall(PsiMethodCallExpression call) {
if ("of".equals(call.getMethodExpression().getReferenceName())) {
PsiExpression[] args = call.getArgumentList().getExpressions();
if(args.length == 1) {
PsiMethod method = call.resolveMethod();
if (method != null && method.getParameterList().getParametersCount() == 1) {
PsiClass aClass = method.getContainingClass();
if(aClass != null && CommonClassNames.JAVA_UTIL_OPTIONAL.equals(aClass.getQualifiedName())) {
return true;
}
}
}
}
return false;
}
/**
* Generates an expression text which will unwrap an {@link java.util.Optional}.
*
* @param qualifier the text representing a qualifier of Optional type
* @param var a variable used to refer optional value inside {@code trueExpression}
* @param trueExpression an expression which should be evaluated if Optional is non-empty
* @param falseExpression an expression which should be returned if Optional is empty
* @param targetType a type of target expression
* @param useOrElseGet if true, use orElseGet if necessary
* @return an expression text which will unwrap an {@code Optional}.
*/
public static String generateOptionalUnwrap(String qualifier, PsiVariable var,
PsiExpression trueExpression, PsiExpression falseExpression,
PsiType targetType, boolean useOrElseGet) {
if (!ExpressionUtils.isIdentityMapping(var, trueExpression)) {
if(trueExpression instanceof PsiTypeCastExpression && ExpressionUtils.isNullLiteral(falseExpression)) {
PsiTypeCastExpression castExpression = (PsiTypeCastExpression)trueExpression;
PsiTypeElement castType = castExpression.getCastType();
// pull cast outside to avoid the .map() step
if(castType != null && ExpressionUtils.isIdentityMapping(var, castExpression.getOperand())) {
return "(" + castType.getText() + ")" + qualifier + ".orElse(null)";
}
}
if(ExpressionUtils.isLiteral(falseExpression, Boolean.FALSE) && PsiType.BOOLEAN.equals(trueExpression.getType())) {
return qualifier + ".filter(" + LambdaUtil.createLambda(var, trueExpression) + ").isPresent()";
}
if(trueExpression instanceof PsiConditionalExpression) {
PsiConditionalExpression condition = (PsiConditionalExpression)trueExpression;
PsiExpression elseExpression = condition.getElseExpression();
if(elseExpression != null && PsiEquivalenceUtil.areElementsEquivalent(falseExpression, elseExpression)) {
return generateOptionalUnwrap(
qualifier + ".filter(" + LambdaUtil.createLambda(var, condition.getCondition()) + ")", var,
condition.getThenExpression(), falseExpression, targetType, useOrElseGet);
}
}
if(falseExpression instanceof PsiMethodCallExpression && isOptionalEmptyCall((PsiMethodCallExpression)falseExpression)) {
// simplify "qualifier.map(x -> Optional.of(x)).orElse(Optional.empty())" to "qualifier"
if (trueExpression instanceof PsiMethodCallExpression && isOptionalOfCall((PsiMethodCallExpression)trueExpression)) {
PsiExpression arg = ((PsiMethodCallExpression)trueExpression).getArgumentList().getExpressions()[0];
if(ExpressionUtils.isIdentityMapping(var, arg)) {
return qualifier;
}
return qualifier + ".map(" + LambdaUtil.createLambda(var, arg) + ")";
}
return qualifier + ".flatMap(" + LambdaUtil.createLambda(var, trueExpression) + ")";
}
trueExpression =
targetType == null ? trueExpression : RefactoringUtil.convertInitializerToNormalExpression(trueExpression, targetType);
qualifier += ".map(" + LambdaUtil.createLambda(var, trueExpression) + ")";
}
if (useOrElseGet && !ExpressionUtils.isSimpleExpression(falseExpression)) {
return qualifier + ".orElseGet(() -> " + falseExpression.getText() + ")";
} else {
return qualifier + ".orElse(" + falseExpression.getText() + ")";
}
}
}

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElseGet()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with ifPresent()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with ifPresent()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static String test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return (String) first.orElse(null);
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -0,0 +1,12 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Optional;
public class Main {
public Optional<String> get() {
Optional<String> port = Optional.ofNullable(System.getProperty("abc");
Optional<String> result;
result = port.map(String::trim);
return result;
}
}

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static String test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return (String) first.orElse(null);
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,20 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
public static Optional<String> trimmed(String s) {
return s.isEmpty() ? Optional.empty() : Optional.of(s.trim());
}
private static Optional<String> test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return first.flatMap(o -> trimmed((String) o));
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static Optional<String> test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return first.map(o -> (String) o);
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static Optional<Object> test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return first;
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElseGet()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with ifPresent()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with ifPresent()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with ifPresent()" "false"
// "Replace Optional.isPresent() condition with functional style expression" "false"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with ifPresent()" "false"
// "Replace Optional.isPresent() condition with functional style expression" "false"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -0,0 +1,19 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static String test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
if(first.isPre<caret>sent()) {
return (String)first.get();
}
return null;
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "false"
// "Replace Optional.isPresent() condition with functional style expression" "false"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "false"
// "Replace Optional.isPresent() condition with functional style expression" "false"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with map().orElse()" "false"
// "Replace Optional.isPresent() condition with functional style expression" "false"
import java.util.*;

View File

@@ -1,4 +1,4 @@
// "Replace Optional.isPresent() condition with orElse()" "true"
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.*;

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Optional;
public class Main {
public Optional<String> get() {
Optional<String> port = Optional.ofNullable(System.getProperty("abc");
Optional<String> result;
if(po<caret>rt.isPresent()) {
result = Optional.of(port.get().trim());
} else {
result = port;
}
return result;
}
}

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static String test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return fi<caret>rst.isPresent() ? (String) first.get() : null;
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,20 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
public static Optional<String> trimmed(String s) {
return s.isEmpty() ? Optional.empty() : Optional.of(s.trim());
}
private static Optional<String> test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return first.is<caret>Present() ? trimmed((String) first.get()) : Optional.empty();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static Optional<String> test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return !fi<caret>rst.isPresent() ? Optional.empty() : Optional.of((String) first.get());
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,16 @@
// "Replace Optional.isPresent() condition with functional style expression" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class Main {
private static Optional<Object> test(List<Object> list) {
Optional<Object> first = list.stream().filter(obj -> obj instanceof String).findFirst();
return fir<caret>st.isPresent() ? Optional.of(first.get()) : Optional.empty();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,17 @@
// "Replace with findFirst()" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
public class Main {
private static String test(List<String> list) {
Optional<String> found = list.stream().filter(Objects::nonNull).findFirst();
return found.orElse(null);
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,15 @@
// "Replace with findFirst()" "true"
import java.util.List;
import java.util.Optional;
public class Main {
public Optional<String> trim(String s) {
return s.isEmpty() ? Optional.empty() : Optional.of(s.trim());
}
public Optional<String> test(List<Object> objects) {
Optional<String> result = objects.stream().filter(obj -> obj instanceof String).findFirst().flatMap(obj -> trim((String) obj));
return result;
}
}

View File

@@ -0,0 +1,23 @@
// "Replace with findFirst()" "true"
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
public class Main {
private static String test(List<String> list) {
Optional<String> found = Optional.empty();
for (String s : li<caret>st) {
if (Objects.nonNull(s)) {
found = Optional.of(s);
break;
}
}
return found.orElse(null);
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList(null, null, "aa", "bbb", "c", null, "dd")));
}
}

View File

@@ -0,0 +1,21 @@
// "Replace with findFirst()" "true"
import java.util.List;
import java.util.Optional;
public class Main {
public Optional<String> trim(String s) {
return s.isEmpty() ? Optional.empty() : Optional.of(s.trim());
}
public Optional<String> test(List<Object> objects) {
Optional<String> result = Optional.empty();
for(Object obj : obj<caret>ects) {
if(obj instanceof String) {
result = trim((String)obj);
break;
}
}
return result;
}
}

View File

@@ -792,4 +792,9 @@ public class ExpressionUtils {
}
return true;
}
@Contract("_, null -> false")
public static boolean isIdentityMapping(PsiVariable variable, PsiExpression mapperCall) {
return mapperCall instanceof PsiReferenceExpression && ((PsiReferenceExpression)mapperCall).isReferenceTo(variable);
}
}