From b8c9f1a1e0bcff4032223001af89fb3a35f4ce45 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 17 Feb 2017 12:47:39 +0700 Subject: [PATCH] IDEA-168203 Follow-up: do not suggest if initializer may throw checked exception or accesses non-final variable --- .../streamMigration/CollectMigration.java | 14 +++++++++++--- .../afterCollectCustomConstructor.java | 7 +++++++ .../beforeCollectCustomConstructor.java | 11 +++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java index e50668d03df5..2f79b549231a 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/CollectMigration.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection.streamMigration; +import com.intellij.codeInspection.util.LambdaGenerationUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -174,6 +175,13 @@ class CollectMigration extends BaseStreamApiMigration { } } + @Contract("null -> false") + static boolean hasLambdaCompatibleEmptyInitializer(@Nullable PsiLocalVariable target) { + return target != null && + ConstructionUtils.isEmptyCollectionInitializer(target.getInitializer()) && + LambdaGenerationUtil.canBeUncheckedLambda(target.getInitializer()); + } + static boolean isUsedOutsideOf(PsiVariable collectionVariable, Collection allowedParents) { return !ReferencesSearch.search(collectionVariable) .forEach(ref -> { @@ -240,7 +248,7 @@ class CollectMigration extends BaseStreamApiMigration { PsiMethodCallExpression addCall, PsiLoopStatement loop, InitializerUsageStatus status) { - super(target, loop, ConstructionUtils.isEmptyCollectionInitializer(target.getInitializer()) ? status : ControlFlowUtils.InitializerUsageStatus.UNKNOWN); + super(target, loop, hasLambdaCompatibleEmptyInitializer(target) ? status : ControlFlowUtils.InitializerUsageStatus.UNKNOWN); myTargetType = target.getType(); myInitializer = target.getInitializer(); myElement = element; @@ -445,7 +453,7 @@ class CollectMigration extends BaseStreamApiMigration { PsiExpression body = LambdaUtil.extractSingleExpressionFromBody(lambda.getBody()); if (ConstructionUtils.isEmptyCollectionInitializer(body)) { PsiLocalVariable variable = extractQualifierVariable(tb, qualifierCall); - if (variable != null && ConstructionUtils.isEmptyCollectionInitializer(variable.getInitializer())) { + if (hasLambdaCompatibleEmptyInitializer(variable)) { PsiType mapType = variable.getType(); PsiType valueType = PsiUtil.substituteTypeParameter(mapType, CommonClassNames.JAVA_UTIL_MAP, 1, false); if (valueType == null) return null; @@ -519,7 +527,7 @@ class CollectMigration extends BaseStreamApiMigration { return null; } PsiLocalVariable variable = extractQualifierVariable(tb, call); - if (variable == null || !ConstructionUtils.isEmptyCollectionInitializer(variable.getInitializer())) return null; + if (!hasLambdaCompatibleEmptyInitializer(variable)) return null; InitializerUsageStatus status = getInitializerUsageStatus(variable, tb.getMainLoop()); return new ToMapTerminal(call, tb.getVariable(), variable, tb.getMainLoop(), status); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectCustomConstructor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectCustomConstructor.java index ac0b5bcf3f96..52e7fcaef38d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectCustomConstructor.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectCustomConstructor.java @@ -16,6 +16,13 @@ public class Test { ArrayList result3 = new ArrayList<>(input); input.stream().filter(s -> !s.isEmpty()).forEach(result3::add); System.out.println(result3); + + // Non-final var used in initializer + int size = 5; + if(size < input.size()) size = input.size(); + List result4 = new ArrayList<>(size); + input.stream().filter(s -> !s.isEmpty()).forEach(result4::add); + System.out.println(result4); } void testSet(List input) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectCustomConstructor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectCustomConstructor.java index 503747e9d353..e1e4c3cd7de0 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectCustomConstructor.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectCustomConstructor.java @@ -29,6 +29,17 @@ public class Test { } } System.out.println(result3); + + // Non-final var used in initializer + int size = 5; + if(size < input.size()) size = input.size(); + List result4 = new ArrayList<>(size); + for (String s : input) { + if(!s.isEmpty()) { + result4.add(s); + } + } + System.out.println(result4); } void testSet(List input) {