From afd25548a25ff79a703aff29f4a01605b5173600 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 14 Oct 2016 16:35:12 +0300 Subject: [PATCH] KT-14209 for loop to stdlib: sum is not recognized if before was check for type #KT-14209 Fixed --- .../loopToCallChain/result/SumTransformation.kt | 9 ++++++++- .../intentions/loopToCallChain/sum/smartCast.kt | 9 +++++++++ .../loopToCallChain/sum/smartCast.kt.after | 8 ++++++++ .../loopToCallChain/sum/smartCast.kt.after2 | 9 +++++++++ .../loopToCallChain/sum/smartCastNotNull.kt | 9 +++++++++ .../loopToCallChain/sum/smartCastNotNull.kt.after | 8 ++++++++ .../loopToCallChain/sum/smartCastNotNull.kt.after2 | 9 +++++++++ .../idea/intentions/IntentionTest2Generated.java | 12 ++++++++++++ .../idea/intentions/IntentionTestGenerated.java | 12 ++++++++++++ 9 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 idea/testData/intentions/loopToCallChain/sum/smartCast.kt create mode 100644 idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after2 create mode 100644 idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt create mode 100644 idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after2 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/SumTransformation.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/SumTransformation.kt index d37d796733d..191fa8d5cc0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/SumTransformation.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/SumTransformation.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.intentions.loopToCallChain.* import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.MapTransformation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.KotlinType @@ -66,7 +67,7 @@ abstract class SumTransformationBase( val value = statement.right ?: return null - val valueType = value.analyze(BodyResolveMode.PARTIAL).getType(value)?.toSupportedType() ?: return null + val valueType = value.typeWithSmartCast()?.toSupportedType() ?: return null val sumType = (variableInitialization.variable.resolveToDescriptorIfAny() as? VariableDescriptor)?.type?.toSupportedType() ?: return null val conversionFunctionName = when (sumType) { @@ -140,6 +141,12 @@ abstract class SumTransformationBase( else -> null } } + + private fun KtExpression.typeWithSmartCast(): KotlinType? { + val bindingContext = analyze(BodyResolveMode.PARTIAL) + return bindingContext[BindingContext.SMARTCAST, this]?.defaultType + ?: bindingContext.getType(this) + } } } diff --git a/idea/testData/intentions/loopToCallChain/sum/smartCast.kt b/idea/testData/intentions/loopToCallChain/sum/smartCast.kt new file mode 100644 index 00000000000..139361a4c78 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/sum/smartCast.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterIsInstance<>().sum()'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterIsInstance<>().sum()'" +fun foo(list: List){ + var result = 0 + for (l in list) + if (l is Int) + result += l +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after b/idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after new file mode 100644 index 00000000000..4050082f424 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterIsInstance<>().sum()'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterIsInstance<>().sum()'" +fun foo(list: List){ + val result = list + .filterIsInstance() + .sum() +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after2 b/idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after2 new file mode 100644 index 00000000000..d83be6f5e99 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/sum/smartCast.kt.after2 @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterIsInstance<>().sum()'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterIsInstance<>().sum()'" +fun foo(list: List){ + val result = list + .asSequence() + .filterIsInstance() + .sum() +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt b/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt new file mode 100644 index 00000000000..164a648d27e --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull().sum()'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().sum()'" +fun foo(list: List){ + var result = 0 + for (l in list) + if (l != null) + result += l +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after b/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after new file mode 100644 index 00000000000..19f30da5928 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull().sum()'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().sum()'" +fun foo(list: List){ + val result = list + .filterNotNull() + .sum() +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after2 b/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after2 new file mode 100644 index 00000000000..f413b447854 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt.after2 @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull().sum()'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().sum()'" +fun foo(list: List){ + val result = list + .asSequence() + .filterNotNull() + .sum() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java index 5828d27d074..612694abc11 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java @@ -1267,6 +1267,18 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 { doTest(fileName); } + @TestMetadata("smartCast.kt") + public void testSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/sum/smartCast.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastNotNull.kt") + public void testSmartCastNotNull() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt"); + doTest(fileName); + } + @TestMetadata("sumByDouble.kt") public void testSumByDouble() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/sum/sumByDouble.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 76cb248fe59..07c56e004e0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -9175,6 +9175,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("smartCast.kt") + public void testSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/sum/smartCast.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastNotNull.kt") + public void testSmartCastNotNull() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/sum/smartCastNotNull.kt"); + doTest(fileName); + } + @TestMetadata("sumByDouble.kt") public void testSumByDouble() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/sum/sumByDouble.kt");