IDEA-161002 anyMatch/noneMatch disabled for non-final vars; allMatch is supported

This commit is contained in:
Tagir Valeev
2016-09-12 14:28:24 +07:00
parent e59b6864f0
commit 6da7838df4
6 changed files with 103 additions and 10 deletions
@@ -135,15 +135,14 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
.findExitPointsAndStatements(controlFlow, tb.getStartOffset(controlFlow), tb.getEndOffset(controlFlow),
new IntArrayList(), PsiContinueStatement.class,
PsiBreakStatement.class, PsiReturnStatement.class, PsiThrowStatement.class);
int startOffset = controlFlow.getStartOffset(body);
int endOffset = controlFlow.getEndOffset(body);
final List<PsiVariable> nonFinalVariables = StreamEx
.of(ControlFlowUtil.getUsedVariables(controlFlow, startOffset, endOffset))
.remove(variable -> HighlightControlFlowUtil.isEffectivelyFinal(variable, body, null))
.toList();
if (exitPoints.isEmpty()) {
int startOffset = controlFlow.getStartOffset(body);
int endOffset = controlFlow.getEndOffset(body);
final List<PsiVariable> nonFinalVariables = StreamEx
.of(ControlFlowUtil.getUsedVariables(controlFlow, startOffset, endOffset))
.remove(variable -> HighlightControlFlowUtil.isEffectivelyFinal(variable, body, null))
.toList();
if(getIncrementedVariable(tb, operations, nonFinalVariables) != null) {
registerProblem(holder, statement, "count", new ReplaceWithCountFix());
}
@@ -181,7 +180,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
registerProblem(holder, statement, "forEach", fixes.toArray(new LocalQuickFix[fixes.size()]));
}
} else {
if(tb.getSingleStatement() instanceof PsiReturnStatement) {
if(nonFinalVariables.isEmpty() && tb.getSingleStatement() instanceof PsiReturnStatement) {
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
PsiExpression value = returnStatement.getReturnValue();
if(isLiteral(value, Boolean.TRUE) || isLiteral(value, Boolean.FALSE)) {
@@ -190,7 +189,19 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if(nextStatement instanceof PsiReturnStatement) {
PsiReturnStatement nextReturnStatement = (PsiReturnStatement)nextStatement;
if(isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
String methodName = foundResult ? "anyMatch" : "noneMatch";
String methodName;
if (foundResult) {
methodName = "anyMatch";
}
else {
methodName = "noneMatch";
if(!operations.isEmpty()) {
Operation lastOp = operations.get(operations.size() - 1);
if(lastOp instanceof FilterOp && BoolUtils.isNegation(lastOp.getExpression())) {
methodName = "allMatch";
}
}
}
registerProblem(holder, statement, methodName, new ReplaceWithMatchFix(methodName));
}
}
@@ -889,6 +900,25 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if(!(stream instanceof PsiMethodCallExpression)) return;
PsiElement nameElement = ((PsiMethodCallExpression)stream).getMethodExpression().getReferenceNameElement();
if(nameElement != null && nameElement.getText().equals("filter")) {
if(!foundResult) {
PsiExpression[] expressions = ((PsiMethodCallExpression)stream).getArgumentList().getExpressions();
if(expressions.length == 1 && expressions[0] instanceof PsiLambdaExpression) {
PsiLambdaExpression lambda = (PsiLambdaExpression)expressions[0];
PsiElement lambdaBody = lambda.getBody();
if(lambdaBody instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)lambdaBody)) {
PsiExpression negated = BoolUtils.getNegated((PsiExpression)lambdaBody);
LOG.assertTrue(negated != null);
String methodReferenceText = LambdaCanBeMethodReferenceInspection
.convertToMethodReference(negated, lambda.getParameterList().getParameters(), lambda.getFunctionalInterfaceType(), lambda);
if(methodReferenceText != null) {
lambda.replace(elementFactory.createExpressionFromText(methodReferenceText, lambda));
} else {
lambdaBody.replace(negated);
}
methodName = "allMatch";
}
}
}
nameElement.replace(elementFactory.createIdentifier(methodName));
streamText = stream.getText();
} else {
@@ -0,0 +1,9 @@
// "Replace with allMatch()" "true"
import java.util.Arrays;
public class Main {
boolean find(String[][] data) {
return Arrays.stream(data).flatMap(Arrays::stream).allMatch(str -> str.startsWith("xyz"));
}
}
@@ -0,0 +1,9 @@
// "Replace with allMatch()" "true"
import java.util.Arrays;
public class Main {
boolean allEmpty(String[][] data) {
return Arrays.stream(data).flatMap(Arrays::stream).allMatch(String::isEmpty);
}
}
@@ -0,0 +1,14 @@
// "Replace with allMatch()" "true"
public class Main {
boolean find(String[][] data) {
for(String[] arr : da<caret>ta) {
for(String str : arr) {
if(!str.startsWith("xyz")) {
return false;
}
}
}
return true;
}
}
@@ -0,0 +1,14 @@
// "Replace with allMatch()" "true"
public class Main {
boolean allEmpty(String[][] data) {
for(String[] arr : da<caret>ta) {
for(String str : arr) {
if(!str.isEmpty()) {
return false;
}
}
}
return true;
}
}
@@ -0,0 +1,17 @@
// "Replace with anyMatch()" "false"
import java.util.List;
public class Main {
boolean find(List<String> data, String prefix) {
if(prefix == null)
prefix = "xyz";
for(String e : da<caret>ta) {
String trimmed = e.trim();
if(trimmed.startsWith(prefix)) {
return true;
}
}
return false;
}
}