Don't suggest "Implement as constructor parameters" in actual class

This applies if expect class has primary constructor declared
#KT-27791 Fixed
This commit is contained in:
Mikhail Glukhikh
2018-11-06 14:34:07 +03:00
parent 63856cff1b
commit fcfeb33501
8 changed files with 54 additions and 3 deletions
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.util.expectedDescriptors
import org.jetbrains.kotlin.js.descriptorUtils.hasPrimaryConstructor
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtEnumEntry
@@ -32,7 +34,7 @@ import org.jetbrains.kotlin.resolve.OverrideResolver
open class ImplementMembersHandler : OverrideImplementMembersHandler(), IntentionAction {
override fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection<OverrideMemberChooserObject> {
return OverrideResolver.getMissingImplementations(descriptor)
.map { OverrideMemberChooserObject.create(project, it, it, OverrideMemberChooserObject.BodyType.EMPTY) }
.map { OverrideMemberChooserObject.create(project, it, it, OverrideMemberChooserObject.BodyType.EMPTY) }
}
override fun getChooserTitle() = "Implement Members"
@@ -51,12 +53,20 @@ class ImplementAsConstructorParameter : ImplementMembersHandler() {
override fun isValidForClass(classOrObject: KtClassOrObject): Boolean {
if (classOrObject !is KtClass || classOrObject is KtEnumEntry || classOrObject.isInterface()) return false
val classDescriptor = classOrObject.resolveToDescriptorIfAny() ?: return false
if (classDescriptor.isActual) {
if (classDescriptor.expectedDescriptors().any {
it is ClassDescriptor && it.hasPrimaryConstructor()
}
) {
return false
}
}
return OverrideResolver.getMissingImplementations(classDescriptor).any { it is PropertyDescriptor }
}
override fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection<OverrideMemberChooserObject> {
return OverrideResolver.getMissingImplementations(descriptor)
.filter { it is PropertyDescriptor }
.map { OverrideMemberChooserObject.create(project, it, it, OverrideMemberChooserObject.BodyType.EMPTY, true) }
.filter { it is PropertyDescriptor }
.map { OverrideMemberChooserObject.create(project, it, it, OverrideMemberChooserObject.BodyType.EMPTY, true) }
}
}
@@ -0,0 +1,5 @@
interface IFoo {
val a: Int
}
expect class End : IFoo
@@ -0,0 +1,5 @@
interface IFoo {
val a: Int
}
expect class End : IFoo
@@ -0,0 +1,4 @@
// "Implement as constructor parameters" "true"
// ERROR: Class 'End' is not abstract and does not implement abstract member public abstract val a: Int defined in IFoo
actual class <caret>End : IFoo
@@ -0,0 +1,4 @@
// "Implement as constructor parameters" "true"
// ERROR: Class 'End' is not abstract and does not implement abstract member public abstract val a: Int defined in IFoo
actual class End(override val a: Int) : IFoo
@@ -0,0 +1,5 @@
interface IFoo {
val a: Int
}
expect class End(i: Int) : IFoo
@@ -0,0 +1,8 @@
// "Implement as constructor parameters" "false"
// ERROR: Class 'End' is not abstract and does not implement abstract member public abstract val a: Int defined in IFoo
// ACTION: Create test
// ACTION: Implement members
// ACTION: Make 'End' abstract
// ACTION: Rename file to End.kt
actual class <caret>End actual constructor(i: Int) : IFoo
@@ -30,6 +30,16 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul
runTest("idea/testData/multiModuleQuickFix/abstract/");
}
@TestMetadata("actualImplementAsConstructorParam")
public void testActualImplementAsConstructorParam() throws Exception {
runTest("idea/testData/multiModuleQuickFix/actualImplementAsConstructorParam/");
}
@TestMetadata("actualNoImplementAsConstructorParam")
public void testActualNoImplementAsConstructorParam() throws Exception {
runTest("idea/testData/multiModuleQuickFix/actualNoImplementAsConstructorParam/");
}
@TestMetadata("actualWithoutExpect")
public void testActualWithoutExpect() throws Exception {
runTest("idea/testData/multiModuleQuickFix/actualWithoutExpect/");