diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createImpl/CreateActualFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createImpl/CreateActualFix.kt index 7c01105cca8..6aaeedd179b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createImpl/CreateActualFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createImpl/CreateActualFix.kt @@ -210,38 +210,52 @@ private fun KtPsiFactory.generateClassOrObject( ): KtClassOrObject { val expectedText = expectedClass.text val actualClass = if (expectedClass is KtObjectDeclaration) createObject(expectedText) else createClass(expectedText) - if (expectedClass !is KtClass || !expectedClass.isInterface()) { - actualClass.declarations.forEach { - if (it !is KtEnumEntry && - !it.hasModifier(KtTokens.ABSTRACT_KEYWORD)) { - it.delete() - } - } - - declLoop@ for (expectedDeclaration in expectedClass.declarations) { - if (expectedDeclaration.hasModifier(KtTokens.ABSTRACT_KEYWORD)) continue - val descriptor = expectedDeclaration.toDescriptor() ?: continue - val actualDeclaration: KtDeclaration = when (expectedDeclaration) { - is KtClassOrObject -> - if (expectedDeclaration !is KtEnumEntry) { - generateClassOrObject(project, expectedDeclaration, actualNeeded = true) - } - else { - continue@declLoop - } - is KtFunction -> generateFunction(project, expectedDeclaration, descriptor as FunctionDescriptor, actualNeeded = true) - is KtProperty -> generateProperty(project, expectedDeclaration, descriptor as PropertyDescriptor, actualNeeded = true) - else -> continue@declLoop - } - actualClass.addDeclaration(actualDeclaration) - } - - actualClass.primaryConstructor?.let { - it.addModifier(KtTokens.ACTUAL_KEYWORD) - for (parameter in it.valueParameters) { - if (parameter.hasValOrVar()) { - parameter.addModifier(KtTokens.ACTUAL_KEYWORD) + val isInterface = expectedClass is KtClass && expectedClass.isInterface() + actualClass.declarations.forEach { + when (it) { + is KtEnumEntry -> return@forEach + is KtClassOrObject -> it.delete() + is KtCallableDeclaration -> { + if (!isInterface && !it.hasModifier(KtTokens.ABSTRACT_KEYWORD)) { + it.delete() } + else { + it.addModifier(KtTokens.ACTUAL_KEYWORD) + } + } + } + } + + declLoop@ for (expectedDeclaration in expectedClass.declarations) { + val descriptor = expectedDeclaration.toDescriptor() ?: continue + val actualDeclaration: KtDeclaration = when (expectedDeclaration) { + is KtClassOrObject -> + if (expectedDeclaration !is KtEnumEntry) { + generateClassOrObject(project, expectedDeclaration, actualNeeded = true) + } + else { + continue@declLoop + } + is KtCallableDeclaration -> { + if (isInterface || expectedDeclaration.hasModifier(KtTokens.ABSTRACT_KEYWORD)) { + continue@declLoop + } + when (expectedDeclaration) { + is KtFunction -> generateFunction(project, expectedDeclaration, descriptor as FunctionDescriptor, actualNeeded = true) + is KtProperty -> generateProperty(project, expectedDeclaration, descriptor as PropertyDescriptor, actualNeeded = true) + else -> continue@declLoop + } + } + else -> continue@declLoop + } + actualClass.addDeclaration(actualDeclaration) + } + + actualClass.primaryConstructor?.let { + it.addModifier(KtTokens.ACTUAL_KEYWORD) + for (parameter in it.valueParameters) { + if (parameter.hasValOrVar()) { + parameter.addModifier(KtTokens.ACTUAL_KEYWORD) } } } diff --git a/idea/testData/multiModuleQuickFix/abstract/js/Abstract.kt.after b/idea/testData/multiModuleQuickFix/abstract/js/Abstract.kt.after index 41436b019fa..e0779b9a554 100644 --- a/idea/testData/multiModuleQuickFix/abstract/js/Abstract.kt.after +++ b/idea/testData/multiModuleQuickFix/abstract/js/Abstract.kt.after @@ -1,9 +1,9 @@ // Abstract: to be implemented actual abstract class Abstract { - abstract fun String.bar(y: Double): Boolean + actual abstract fun String.bar(y: Double): Boolean - abstract var status: Int + actual abstract var status: Int actual fun foo(param: String): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } diff --git a/idea/testData/multiModuleQuickFix/interface/header/header.kt b/idea/testData/multiModuleQuickFix/interface/header/header.kt index e1f2ef95e15..74e3306b61e 100644 --- a/idea/testData/multiModuleQuickFix/interface/header/header.kt +++ b/idea/testData/multiModuleQuickFix/interface/header/header.kt @@ -8,4 +8,8 @@ expect interface Interface { val isGood: Boolean var status: Int + + class Nested { + fun bar() + } } \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/interface/header/header.kt.after b/idea/testData/multiModuleQuickFix/interface/header/header.kt.after index f669f51e5c6..6c51d39d272 100644 --- a/idea/testData/multiModuleQuickFix/interface/header/header.kt.after +++ b/idea/testData/multiModuleQuickFix/interface/header/header.kt.after @@ -8,4 +8,8 @@ expect interface Interface { val isGood: Boolean var status: Int + + class Nested { + fun bar() + } } \ No newline at end of file diff --git a/idea/testData/multiModuleQuickFix/interface/jvm/Interface.kt.after b/idea/testData/multiModuleQuickFix/interface/jvm/Interface.kt.after index 1b53b7f8241..01187eff904 100644 --- a/idea/testData/multiModuleQuickFix/interface/jvm/Interface.kt.after +++ b/idea/testData/multiModuleQuickFix/interface/jvm/Interface.kt.after @@ -1,10 +1,15 @@ // Interface: to be implemented actual interface Interface { - fun foo(param: String): Int + actual fun foo(param: String): Int - fun String.bar(y: Double): Boolean + actual fun String.bar(y: Double): Boolean - val isGood: Boolean + actual val isGood: Boolean + + actual var status: Int + + actual class Nested { + actual fun bar() {} + } - var status: Int } \ No newline at end of file