diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddInlineModifierFix.kt similarity index 50% rename from idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt rename to idea/src/org/jetbrains/kotlin/idea/quickfix/AddInlineModifierFix.kt index 436fdf5cd72..9aea161151f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddInlineModifierFix.kt @@ -17,8 +17,6 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.codeInsight.intention.IntentionAction -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.project.Project import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.KtModifierKeywordToken @@ -27,38 +25,43 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType class AddInlineModifierFix( - element: KtNameReferenceExpression, - private val modifier: KtModifierKeywordToken -) : KotlinQuickFixAction(element) { - override fun getText() = element?.let { "Add '${modifier.value}' to parameter '${it.getReferencedName()}'" } ?: "" + parameter: KtParameter, + modifier: KtModifierKeywordToken +) : AddModifierFix(parameter, modifier) { + + override fun getText() = element?.let { "Add '${modifier.value}' to parameter '${it.name}'" } ?: "" override fun getFamilyName() = "Add '${modifier.value}' to parameter" - override fun invoke(project: Project, editor: Editor?, file: KtFile) { - val element = element ?: return - val parameter = element.findParameterWithName(element.getReferencedName()) ?: return - if (!parameter.hasModifier(modifier)) { - parameter.addModifier(modifier) + companion object { + private fun KtElement.findParameterWithName(name: String): KtParameter? { + val function = getStrictParentOfType() ?: return null + return function.valueParameters.firstOrNull { it.name == name } ?: function.findParameterWithName(name) } } - private fun KtElement.findParameterWithName(name: String): KtParameter? { - val function = getStrictParentOfType() ?: return null - return function.valueParameters.firstOrNull { it.name == name } ?: function.findParameterWithName(name) - } - - object CrossInlineFactory : KotlinIntentionActionsFactory() { - override fun doCreateActions(diagnostic: Diagnostic): List { + object CrossInlineFactory : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { val casted = Errors.NON_LOCAL_RETURN_NOT_ALLOWED.cast(diagnostic) - val reference = casted.a as? KtNameReferenceExpression ?: return emptyList() - return listOf(AddInlineModifierFix(reference, KtTokens.CROSSINLINE_KEYWORD)) + val reference = casted.a as? KtNameReferenceExpression ?: return null + val parameter = reference.findParameterWithName(reference.getReferencedName()) ?: return null + return AddInlineModifierFix(parameter, KtTokens.CROSSINLINE_KEYWORD) } } - object NoInlineFactory : KotlinIntentionActionsFactory() { - override fun doCreateActions(diagnostic: Diagnostic): List { + object NoInlineFactory : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { val casted = Errors.USAGE_IS_NOT_INLINABLE.cast(diagnostic) - val reference = casted.a as? KtNameReferenceExpression ?: return emptyList() - return listOf(AddInlineModifierFix(reference, KtTokens.NOINLINE_KEYWORD)) + val reference = casted.a as? KtNameReferenceExpression ?: return null + val parameter = reference.findParameterWithName(reference.getReferencedName()) ?: return null + return AddInlineModifierFix(parameter, KtTokens.NOINLINE_KEYWORD) } } + + object SuspendFactory : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val parameter = diagnostic.psiElement as? KtParameter ?: return null + return AddInlineModifierFix(parameter, KtTokens.NOINLINE_KEYWORD) + } + } + } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt index 246d591a0d5..b5893007436 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt @@ -37,7 +37,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode open class AddModifierFix( element: KtModifierListOwner, - private val modifier: KtModifierKeywordToken + protected val modifier: KtModifierKeywordToken ) : KotlinQuickFixAction(element) { override fun getText(): String { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index b8d671a6ef9..6168148dac3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -470,6 +470,8 @@ class QuickFixRegistrar : QuickFixContributor { ErrorsJs.WRONG_EXTERNAL_DECLARATION.registerFactory(MigrateExternalExtensionFix) ILLEGAL_SUSPEND_FUNCTION_CALL.registerFactory(AddSuspendModifierFix) + INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED.registerFactory(AddInlineModifierFix.SuspendFactory) + UNRESOLVED_REFERENCE.registerFactory(AddSuspendModifierFix.UnresolvedReferenceFactory) UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AddSuspendModifierFix.UnresolvedReferenceFactory) diff --git a/idea/testData/quickfix/addNoinline/suspend.kt b/idea/testData/quickfix/addNoinline/suspend.kt new file mode 100644 index 00000000000..8abe740a29f --- /dev/null +++ b/idea/testData/quickfix/addNoinline/suspend.kt @@ -0,0 +1,3 @@ +// "Add 'noinline' to parameter 'x'" "true" + +inline fun foo(x: suspend () -> Unit) {} \ No newline at end of file diff --git a/idea/testData/quickfix/addNoinline/suspend.kt.after b/idea/testData/quickfix/addNoinline/suspend.kt.after new file mode 100644 index 00000000000..4bb171c299a --- /dev/null +++ b/idea/testData/quickfix/addNoinline/suspend.kt.after @@ -0,0 +1,3 @@ +// "Add 'noinline' to parameter 'x'" "true" + +inline fun foo(noinline x: suspend () -> Unit) {} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 22acfc72179..cafab93460c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -445,6 +445,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addNoinline/basic.kt"); doTest(fileName); } + + @TestMetadata("suspend.kt") + public void testSuspend() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addNoinline/suspend.kt"); + doTest(fileName); + } } @TestMetadata("idea/testData/quickfix/addReifiedToTypeParameterOfFunctionFix")