Suggest dialog if all members without actual modifier
Relates to #KT-31476
This commit is contained in:
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.idea.core.util.DescriptorMemberChooserObject
|
|||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
||||||
import org.jetbrains.kotlin.idea.util.allowedValOrVar
|
import org.jetbrains.kotlin.idea.util.allowedValOrVar
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.idea.util.isEffectivelyActual
|
|
||||||
import org.jetbrains.kotlin.idea.util.liftToExpected
|
import org.jetbrains.kotlin.idea.util.liftToExpected
|
||||||
import org.jetbrains.kotlin.idea.util.module
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -111,19 +110,21 @@ class CreateExpectedClassFix(
|
|||||||
outerExpectedClass: KtClassOrObject?,
|
outerExpectedClass: KtClassOrObject?,
|
||||||
commonModule: Module
|
commonModule: Module
|
||||||
) : CreateExpectedFix<KtClassOrObject>(klass, outerExpectedClass, commonModule, block@{ project, element ->
|
) : CreateExpectedFix<KtClassOrObject>(klass, outerExpectedClass, commonModule, block@{ project, element ->
|
||||||
val originalCollection = element.collectDeclarations(false).filter(KtDeclaration::canAddActualModifier).toList()
|
val originalElements = element.collectDeclarations(false).filter(KtDeclaration::canAddActualModifier).toList()
|
||||||
val collection = originalCollection.filterNot(KtDeclaration::isAlwaysActual)
|
val members = originalElements.filterNot(KtDeclaration::isAlwaysActual)
|
||||||
val selectedElements = when {
|
val selectedElements = when {
|
||||||
ApplicationManager.getApplication().isUnitTestMode -> collection.filter { it.isEffectivelyActual(false) }
|
members.all(KtDeclaration::hasActualModifier) -> originalElements
|
||||||
collection.any(KtDeclaration::hasActualModifier) && collection.any { !it.hasActualModifier() } -> {
|
ApplicationManager.getApplication().isUnitTestMode -> members.filter(KtDeclaration::hasActualModifier)
|
||||||
|
else -> {
|
||||||
val prefix = klass.fqName?.asString()?.plus(".") ?: ""
|
val prefix = klass.fqName?.asString()?.plus(".") ?: ""
|
||||||
chooseMembers(project, collection, prefix) ?: return@block null
|
chooseMembers(project, members, prefix) ?: return@block null
|
||||||
}
|
}
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.executeWriteCommand("Repair actual members") {
|
if (originalElements.isNotEmpty()) {
|
||||||
repairActualModifiers(originalCollection, selectedElements)
|
project.executeWriteCommand("Repair actual members") {
|
||||||
|
repairActualModifiers(originalElements, selectedElements)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateClassOrObject(project, true, element, listOfNotNull(outerExpectedClass))
|
generateClassOrObject(project, true, element, listOfNotNull(outerExpectedClass))
|
||||||
@@ -140,6 +141,11 @@ private fun KtDeclaration.canAddActualModifier() = when (this) {
|
|||||||
*/
|
*/
|
||||||
private fun chooseMembers(project: Project, collection: Collection<KtDeclaration>, prefixToRemove: String): List<KtDeclaration>? {
|
private fun chooseMembers(project: Project, collection: Collection<KtDeclaration>, prefixToRemove: String): List<KtDeclaration>? {
|
||||||
val classMembers = collection.map { Member(prefixToRemove, it, it.resolveToDescriptorIfAny()!!) }
|
val classMembers = collection.map { Member(prefixToRemove, it, it.resolveToDescriptorIfAny()!!) }
|
||||||
|
val filter = if (collection.any(KtDeclaration::hasActualModifier)) {
|
||||||
|
{ declaration: KtDeclaration -> declaration.hasActualModifier() }
|
||||||
|
} else {
|
||||||
|
{ true }
|
||||||
|
}
|
||||||
return MemberChooser(
|
return MemberChooser(
|
||||||
classMembers.toTypedArray(),
|
classMembers.toTypedArray(),
|
||||||
true,
|
true,
|
||||||
@@ -148,7 +154,7 @@ private fun chooseMembers(project: Project, collection: Collection<KtDeclaration
|
|||||||
).run {
|
).run {
|
||||||
title = "Choose actual members"
|
title = "Choose actual members"
|
||||||
setCopyJavadocVisible(false)
|
setCopyJavadocVisible(false)
|
||||||
selectElements(classMembers.filter { (it.element as KtDeclaration).hasActualModifier() }.toTypedArray())
|
selectElements(classMembers.filter { filter((it.element as KtDeclaration)) }.toTypedArray())
|
||||||
show()
|
show()
|
||||||
if (!isOK) null else selectedElements?.map { it.element as KtDeclaration }.orEmpty()
|
if (!isOK) null else selectedElements?.map { it.element as KtDeclaration }.orEmpty()
|
||||||
}
|
}
|
||||||
@@ -175,25 +181,24 @@ private fun KtClassOrObject.collectDeclarations(withSelf: Boolean = true): Seque
|
|||||||
|
|
||||||
private fun repairActualModifiers(
|
private fun repairActualModifiers(
|
||||||
originalElements: Collection<KtDeclaration>,
|
originalElements: Collection<KtDeclaration>,
|
||||||
// If null, all class declarations are actual
|
selectedElements: Collection<KtDeclaration>
|
||||||
selectedElements: Collection<KtDeclaration>?
|
|
||||||
) {
|
) {
|
||||||
if (selectedElements == null)
|
if (originalElements.size == selectedElements.size)
|
||||||
for (original in originalElements) {
|
for (original in originalElements) {
|
||||||
original.recursivelyMakeActual()
|
original.makeActualWithParents()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (original in originalElements) {
|
for (original in originalElements) {
|
||||||
if (original.isAlwaysActual() || original in selectedElements)
|
if (original.isAlwaysActual() || original in selectedElements)
|
||||||
original.recursivelyMakeActual()
|
original.makeActualWithParents()
|
||||||
else
|
else
|
||||||
original.makeNotActual()
|
original.makeNotActual()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private tailrec fun KtDeclaration.recursivelyMakeActual() {
|
private tailrec fun KtDeclaration.makeActualWithParents() {
|
||||||
makeActual()
|
makeActual()
|
||||||
containingClassOrObject?.takeUnless(KtDeclaration::hasActualModifier)?.recursivelyMakeActual()
|
containingClassOrObject?.takeUnless(KtDeclaration::hasActualModifier)?.makeActualWithParents()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtDeclaration.isAlwaysActual(): Boolean = when (this) {
|
private fun KtDeclaration.isAlwaysActual(): Boolean = when (this) {
|
||||||
|
|||||||
Reference in New Issue
Block a user