mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
StreamToLoop: special handling of max().orElse(MIN_VALUE), etc.
This commit is contained in:
@@ -502,6 +502,22 @@ public class StreamToLoopInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean tryUnwrapOrElse(@NotNull Number wantedValue) {
|
||||
if (!(myStreamExpression instanceof PsiExpression)) return false;
|
||||
PsiMethodCallExpression call = ExpressionUtils.getCallForQualifier((PsiExpression)myStreamExpression);
|
||||
if (call == null ||
|
||||
call.getParent() instanceof PsiExpressionStatement ||
|
||||
!"orElse".equals(call.getMethodExpression().getReferenceName())) {
|
||||
return false;
|
||||
}
|
||||
PsiExpression[] args = call.getArgumentList().getExpressions();
|
||||
if (args.length == 1 && wantedValue.equals(ExpressionUtils.computeConstantExpression(args[0]))) {
|
||||
myStreamExpression = call;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isCompatibleType(@NotNull PsiVariable var, @NotNull PsiType type, @Nullable String mostAbstractAllowedType) {
|
||||
if (EquivalenceChecker.getCanonicalPsiEquivalence().typesAreEquivalent(var.getType(), type)) return true;
|
||||
if (mostAbstractAllowedType == null) return false;
|
||||
|
||||
@@ -798,11 +798,13 @@ abstract class TerminalOperation extends Operation {
|
||||
private final PsiType myType;
|
||||
private final String myTemplate;
|
||||
private @Nullable final FunctionHelper myComparator;
|
||||
private final boolean myMax;
|
||||
|
||||
public MinMaxTerminalOperation(PsiType type, String template, @Nullable FunctionHelper comparator) {
|
||||
public MinMaxTerminalOperation(PsiType type, String template, @Nullable FunctionHelper comparator, boolean max) {
|
||||
myType = type;
|
||||
myTemplate = template;
|
||||
myComparator = comparator;
|
||||
myMax = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -812,8 +814,33 @@ abstract class TerminalOperation extends Operation {
|
||||
}
|
||||
}
|
||||
|
||||
Number getExtremeValue() {
|
||||
if (PsiType.INT.equals(myType)) {
|
||||
return myMax ? Integer.MIN_VALUE : Integer.MAX_VALUE;
|
||||
}
|
||||
if (PsiType.LONG.equals(myType)) {
|
||||
return myMax ? Long.MIN_VALUE : Long.MAX_VALUE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getExtremeValueExpression() {
|
||||
if (PsiType.INT.equals(myType)) {
|
||||
return CommonClassNames.JAVA_LANG_INTEGER + (myMax ? ".MIN_VALUE" : ".MAX_VALUE");
|
||||
}
|
||||
if (PsiType.LONG.equals(myType)) {
|
||||
return CommonClassNames.JAVA_LANG_LONG + (myMax ? ".MIN_VALUE" : ".MAX_VALUE");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
String generate(StreamVariable inVar, StreamToLoopReplacementContext context) {
|
||||
if (getExtremeValue() != null && context.tryUnwrapOrElse(getExtremeValue())) {
|
||||
String best = context.declareResult("best", myType, getExtremeValueExpression(), ResultKind.NON_FINAL);
|
||||
String comparePredicate = myTemplate.replace("{best}", best).replace("{item}", inVar.getName());
|
||||
return "if(" + comparePredicate + ")\n" + best + "=" + inVar + ";\n";
|
||||
}
|
||||
String seen = context.declare("seen", "boolean", "false");
|
||||
String best = context.declareResult("best", myType, myType instanceof PsiPrimitiveType ? "0" : "null", ResultKind.UNKNOWN);
|
||||
context.setFinisher(new ConditionalExpression.Optional(myType, seen, best));
|
||||
@@ -837,16 +864,16 @@ abstract class TerminalOperation extends Operation {
|
||||
String sign = max ? ">" : "<";
|
||||
if(comparator == null) {
|
||||
if (PsiType.INT.equals(elementType) || PsiType.LONG.equals(elementType)) {
|
||||
return new MinMaxTerminalOperation(elementType, "{item}" + sign + "{best}", null);
|
||||
return new MinMaxTerminalOperation(elementType, "{item}" + sign + "{best}", null, max);
|
||||
}
|
||||
if (PsiType.DOUBLE.equals(elementType)) {
|
||||
return new MinMaxTerminalOperation(elementType, "java.lang.Double.compare({item},{best})" + sign + "0", null);
|
||||
return new MinMaxTerminalOperation(elementType, "java.lang.Double.compare({item},{best})" + sign + "0", null, max);
|
||||
}
|
||||
}
|
||||
else {
|
||||
FunctionHelper fn = FunctionHelper.create(comparator, 2);
|
||||
if(fn != null) {
|
||||
return new MinMaxTerminalOperation(elementType, "{comparator}"+sign+"0", fn);
|
||||
return new MinMaxTerminalOperation(elementType, "{comparator}" + sign + "0", fn, max);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -104,6 +104,26 @@ public class Main {
|
||||
return seen ? best : supplier.getAsInt();
|
||||
}
|
||||
|
||||
public static int testMinMaxValue(List<String> strings) {
|
||||
int best = Integer.MAX_VALUE;
|
||||
for (String string : strings) {
|
||||
int length = string.length();
|
||||
if (length < best)
|
||||
best = length;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
public static long testMaxMinValue(List<String> strings) {
|
||||
long max = Long.MIN_VALUE;
|
||||
for (String string : strings) {
|
||||
long length = string.length();
|
||||
if (length > max)
|
||||
max = length;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(testMaxComparator(Arrays.asList()));
|
||||
System.out.println(testMaxComparator(Arrays.asList("a", "bbb", "cc", "d", "eee")));
|
||||
|
||||
@@ -36,6 +36,15 @@ public class Main {
|
||||
return strings.stream().mapToInt(String::length).min().orElseGet(supplier);
|
||||
}
|
||||
|
||||
public static int testMinMaxValue(List<String> strings) {
|
||||
return strings.stream().mapToInt(String::length).min().orElse(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public static long testMaxMinValue(List<String> strings) {
|
||||
long max = strings.stream().mapToLong(String::length).max().orElse(Long.MIN_VALUE);
|
||||
return max;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(testMaxComparator(Arrays.asList()));
|
||||
System.out.println(testMaxComparator(Arrays.asList("a", "bbb", "cc", "d", "eee")));
|
||||
|
||||
Reference in New Issue
Block a user