diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt index 8f09bad959a..62e6621aee0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSingleLineLetIntention.kt @@ -90,21 +90,35 @@ class ReplaceSingleLineLetIntention : SelfTargetingOffsetIndependentIntention if (left.text != parameterName) return false - is KtDotQualifiedExpression -> if (!left.isApplicable(parameterName)) return false - else -> return false + if (isTopLevel) { + when (left) { + is KtNameReferenceExpression -> if (left.text != parameterName) return false + is KtDotQualifiedExpression -> if (!left.isApplicable(parameterName)) return false + else -> return false + } + } + else { + if (!left.isApplicable(parameterName)) return false } val right = right ?: return false - return when (right) { - is KtNameReferenceExpression -> right.text != parameterName - is KtDotQualifiedExpression -> !right.hasLambdaExpression() && !right.nameUsed(parameterName) - is KtConstantExpression -> true - else -> false - } + return right.isApplicable(parameterName) + } + + private fun KtExpression.isApplicable(parameterName: String): Boolean = when (this) { + is KtNameReferenceExpression -> text != parameterName + is KtDotQualifiedExpression -> !hasLambdaExpression() && !nameUsed(parameterName) + is KtBinaryExpression -> isApplicable(parameterName, isTopLevel = false) + is KtCallExpression -> isApplicable(parameterName) + is KtConstantExpression -> true + else -> false + } + + private fun KtCallExpression.isApplicable(parameterName: String): Boolean = valueArguments.all { + val argumentExpression = it.getArgumentExpression() ?: return@all false + argumentExpression.isApplicable(parameterName) } private fun KtDotQualifiedExpression.isApplicable(parameterName: String) = diff --git a/idea/testData/intentions/replaceSingleLineLetIntention/in.kt b/idea/testData/intentions/replaceSingleLineLetIntention/in.kt new file mode 100644 index 00000000000..2ee7210e378 --- /dev/null +++ b/idea/testData/intentions/replaceSingleLineLetIntention/in.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: true + +fun foo(list: List) { + list.filter { it.let { it in 1000..3000 } } +} \ No newline at end of file diff --git a/idea/testData/intentions/replaceSingleLineLetIntention/in.kt.after b/idea/testData/intentions/replaceSingleLineLetIntention/in.kt.after new file mode 100644 index 00000000000..5ca4a89cc73 --- /dev/null +++ b/idea/testData/intentions/replaceSingleLineLetIntention/in.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: true + +fun foo(list: List) { + list.filter { it in 1000..3000 } +} \ No newline at end of file diff --git a/idea/testData/intentions/replaceSingleLineLetIntention/inWithMultipleParam.kt b/idea/testData/intentions/replaceSingleLineLetIntention/inWithMultipleParam.kt new file mode 100644 index 00000000000..dc73ad41f37 --- /dev/null +++ b/idea/testData/intentions/replaceSingleLineLetIntention/inWithMultipleParam.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false + +fun foo(list: List) { + list.filter { it.let { value -> value in value..3000 } } +} \ No newline at end of file diff --git a/idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt b/idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt new file mode 100644 index 00000000000..7d01eb46ea4 --- /dev/null +++ b/idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: true + +fun foo(list: List) { + list.filter { it.let { it in IntRange(1, 10) } } +} \ No newline at end of file diff --git a/idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt.after b/idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt.after new file mode 100644 index 00000000000..515a38d852b --- /dev/null +++ b/idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: true + +fun foo(list: List) { + list.filter { it in IntRange(1, 10) } +} \ No newline at end of file diff --git a/idea/testData/intentions/replaceSingleLineLetIntention/inWithRangeMultipleParam.kt b/idea/testData/intentions/replaceSingleLineLetIntention/inWithRangeMultipleParam.kt new file mode 100644 index 00000000000..7aafc23970a --- /dev/null +++ b/idea/testData/intentions/replaceSingleLineLetIntention/inWithRangeMultipleParam.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false + +fun foo(list: List) { + list.filter { it.let { it in IntRange(it - 1, 10) } } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 425999ebfe2..b118cf98e6f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -14174,6 +14174,30 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("in.kt") + public void testIn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceSingleLineLetIntention/in.kt"); + doTest(fileName); + } + + @TestMetadata("inWithMultipleParam.kt") + public void testInWithMultipleParam() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceSingleLineLetIntention/inWithMultipleParam.kt"); + doTest(fileName); + } + + @TestMetadata("inWithRange.kt") + public void testInWithRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceSingleLineLetIntention/inWithRange.kt"); + doTest(fileName); + } + + @TestMetadata("inWithRangeMultipleParam.kt") + public void testInWithRangeMultipleParam() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceSingleLineLetIntention/inWithRangeMultipleParam.kt"); + doTest(fileName); + } + @TestMetadata("lambdaWithBinaryExpression.kt") public void testLambdaWithBinaryExpression() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceSingleLineLetIntention/lambdaWithBinaryExpression.kt");