diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddSuspendModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddSuspendModifierFix.kt new file mode 100644 index 00000000000..eac90d94c29 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddSuspendModifierFix.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.quickfix + +import com.intellij.codeInsight.intention.IntentionAction +import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* + +class AddSuspendModifierFix(element: KtModifierListOwner): AddModifierFix(element, KtTokens.SUSPEND_KEYWORD) { + + override fun getText() = + when (element) { + is KtNamedFunction -> "Make ${element?.name ?: "containing function"} suspend" + else -> super.getText() + } + + companion object : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val element = diagnostic.psiElement + val function = (element as? KtElement)?.containingDeclarationForPseudocode as? KtNamedFunction ?: return null + + return AddSuspendModifierFix(function) + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 8ab980ba6a2..170ff403004 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) + UNSUPPORTED_FEATURE.registerFactory(EnableUnsupportedFeatureFix) EXPERIMENTAL_FEATURE_ERROR.registerFactory(ChangeCoroutineSupportFix) diff --git a/idea/testData/quickfix/modifiers/suspend/base.kt b/idea/testData/quickfix/modifiers/suspend/base.kt new file mode 100644 index 00000000000..a3583f9975d --- /dev/null +++ b/idea/testData/quickfix/modifiers/suspend/base.kt @@ -0,0 +1,6 @@ +// "Make bar suspend" "true" + +suspend fun foo() {} +fun bar() { + foo() +} \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/suspend/base.kt.after b/idea/testData/quickfix/modifiers/suspend/base.kt.after new file mode 100644 index 00000000000..d85cb9a7ece --- /dev/null +++ b/idea/testData/quickfix/modifiers/suspend/base.kt.after @@ -0,0 +1,6 @@ +// "Make bar suspend" "true" + +suspend fun foo() {} +suspend fun bar() { + foo() +} \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/suspend/init.kt b/idea/testData/quickfix/modifiers/suspend/init.kt new file mode 100644 index 00000000000..2e7dd669505 --- /dev/null +++ b/idea/testData/quickfix/modifiers/suspend/init.kt @@ -0,0 +1,10 @@ +// "Make bar suspend" "false" +// ERROR: Suspend functions are only allowed to be called from a coroutine or another suspend function + +suspend fun foo() {} + +class My { + init { + foo() + } +} diff --git a/idea/testData/quickfix/modifiers/suspend/topLevel.kt b/idea/testData/quickfix/modifiers/suspend/topLevel.kt new file mode 100644 index 00000000000..bc8c1a94d9f --- /dev/null +++ b/idea/testData/quickfix/modifiers/suspend/topLevel.kt @@ -0,0 +1,6 @@ +// "Make bar suspend" "false" +// ACTION: Convert property initializer to getter +// ERROR: Suspend functions are only allowed to be called from a coroutine or another suspend function + +suspend fun foo() = 42 +val x = foo() diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 3f274ed364e..fd022c65231 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -1758,6 +1758,7 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } } + } @TestMetadata("idea/testData/quickfix/nullables") diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 286305a9daa..83746fda7ed 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -6725,6 +6725,33 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } } + + @TestMetadata("idea/testData/quickfix/modifiers/suspend") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Suspend extends AbstractQuickFixTest { + public void testAllFilesPresentInSuspend() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/modifiers/suspend"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("base.kt") + public void testBase() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/suspend/base.kt"); + doTest(fileName); + } + + @TestMetadata("init.kt") + public void testInit() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/suspend/init.kt"); + doTest(fileName); + } + + @TestMetadata("topLevel.kt") + public void testTopLevel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/modifiers/suspend/topLevel.kt"); + doTest(fileName); + } + } } @TestMetadata("idea/testData/quickfix/moveToConstructorParameters")