From 80e4e7939d7a8f24df3d6bb67fdd654dc7b31a69 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Sun, 12 Jul 2020 16:07:06 +0900 Subject: [PATCH] "Create abstract function" quick fix: don't suggest it if super classes are not writable #KT-40215 Fixed --- .../CreateCallableFromCallActionFactory.kt | 10 +++++++++- .../call/abstract/notWritableAbstractSuperclass.kt | 9 +++++++++ .../kotlin/idea/quickfix/QuickFixTestGenerated.java | 5 +++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notWritableAbstractSuperclass.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt index 65da722ad15..ca68f4b6783 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt @@ -148,7 +148,10 @@ sealed class CreateCallableFromCallActionFactory( receiverTypeInfo = TypeInfo(receiverType, Variance.IN_VARIANCE).ofThis() } - if (!receiverType.isAbstract() && TypeUtils.getAllSupertypes(receiverType).all { !it.isAbstract() }) return null + val project = originalExpression.project + if (!receiverType.isAbstract() && TypeUtils.getAllSupertypes(receiverType).none { it.isAbstract() && it.canRefactor(project) }) { + return null + } return mainCallable.copy( receiverTypeInfo = receiverTypeInfo, @@ -157,6 +160,11 @@ sealed class CreateCallableFromCallActionFactory( ) } + private fun KotlinType.canRefactor(project: Project): Boolean { + val declarationDescriptor = constructor.declarationDescriptor ?: return false + return DescriptorToSourceUtilsIde.getAnyDeclaration(project, declarationDescriptor)?.canRefactor() == true + } + protected fun getCallableWithReceiverInsideExtension( mainCallable: CallableInfo, originalExpression: KtExpression, diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notWritableAbstractSuperclass.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notWritableAbstractSuperclass.kt new file mode 100644 index 00000000000..196a59fa1ed --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notWritableAbstractSuperclass.kt @@ -0,0 +1,9 @@ +// "Create abstract function 'bar'" "false" +// ACTION: Create function 'bar' +// ACTION: Rename reference +// ERROR: Unresolved reference: bar +class Foo : Runnable { + override fun run() { + bar() + } +} \ 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 64c6286029e..b45c6db092d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -4478,6 +4478,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notAbstractClass.kt"); } + @TestMetadata("notWritableAbstractSuperclass.kt") + public void testNotWritableAbstractSuperclass() throws Exception { + runTest("idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notWritableAbstractSuperclass.kt"); + } + @TestMetadata("otherExplicitReceiver.kt") public void testOtherExplicitReceiver() throws Exception { runTest("idea/testData/quickfix/createFromUsage/createFunction/call/abstract/otherExplicitReceiver.kt");