From c9781f50149a88baac6a04456464f499686ba9e1 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 11 Jan 2017 12:55:11 +0300 Subject: [PATCH] Extract Interface/Pull Up: Disable "Make abstract" and assume it to be true for primary constructor parameter when moving to an interface #KT-15643 Fixed --- ChangeLog.md | 1 + .../extractClass/ui/KotlinExtractInterfaceDialog.kt | 8 ++++++-- .../kotlin/idea/refactoring/kotlinRefactoringUtil.kt | 2 ++ .../kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt | 8 ++++++++ .../kotlin/idea/refactoring/pullUp/pullUpUtils.kt | 1 + 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 5e536b4e1db..aa9e5e8d4e5 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -477,6 +477,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-15563`](https://youtrack.jetbrains.com/issue/KT-15563) Override Members: Allow overriding virtual synthetic members (e.g. equals(), hashCode(), toString(), etc.) in data classes - [`KT-15355`](https://youtrack.jetbrains.com/issue/KT-15355) Extract Interface: Disable "Make abstract" and assume it to be true for abstract members of an interface - [`KT-15353`](https://youtrack.jetbrains.com/issue/KT-15353) Extract Superclass/Interface: Allow extracting class with special name (and quotes) +- [`KT-15643`](https://youtrack.jetbrains.com/issue/KT-15643) Extract Interface/Pull Up: Disable "Make abstract" and assume it to be true for primary constructor parameter when moving to an interface #### Intention actions, inspections and quickfixes diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractClass/ui/KotlinExtractInterfaceDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractClass/ui/KotlinExtractInterfaceDialog.kt index bbdd65887a3..af620aa5e54 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractClass/ui/KotlinExtractInterfaceDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractClass/ui/KotlinExtractInterfaceDialog.kt @@ -22,6 +22,7 @@ import com.intellij.refactoring.JavaRefactoringSettings import com.intellij.refactoring.RefactoringBundle import org.jetbrains.kotlin.idea.refactoring.introduce.extractClass.ExtractSuperInfo import org.jetbrains.kotlin.idea.refactoring.introduce.extractClass.KotlinExtractInterfaceHandler +import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo import org.jetbrains.kotlin.idea.refactoring.memberInfo.extractClassMembers import org.jetbrains.kotlin.idea.refactoring.pullUp.getInterfaceContainmentVerifier @@ -68,11 +69,14 @@ class KotlinExtractInterfaceDialog( if (!super.isAbstractEnabled(memberInfo)) return false val member = memberInfo.member if (member.isAbstractInInterface(originalClass)) return false + if (member.isConstructorDeclaredProperty()) return false return member is KtNamedFunction || (member is KtProperty && !member.mustBeAbstractInInterface()) || member is KtParameter } - override fun isAbstractWhenDisabled(member: KotlinMemberInfo) = - member.member is KtProperty || member.member.isAbstractInInterface(originalClass) + override fun isAbstractWhenDisabled(memberInfo: KotlinMemberInfo): Boolean { + val member = memberInfo.member + return member is KtProperty || member.isAbstractInInterface(originalClass) || member.isConstructorDeclaredProperty() + } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index 6b81ced05b2..30df88c435e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -726,6 +726,8 @@ fun KtNamedDeclaration.isAbstract(): Boolean { } } +fun KtNamedDeclaration.isConstructorDeclaredProperty() = this is KtParameter && ownerFunction is KtPrimaryConstructor && hasValOrVar() + fun replaceListPsiAndKeepDelimiters( originalList: ListType, newList: ListType, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt index 8dfbbf0d702..61512e4c519 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/KotlinPullUpDialog.kt @@ -27,6 +27,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel import com.intellij.refactoring.memberPullUp.PullUpProcessor import com.intellij.refactoring.util.DocCommentPolicy import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty import org.jetbrains.kotlin.idea.refactoring.isCompanionMemberOf import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass import org.jetbrains.kotlin.idea.refactoring.memberInfo.* @@ -57,6 +58,10 @@ class KotlinPullUpDialog( ) { private var lastSuperClass: PsiNamedElement? = null + private fun KtNamedDeclaration.isConstructorParameterWithInterfaceTarget(targetClass: PsiNamedElement): Boolean { + return targetClass is KtClass && targetClass.isInterface() && isConstructorDeclaredProperty() + } + // Abstract members remain abstract override fun isFixedAbstract(memberInfo: KotlinMemberInfo?) = true @@ -78,6 +83,7 @@ class KotlinPullUpDialog( member.hasModifier(KtTokens.EXTERNAL_KEYWORD) || member.hasModifier(KtTokens.LATEINIT_KEYWORD)) return false if (member.isAbstractInInterface(sourceClass)) return false + if (member.isConstructorParameterWithInterfaceTarget(superClass)) return false if (member.isCompanionMemberOf(sourceClass)) return false if (!superClass.isInterface()) return true @@ -86,9 +92,11 @@ class KotlinPullUpDialog( } override fun isAbstractWhenDisabled(memberInfo: KotlinMemberInfo): Boolean { + val superClass = superClass val member = memberInfo.member if (member.isCompanionMemberOf(sourceClass)) return false if (member.isAbstractInInterface(sourceClass)) return true + if (superClass != null && member.isConstructorParameterWithInterfaceTarget(superClass)) return true return ((member is KtProperty || member is KtParameter) && superClass !is PsiClass) || (member is KtNamedFunction && superClass is PsiClass) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt index 35a18392735..112a0dfa2ea 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pullUp/pullUpUtils.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.refactoring.pullUp import com.intellij.psi.PsiClass import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiNamedElement import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor