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");