CollectMigration: support toUnmodifiableMap

Fixes IDEA-187213 Stream API migration: support Java 10 toUnmodifiableList/Set/Map collections
This commit is contained in:
Tagir Valeev
2018-04-17 15:06:35 +07:00
parent 000f124c33
commit a1a4663b73
3 changed files with 57 additions and 6 deletions
@@ -586,6 +586,10 @@ class CollectMigration extends BaseStreamApiMigration {
@Override
public String generateTerminal(CommentTracker ct, boolean strictMode) {
return generateTerminal(ct, "toMap");
}
public String generateTerminal(CommentTracker ct, final String collectorName) {
PsiExpression[] args = myMapUpdateCall.getArgumentList().getExpressions();
LOG.assertTrue(args.length >= 2);
String methodName = myMapUpdateCall.getMethodExpression().getReferenceName();
@@ -609,14 +613,14 @@ class CollectMigration extends BaseStreamApiMigration {
default:
return null;
}
StringBuilder collector = new StringBuilder(".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + ".toMap(");
StringBuilder collector = new StringBuilder(".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + "." + collectorName + "(");
collector.append(ct.lambdaText(myElementVariable, args[0])).append(',')
.append(ct.lambdaText(myElementVariable, args[1])).append(',')
.append(merger);
PsiLocalVariable variable = Objects.requireNonNull(getTargetVariable());
PsiExpression initializer = variable.getInitializer();
LOG.assertTrue(initializer != null);
if (!isHashMap(variable)) {
if ("toMap".equals(collectorName) && !isHashMap(variable)) {
collector.append(",()->").append(ct.text(initializer));
}
collector.append("))");
@@ -885,12 +889,13 @@ class CollectMigration extends BaseStreamApiMigration {
private static final Map<String, String> TYPE_TO_UNMODIFIABLE_WRAPPER = EntryStream.of(
CommonClassNames.JAVA_UTIL_ARRAY_LIST, "toUnmodifiableList",
"java.util.LinkedList", "toUnmodifiableList",
CommonClassNames.JAVA_UTIL_HASH_SET, "toUnmodifiableSet"
CommonClassNames.JAVA_UTIL_HASH_SET, "toUnmodifiableSet",
CommonClassNames.JAVA_UTIL_HASH_MAP, "toUnmodifiableMap"
).toMap();
private static final CallMatcher UNMODIFIABLE_WRAPPER =
CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_COLLECTIONS, "unmodifiableList", "unmodifiableSet", "unmodifiableCollection")
.parameterCount(1);
private static final CallMatcher UNMODIFIABLE_WRAPPER = CallMatcher.staticCall(
CommonClassNames.JAVA_UTIL_COLLECTIONS,
"unmodifiableList", "unmodifiableSet", "unmodifiableCollection", "unmodifiableMap").parameterCount(1);
private static final CallMatcher STREAM_COLLECT =
CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_STREAM_STREAM, "collect").parameterTypes("java.util.stream.Collector");
@@ -911,6 +916,9 @@ class CollectMigration extends BaseStreamApiMigration {
@Override
public String generateTerminal(CommentTracker ct, boolean strictMode) {
if (myUpstream instanceof ToMapTerminal) {
return ((ToMapTerminal)myUpstream).generateTerminal(ct, myUnmodifiableCollector);
}
return ".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + "." + myUnmodifiableCollector + "())";
}
@@ -20,4 +20,17 @@ class Test {
// toUnmodifiableSet will not preserve order; not suggested here
return Collections.unmodifiableSet(result);
}
Map<String, Integer> map(List<String> input) {
return input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toUnmodifiableMap(s -> s, s -> s.length(), (a, b) -> b));
}
Map<String, Integer> map1(List<String> input) {
Map<String, Integer> result = input.stream().filter(s -> !s.isEmpty()).collect(Collectors.toMap(s -> s, String::length, (a, b) -> b, TreeMap::new));
return Collections.unmodifiableMap(result);
}
Map<String, Integer> map2(int[] input) {
return Arrays.stream(input).filter(s -> s > 0).boxed().collect(Collectors.toUnmodifiableMap(s -> String.valueOf(s), s -> s, (a, b) -> b));
}
}
@@ -47,4 +47,34 @@ class Test {
// toUnmodifiableSet will not preserve order; not suggested here
return Collections.unmodifiableSet(result);
}
Map<String, Integer> map(List<String> input) {
Map<String, Integer> result = new HashMap<>(100);
for (String s : input) {
if (!s.isEmpty()) {
result.put(s, s.length());
}
}
return Collections.unmodifiableMap(result);
}
Map<String, Integer> map1(List<String> input) {
Map<String, Integer> result = new TreeMap<>();
for (String s : input) {
if (!s.isEmpty()) {
result.put(s, s.length());
}
}
return Collections.unmodifiableMap(result);
}
Map<String, Integer> map2(int[] input) {
Map<String, Integer> result = new HashMap<>();
for (int s : input) {
if (s > 0) {
result.put(String.valueOf(s), s);
}
}
return Collections.unmodifiableMap(result);
}
}