Handle interface / abstract members correctly in "Create actual" fix

So #KT-20243 Fixed
This commit is contained in:
Mikhail Glukhikh
2017-10-03 15:34:21 +03:00
parent fe786ad7f3
commit e8321be380
5 changed files with 64 additions and 37 deletions
@@ -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)
}
}
}
@@ -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.
}
@@ -8,4 +8,8 @@ expect interface <caret>Interface {
val isGood: Boolean
var status: Int
class Nested {
fun bar()
}
}
@@ -8,4 +8,8 @@ expect interface Interface {
val isGood: Boolean
var status: Int
class Nested {
fun bar()
}
}
@@ -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
}