expectActualUtil: introduce runCommandOnAllExpectAndActualDeclaration function

This commit is contained in:
Dmitry Gridin
2019-10-22 22:02:40 +07:00
parent 9aa49e61fe
commit 18aa9ffce8
2 changed files with 41 additions and 23 deletions
@@ -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<KtDeclaration> = when {
isExpectDeclaration() -> actualsForExpected() + this
hasActualModifier() -> liftToExpected()?.let { it.actualsForExpected() + it }.orEmpty()
fun KtDeclaration.collectAllExpectAndActualDeclaration(withSelf: Boolean = true): Set<KtDeclaration> = 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)
}
}
@@ -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? {