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
|
// keep original modifiers
|
||||||
val modifierList = KtPsiFactory(context.project).createModifierList(dummyMember.modifierList!!.text)
|
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)
|
prototype.modifierList!!.replace(modifierList)
|
||||||
val insertedMember = dummyMember.replaced(prototype)
|
val insertedMember = dummyMember.replaced(prototype)
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -106,8 +106,7 @@ abstract class OverrideImplementMembersHandler : LanguageCodeInsightActionHandle
|
|||||||
selectedElements: Collection<OverrideMemberChooserObject>,
|
selectedElements: Collection<OverrideMemberChooserObject>,
|
||||||
copyDoc: Boolean
|
copyDoc: Boolean
|
||||||
) {
|
) {
|
||||||
val project = classOrObject.project
|
insertMembersAfter(editor, classOrObject, selectedElements.map { it.generateMember(classOrObject, copyDoc) })
|
||||||
insertMembersAfter(editor, classOrObject, selectedElements.map { it.generateMember(project, 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.kdoc.KDocElementFactory
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.findDocComment.findDocComment
|
import org.jetbrains.kotlin.psi.findDocComment.findDocComment
|
||||||
import org.jetbrains.kotlin.renderer.*
|
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
|
val descriptor = immediateSuper
|
||||||
if (preferConstructorParameter && descriptor is PropertyDescriptor) return generateConstructorParameter(project, descriptor)
|
if (preferConstructorParameter && descriptor is PropertyDescriptor) return generateConstructorParameter(project, descriptor)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -164,7 +164,7 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase<Kot
|
|||||||
if (!needEquals) return null
|
if (!needEquals) return null
|
||||||
|
|
||||||
val superEquals = classDescriptor.getSuperClassOrAny().findDeclaredEquals(true)!!
|
val superEquals = classDescriptor.getSuperClassOrAny().findDeclaredEquals(true)!!
|
||||||
val equalsFun = generateFunctionSkeleton(superEquals, project)
|
val equalsFun = generateFunctionSkeleton(superEquals, targetClass)
|
||||||
|
|
||||||
val paramName = equalsFun.valueParameters.first().name!!.quoteIfNeeded()
|
val paramName = equalsFun.valueParameters.first().name!!.quoteIfNeeded()
|
||||||
var typeForCast = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(classDescriptor)
|
var typeForCast = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(classDescriptor)
|
||||||
@@ -249,7 +249,7 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase<Kot
|
|||||||
if (!needHashCode) return null
|
if (!needHashCode) return null
|
||||||
|
|
||||||
val superHashCode = classDescriptor.getSuperClassOrAny().findDeclaredHashCode(true)!!
|
val superHashCode = classDescriptor.getSuperClassOrAny().findDeclaredHashCode(true)!!
|
||||||
val hashCodeFun = generateFunctionSkeleton(superHashCode, project)
|
val hashCodeFun = generateFunctionSkeleton(superHashCode, targetClass)
|
||||||
val builtins = superHashCode.builtIns
|
val builtins = superHashCode.builtIns
|
||||||
|
|
||||||
val propertyIterator = variablesForHashCode.iterator()
|
val propertyIterator = variablesForHashCode.iterator()
|
||||||
|
|||||||
@@ -178,16 +178,16 @@ class KotlinGenerateToStringAction : KotlinGenerateMemberActionBase<KotlinGenera
|
|||||||
project)
|
project)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateToString(project: Project, info: Info): KtNamedFunction? {
|
private fun generateToString(targetClass: KtClassOrObject, info: Info): KtNamedFunction? {
|
||||||
val superToString = info.classDescriptor.getSuperClassOrAny().findDeclaredToString(true)!!
|
val superToString = info.classDescriptor.getSuperClassOrAny().findDeclaredToString(true)!!
|
||||||
return generateFunctionSkeleton(superToString, project).apply {
|
return generateFunctionSkeleton(superToString, targetClass).apply {
|
||||||
bodyExpression!!.replace(KtPsiFactory(project).createExpression("{\n${info.generator.generate(info)}\n}"))
|
bodyExpression!!.replace(KtPsiFactory(targetClass).createExpression("{\n${info.generator.generate(info)}\n}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateMembers(project: Project, editor: Editor?, info: Info): List<KtDeclaration> {
|
override fun generateMembers(project: Project, editor: Editor?, info: Info): List<KtDeclaration> {
|
||||||
val targetClass = info.classDescriptor.source.getPsi() as KtClass
|
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() }
|
val anchor = with(targetClass.declarations) { lastIsInstanceOrNull<KtNamedFunction>() ?: lastOrNull() }
|
||||||
return insertMembersAfter(editor, targetClass, listOf(prototype), anchor)
|
return insertMembersAfter(editor, targetClass, listOf(prototype), anchor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ fun confirmMemberRewrite(targetClass: KtClass, vararg descriptors: FunctionDescr
|
|||||||
Messages.getQuestionIcon()) == Messages.YES
|
Messages.getQuestionIcon()) == Messages.YES
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateFunctionSkeleton(descriptor: FunctionDescriptor, project: Project): KtNamedFunction {
|
fun generateFunctionSkeleton(descriptor: FunctionDescriptor, targetClass: KtClassOrObject): KtNamedFunction {
|
||||||
return OverrideMemberChooserObject
|
return OverrideMemberChooserObject
|
||||||
.create(project, descriptor, descriptor, OverrideMemberChooserObject.BodyType.EMPTY)
|
.create(targetClass.project, descriptor, descriptor, OverrideMemberChooserObject.BodyType.EMPTY)
|
||||||
.generateMember(project, false) as KtNamedFunction
|
.generateMember(targetClass, false) as KtNamedFunction
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ class SpecifyOverrideExplicitlyFix(
|
|||||||
project, delegatedDescriptor, overriddenDescriptor,
|
project, delegatedDescriptor, overriddenDescriptor,
|
||||||
OverrideMemberChooserObject.BodyType.Delegate(delegateTargetDescriptor.name.asString())
|
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)
|
val insertedMember = element.addDeclaration(member)
|
||||||
ShortenReferences.DEFAULT.process(insertedMember)
|
ShortenReferences.DEFAULT.process(insertedMember)
|
||||||
return
|
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
|
@Test
|
||||||
fun testFunctionTypeReceiverToParameterByImpl() = doTestHeaderWithJvmAndJs()
|
fun testFunctionTypeReceiverToParameterByImpl() = doTestHeaderWithJvmAndJs()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testImplementMembersInHeaderClass() = doMultiPlatformTest(impls = *arrayOf())
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user