Implement Members Quick-Fix: Support primary constructor parameters
#KT-8427 In Progress
This commit is contained in:
+22
-1
@@ -21,10 +21,15 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
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.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
|
||||
public class ImplementMembersHandler : OverrideImplementMembersHandler(), IntentionAction {
|
||||
public 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) }
|
||||
@@ -39,3 +44,19 @@ public class ImplementMembersHandler : OverrideImplementMembersHandler(), Intent
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor, file: PsiFile) = isValidFor(editor, file)
|
||||
}
|
||||
|
||||
public class ImplementAsConstructorParameter : ImplementMembersHandler() {
|
||||
override fun getText() = "Implement as constructor parameters"
|
||||
|
||||
override fun isValidForClass(classOrObject: KtClassOrObject): Boolean {
|
||||
if (classOrObject !is KtClass || classOrObject is KtEnumEntry || classOrObject.isInterface()) return false
|
||||
val classDescriptor = classOrObject.resolveToDescriptorIfAny() as? ClassDescriptor ?: 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) }
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -51,11 +51,13 @@ public abstract class OverrideImplementMembersHandler : LanguageCodeInsightActio
|
||||
|
||||
protected abstract fun getChooserTitle(): String
|
||||
|
||||
protected open fun isValidForClass(classOrObject: KtClassOrObject) = true
|
||||
|
||||
override fun isValidFor(editor: Editor, file: PsiFile): Boolean {
|
||||
if (file !is KtFile) return false
|
||||
val elementAtCaret = file.findElementAt(editor.caretModel.offset)
|
||||
val classOrObject = elementAtCaret?.getNonStrictParentOfType<KtClassOrObject>()
|
||||
return classOrObject != null
|
||||
return classOrObject != null && isValidForClass(classOrObject)
|
||||
}
|
||||
|
||||
protected abstract fun getNoMembersFoundHint(): String
|
||||
|
||||
+15
-10
@@ -39,15 +39,21 @@ interface OverrideMemberChooserObject : ClassMember {
|
||||
val descriptor: CallableMemberDescriptor
|
||||
val immediateSuper: CallableMemberDescriptor
|
||||
val bodyType: BodyType
|
||||
val preferConstructorParameter: Boolean
|
||||
|
||||
companion object {
|
||||
fun create(project: Project, descriptor: CallableMemberDescriptor, immediateSuper: CallableMemberDescriptor, bodyType: BodyType): OverrideMemberChooserObject {
|
||||
fun create(project: Project,
|
||||
descriptor: CallableMemberDescriptor,
|
||||
immediateSuper: CallableMemberDescriptor,
|
||||
bodyType: BodyType,
|
||||
preferConstructorParameter: Boolean = false
|
||||
): OverrideMemberChooserObject {
|
||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor)
|
||||
if (declaration != null) {
|
||||
return WithDeclaration(descriptor, declaration, immediateSuper, bodyType)
|
||||
return WithDeclaration(descriptor, declaration, immediateSuper, bodyType, preferConstructorParameter)
|
||||
}
|
||||
else {
|
||||
return WithoutDeclaration(descriptor, immediateSuper, bodyType)
|
||||
return WithoutDeclaration(descriptor, immediateSuper, bodyType, preferConstructorParameter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +61,8 @@ interface OverrideMemberChooserObject : ClassMember {
|
||||
descriptor: CallableMemberDescriptor,
|
||||
declaration: PsiElement,
|
||||
override val immediateSuper: CallableMemberDescriptor,
|
||||
override val bodyType: BodyType
|
||||
override val bodyType: BodyType,
|
||||
override val preferConstructorParameter: Boolean
|
||||
) : DescriptorMemberChooserObject(declaration, descriptor), OverrideMemberChooserObject {
|
||||
|
||||
override val descriptor: CallableMemberDescriptor
|
||||
@@ -65,7 +72,8 @@ interface OverrideMemberChooserObject : ClassMember {
|
||||
private class WithoutDeclaration(
|
||||
override val descriptor: CallableMemberDescriptor,
|
||||
override val immediateSuper: CallableMemberDescriptor,
|
||||
override val bodyType: BodyType
|
||||
override val bodyType: BodyType,
|
||||
override val preferConstructorParameter: Boolean
|
||||
) : MemberChooserObjectBase(DescriptorMemberChooserObject.getText(descriptor), DescriptorMemberChooserObject.getIcon(null, descriptor)), OverrideMemberChooserObject {
|
||||
|
||||
override fun getParentNodeDelegate(): MemberChooserObject? {
|
||||
@@ -76,12 +84,9 @@ interface OverrideMemberChooserObject : ClassMember {
|
||||
}
|
||||
}
|
||||
|
||||
fun OverrideMemberChooserObject.generateMember(project: Project, asConstructorParameter: Boolean = false): KtCallableDeclaration {
|
||||
fun OverrideMemberChooserObject.generateMember(project: Project): KtCallableDeclaration {
|
||||
val descriptor = immediateSuper
|
||||
if (asConstructorParameter) {
|
||||
assert(descriptor is PropertyDescriptor) { "asConstructorParameter is valid only for PropertyDescriptor" }
|
||||
return generateConstructorParameter(project, descriptor as PropertyDescriptor)
|
||||
}
|
||||
if (preferConstructorParameter && descriptor is PropertyDescriptor) return generateConstructorParameter(project, descriptor)
|
||||
|
||||
return when (descriptor) {
|
||||
is SimpleFunctionDescriptor -> generateFunction(project, descriptor, bodyType)
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import java.util.*
|
||||
|
||||
public class OverrideMembersHandler : OverrideImplementMembersHandler() {
|
||||
public class OverrideMembersHandler(private val preferConstructorParameters: Boolean = false) : OverrideImplementMembersHandler() {
|
||||
override fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection<OverrideMemberChooserObject> {
|
||||
val result = ArrayList<OverrideMemberChooserObject>()
|
||||
for (member in descriptor.unsubstitutedMemberScope.getContributedDescriptors()) {
|
||||
@@ -73,7 +73,7 @@ public class OverrideMembersHandler : OverrideImplementMembersHandler() {
|
||||
else
|
||||
OverrideMemberChooserObject.BodyType.QUALIFIED_SUPER
|
||||
|
||||
result.add(OverrideMemberChooserObject.create(project, realSuper, immediateSuperToUse, bodyType))
|
||||
result.add(OverrideMemberChooserObject.create(project, realSuper, immediateSuperToUse, bodyType, preferConstructorParameters))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user