Implement Members Quick-Fix: Support primary constructor parameters

#KT-8427 In Progress
This commit is contained in:
Alexey Sedunov
2015-12-24 16:40:24 +03:00
committed by Alexey
parent 00cc9d4150
commit 2b4f03feef
11 changed files with 105 additions and 20 deletions
@@ -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) }
}
}
@@ -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
@@ -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)
@@ -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))
}
}
}