From 34387e228fb19948d40a8432df0b562d2427b45d Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Mon, 12 Apr 2021 14:15:33 -0700 Subject: [PATCH] FIR IDE: extract common logic idea.core.overrideImplement Also rename OverrideImplementMemberHandler to GenerateMemberHandler to align with the naming of its member functions. --- .../kotlin/idea/core/oldGenerateUtil.kt | 41 +++++++ ...rsHandler.kt => GenerateMembersHandler.kt} | 86 +++------------ .../ImplementMembersHandler.kt | 16 +-- .../OverrideMemberChooserObject.kt | 25 +---- .../OverrideMembersHandler.kt | 10 +- .../messages/KotlinIdeaCoreBundle.properties | 0 .../kotlin/idea/core/generateUtil.kt | 101 +++++++----------- .../AbstractGenerateMembersHandler.kt | 95 ++++++++++++++++ .../idea/core/overrideImplement/BodyType.kt | 16 +++ .../overrideImplement/MemberGenerateMode.kt | 12 +++ .../jetbrains/kotlin/idea/core/templates.kt | 2 +- .../idea/core/util/KotlinIdeaCoreBundle.kt | 2 +- .../kotlin/idea/j2k/DocCommentConverter.kt | 2 +- .../idea/j2k/IdeaDocCommentConverter.kt | 2 +- .../KotlinGenerateEqualsAndHashcodeAction.kt | 4 +- ...otlinGenerateSecondaryConstructorAction.kt | 2 +- .../KotlinGenerateTestSupportActionBase.kt | 2 +- .../generate/KotlinGenerateToStringAction.kt | 4 +- .../kotlin/idea/actions/generate/utils.kt | 3 +- .../ImplementAbstractMemberIntention.kt | 7 +- .../MakePrivateAndOverrideMemberFix.kt | 4 +- .../quickfix/SpecifyOverrideExplicitlyFix.kt | 3 +- .../expectactual/ExpectActualUtils.kt | 4 +- .../AbstractOverrideImplementTest.kt | 16 +-- 24 files changed, 264 insertions(+), 195 deletions(-) create mode 100644 idea/idea-core/src/org/jetbrains/kotlin/idea/core/oldGenerateUtil.kt rename idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/{OverrideImplementMembersHandler.kt => GenerateMembersHandler.kt} (59%) rename idea/{idea-core/resources => idea-frontend-independent/resources-en}/messages/KotlinIdeaCoreBundle.properties (100%) rename idea/{idea-core => idea-frontend-independent}/src/org/jetbrains/kotlin/idea/core/generateUtil.kt (70%) create mode 100644 idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/AbstractGenerateMembersHandler.kt create mode 100644 idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/BodyType.kt create mode 100644 idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/MemberGenerateMode.kt rename idea/{idea-core => idea-frontend-independent}/src/org/jetbrains/kotlin/idea/core/templates.kt (97%) rename idea/{idea-core => idea-frontend-independent}/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt (90%) rename idea/{idea-core => idea-frontend-independent}/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt (93%) rename idea/{idea-core => idea-frontend-independent}/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt (99%) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/oldGenerateUtil.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/oldGenerateUtil.kt new file mode 100644 index 00000000000..faa969b1db3 --- /dev/null +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/oldGenerateUtil.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.core + +import com.intellij.openapi.editor.Editor +import com.intellij.psi.PsiElement +import com.intellij.psi.codeStyle.CodeStyleManager +import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtDeclaration + +fun insertMembersAfterAndReformat( + editor: Editor?, + classOrObject: KtClassOrObject, + members: Collection, + anchor: PsiElement? = null, + getAnchor: (KtDeclaration) -> PsiElement? = { null }, +): List { + val codeStyleManager = CodeStyleManager.getInstance(classOrObject.project) + return runWriteAction { + val insertedMembersElementPointers = insertMembersAfter(editor, classOrObject, members, anchor, getAnchor) + val firstElement = insertedMembersElementPointers.firstOrNull() ?: return@runWriteAction emptyList() + + fun insertedMembersElements() = insertedMembersElementPointers.mapNotNull { it.element } + + ShortenReferences.DEFAULT.process(insertedMembersElements()) + if (editor != null) { + firstElement.element?.let { moveCaretIntoGeneratedElement(editor, it) } + } + + insertedMembersElementPointers.onEach { it.element?.let { element -> codeStyleManager.reformat(element) } } + insertedMembersElements() + } +} + +fun insertMember(editor: Editor?, classOrObject: KtClassOrObject, declaration: T, anchor: PsiElement? = null): T { + return insertMembersAfterAndReformat(editor, classOrObject, listOf(declaration), anchor).single() +} diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/GenerateMembersHandler.kt similarity index 59% rename from idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt rename to idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/GenerateMembersHandler.kt index b0caaeac525..68434d4c571 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideImplementMembersHandler.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/GenerateMembersHandler.kt @@ -16,28 +16,18 @@ package org.jetbrains.kotlin.idea.core.overrideImplement -import com.intellij.codeInsight.FileModificationService -import com.intellij.codeInsight.hint.HintManager -import com.intellij.ide.util.MemberChooser -import com.intellij.lang.LanguageCodeInsightActionHandler -import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.openapi.ui.DialogWrapper -import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFile import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.idea.core.insertMembersAfter +import org.jetbrains.kotlin.idea.core.insertMembersAfterAndReformat import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.prevSiblingOfSameType import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -45,74 +35,24 @@ import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.util.findCallableMemberBySignature import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult -abstract class OverrideImplementMembersHandler : LanguageCodeInsightActionHandler { +abstract class GenerateMembersHandler : AbstractGenerateMembersHandler() { - fun collectMembersToGenerate(classOrObject: KtClassOrObject): Collection { + override fun collectMembersToGenerate(classOrObject: KtClassOrObject): Collection { val descriptor = classOrObject.resolveToDescriptorIfAny() ?: return emptySet() return collectMembersToGenerate(descriptor, classOrObject.project) } protected abstract fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection - private fun showOverrideImplementChooser( - project: Project, - members: Array - ): MemberChooser? { - val chooser = MemberChooser(members, true, true, project) - chooser.title = getChooserTitle() - chooser.show() - if (chooser.exitCode != DialogWrapper.OK_EXIT_CODE) return null - return chooser + override fun generateMembers( + editor: Editor, + classOrObject: KtClassOrObject, + selectedElements: Collection, + copyDoc: Boolean + ) { + return Companion.generateMembers(editor, classOrObject, selectedElements, copyDoc) } - 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() - return classOrObject != null && isValidForClass(classOrObject) - } - - protected abstract fun getNoMembersFoundHint(): String - - fun invoke(project: Project, editor: Editor, file: PsiFile, implementAll: Boolean) { - val elementAtCaret = file.findElementAt(editor.caretModel.offset) - val classOrObject = elementAtCaret?.getNonStrictParentOfType() ?: return - - if (!FileModificationService.getInstance().prepareFileForWrite(file)) return - - val members = collectMembersToGenerate(classOrObject) - if (members.isEmpty() && !implementAll) { - HintManager.getInstance().showErrorHint(editor, getNoMembersFoundHint()) - return - } - - val copyDoc: Boolean - val selectedElements: Collection - if (implementAll) { - selectedElements = members - copyDoc = false - } else { - val chooser = showOverrideImplementChooser(project, members.toTypedArray()) ?: return - selectedElements = chooser.selectedElements ?: return - copyDoc = chooser.isCopyJavadoc - } - if (selectedElements.isEmpty()) return - - PsiDocumentManager.getInstance(project).commitAllDocuments() - - generateMembers(editor, classOrObject, selectedElements, copyDoc) - } - - override fun invoke(project: Project, editor: Editor, file: PsiFile) { - invoke(project, editor, file, implementAll = ApplicationManager.getApplication().isUnitTestMode) - } - - override fun startInWriteAction(): Boolean = false - companion object { fun generateMembers( editor: Editor?, @@ -124,7 +64,7 @@ abstract class OverrideImplementMembersHandler : LanguageCodeInsightActionHandle val classBody = classOrObject.body if (classBody == null) { - insertMembersAfter(editor, classOrObject, selectedMemberDescriptors.keys) + insertMembersAfterAndReformat(editor, classOrObject, selectedMemberDescriptors.keys) return } val offset = editor?.caretModel?.offset ?: classBody.startOffset @@ -132,7 +72,7 @@ abstract class OverrideImplementMembersHandler : LanguageCodeInsightActionHandle it.parent == classBody } if (offsetCursorElement != null && offsetCursorElement != classBody.rBrace) { - insertMembersAfter(editor, classOrObject, selectedMemberDescriptors.keys) + insertMembersAfterAndReformat(editor, classOrObject, selectedMemberDescriptors.keys) return } val classLeftBrace = classBody.lBrace @@ -173,7 +113,7 @@ abstract class OverrideImplementMembersHandler : LanguageCodeInsightActionHandle return lastElement } - insertMembersAfter(editor, classOrObject, selectedMemberDescriptors.keys) { getAnchor(it) } + insertMembersAfterAndReformat(editor, classOrObject, selectedMemberDescriptors.keys) { getAnchor(it) } } } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/ImplementMembersHandler.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/ImplementMembersHandler.kt index 86ee3dffb24..a1b1ee43307 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/ImplementMembersHandler.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/ImplementMembersHandler.kt @@ -22,8 +22,8 @@ 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.idea.core.util.KotlinIdeaCoreBundle import org.jetbrains.kotlin.idea.util.expectedDescriptors import org.jetbrains.kotlin.js.descriptorUtils.hasPrimaryConstructor import org.jetbrains.kotlin.psi.KtClass @@ -31,24 +31,24 @@ import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.resolve.OverrideResolver -open class ImplementMembersHandler : OverrideImplementMembersHandler(), IntentionAction { +open class ImplementMembersHandler : GenerateMembersHandler(), IntentionAction { override fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection { return OverrideResolver.getMissingImplementations(descriptor) - .map { OverrideMemberChooserObject.create(project, it, it, OverrideMemberChooserObject.BodyType.FROM_TEMPLATE) } + .map { OverrideMemberChooserObject.create(project, it, it, BodyType.FROM_TEMPLATE) } } - override fun getChooserTitle() = KotlinIdeaCoreBundle.message("implement.members.handler.title") + override fun getChooserTitle() = KotlinBundle.message("implement.members.handler.title") - override fun getNoMembersFoundHint() = KotlinIdeaCoreBundle.message("implement.members.handler.no.members.hint") + override fun getNoMembersFoundHint() = KotlinBundle.message("implement.members.handler.no.members.hint") override fun getText() = familyName - override fun getFamilyName() = KotlinIdeaCoreBundle.message("implement.members.handler.family") + override fun getFamilyName() = KotlinBundle.message("implement.members.handler.family") override fun isAvailable(project: Project, editor: Editor, file: PsiFile) = isValidFor(editor, file) } class ImplementAsConstructorParameter : ImplementMembersHandler() { - override fun getText() = KotlinIdeaCoreBundle.message("action.text.implement.as.constructor.parameters") + override fun getText() = KotlinBundle.message("action.text.implement.as.constructor.parameters") override fun isValidForClass(classOrObject: KtClassOrObject): Boolean { if (classOrObject !is KtClass || classOrObject is KtEnumEntry || classOrObject.isInterface()) return false @@ -67,6 +67,6 @@ class ImplementAsConstructorParameter : ImplementMembersHandler() { override fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection { return OverrideResolver.getMissingImplementations(descriptor) .filterIsInstance() - .map { OverrideMemberChooserObject.create(project, it, it, OverrideMemberChooserObject.BodyType.FROM_TEMPLATE, true) } + .map { OverrideMemberChooserObject.create(project, it, it, BodyType.FROM_TEMPLATE, true) } } } \ No newline at end of file diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt index fa616c801f3..3df7465bb01 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt @@ -17,7 +17,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.core.TemplateKind import org.jetbrains.kotlin.idea.core.getFunctionBodyTextFromTemplate -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject.BodyType.* +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType.* import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject import org.jetbrains.kotlin.idea.j2k.IdeaDocCommentConverter import org.jetbrains.kotlin.idea.kdoc.KDocElementFactory @@ -40,15 +40,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden import org.jetbrains.kotlin.util.findCallableMemberBySignature interface OverrideMemberChooserObject : ClassMember { - sealed class BodyType(val requiresReturn: Boolean = true) { - object NO_BODY : BodyType() - object EMPTY_OR_TEMPLATE : BodyType(requiresReturn = false) - object FROM_TEMPLATE : BodyType(requiresReturn = false) - object SUPER : BodyType() - object QUALIFIED_SUPER : BodyType() - - class Delegate(val receiverName: String) : BodyType() - } val descriptor: CallableMemberDescriptor val immediateSuper: CallableMemberDescriptor @@ -111,12 +102,6 @@ interface OverrideMemberChooserObject : ClassMember { } } -enum class MemberGenerateMode { - OVERRIDE, - ACTUAL, - EXPECT -} - fun OverrideMemberChooserObject.generateMember( targetClass: KtClassOrObject, copyDoc: Boolean @@ -271,7 +256,7 @@ private fun generateProperty( project: Project, descriptor: PropertyDescriptor, renderer: DescriptorRenderer, - bodyType: OverrideMemberChooserObject.BodyType, + bodyType: BodyType, forceOverride: Boolean ): KtProperty { val newDescriptor = descriptor.wrap(forceOverride) @@ -308,7 +293,7 @@ private fun generateFunction( project: Project, descriptor: FunctionDescriptor, renderer: DescriptorRenderer, - bodyType: OverrideMemberChooserObject.BodyType, + bodyType: BodyType, forceOverride: Boolean ): KtFunction { val newDescriptor = descriptor.wrap(forceOverride) @@ -336,13 +321,13 @@ private fun generateFunction( } } -private fun OverrideMemberChooserObject.BodyType.effectiveBodyType(canBeEmpty: Boolean): OverrideMemberChooserObject.BodyType = +private fun BodyType.effectiveBodyType(canBeEmpty: Boolean): BodyType = if (!canBeEmpty && this == EMPTY_OR_TEMPLATE) FROM_TEMPLATE else this fun generateUnsupportedOrSuperCall( project: Project, descriptor: CallableMemberDescriptor, - bodyType: OverrideMemberChooserObject.BodyType, + bodyType: BodyType, canBeEmpty: Boolean = true ): String { when (bodyType.effectiveBodyType(canBeEmpty)) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMembersHandler.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMembersHandler.kt index d5aea0122db..97537e54905 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMembersHandler.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMembersHandler.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import java.util.* -class OverrideMembersHandler(private val preferConstructorParameters: Boolean = false) : OverrideImplementMembersHandler() { +class OverrideMembersHandler(private val preferConstructorParameters: Boolean = false) : GenerateMembersHandler() { override fun collectMembersToGenerate(descriptor: ClassDescriptor, project: Project): Collection { val result = ArrayList() for (member in descriptor.unsubstitutedMemberScope.getContributedDescriptors()) { @@ -56,13 +56,13 @@ class OverrideMembersHandler(private val preferConstructorParameters: Boolean = val bodyType = when { descriptor.kind == ClassKind.INTERFACE && realSuper.builtIns.isMemberOfAny(realSuper) -> - OverrideMemberChooserObject.BodyType.NO_BODY + BodyType.NO_BODY immediateSuperToUse.modality == Modality.ABSTRACT -> - OverrideMemberChooserObject.BodyType.FROM_TEMPLATE + BodyType.FROM_TEMPLATE realSupersToUse.size == 1 -> - OverrideMemberChooserObject.BodyType.SUPER + BodyType.SUPER else -> - OverrideMemberChooserObject.BodyType.QUALIFIED_SUPER + BodyType.QUALIFIED_SUPER } result.add( diff --git a/idea/idea-core/resources/messages/KotlinIdeaCoreBundle.properties b/idea/idea-frontend-independent/resources-en/messages/KotlinIdeaCoreBundle.properties similarity index 100% rename from idea/idea-core/resources/messages/KotlinIdeaCoreBundle.properties rename to idea/idea-frontend-independent/resources-en/messages/KotlinIdeaCoreBundle.properties diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/generateUtil.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/generateUtil.kt similarity index 70% rename from idea/idea-core/src/org/jetbrains/kotlin/idea/core/generateUtil.kt rename to idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/generateUtil.kt index fc513c5cc02..713bead0040 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/generateUtil.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/generateUtil.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -9,17 +9,14 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.ScrollType import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.* -import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.SmartList -import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.allChildren import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.utils.ifEmpty import kotlin.math.min fun moveCaretIntoGeneratedElement(editor: Editor, element: PsiElement) { @@ -200,75 +197,55 @@ private fun removeAfterOffset(offset: Int, whiteSpace: PsiWhiteSpace): PsiElemen return whiteSpace } -@JvmOverloads fun insertMembersAfter( editor: Editor?, classOrObject: KtClassOrObject, members: Collection, anchor: PsiElement? = null, - getAnchor: (KtDeclaration) -> PsiElement? = { null } -): List { + getAnchor: (KtDeclaration) -> PsiElement? = { null }, +): List> { members.ifEmpty { return emptyList() } - val project = classOrObject.project - return runWriteAction { - val insertedMembers = SmartList>() - fun insertedMembersElements() = insertedMembers.mapNotNull { it.element } + val insertedMembers = SmartList>() + val (parameters, otherMembers) = members.partition { it is KtParameter } - val (parameters, otherMembers) = members.partition { it is KtParameter } + parameters.mapNotNullTo(insertedMembers) { + if (classOrObject !is KtClass) return@mapNotNullTo null - parameters.mapNotNullTo(insertedMembers) { - if (classOrObject !is KtClass) return@mapNotNullTo null + @Suppress("UNCHECKED_CAST") + SmartPointerManager.createPointer( + classOrObject.createPrimaryConstructorParameterListIfAbsent().addParameter(it as KtParameter) as T + ) + } + + if (otherMembers.isNotEmpty()) { + val body = classOrObject.getOrCreateBody() + + var afterAnchor = anchor ?: findInsertAfterAnchor(editor, body) ?: return emptyList() + otherMembers.mapTo(insertedMembers) { + afterAnchor = getAnchor(it) ?: afterAnchor + + if (classOrObject is KtClass && classOrObject.isEnum()) { + val enumEntries = classOrObject.declarations.filterIsInstance() + val bound = (enumEntries.lastOrNull() ?: classOrObject.allChildren.firstOrNull { element -> + element.node.elementType == KtTokens.SEMICOLON + }) + if (it !is KtEnumEntry) { + if (bound != null && afterAnchor.startOffset <= bound.startOffset) { + afterAnchor = bound + } + } else if (bound == null && body.declarations.isNotEmpty()) { + afterAnchor = body.lBrace!! + } else if (bound != null && afterAnchor.startOffset > bound.startOffset) { + afterAnchor = bound.prevSibling!! + } + } + + it.removeModifier(KtTokens.EXTERNAL_KEYWORD) @Suppress("UNCHECKED_CAST") - SmartPointerManager.createPointer( - classOrObject.createPrimaryConstructorParameterListIfAbsent().addParameter(it as KtParameter) as T - ) + SmartPointerManager.createPointer((body.addAfter(it, afterAnchor) as T).apply { afterAnchor = this }) } - - if (otherMembers.isNotEmpty()) { - val body = classOrObject.getOrCreateBody() - - var afterAnchor = anchor ?: findInsertAfterAnchor(editor, body) ?: return@runWriteAction emptyList() - otherMembers.mapTo(insertedMembers) { - afterAnchor = getAnchor(it) ?: afterAnchor - - if (classOrObject is KtClass && classOrObject.isEnum()) { - val enumEntries = classOrObject.declarations.filterIsInstance() - val bound = (enumEntries.lastOrNull() ?: classOrObject.allChildren.firstOrNull { element -> - element.node.elementType == KtTokens.SEMICOLON - }) - if (it !is KtEnumEntry) { - if (bound != null && afterAnchor.startOffset <= bound.startOffset) { - afterAnchor = bound - } - } else if (bound == null && body.declarations.isNotEmpty()) { - afterAnchor = body.lBrace!! - } else if (bound != null && afterAnchor.startOffset > bound.startOffset) { - afterAnchor = bound.prevSibling!! - } - } - - it.removeModifier(KtTokens.EXTERNAL_KEYWORD) - - @Suppress("UNCHECKED_CAST") - SmartPointerManager.createPointer((body.addAfter(it, afterAnchor) as T).apply { afterAnchor = this }) - } - } - - ShortenReferences.DEFAULT.process(insertedMembersElements()) - - val firstElement = insertedMembersElements().firstOrNull() ?: return@runWriteAction emptyList() - if (editor != null) { - moveCaretIntoGeneratedElement(editor, firstElement) - } - - val codeStyleManager = CodeStyleManager.getInstance(project) - insertedMembersElements().forEach { codeStyleManager.reformat(it) } - - insertedMembersElements().toList() } -} -fun insertMember(editor: Editor?, classOrObject: KtClassOrObject, declaration: T, anchor: PsiElement? = null): T { - return insertMembersAfter(editor, classOrObject, listOf(declaration), anchor).single() + return insertedMembers } diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/AbstractGenerateMembersHandler.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/AbstractGenerateMembersHandler.kt new file mode 100644 index 00000000000..df125b114c8 --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/AbstractGenerateMembersHandler.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.core.overrideImplement + +import com.intellij.codeInsight.FileModificationService +import com.intellij.codeInsight.generation.ClassMember +import com.intellij.codeInsight.hint.HintManager +import com.intellij.ide.util.MemberChooser +import com.intellij.lang.LanguageCodeInsightActionHandler +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.DialogWrapper +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType + +abstract class AbstractGenerateMembersHandler : LanguageCodeInsightActionHandler { + + abstract fun collectMembersToGenerate(classOrObject: KtClassOrObject): Collection + + protected abstract fun getChooserTitle(): String + + protected abstract fun getNoMembersFoundHint(): String + + protected abstract fun generateMembers( + editor: Editor, + classOrObject: KtClassOrObject, + selectedElements: Collection, + copyDoc: Boolean + ) + + protected open fun isValidForClass(classOrObject: KtClassOrObject) = true + + private fun showOverrideImplementChooser( + project: Project, + members: Collection + ): MemberChooser? { + @Suppress("UNCHECKED_CAST") + val memberArray = members.toTypedArray() as Array + val chooser = MemberChooser(memberArray, true, true, project) + chooser.title = getChooserTitle() + chooser.show() + if (chooser.exitCode != DialogWrapper.OK_EXIT_CODE) return null + return chooser + } + + 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() + return classOrObject != null && isValidForClass(classOrObject) + } + + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + invoke(project, editor, file, implementAll = ApplicationManager.getApplication().isUnitTestMode) + } + + fun invoke(project: Project, editor: Editor, file: PsiFile, implementAll: Boolean) { + val elementAtCaret = file.findElementAt(editor.caretModel.offset) + val classOrObject = elementAtCaret?.getNonStrictParentOfType() ?: return + + if (!FileModificationService.getInstance().prepareFileForWrite(file)) return + + val members = collectMembersToGenerate(classOrObject) + if (members.isEmpty() && !implementAll) { + HintManager.getInstance().showErrorHint(editor, getNoMembersFoundHint()) + return + } + + val copyDoc: Boolean + val selectedElements: Collection + if (implementAll) { + selectedElements = members + copyDoc = false + } else { + val chooser = showOverrideImplementChooser(project, members) ?: return + selectedElements = chooser.selectedElements ?: return + copyDoc = chooser.isCopyJavadoc + } + if (selectedElements.isEmpty()) return + + PsiDocumentManager.getInstance(project).commitAllDocuments() + + generateMembers(editor, classOrObject, selectedElements, copyDoc) + } + + override fun startInWriteAction(): Boolean = false +} \ No newline at end of file diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/BodyType.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/BodyType.kt new file mode 100644 index 00000000000..a8fc319b429 --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/BodyType.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.core.overrideImplement + +sealed class BodyType(val requiresReturn: Boolean = true) { + object NO_BODY : BodyType() + object EMPTY_OR_TEMPLATE : BodyType(requiresReturn = false) + object FROM_TEMPLATE : BodyType(requiresReturn = false) + object SUPER : BodyType() + object QUALIFIED_SUPER : BodyType() + + class Delegate(val receiverName: String) : BodyType() +} \ No newline at end of file diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/MemberGenerateMode.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/MemberGenerateMode.kt new file mode 100644 index 00000000000..1abcaf6014e --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/overrideImplement/MemberGenerateMode.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.core.overrideImplement + +enum class MemberGenerateMode { + OVERRIDE, + ACTUAL, + EXPECT +} \ No newline at end of file diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/templates.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/templates.kt similarity index 97% rename from idea/idea-core/src/org/jetbrains/kotlin/idea/core/templates.kt rename to idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/templates.kt index fa8cd1594c2..5e86ffa546d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/templates.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/templates.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt similarity index 90% rename from idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt rename to idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt index 3227b0d1e1c..19e435c9c3e 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/core/util/KotlinIdeaCoreBundle.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt similarity index 93% rename from idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt rename to idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt index 869595ed7be..e1fad80d1cf 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/j2k/DocCommentConverter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt similarity index 99% rename from idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt rename to idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt index edeb13e651a..5a0a269edc5 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt index 1027df0fd70..1670892fae1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsAndHashcodeAction.kt @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.core.CollectingNameValidator import org.jetbrains.kotlin.idea.core.KotlinNameSuggester -import org.jetbrains.kotlin.idea.core.insertMembersAfter +import org.jetbrains.kotlin.idea.core.insertMembersAfterAndReformat import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.platform import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -326,6 +326,6 @@ class KotlinGenerateEqualsAndHashcodeAction : KotlinGenerateMemberActionBase() ?: lastOrNull() } - return insertMembersAfter(editor, targetClass, prototypes, anchor) + return insertMembersAfterAndReformat(editor, targetClass, prototypes, anchor) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateSecondaryConstructorAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateSecondaryConstructorAction.kt index a357503612d..5c527240ac5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateSecondaryConstructorAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateSecondaryConstructorAction.kt @@ -124,7 +124,7 @@ class KotlinGenerateSecondaryConstructorAction : KotlinGenerateMemberActionBase< return emptyList() } - insertMembersAfter(editor, targetClass, prototypes, findAnchor()) + insertMembersAfterAndReformat(editor, targetClass, prototypes, findAnchor()) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt index 5686ec10a9b..b4b8d43f060 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.core.insertMember -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject.BodyType +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType import org.jetbrains.kotlin.idea.core.overrideImplement.generateUnsupportedOrSuperCall import org.jetbrains.kotlin.idea.j2k.j2k import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.setupEditorSelection diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateToStringAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateToStringAction.kt index 27ee86e3df6..ef03485aa5d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateToStringAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateToStringAction.kt @@ -34,7 +34,7 @@ import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde -import org.jetbrains.kotlin.idea.core.insertMembersAfter +import org.jetbrains.kotlin.idea.core.insertMembersAfterAndReformat import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.psi.* @@ -202,6 +202,6 @@ class KotlinGenerateToStringAction : KotlinGenerateMemberActionBase() ?: lastOrNull() } - return insertMembersAfter(editor, targetClass, listOf(prototype), anchor) + return insertMembersAfterAndReformat(editor, targetClass, listOf(prototype), anchor) } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/utils.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/utils.kt index 28f7b54f0e5..03583b897ec 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/utils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/utils.kt @@ -11,6 +11,7 @@ import com.intellij.openapi.ui.Messages import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject import org.jetbrains.kotlin.idea.core.overrideImplement.generateMember import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -70,6 +71,6 @@ fun confirmMemberRewrite(targetClass: KtClass, vararg descriptors: FunctionDescr fun generateFunctionSkeleton(descriptor: FunctionDescriptor, targetClass: KtClassOrObject): KtNamedFunction { return OverrideMemberChooserObject - .create(targetClass.project, descriptor, descriptor, OverrideMemberChooserObject.BodyType.FROM_TEMPLATE) + .create(targetClass.project, descriptor, descriptor, BodyType.FROM_TEMPLATE) .generateMember(targetClass, false) as KtNamedFunction } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt index 27e84b8c542..87471fce4a6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt @@ -30,7 +30,8 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideImplementMembersHandler +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType +import org.jetbrains.kotlin.idea.core.overrideImplement.GenerateMembersHandler import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject import org.jetbrains.kotlin.idea.core.util.runSynchronouslyWithProgress import org.jetbrains.kotlin.idea.refactoring.isAbstract @@ -120,10 +121,10 @@ abstract class ImplementAbstractMemberIntentionBase : SelfTargetingRangeIntentio member.project, descriptorToImplement, descriptorToImplement, - OverrideMemberChooserObject.BodyType.FROM_TEMPLATE, + BodyType.FROM_TEMPLATE, preferConstructorParameters ) - OverrideImplementMembersHandler.generateMembers(editor, targetClass, listOf(chooserObject), false) + GenerateMembersHandler.generateMembers(editor, targetClass, listOf(chooserObject), false) } private fun implementInJavaClass(member: KtNamedDeclaration, targetClass: PsiClass) { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakePrivateAndOverrideMemberFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakePrivateAndOverrideMemberFix.kt index 7fcf0d80f82..0017b7e6053 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakePrivateAndOverrideMemberFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakePrivateAndOverrideMemberFix.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideImplementMembersHandler +import org.jetbrains.kotlin.idea.core.overrideImplement.GenerateMembersHandler import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.lexer.KtTokens @@ -60,7 +60,7 @@ class MakePrivateAndOverrideMemberFix( if (makePrivate) { element.addModifier(KtTokens.PRIVATE_KEYWORD) } - OverrideImplementMembersHandler.generateMembers(editor, containingClassOrObject, listOf(memberToOverride), false) + GenerateMembersHandler.generateMembers(editor, containingClassOrObject, listOf(memberToOverride), false) } object AccidentalOverrideFactory : KotlinSingleIntentionActionFactory() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyOverrideExplicitlyFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyOverrideExplicitlyFix.kt index 53574d9c5f4..4ae933d2aed 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyOverrideExplicitlyFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/SpecifyOverrideExplicitlyFix.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.core.ShortenReferences +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject import org.jetbrains.kotlin.idea.core.overrideImplement.generateMember import org.jetbrains.kotlin.lexer.KtTokens @@ -72,7 +73,7 @@ class SpecifyOverrideExplicitlyFix( val overrideMemberChooserObject = OverrideMemberChooserObject.create( project, delegatedDescriptor, overriddenDescriptor, - OverrideMemberChooserObject.BodyType.Delegate(delegateTargetDescriptor.name.asString()) + BodyType.Delegate(delegateTargetDescriptor.name.asString()) ) val member = overrideMemberChooserObject.generateMember(element, copyDoc = false) val insertedMember = element.addDeclaration(member) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt index c28eeebe301..cbd67a43c8f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/expectactual/ExpectActualUtils.kt @@ -20,8 +20,8 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.findOrCreateDirectoryForPackage import org.jetbrains.kotlin.idea.core.getFqNameWithImplicitPrefix import org.jetbrains.kotlin.idea.core.overrideImplement.MemberGenerateMode -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject.BodyType.EMPTY_OR_TEMPLATE -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject.BodyType.NO_BODY +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType.EMPTY_OR_TEMPLATE +import org.jetbrains.kotlin.idea.core.overrideImplement.BodyType.NO_BODY import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject.Companion.create import org.jetbrains.kotlin.idea.core.overrideImplement.generateMember import org.jetbrains.kotlin.idea.core.overrideImplement.makeNotActual diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.kt index b12842733a4..57c5c89cb05 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.kt @@ -19,7 +19,7 @@ import com.intellij.util.SmartList import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler -import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideImplementMembersHandler +import org.jetbrains.kotlin.idea.core.overrideImplement.GenerateMembersHandler import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMembersHandler import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase @@ -88,33 +88,33 @@ abstract class AbstractOverrideImplementTest : KotlinLightCodeInsightFixtureTest myFixture.checkResultByFile(getTestName(true) + "/foo/JavaClass.java.after") } - private fun doFileTest(handler: OverrideImplementMembersHandler, memberToOverride: String? = null) { + private fun doFileTest(handler: GenerateMembersHandler, memberToOverride: String? = null) { myFixture.configureByFile(getTestName(true) + ".kt") doOverrideImplement(handler, memberToOverride) checkResultByFile(getTestName(true) + ".kt.after") } - private fun doMultiFileTest(handler: OverrideImplementMembersHandler) { + private fun doMultiFileTest(handler: GenerateMembersHandler) { myFixture.configureByFile(getTestName(true) + ".kt") doMultiOverrideImplement(handler) checkResultByFile(getTestName(true) + ".kt.after") } - private fun doDirectoryTest(handler: OverrideImplementMembersHandler, memberToOverride: String? = null) { + private fun doDirectoryTest(handler: GenerateMembersHandler, memberToOverride: String? = null) { myFixture.copyDirectoryToProject(getTestName(true), "") myFixture.configureFromTempProjectFile("foo/Impl.kt") doOverrideImplement(handler, memberToOverride) checkResultByFile(getTestName(true) + "/foo/Impl.kt.after") } - private fun doMultiDirectoryTest(handler: OverrideImplementMembersHandler) { + private fun doMultiDirectoryTest(handler: GenerateMembersHandler) { myFixture.copyDirectoryToProject(getTestName(true), "") myFixture.configureFromTempProjectFile("foo/Impl.kt") doMultiOverrideImplement(handler) checkResultByFile(getTestName(true) + "/foo/Impl.kt.after") } - private fun doOverrideImplement(handler: OverrideImplementMembersHandler, memberToOverride: String?) { + private fun doOverrideImplement(handler: GenerateMembersHandler, memberToOverride: String?) { val elementAtCaret = myFixture.file.findElementAt(myFixture.editor.caretModel.offset) val classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, KtClassOrObject::class.java) ?: error("Caret should be inside class or object") @@ -138,7 +138,7 @@ abstract class AbstractOverrideImplementTest : KotlinLightCodeInsightFixtureTest performGenerateCommand(classOrObject, listOf(singleToOverride)) } - private fun doMultiOverrideImplement(handler: OverrideImplementMembersHandler) { + private fun doMultiOverrideImplement(handler: GenerateMembersHandler) { val elementAtCaret = myFixture.file.findElementAt(myFixture.editor.caretModel.offset) val classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, KtClassOrObject::class.java) ?: error("Caret should be inside class or object") @@ -167,7 +167,7 @@ abstract class AbstractOverrideImplementTest : KotlinLightCodeInsightFixtureTest try { val copyDoc = InTextDirectivesUtils.isDirectiveDefined(classOrObject.containingFile.text, "// COPY_DOC") myFixture.project.executeWriteCommand("") { - OverrideImplementMembersHandler.generateMembers(myFixture.editor, classOrObject, selectedElements, copyDoc) + GenerateMembersHandler.generateMembers(myFixture.editor, classOrObject, selectedElements, copyDoc) } } catch (throwable: Throwable) { throw rethrow(throwable)