Override/Implement: Do not generate bodies for header class members
#KT-15659 Fixed
This commit is contained in:
+1
-1
@@ -119,7 +119,7 @@ class OverridesCompletion(
|
||||
// keep original modifiers
|
||||
val modifierList = KtPsiFactory(context.project).createModifierList(dummyMember.modifierList!!.text)
|
||||
|
||||
val prototype = memberObject.generateMember(context.project, false)
|
||||
val prototype = memberObject.generateMember(classOrObject, false)
|
||||
prototype.modifierList!!.replace(modifierList)
|
||||
val insertedMember = dummyMember.replaced(prototype)
|
||||
|
||||
|
||||
+1
-2
@@ -106,8 +106,7 @@ abstract class OverrideImplementMembersHandler : LanguageCodeInsightActionHandle
|
||||
selectedElements: Collection<OverrideMemberChooserObject>,
|
||||
copyDoc: Boolean
|
||||
) {
|
||||
val project = classOrObject.project
|
||||
insertMembersAfter(editor, classOrObject, selectedElements.map { it.generateMember(project, copyDoc) })
|
||||
insertMembersAfter(editor, classOrObject, selectedElements.map { it.generateMember(classOrObject, copyDoc) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.j2k.IdeaDocCommentConverter
|
||||
import org.jetbrains.kotlin.idea.kdoc.KDocElementFactory
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.findDocComment.findDocComment
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
@@ -95,7 +96,11 @@ interface OverrideMemberChooserObject : ClassMember {
|
||||
}
|
||||
}
|
||||
|
||||
fun OverrideMemberChooserObject.generateMember(project: Project, copyDoc: Boolean): KtCallableDeclaration {
|
||||
fun OverrideMemberChooserObject.generateMember(targetClass: KtClassOrObject, copyDoc: Boolean): KtCallableDeclaration {
|
||||
val project = targetClass.project
|
||||
|
||||
val bodyType = if (targetClass.hasModifier(KtTokens.HEADER_KEYWORD)) OverrideMemberChooserObject.BodyType.NO_BODY else bodyType
|
||||
|
||||
val descriptor = immediateSuper
|
||||
if (preferConstructorParameter && descriptor is PropertyDescriptor) return generateConstructorParameter(project, descriptor)
|
||||
|
||||
|
||||
+2
-2
@@ -164,7 +164,7 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase<Kot
|
||||
if (!needEquals) return null
|
||||
|
||||
val superEquals = classDescriptor.getSuperClassOrAny().findDeclaredEquals(true)!!
|
||||
val equalsFun = generateFunctionSkeleton(superEquals, project)
|
||||
val equalsFun = generateFunctionSkeleton(superEquals, targetClass)
|
||||
|
||||
val paramName = equalsFun.valueParameters.first().name!!.quoteIfNeeded()
|
||||
var typeForCast = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(classDescriptor)
|
||||
@@ -249,7 +249,7 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase<Kot
|
||||
if (!needHashCode) return null
|
||||
|
||||
val superHashCode = classDescriptor.getSuperClassOrAny().findDeclaredHashCode(true)!!
|
||||
val hashCodeFun = generateFunctionSkeleton(superHashCode, project)
|
||||
val hashCodeFun = generateFunctionSkeleton(superHashCode, targetClass)
|
||||
val builtins = superHashCode.builtIns
|
||||
|
||||
val propertyIterator = variablesForHashCode.iterator()
|
||||
|
||||
@@ -178,16 +178,16 @@ class KotlinGenerateToStringAction : KotlinGenerateMemberActionBase<KotlinGenera
|
||||
project)
|
||||
}
|
||||
|
||||
private fun generateToString(project: Project, info: Info): KtNamedFunction? {
|
||||
private fun generateToString(targetClass: KtClassOrObject, info: Info): KtNamedFunction? {
|
||||
val superToString = info.classDescriptor.getSuperClassOrAny().findDeclaredToString(true)!!
|
||||
return generateFunctionSkeleton(superToString, project).apply {
|
||||
bodyExpression!!.replace(KtPsiFactory(project).createExpression("{\n${info.generator.generate(info)}\n}"))
|
||||
return generateFunctionSkeleton(superToString, targetClass).apply {
|
||||
bodyExpression!!.replace(KtPsiFactory(targetClass).createExpression("{\n${info.generator.generate(info)}\n}"))
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateMembers(project: Project, editor: Editor?, info: Info): List<KtDeclaration> {
|
||||
val targetClass = info.classDescriptor.source.getPsi() as KtClass
|
||||
val prototype = generateToString(project, info) ?: return emptyList()
|
||||
val prototype = generateToString(targetClass, info) ?: return emptyList()
|
||||
val anchor = with(targetClass.declarations) { lastIsInstanceOrNull<KtNamedFunction>() ?: lastOrNull() }
|
||||
return insertMembersAfter(editor, targetClass, listOf(prototype), anchor)
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@ fun confirmMemberRewrite(targetClass: KtClass, vararg descriptors: FunctionDescr
|
||||
Messages.getQuestionIcon()) == Messages.YES
|
||||
}
|
||||
|
||||
fun generateFunctionSkeleton(descriptor: FunctionDescriptor, project: Project): KtNamedFunction {
|
||||
fun generateFunctionSkeleton(descriptor: FunctionDescriptor, targetClass: KtClassOrObject): KtNamedFunction {
|
||||
return OverrideMemberChooserObject
|
||||
.create(project, descriptor, descriptor, OverrideMemberChooserObject.BodyType.EMPTY)
|
||||
.generateMember(project, false) as KtNamedFunction
|
||||
.create(targetClass.project, descriptor, descriptor, OverrideMemberChooserObject.BodyType.EMPTY)
|
||||
.generateMember(targetClass, false) as KtNamedFunction
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class SpecifyOverrideExplicitlyFix(
|
||||
project, delegatedDescriptor, overriddenDescriptor,
|
||||
OverrideMemberChooserObject.BodyType.Delegate(delegateTargetDescriptor.name.asString())
|
||||
)
|
||||
val member = overrideMemberChooserObject.generateMember(project, copyDoc = false)
|
||||
val member = overrideMemberChooserObject.generateMember(element, copyDoc = false)
|
||||
val insertedMember = element.addDeclaration(member)
|
||||
ShortenReferences.DEFAULT.process(insertedMember)
|
||||
return
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Implement members" "true"
|
||||
// DISABLE-ERRORS
|
||||
|
||||
interface I {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
header class <caret>Bar : I
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Implement members" "true"
|
||||
// DISABLE-ERRORS
|
||||
|
||||
interface I {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
header class <caret>Bar : I {
|
||||
override fun foo()
|
||||
}
|
||||
@@ -153,4 +153,7 @@ class QuickFixMultiModuleTest : AbstractQuickFixMultiModuleTest() {
|
||||
|
||||
@Test
|
||||
fun testFunctionTypeReceiverToParameterByImpl() = doTestHeaderWithJvmAndJs()
|
||||
|
||||
@Test
|
||||
fun testImplementMembersInHeaderClass() = doMultiPlatformTest(impls = *arrayOf())
|
||||
}
|
||||
Reference in New Issue
Block a user