Handle interface / abstract members correctly in "Create actual" fix
So #KT-20243 Fixed
This commit is contained in:
@@ -210,38 +210,52 @@ private fun KtPsiFactory.generateClassOrObject(
|
|||||||
): KtClassOrObject {
|
): KtClassOrObject {
|
||||||
val expectedText = expectedClass.text
|
val expectedText = expectedClass.text
|
||||||
val actualClass = if (expectedClass is KtObjectDeclaration) createObject(expectedText) else createClass(expectedText)
|
val actualClass = if (expectedClass is KtObjectDeclaration) createObject(expectedText) else createClass(expectedText)
|
||||||
if (expectedClass !is KtClass || !expectedClass.isInterface()) {
|
val isInterface = expectedClass is KtClass && expectedClass.isInterface()
|
||||||
actualClass.declarations.forEach {
|
actualClass.declarations.forEach {
|
||||||
if (it !is KtEnumEntry &&
|
when (it) {
|
||||||
!it.hasModifier(KtTokens.ABSTRACT_KEYWORD)) {
|
is KtEnumEntry -> return@forEach
|
||||||
it.delete()
|
is KtClassOrObject -> it.delete()
|
||||||
}
|
is KtCallableDeclaration -> {
|
||||||
}
|
if (!isInterface && !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)
|
|
||||||
}
|
}
|
||||||
|
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
|
// Abstract: to be implemented
|
||||||
actual abstract class Abstract {
|
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 {
|
actual fun foo(param: String): Int {
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
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
|
val isGood: Boolean
|
||||||
|
|
||||||
var status: Int
|
var status: Int
|
||||||
|
|
||||||
|
class Nested {
|
||||||
|
fun bar()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,4 +8,8 @@ expect interface Interface {
|
|||||||
val isGood: Boolean
|
val isGood: Boolean
|
||||||
|
|
||||||
var status: Int
|
var status: Int
|
||||||
|
|
||||||
|
class Nested {
|
||||||
|
fun bar()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
// Interface: to be implemented
|
// Interface: to be implemented
|
||||||
actual interface Interface {
|
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
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user