From 3f266647f01f5de4762497f155d6522775007bcc Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 15 Apr 2016 17:35:08 +0300 Subject: [PATCH] Does not replace explicit lambda parameter with 'it' if conflicting nested literal available #KT-11849 Fixed --- ...licitFunctionLiteralParamWithItIntention.kt | 10 ++++++++++ .../applicable_nestedLiteralsNoUseInside.kt | 10 ++++++++++ ...plicable_nestedLiteralsNoUseInside.kt.after | 10 ++++++++++ .../notApplicable_nestedLiterals.kt | 12 ++++++++++++ .../notApplicable_nestedLiteralsNoIt.kt | 10 ++++++++++ .../intentions/IntentionTestGenerated.java | 18 ++++++++++++++++++ 6 files changed, 70 insertions(+) create mode 100644 idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt create mode 100644 idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt.after create mode 100644 idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiterals.kt create mode 100644 idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiteralsNoIt.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt index 07605316939..980f18e43ef 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceExplicitFunctionLiteralParamWithItIntention.kt @@ -30,6 +30,8 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.psi.KtFunctionLiteral import org.jetbrains.kotlin.psi.KtNameReferenceExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils @@ -44,6 +46,14 @@ class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBaseInten val parameter = functionLiteral.valueParameters.singleOrNull() ?: return false if (parameter.typeReference != null) return false + if (functionLiteral.anyDescendantOfType() { literal -> + literal !== functionLiteral && + !literal.hasParameterSpecification() && + literal.anyDescendantOfType { nameExpr -> + nameExpr.getReferencedName() == element.text + } + } ) return false + text = "Replace explicit parameter '${parameter.name}' with 'it'" return true } diff --git a/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt new file mode 100644 index 00000000000..bf14d8ec1ce --- /dev/null +++ b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt @@ -0,0 +1,10 @@ +// IS_APPLICABLE: true + +inline fun T.let(block: (T) -> R): R = block(this) + +fun foo(arg: Any?, y: Any?): Any? { + return arg?.let { + x -> x.toString().let { y } + } +} + diff --git a/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt.after b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt.after new file mode 100644 index 00000000000..635d313449e --- /dev/null +++ b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt.after @@ -0,0 +1,10 @@ +// IS_APPLICABLE: true + +inline fun T.let(block: (T) -> R): R = block(this) + +fun foo(arg: Any?, y: Any?): Any? { + return arg?.let { + it.toString().let { y } + } +} + diff --git a/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiterals.kt b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiterals.kt new file mode 100644 index 00000000000..ce4df756636 --- /dev/null +++ b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiterals.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false + +inline fun T.let(block: (T) -> R): R = block(this) + +fun foo(arg: Any?): Int? { + return arg?.let { + x -> x.toString().let { + x.hashCode() + it.hashCode() + } + } +} + diff --git a/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiteralsNoIt.kt b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiteralsNoIt.kt new file mode 100644 index 00000000000..24978236abd --- /dev/null +++ b/idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiteralsNoIt.kt @@ -0,0 +1,10 @@ +// IS_APPLICABLE: false + +inline fun T.let(block: (T) -> R): R = block(this) + +fun foo(arg: Any?): Any? { + return arg?.let { + x -> x.toString().let { x } + } +} + diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 6fde0b0ea70..3e6f560a177 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -7933,6 +7933,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("applicable_nestedLiteralsNoUseInside.kt") + public void testApplicable_nestedLiteralsNoUseInside() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt"); + doTest(fileName); + } + @TestMetadata("notApplicable_alreadyUsesImplicitIt.kt") public void testNotApplicable_alreadyUsesImplicitIt() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_alreadyUsesImplicitIt.kt"); @@ -7945,6 +7951,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("notApplicable_nestedLiterals.kt") + public void testNotApplicable_nestedLiterals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiterals.kt"); + doTest(fileName); + } + + @TestMetadata("notApplicable_nestedLiteralsNoIt.kt") + public void testNotApplicable_nestedLiteralsNoIt() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_nestedLiteralsNoIt.kt"); + doTest(fileName); + } + @TestMetadata("notApplicable_notFunctionLiteralParameter.kt") public void testNotApplicable_notFunctionLiteralParameter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_notFunctionLiteralParameter.kt");