StreamAPI migration: propose to use any/all/noneMatch if next return is not true/false (using || or &&)

This commit is contained in:
Tagir Valeev
2016-10-04 15:32:19 +07:00
parent 94bd721ae1
commit 10c8616d19
5 changed files with 54 additions and 13 deletions
@@ -23,6 +23,7 @@ import com.intellij.psi.*;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NotNull;
/**
@@ -57,13 +58,19 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
if (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE)) {
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
PsiReturnStatement nextReturnStatement = StreamApiMigrationInspection.getNextReturnStatement(foreachStatement);
if (nextReturnStatement != null && ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
if (nextReturnStatement != null) {
PsiExpression returnValue = nextReturnStatement.getReturnValue();
if(returnValue == null) return null;
String methodName = foundResult ? "anyMatch" : "noneMatch";
String streamText = generateStream(iteratedValue, tb.getLastOperation()).toString();
streamText = addTerminalOperation(streamText, methodName, foreachStatement, tb);
restoreComments(foreachStatement, body);
if (nextReturnStatement.getParent() == foreachStatement.getParent()) {
nextReturnStatement.delete();
if(!ExpressionUtils.isLiteral(returnValue, !foundResult)) {
streamText+= (foundResult ? "||" : "&&") + ParenthesesUtils.getText(returnValue, ParenthesesUtils.AND_PRECEDENCE);
}
removeLoop(foreachStatement);
return returnValue.replace(elementFactory.createExpressionFromText(streamText, nextReturnStatement));
}
return foreachStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", foreachStatement));
}
@@ -596,18 +596,19 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if (nextReturnStatement != null &&
(ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) {
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
if(ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
String methodName;
if (foundResult) {
methodName = "anyMatch";
}
else {
methodName = "noneMatch";
Operation lastOp = tb.getLastOperation();
if(lastOp instanceof FilterOp && (((FilterOp)lastOp).isNegated() ^ BoolUtils.isNegation(lastOp.getExpression()))) {
methodName = "allMatch";
}
String methodName;
if (foundResult) {
methodName = "anyMatch";
}
else {
methodName = "noneMatch";
Operation lastOp = tb.getLastOperation();
if(lastOp instanceof FilterOp && (((FilterOp)lastOp).isNegated() ^ BoolUtils.isNegation(lastOp.getExpression()))) {
methodName = "allMatch";
}
}
if(nextReturnStatement.getParent() == statement.getParent() ||
ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
registerProblem(statement, methodName, new ReplaceWithMatchFix(methodName));
return;
}
@@ -0,0 +1,9 @@
// "Replace with allMatch()" "true"
import java.util.List;
public class Main {
boolean find(List<String> data, boolean other, boolean third) {
return data.stream().map(String::trim).allMatch(trimmed -> trimmed.startsWith("xyz")) && (other || third);
}
}
@@ -0,0 +1,9 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
boolean find(List<String> data, boolean other, boolean third) {
return data.stream().map(String::trim).anyMatch(trimmed -> trimmed.startsWith("xyz")) || (other || third);
}
}
@@ -0,0 +1,15 @@
// "Replace with allMatch()" "true"
import java.util.List;
public class Main {
boolean find(List<String> data, boolean other, boolean third) {
for(String e : da<caret>ta) {
String trimmed = e.trim();
if(!trimmed.startsWith("xyz")) {
return false;
}
}
return other || third;
}
}