mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 02:09:59 +07:00
IDEA-163627 Simplify optional.isPresent() inspection could better handle some specific cases
IDEA-163462 Simplify Optional.isPresent() ? Optional.get() : ...
This commit is contained in:
@@ -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) + ");";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()" : "";
|
||||
}
|
||||
|
||||
@@ -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" +
|
||||
|
||||
@@ -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() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElseGet()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with ifPresent()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with ifPresent()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElseGet()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with ifPresent()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with ifPresent()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with ifPresent()" "false"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "false"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with ifPresent()" "false"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "false"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "false"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "false"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "false"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "false"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with map().orElse()" "false"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "false"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Replace Optional.isPresent() condition with orElse()" "true"
|
||||
// "Replace Optional.isPresent() condition with functional style expression" "true"
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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")));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user