From a4239afcb3793c396b8c0537766b7326e5d5b256 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Mon, 30 Mar 2020 12:18:53 +0900 Subject: [PATCH] Convert to anonymous function: do not suggest for suspend functions #KT-37842 Fixed --- .../LambdaToAnonymousFunctionIntention.kt | 16 +++++++++++++--- .../lambdaToAnonymousFunction/suspendFunction.kt | 9 +++++++++ .../idea/intentions/IntentionTestGenerated.java | 5 +++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 idea/testData/intentions/lambdaToAnonymousFunction/suspendFunction.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt index 4f598cd8ac7..f0ce8c935f6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/LambdaToAnonymousFunctionIntention.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.openapi.editor.Editor +import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.idea.KotlinBundle @@ -22,7 +23,10 @@ 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.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.getTargetFunctionDescriptor +import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.isFlexible import org.jetbrains.kotlin.types.typeUtil.isTypeParameter @@ -35,10 +39,16 @@ class LambdaToAnonymousFunctionIntention : SelfTargetingIntention() == null) return false - if (element.getStrictParentOfType()?.hasModifier(KtTokens.INLINE_KEYWORD) == true) return false - val descriptor = element.functionLiteral.descriptor as? AnonymousFunctionDescriptor ?: return false + val argument = element.getStrictParentOfType() ?: return false + val call = argument.getStrictParentOfType() ?: return false + if (call.getStrictParentOfType()?.hasModifier(KtTokens.INLINE_KEYWORD) == true) return false + + val context = call.analyze(BodyResolveMode.PARTIAL) + if (call.getResolvedCall(context)?.getParameterForArgument(argument)?.type?.isSuspendFunctionType == true) return false + val descriptor = + context[BindingContext.DECLARATION_TO_DESCRIPTOR, element.functionLiteral] as? AnonymousFunctionDescriptor ?: return false if (descriptor.valueParameters.any { it.name.isSpecial }) return false + val lastElement = element.functionLiteral.arrow ?: element.functionLiteral.lBrace return caretOffset <= lastElement.endOffset } diff --git a/idea/testData/intentions/lambdaToAnonymousFunction/suspendFunction.kt b/idea/testData/intentions/lambdaToAnonymousFunction/suspendFunction.kt new file mode 100644 index 00000000000..f624eadc2e5 --- /dev/null +++ b/idea/testData/intentions/lambdaToAnonymousFunction/suspendFunction.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false +suspend fun sus(i: Int, block: suspend (Int) -> Unit) { + block(i) +} + +suspend fun main() { + sus(1) { + } +} \ 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 e217ba355c0..cc649281b1b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -10528,6 +10528,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/lambdaToAnonymousFunction/returnUnit.kt"); } + @TestMetadata("suspendFunction.kt") + public void testSuspendFunction() throws Exception { + runTest("idea/testData/intentions/lambdaToAnonymousFunction/suspendFunction.kt"); + } + @TestMetadata("underscoreParameter.kt") public void testUnderscoreParameter() throws Exception { runTest("idea/testData/intentions/lambdaToAnonymousFunction/underscoreParameter.kt");