From 6a1ddd6c70ea5332e0aae7c568cc9a98155a5a33 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 15 May 2018 15:26:02 +0300 Subject: [PATCH] Lambda to anonymous: report only from left brace to arrow --- .../idea/intentions/LambdaToAnonymousFunctionIntention.kt | 5 ++++- .../intentions/lambdaToAnonymousFunction/extention1.kt | 2 +- .../intentions/lambdaToAnonymousFunction/extention2.kt | 2 +- .../intentions/lambdaToAnonymousFunction/hasReturn2.kt | 4 ++-- .../intentions/lambdaToAnonymousFunction/hasReturn3.kt | 4 ++-- .../lambdaToAnonymousFunction/incorrectOffset.kt | 7 +++++++ .../intentions/lambdaToAnonymousFunction/noParameter.kt | 2 +- .../intentions/lambdaToAnonymousFunction/returnUnit.kt | 4 ++-- .../letWithWrongImplicitThis.kt | 1 - .../kotlin/idea/intentions/IntentionTestGenerated.java | 5 +++++ 10 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 idea/testData/intentions/lambdaToAnonymousFunction/incorrectOffset.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt index 8a382847d6a..78c0abcac4d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType +import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.bindingContextUtil.getTargetFunctionDescriptor import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -32,7 +33,9 @@ class LambdaToAnonymousFunctionIntention : SelfTargetingIntention() == null) return false val descriptor = element.functionLiteral.descriptor as? AnonymousFunctionDescriptor ?: return false - return descriptor.valueParameters.none { it.name.isSpecial } + if (descriptor.valueParameters.any { it.name.isSpecial }) return false + val lastElement = element.functionLiteral.arrow ?: element.functionLiteral.lBrace + return caretOffset <= lastElement.endOffset } override fun applyTo(element: KtLambdaExpression, editor: Editor?) { diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/extention1.kt b/idea/testData/intentions/lambdaToAnonymousFunction/extention1.kt index ad2bbaf208b..abebcd203ca 100644 --- a/idea/testData/intentions/lambdaToAnonymousFunction/extention1.kt +++ b/idea/testData/intentions/lambdaToAnonymousFunction/extention1.kt @@ -2,5 +2,5 @@ class Foo fun bar(f: Foo.() -> Unit) {} fun main(args: Array) { - bar {} + bar {} } \ No newline at end of file diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/extention2.kt b/idea/testData/intentions/lambdaToAnonymousFunction/extention2.kt index 583e491436a..199f54cc490 100644 --- a/idea/testData/intentions/lambdaToAnonymousFunction/extention2.kt +++ b/idea/testData/intentions/lambdaToAnonymousFunction/extention2.kt @@ -2,5 +2,5 @@ class Foo fun baz(f: Foo.(i: Int, j: Int) -> Int) {} fun main(args: Array) { - baz { i, j -> i + j } + baz { i, j -> i + j } } \ No newline at end of file diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn2.kt b/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn2.kt index 761d6fa6dca..9d6786851ad 100644 --- a/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn2.kt +++ b/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn2.kt @@ -1,10 +1,10 @@ fun foo(f: (Int) -> String) {} fun test() { - foo { + foo { if (it == 1) { return@foo "1" } "$it" - } + } } \ No newline at end of file diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn3.kt b/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn3.kt index b0c58484881..39127f2e1f5 100644 --- a/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn3.kt +++ b/idea/testData/intentions/lambdaToAnonymousFunction/hasReturn3.kt @@ -1,7 +1,7 @@ fun foo(f: (Int) -> String) {} fun test() { - foo { + foo { if (it == 1) { return@foo "1" } else if (it == 2) { @@ -9,5 +9,5 @@ fun test() { } else { return@foo "$it" } - } + } } \ No newline at end of file diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/incorrectOffset.kt b/idea/testData/intentions/lambdaToAnonymousFunction/incorrectOffset.kt new file mode 100644 index 00000000000..19ae7e1c45b --- /dev/null +++ b/idea/testData/intentions/lambdaToAnonymousFunction/incorrectOffset.kt @@ -0,0 +1,7 @@ +// IS_APPLICABLE: false + +fun foo(f: () -> String) {} + +fun test() { + foo { -> "" } +} \ No newline at end of file diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/noParameter.kt b/idea/testData/intentions/lambdaToAnonymousFunction/noParameter.kt index 031f05d615e..b0096c1fba8 100644 --- a/idea/testData/intentions/lambdaToAnonymousFunction/noParameter.kt +++ b/idea/testData/intentions/lambdaToAnonymousFunction/noParameter.kt @@ -1,5 +1,5 @@ fun foo(f: () -> String) {} fun test() { - foo { "" } + foo { -> "" } } \ No newline at end of file diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/returnUnit.kt b/idea/testData/intentions/lambdaToAnonymousFunction/returnUnit.kt index 0079f1b10c1..262b9273310 100644 --- a/idea/testData/intentions/lambdaToAnonymousFunction/returnUnit.kt +++ b/idea/testData/intentions/lambdaToAnonymousFunction/returnUnit.kt @@ -3,8 +3,8 @@ fun unit(f: (Int) -> Unit) {} fun foo(i: Int) {} fun test() { - unit { + unit { foo(it) foo(it) - } + } } \ No newline at end of file diff --git a/idea/testData/quickfix/replaceWithSafeCallForScopeFunction/letWithWrongImplicitThis.kt b/idea/testData/quickfix/replaceWithSafeCallForScopeFunction/letWithWrongImplicitThis.kt index c0554205d35..a4b33f616c0 100644 --- a/idea/testData/quickfix/replaceWithSafeCallForScopeFunction/letWithWrongImplicitThis.kt +++ b/idea/testData/quickfix/replaceWithSafeCallForScopeFunction/letWithWrongImplicitThis.kt @@ -6,7 +6,6 @@ // ACTION: Replace with safe (this?.) call // ACTION: Specify explicit lambda signature // ACTION: Add return@let -// ACTION: Convert to anonymous function // ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String? fun String?.foo(a: String?) { diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index a8e6d0b3e2e..a02f491ecf1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -9704,6 +9704,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/lambdaToAnonymousFunction/implicitParameterName.kt"); } + @TestMetadata("incorrectOffset.kt") + public void testIncorrectOffset() throws Exception { + runTest("idea/testData/intentions/lambdaToAnonymousFunction/incorrectOffset.kt"); + } + @TestMetadata("namedArgument.kt") public void testNamedArgument() throws Exception { runTest("idea/testData/intentions/lambdaToAnonymousFunction/namedArgument.kt");