From 18aa9ffce8d4484dade493cfa8d8aaab53099b9b Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 22 Oct 2019 22:02:40 +0700 Subject: [PATCH] expectActualUtil: introduce `runCommandOnAllExpectAndActualDeclaration` function --- .../kotlin/idea/util/expectActualUtil.kt | 38 +++++++++++++++---- .../ChangeVisibilityModifierIntention.kt | 26 +++++-------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt index cab04b43631..d5ae533614f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/expectActualUtil.kt @@ -14,14 +14,14 @@ import org.jetbrains.kotlin.idea.caches.project.implementingDescriptors import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny import org.jetbrains.kotlin.idea.core.toDescriptor +import org.jetbrains.kotlin.idea.util.application.executeCommand +import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtConstructor import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.psiUtil.containingClass -import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier -import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier +import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -149,8 +149,32 @@ fun KtDeclaration.runOnExpectAndAllActuals(checkExpect: Boolean = true, useOnSel if (useOnSelf) f(this) } -fun KtDeclaration.collectAllExpectAndActualDeclaration(): Set = when { - isExpectDeclaration() -> actualsForExpected() + this - hasActualModifier() -> liftToExpected()?.let { it.actualsForExpected() + it }.orEmpty() +fun KtDeclaration.collectAllExpectAndActualDeclaration(withSelf: Boolean = true): Set = when { + isExpectDeclaration() -> actualsForExpected() + hasActualModifier() -> liftToExpected()?.let { it.actualsForExpected() + it - this }.orEmpty() else -> emptySet() +}.let { if (withSelf) it + this else it } + +fun KtDeclaration.runCommandOnAllExpectAndActualDeclaration( + command: String = "", + writeAction: Boolean = false, + withSelf: Boolean = true, + f: (KtDeclaration) -> Unit +) { + val (pointers, project) = runReadAction { + collectAllExpectAndActualDeclaration(withSelf).map { it.createSmartPointer() } to project + } + + fun process() { + for (pointer in pointers) { + val declaration = pointer.element ?: continue + f(declaration) + } + } + + if (writeAction) { + project.executeWriteCommand(command, ::process) + } else { + project.executeCommand(command, command = ::process) + } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt index 9488d8e68e4..80507a444e6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt @@ -23,12 +23,14 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.idea.core.* -import org.jetbrains.kotlin.idea.util.application.executeWriteCommand -import org.jetbrains.kotlin.idea.util.collectAllExpectAndActualDeclaration +import org.jetbrains.kotlin.idea.util.runCommandOnAllExpectAndActualDeclaration import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi.psiUtil.toVisibility +import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier +import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType open class ChangeVisibilityModifierIntention protected constructor( val modifier: KtModifierKeywordToken @@ -81,21 +83,13 @@ open class ChangeVisibilityModifierIntention protected constructor( } override fun applyTo(element: KtDeclaration, editor: Editor?) { - val pointers = element.collectAllExpectAndActualDeclaration().map { it.createSmartPointer() } - - val project = element.project - val factory = KtPsiFactory(project) - project.executeWriteCommand("Change visibility modifier") { - for (pointer in pointers) { - val declaration = pointer.element ?: continue - - declaration.setVisibility(modifier) - if (declaration is KtPropertyAccessor) { - declaration.modifierList?.nextSibling?.replace(factory.createWhiteSpace()) - } + val factory = KtPsiFactory(element) + element.runCommandOnAllExpectAndActualDeclaration("Change visibility modifier", writeAction = true) { + it.setVisibility(modifier) + if (it is KtPropertyAccessor) { + it.modifierList?.nextSibling?.replace(factory.createWhiteSpace()) } } - } private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? {