diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/DeclarationCantBeInlinedFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/DeclarationCantBeInlinedFactory.kt new file mode 100644 index 00000000000..2afe0ed69da --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/DeclarationCantBeInlinedFactory.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +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.idea.intentions.declarations.ConvertMemberToExtensionIntention +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.psiUtil.containingClass + +object DeclarationCantBeInlinedFactory : KotlinIntentionActionsFactory() { + override fun doCreateActions(diagnostic: Diagnostic): List { + val function = diagnostic.psiElement as? KtNamedFunction ?: return emptyList() + val containingClass = function.containingClass() ?: return emptyList() + val fixes = mutableListOf() + if (containingClass.isInterface()) { + fixes.add(ConvertMemberToExtensionFix(function)) + } else if (function.hasModifier(KtTokens.OPEN_KEYWORD)) { + fixes.add(RemoveModifierFix(function, KtTokens.OPEN_KEYWORD, false)) + } + return fixes + } +} + +private class ConvertMemberToExtensionFix(element: KtNamedFunction) : KotlinQuickFixAction(element) { + override fun getText() = "Convert member to extension" + + override fun getFamilyName() = text + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + element?.also { ConvertMemberToExtensionIntention.convert(it) } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 7575783da0c..43e6b178559 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -576,5 +576,7 @@ class QuickFixRegistrar : QuickFixContributor { RESOLUTION_TO_CLASSIFIER.registerFactory(ConvertToAnonymousObjectFix) NOTHING_TO_INLINE.registerFactory(RemoveModifierFix.createRemoveModifierFactory(isRedundant = false)) + + DECLARATION_CANT_BE_INLINED.registerFactory(DeclarationCantBeInlinedFactory) } } diff --git a/idea/testData/quickfix/declarationCantBeInlined/inClass.kt b/idea/testData/quickfix/declarationCantBeInlined/inClass.kt new file mode 100644 index 00000000000..1188ecfeb6b --- /dev/null +++ b/idea/testData/quickfix/declarationCantBeInlined/inClass.kt @@ -0,0 +1,4 @@ +// "Make 'foo' not open" "true" +open class A { + inline open fun foo() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/declarationCantBeInlined/inClass.kt.after b/idea/testData/quickfix/declarationCantBeInlined/inClass.kt.after new file mode 100644 index 00000000000..7b82beb85fc --- /dev/null +++ b/idea/testData/quickfix/declarationCantBeInlined/inClass.kt.after @@ -0,0 +1,4 @@ +// "Make 'foo' not open" "true" +open class A { + inline fun foo() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/declarationCantBeInlined/inInterface.kt b/idea/testData/quickfix/declarationCantBeInlined/inInterface.kt new file mode 100644 index 00000000000..c362c20649d --- /dev/null +++ b/idea/testData/quickfix/declarationCantBeInlined/inInterface.kt @@ -0,0 +1,5 @@ +// "Convert member to extension" "true" +// WITH_RUNTIME +interface B { + inline fun foo() +} \ No newline at end of file diff --git a/idea/testData/quickfix/declarationCantBeInlined/inInterface.kt.after b/idea/testData/quickfix/declarationCantBeInlined/inInterface.kt.after new file mode 100644 index 00000000000..0472973ca3a --- /dev/null +++ b/idea/testData/quickfix/declarationCantBeInlined/inInterface.kt.after @@ -0,0 +1,8 @@ +// "Convert member to extension" "true" +// WITH_RUNTIME +interface B { +} + +inline fun B.foo() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 5f23b780919..989eb23149f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -2236,6 +2236,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } + @TestMetadata("idea/testData/quickfix/declarationCantBeInlined") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class DeclarationCantBeInlined extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInDeclarationCantBeInlined() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/declarationCantBeInlined"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); + } + } + @TestMetadata("idea/testData/quickfix/decreaseVisibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index d5e56180617..ec662d77db7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -5056,6 +5056,29 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/declarationCantBeInlined") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class DeclarationCantBeInlined extends AbstractQuickFixTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInDeclarationCantBeInlined() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/declarationCantBeInlined"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("inClass.kt") + public void testInClass() throws Exception { + runTest("idea/testData/quickfix/declarationCantBeInlined/inClass.kt"); + } + + @TestMetadata("inInterface.kt") + public void testInInterface() throws Exception { + runTest("idea/testData/quickfix/declarationCantBeInlined/inInterface.kt"); + } + } + @TestMetadata("idea/testData/quickfix/decreaseVisibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)