mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-161002 More anyMatch cases supported with if statement
This commit is contained in:
+80
-51
@@ -184,34 +184,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
} else {
|
||||
if(nonFinalVariables.isEmpty() && tb.getSingleStatement() instanceof PsiReturnStatement) {
|
||||
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
|
||||
PsiExpression value = returnStatement.getReturnValue();
|
||||
PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement);
|
||||
if(nextReturnStatement != null) {
|
||||
if(isLiteral(value, Boolean.TRUE) || isLiteral(value, Boolean.FALSE)) {
|
||||
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
|
||||
if(isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
|
||||
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, isOnTheFly, statement, methodName, new ReplaceWithMatchFix(methodName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(ExpressionUtils.isSimpleExpression(nextReturnStatement.getReturnValue())) {
|
||||
registerProblem(holder, isOnTheFly, statement, "findFirst", new ReplaceWithFindFirstFix());
|
||||
}
|
||||
}
|
||||
handleSingleReturn(statement, tb, operations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,6 +195,40 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
}
|
||||
|
||||
void handleSingleReturn(PsiForeachStatement statement,
|
||||
TerminalBlock tb,
|
||||
List<Operation> operations) {
|
||||
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
|
||||
PsiExpression value = returnStatement.getReturnValue();
|
||||
PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement);
|
||||
if(nextReturnStatement != null && (isLiteral(value, Boolean.TRUE) || isLiteral(value, Boolean.FALSE))) {
|
||||
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
|
||||
if(isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
|
||||
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, isOnTheFly, statement, methodName, new ReplaceWithMatchFix(methodName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!isVariableReferenced(tb.getVariable(), value)) {
|
||||
registerProblem(holder, isOnTheFly, statement, "anyMatch", new ReplaceWithMatchFix("anyMatch"));
|
||||
}
|
||||
if(nextReturnStatement != null && ExpressionUtils.isSimpleExpression(nextReturnStatement.getReturnValue())) {
|
||||
registerProblem(holder, isOnTheFly, statement, "findFirst", new ReplaceWithFindFirstFix());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRawSubstitution(PsiType iteratedValueType, PsiClass collectionClass) {
|
||||
return iteratedValueType instanceof PsiClassType && PsiUtil
|
||||
.isRawSubstitutor(collectionClass, TypeConversionUtil.getSuperClassSubstitutor(collectionClass, (PsiClassType)iteratedValueType));
|
||||
@@ -229,6 +236,12 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
};
|
||||
}
|
||||
|
||||
@Contract("_, null -> false")
|
||||
private static boolean isVariableReferenced(PsiVariable variable, PsiExpression value) {
|
||||
return !PsiTreeUtil
|
||||
.processElements(value, e -> !(e instanceof PsiReferenceExpression) || ((PsiReferenceExpression)e).resolve() != variable);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static PsiReturnStatement getNextReturnStatement(PsiStatement statement) {
|
||||
PsiElement nextStatement = PsiTreeUtil.skipSiblingsForward(statement, PsiWhiteSpace.class, PsiComment.class);
|
||||
@@ -859,24 +872,47 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
@NotNull List<String> intermediateOps) {
|
||||
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
|
||||
PsiExpression value = returnStatement.getReturnValue();
|
||||
if(!isLiteral(value, Boolean.TRUE) && !isLiteral(value, Boolean.FALSE)) return;
|
||||
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
|
||||
PsiReturnStatement nextReturnStatement = getNextReturnStatement(foreachStatement);
|
||||
if (nextReturnStatement == null || !isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) return;
|
||||
String methodName = foundResult ? "anyMatch" : "noneMatch";
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
String streamText = generateStream(iteratedValue, intermediateOps).toString();
|
||||
PsiExpression stream =
|
||||
elementFactory.createExpressionFromText(streamText, foreachStatement);
|
||||
if(!(stream instanceof PsiMethodCallExpression)) return;
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
if (isLiteral(value, Boolean.TRUE) || isLiteral(value, Boolean.FALSE)) {
|
||||
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
|
||||
PsiReturnStatement nextReturnStatement = getNextReturnStatement(foreachStatement);
|
||||
if (nextReturnStatement != null && isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
|
||||
String methodName = foundResult ? "anyMatch" : "noneMatch";
|
||||
String streamText = generateStream(iteratedValue, intermediateOps).toString();
|
||||
streamText = addTerminalOperation(streamText, methodName, foreachStatement, tb);
|
||||
boolean siblings = nextReturnStatement.getParent() == foreachStatement.getParent();
|
||||
PsiElement result =
|
||||
foreachStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", foreachStatement));
|
||||
if (siblings) {
|
||||
nextReturnStatement.delete();
|
||||
}
|
||||
simplifyAndFormat(project, result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!isVariableReferenced(tb.getVariable(), value)) {
|
||||
String streamText = generateStream(iteratedValue, intermediateOps).toString();
|
||||
streamText = addTerminalOperation(streamText, "anyMatch", foreachStatement, tb);
|
||||
String replacement = "if(" + streamText + "){" + returnStatement.getText() + "}";
|
||||
PsiElement result = foreachStatement.replace(elementFactory.createStatementFromText(replacement, foreachStatement));
|
||||
simplifyAndFormat(project, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static String addTerminalOperation(String origStream, String methodName, @NotNull PsiElement contextElement,
|
||||
@NotNull TerminalBlock tb) {
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(contextElement.getProject());
|
||||
PsiExpression stream = elementFactory.createExpressionFromText(origStream, contextElement);
|
||||
LOG.assertTrue(stream instanceof PsiMethodCallExpression);
|
||||
PsiElement nameElement = ((PsiMethodCallExpression)stream).getMethodExpression().getReferenceNameElement();
|
||||
if(nameElement != null && nameElement.getText().equals("filter")) {
|
||||
if(!foundResult) {
|
||||
if (nameElement != null && nameElement.getText().equals("filter")) {
|
||||
if (methodName.equals("noneMatch")) {
|
||||
// Try to reduce noneMatch(x -> !(condition)) to allMatch(x -> condition)
|
||||
PsiExpression[] expressions = ((PsiMethodCallExpression)stream).getArgumentList().getExpressions();
|
||||
if(expressions.length == 1 && expressions[0] instanceof PsiLambdaExpression) {
|
||||
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)) {
|
||||
if (lambdaBody instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)lambdaBody)) {
|
||||
PsiExpression negated = BoolUtils.getNegated((PsiExpression)lambdaBody);
|
||||
LOG.assertTrue(negated != null, lambdaBody.getText());
|
||||
lambdaBody.replace(negated);
|
||||
@@ -885,16 +921,9 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
}
|
||||
nameElement.replace(elementFactory.createIdentifier(methodName));
|
||||
streamText = stream.getText();
|
||||
} else {
|
||||
streamText += "."+methodName+"("+tb.getVariable().getName()+" -> true)";
|
||||
return stream.getText();
|
||||
}
|
||||
boolean siblings = nextReturnStatement.getParent() == foreachStatement.getParent();
|
||||
PsiElement result = foreachStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", foreachStatement));
|
||||
if(siblings) {
|
||||
nextReturnStatement.delete();
|
||||
}
|
||||
simplifyAndFormat(project, result);
|
||||
return origStream + "." + methodName + "(" + tb.getVariable().getName() + " -> true)";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Main {
|
||||
String contains(String[][] haystack, String needle) {
|
||||
if(haystack != null) {
|
||||
if (Arrays.stream(haystack).filter(Objects::nonNull).flatMap(Arrays::stream).anyMatch(needle::equals)) {
|
||||
return "yes" + needle.length();
|
||||
}
|
||||
System.out.println("oops");
|
||||
}
|
||||
return "no";
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Main {
|
||||
boolean contains(String[][] haystack, String needle) {
|
||||
if(haystack != null) {
|
||||
if (Arrays.stream(haystack).filter(Objects::nonNull).flatMap(Arrays::stream).anyMatch(needle::equals)) {
|
||||
return true;
|
||||
}
|
||||
System.out.println("Oops");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Main {
|
||||
void contains(String[][] haystack, String needle) {
|
||||
if(haystack != null) {
|
||||
if (Arrays.stream(haystack).filter(Objects::nonNull).flatMap(Arrays::stream).anyMatch(needle::equals)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
public class Main {
|
||||
String contains(String[][] haystack, String needle) {
|
||||
if(haystack != null) {
|
||||
for (String[] row : haysta<caret>ck) {
|
||||
if (row == null) continue;
|
||||
for (String str : row) {
|
||||
if (needle.equals(str))
|
||||
return "yes"+needle.length();
|
||||
}
|
||||
}
|
||||
System.out.println("oops");
|
||||
}
|
||||
return "no";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Replace with anyMatch()" "false"
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
public class Main {
|
||||
boolean contains(String[][] haystack, String needle) {
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Replace with anyMatch()" "false"
|
||||
|
||||
public class Main {
|
||||
String contains(String[][] haystack, String needle) {
|
||||
if(haystack != null) {
|
||||
for (String[] row : haysta<caret>ck) {
|
||||
if (row == null) continue;
|
||||
for (String str : row) {
|
||||
if (needle.equals(str))
|
||||
return "yes"+str;
|
||||
}
|
||||
}
|
||||
System.out.println("oops");
|
||||
}
|
||||
return "no";
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with anyMatch()" "true"
|
||||
|
||||
public class Main {
|
||||
void contains(String[][] haystack, String needle) {
|
||||
if(haystack != null) {
|
||||
for (String[] row : haysta<caret>ck) {
|
||||
if (row == null) continue;
|
||||
for (String str : row) {
|
||||
if (needle.equals(str))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user