mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-176720 Simplify Stream.of(xyz).anyMatch(predicate) to predicate.test(xyz)
This commit is contained in:
+96
-14
@@ -49,7 +49,7 @@ import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
import static com.siyeh.ig.callMatcher.CallMatcher.instanceCall;
|
||||
import static com.siyeh.ig.callMatcher.CallMatcher.*;
|
||||
import static com.siyeh.ig.psiutils.MethodCallUtils.getQualifierMethodCall;
|
||||
|
||||
/**
|
||||
@@ -81,8 +81,10 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "isPresent").parameterCount(0);
|
||||
private static final CallMatcher BOOLEAN_EQUALS =
|
||||
instanceCall(CommonClassNames.JAVA_LANG_BOOLEAN, "equals").parameterCount(1);
|
||||
private static final CallMatcher STREAM_OF =
|
||||
staticCall(CommonClassNames.JAVA_UTIL_STREAM_STREAM, "of").parameterTypes("T");
|
||||
|
||||
private static final CallMatcher STREAM_MATCH = CallMatcher.anyOf(STREAM_ANY_MATCH, STREAM_NONE_MATCH, STREAM_ALL_MATCH);
|
||||
private static final CallMatcher STREAM_MATCH = anyOf(STREAM_ANY_MATCH, STREAM_NONE_MATCH, STREAM_ALL_MATCH);
|
||||
|
||||
private static final CallMapper<CallChainSimplification> CALL_TO_FIX_MAPPER = new CallMapper<>(
|
||||
ReplaceCollectionStreamFix.handler(),
|
||||
@@ -92,7 +94,8 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
ReplaceWithElementIterationFix.handler(),
|
||||
ReplaceForEachMethodFix.handler(),
|
||||
RemoveBooleanIdentityFix.handler(),
|
||||
ReplaceWithPeekFix.handler()
|
||||
ReplaceWithPeekFix.handler(),
|
||||
SimpleStreamOfFix.handler()
|
||||
).registerAll(SimplifyMatchNegationFix.handlers());
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(SimplifyStreamApiCallChainsInspection.class);
|
||||
@@ -205,7 +208,7 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
}
|
||||
|
||||
static CallMatcher collectorMatcher(String name, int parameterCount) {
|
||||
return CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, name).parameterCount(parameterCount);
|
||||
return staticCall(CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS, name).parameterCount(parameterCount);
|
||||
}
|
||||
|
||||
static boolean isParentNegated(PsiMethodCallExpression methodCall) {
|
||||
@@ -279,14 +282,14 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
|
||||
private static class ReplaceCollectionStreamFix implements CallChainSimplification {
|
||||
private static final CallMatcher EMPTY_LIST =
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "emptyList").parameterCount(0);
|
||||
staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "emptyList").parameterCount(0);
|
||||
private static final CallMatcher EMPTY_SET =
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "emptySet").parameterCount(0);
|
||||
staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "emptySet").parameterCount(0);
|
||||
private static final CallMatcher SINGLETON_LIST =
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singletonList").parameterCount(1);
|
||||
staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singletonList").parameterCount(1);
|
||||
private static final CallMatcher SINGLETON =
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singleton").parameterCount(1);
|
||||
private static final CallMatcher AS_LIST = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_ARRAYS, "asList").parameterCount(1);
|
||||
staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "singleton").parameterCount(1);
|
||||
private static final CallMatcher AS_LIST = staticCall(CommonClassNames.JAVA_UTIL_ARRAYS, "asList").parameterCount(1);
|
||||
|
||||
private static final CallMapper<ReplaceCollectionStreamFix> COLLECTION_TO_STREAM_MAPPER = new CallMapper<ReplaceCollectionStreamFix>()
|
||||
.register(EMPTY_LIST,
|
||||
@@ -786,6 +789,85 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
}
|
||||
}
|
||||
|
||||
private static class SimpleStreamOfFix implements CallChainSimplification {
|
||||
private static final CallMatcher LAMBDA_TERMINAL =
|
||||
instanceCall(CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM, "anyMatch", "allMatch", "noneMatch", "forEach", "forEachOrdered")
|
||||
.parameterCount(1);
|
||||
private static final CallMatcher OPTIONAL_TERMINAL =
|
||||
anyOf(instanceCall(CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM, "findFirst", "findAny").parameterCount(0),
|
||||
instanceCall(CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM, "min", "max", "reduce").parameterCount(1));
|
||||
private ReplacementMode myMode;
|
||||
|
||||
enum ReplacementMode {
|
||||
OPTIONAL, FUNCTION, NEGATED_FUNCTION
|
||||
}
|
||||
|
||||
public SimpleStreamOfFix(ReplacementMode mode) {
|
||||
myMode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
switch (myMode) {
|
||||
case OPTIONAL:
|
||||
return "Replace with 'Optional.of'";
|
||||
default:
|
||||
return "Use Stream element explicitly";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Unnecessary single-element Stream";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement simplify(PsiMethodCallExpression streamOfCall) {
|
||||
PsiExpression streamOfArg = ArrayUtil.getFirstElement(streamOfCall.getArgumentList().getExpressions());
|
||||
if (streamOfArg == null) return null;
|
||||
PsiMethodCallExpression nextCall = ExpressionUtils.getCallForQualifier(streamOfCall);
|
||||
PsiExpression nextArg = ArrayUtil.getFirstElement(nextCall.getArgumentList().getExpressions());
|
||||
String replacement;
|
||||
if (myMode == ReplacementMode.OPTIONAL) {
|
||||
replacement = CommonClassNames.JAVA_UTIL_OPTIONAL + ".of(" + streamOfArg.getText() + ")";
|
||||
}
|
||||
else {
|
||||
if (nextArg == null) return null;
|
||||
PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(nextArg.getType());
|
||||
if (method == null) return null;
|
||||
String name = method.getName();
|
||||
replacement =
|
||||
(myMode == ReplacementMode.NEGATED_FUNCTION ? "!" : "") + nextArg.getText() + "." + name + "(" + streamOfArg.getText() + ")";
|
||||
}
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(streamOfCall.getProject());
|
||||
PsiExpression result = factory.createExpressionFromText(replacement, streamOfCall);
|
||||
return nextCall.replace(result);
|
||||
}
|
||||
|
||||
public static CallHandler<CallChainSimplification> handler() {
|
||||
return CallHandler.of(STREAM_OF, call -> {
|
||||
PsiMethodCallExpression nextCall = ExpressionUtils.getCallForQualifier(call);
|
||||
if (nextCall == null) return null;
|
||||
if (LAMBDA_TERMINAL.test(nextCall)) {
|
||||
PsiExpression arg = PsiUtil.skipParenthesizedExprDown(nextCall.getArgumentList().getExpressions()[0]);
|
||||
if (arg instanceof PsiReferenceExpression || arg instanceof PsiMethodCallExpression) {
|
||||
PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(arg.getType());
|
||||
boolean negate = "noneMatch".equals(nextCall.getMethodExpression().getReferenceName());
|
||||
if (method == null ||
|
||||
negate && PsiUtil.skipParenthesizedExprUp(nextCall.getParent()) instanceof PsiExpressionStatement) {
|
||||
return null;
|
||||
}
|
||||
return new SimpleStreamOfFix(negate ? ReplacementMode.NEGATED_FUNCTION : ReplacementMode.FUNCTION);
|
||||
}
|
||||
}
|
||||
if (OPTIONAL_TERMINAL.test(nextCall)) {
|
||||
return new SimpleStreamOfFix(ReplacementMode.OPTIONAL);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReplaceWithBoxedFix implements CallChainSimplification {
|
||||
private static final CallMatcher MAP_TO_OBJ = instanceCall(CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM, "mapToObj").parameterCount(1);
|
||||
|
||||
@@ -955,11 +1037,11 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
instanceCall(CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM, "map", "mapToLong", "mapToDouble", "mapToObj")
|
||||
.parameterCount(1);
|
||||
private static final CallMatcher INT_STREAM_RANGE =
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM, "range").parameterTypes("int", "int");
|
||||
staticCall(CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM, "range").parameterTypes("int", "int");
|
||||
private static final CallMatcher MIN_INT =
|
||||
CallMatcher.anyOf(
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_LANG_MATH, "min").parameterTypes("int", "int"),
|
||||
CallMatcher.staticCall(CommonClassNames.JAVA_LANG_INTEGER, "min").parameterTypes("int", "int"));
|
||||
anyOf(
|
||||
staticCall(CommonClassNames.JAVA_LANG_MATH, "min").parameterTypes("int", "int"),
|
||||
staticCall(CommonClassNames.JAVA_LANG_INTEGER, "min").parameterTypes("int", "int"));
|
||||
|
||||
private final String myName;
|
||||
|
||||
@@ -1274,7 +1356,7 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
}
|
||||
|
||||
private static class ReplaceStreamSupportWithCollectionStreamFix implements CallChainSimplification {
|
||||
private static final CallMatcher STREAM_SUPPORT = CallMatcher.staticCall("java.util.stream.StreamSupport", "stream")
|
||||
private static final CallMatcher STREAM_SUPPORT = staticCall("java.util.stream.StreamSupport", "stream")
|
||||
.parameterTypes("java.util.Spliterator", "boolean");
|
||||
private static final CallMatcher SPLITERATOR =
|
||||
instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "spliterator").parameterCount(0);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// "Fix all 'Simplify stream API call chains' problems in file" "true"
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class MyClass {
|
||||
void test(String someStr) {
|
||||
|
||||
Predicate<String> predicate = "foo"::equals;
|
||||
boolean b = !predicate.test(someStr);
|
||||
Stream.of(someStr).noneMatch(predicate);
|
||||
boolean x = predicate.test(someStr);
|
||||
boolean y = predicate.test(someStr);
|
||||
boolean z = Stream.of(someStr).allMatch(unresolved);
|
||||
Consumer<String> cons = System.out::println;
|
||||
cons.accept(someStr);
|
||||
|
||||
Optional<String> first = Optional.of(someStr);
|
||||
Optional<String> joined = Optional.of(someStr);
|
||||
Optional<String> max = Optional.of(someStr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// "Fix all 'Simplify stream API call chains' problems in file" "true"
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class MyClass {
|
||||
void test(String someStr) {
|
||||
|
||||
Predicate<String> predicate = "foo"::equals;
|
||||
boolean b = Stream.o<caret>f(someStr).noneMatch(predicate);
|
||||
Stream.of(someStr).noneMatch(predicate);
|
||||
boolean x = Stream.of(someStr).anyMatch(predicate);
|
||||
boolean y = Stream.of(someStr).allMatch(predicate);
|
||||
boolean z = Stream.of(someStr).allMatch(unresolved);
|
||||
Consumer<String> cons = System.out::println;
|
||||
Stream.of(someStr).forEach(cons);
|
||||
|
||||
Optional<String> first = Stream.of(someStr).findFirst();
|
||||
Optional<String> joined = Stream.of(someStr).reduce(String::concat);
|
||||
Optional<String> max = Stream.of(someStr).max(String.CASE_INSENSITIVE_ORDER);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user