From aa4e87fc4b532dd8b4d5d2d1890526ee0a5dde57 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 3 Jul 2018 22:03:26 +0300 Subject: [PATCH] Refactor: Introduce MoveSource class --- .../MoveMemberOutOfObjectIntention.kt | 2 +- .../MoveMemberToCompanionObjectIntention.kt | 2 +- .../cutPaste/MoveDeclarationsProcessor.kt | 14 +++--- .../KotlinChangePackageRefactoring.kt | 15 +++--- .../MoveDeclarationToSeparateFileIntention.kt | 2 +- .../MoveDeclarationsDelegate.kt | 4 +- .../MoveDeclarationsDelegate.kt.173 | 4 +- .../MoveKotlinDeclarationsProcessor.kt | 49 ++++++++++++------- .../ui/MoveKotlinNestedClassesDialog.java | 11 ++++- ...KotlinNestedClassesToUpperLevelDialog.java | 6 +-- .../MoveKotlinTopLevelDeclarationsDialog.java | 4 +- .../MoveKotlinFileHandler.kt | 19 +++---- .../idea/refactoring/move/AbstractMoveTest.kt | 4 +- 13 files changed, 75 insertions(+), 61 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt index 8e394caaeb7..33f64c32172 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt @@ -50,7 +50,7 @@ abstract class MoveMemberOutOfObjectIntention(text: String) : SelfTargetingRange if (element is KtClassOrObject) { val moveDescriptor = MoveDeclarationsDescriptor( project, - listOf(element), + MoveSource(element), KotlinMoveTargetForExistingElement(destination), MoveDeclarationsDelegate.NestedClass() ) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt index 9d15714945f..80b6d002d93 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt @@ -271,7 +271,7 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention(), - moveTarget = KotlinDirectoryMoveTarget(newFqName, file.containingDirectory!!), - delegate = MoveDeclarationsDelegate.TopLevel, - scanEntireFile = true - ), - Mover.Idle // we don't need to move any declarations physically + MoveDeclarationsDescriptor( + project = project, + moveSource = MoveSource(file), + moveTarget = KotlinDirectoryMoveTarget(newFqName, file.containingDirectory!!), + delegate = MoveDeclarationsDelegate.TopLevel + ) ) val declarationUsages = project.runSynchronouslyWithProgress(RefactoringBundle.message("progress.text"), true) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt index ff0527d7838..fd9fe1caf49 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt @@ -102,7 +102,7 @@ class MoveDeclarationToSeparateFileIntention : } val descriptor = MoveDeclarationsDescriptor( project = project, - elementsToMove = listOf(element), + moveSource = MoveSource(element), moveTarget = moveTarget, delegate = MoveDeclarationsDelegate.TopLevel, searchInCommentsAndStrings = false, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt index 17b3dd8efd1..a47ff24b646 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt @@ -79,7 +79,7 @@ sealed class MoveDeclarationsDelegate { } override fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List { - val classToMove = descriptor.elementsToMove.singleOrNull() as? KtClass ?: return emptyList() + val classToMove = descriptor.moveSource.elementsToMove.singleOrNull() as? KtClass ?: return emptyList() return collectOuterInstanceReferences(classToMove) } @@ -152,7 +152,7 @@ sealed class MoveDeclarationsDelegate { if (outerInstanceParameterName == null) return val psiFactory = KtPsiFactory(descriptor.project) val newOuterInstanceRef = psiFactory.createExpression(outerInstanceParameterName) - val classToMove = descriptor.elementsToMove.singleOrNull() as? KtClass + val classToMove = descriptor.moveSource.elementsToMove.singleOrNull() as? KtClass for (usage in usages) { if (usage is MoveRenameUsageInfo) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt.173 b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt.173 index 75b792df31c..a00f51ac7ff 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt.173 +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt.173 @@ -79,7 +79,7 @@ sealed class MoveDeclarationsDelegate { } override fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List { - val classToMove = descriptor.elementsToMove.singleOrNull() as? KtClass ?: return emptyList() + val classToMove = descriptor.moveSource.elementsToMove.singleOrNull() as? KtClass ?: return emptyList() return collectOuterInstanceReferences(classToMove) } @@ -152,7 +152,7 @@ sealed class MoveDeclarationsDelegate { if (outerInstanceParameterName == null) return val psiFactory = KtPsiFactory(descriptor.project) val newOuterInstanceRef = psiFactory.createExpression(outerInstanceParameterName) - val classToMove = descriptor.elementsToMove.singleOrNull() as? KtClass + val classToMove = descriptor.moveSource.elementsToMove.singleOrNull() as? KtClass for (usage in usages) { if (usage is MoveRenameUsageInfo) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt index a6552f83fca..87866606a63 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt @@ -25,7 +25,6 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement import com.intellij.psi.PsiReference import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.search.SearchScope import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.move.MoveCallback @@ -90,26 +89,36 @@ interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration { } } } +} - object Idle : Mover { - override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement) = originalElement +sealed class MoveSource { + abstract val elementsToMove: Collection + + class Elements(override val elementsToMove: Collection) : MoveSource() + + class File(val file: KtFile) : MoveSource() { + override val elementsToMove: Collection + get() = file.declarations.filterIsInstance() } } +fun MoveSource(declaration: KtNamedDeclaration) = MoveSource.Elements(listOf(declaration)) +fun MoveSource(declarations: Collection) = MoveSource.Elements(declarations) +fun MoveSource(file: KtFile) = MoveSource.File(file) + class MoveDeclarationsDescriptor @JvmOverloads constructor( - val project: Project, - val elementsToMove: Collection, - val moveTarget: KotlinMoveTarget, - val delegate: MoveDeclarationsDelegate, - val searchInCommentsAndStrings: Boolean = true, - val searchInNonCode: Boolean = true, - val scanEntireFile: Boolean = false, - val deleteSourceFiles: Boolean = false, - val moveCallback: MoveCallback? = null, - val openInEditor: Boolean = false, - val allElementsToMove: List? = null, - val analyzeConflicts: Boolean = true, - val searchReferences: Boolean = true + val project: Project, + val moveSource: MoveSource, + val moveTarget: KotlinMoveTarget, + val delegate: MoveDeclarationsDelegate, + val searchInCommentsAndStrings: Boolean = true, + val searchInNonCode: Boolean = true, + val deleteSourceFiles: Boolean = false, + val moveCallback: MoveCallback? = null, + val openInEditor: Boolean = false, + val allElementsToMove: List? = null, + val analyzeConflicts: Boolean = true, + val searchReferences: Boolean = true ) class ConflictUsageInfo(element: PsiElement, val messages: Collection) : UsageInfo(element) @@ -144,7 +153,8 @@ class MoveKotlinDeclarationsProcessor( val project get() = descriptor.project private var nonCodeUsages: Array? = null - private val elementsToMove = descriptor.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) } + private val moveEntireFile = descriptor.moveSource is MoveSource.File + private val elementsToMove = descriptor.moveSource.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) } private val kotlinToLightElementsBySourceFile = elementsToMove .groupBy { it.containingKtFile } .mapValues { it.value.keysToMap { it.toLightElements().ifEmpty { listOf(it) } } } @@ -238,7 +248,7 @@ class MoveKotlinDeclarationsProcessor( val internalUsages = LinkedHashSet() val externalUsages = LinkedHashSet() - if (descriptor.scanEntireFile) { + if (moveEntireFile) { val changeInfo = ContainerChangeInfo( ContainerInfo.Package(sourceFile.packageFqName), descriptor.moveTarget.targetContainerFqName?.let { ContainerInfo.Package(it) } ?: ContainerInfo.UnknownPackage @@ -277,6 +287,7 @@ class MoveKotlinDeclarationsProcessor( val targetContainer = moveTarget.getOrCreateTargetPsi(declaration) ?: throw AssertionError("Couldn't create Kotlin file for: ${declaration::class.java}: ${declaration.text}") descriptor.delegate.preprocessDeclaration(descriptor, declaration) + if (moveEntireFile) return declaration return mover(declaration, targetContainer).apply { addToBeShortenedDescendantsToWaitingSet() } @@ -321,7 +332,7 @@ class MoveKotlinDeclarationsProcessor( } } - val internalUsageScopes: List = if (descriptor.scanEntireFile) { + val internalUsageScopes: List = if (moveEntireFile) { newDeclarations.asSequence().map { it.containingKtFile }.distinct().toList() } else { newDeclarations diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java index 3f46a8e748a..63e02bbc47f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesDialog.java @@ -49,6 +49,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo; import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel; import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable; import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*; +import static org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessorKt.MoveSource; import org.jetbrains.kotlin.idea.refactoring.ui.KotlinTypeReferenceEditorComboWithBrowseButton; import org.jetbrains.kotlin.psi.*; @@ -262,7 +263,15 @@ public class MoveKotlinNestedClassesDialog extends RefactoringDialog { KotlinMoveTarget target = new KotlinMoveTargetForExistingElement((KtClassOrObject) targetClass); MoveDeclarationsDelegate.NestedClass delegate = new MoveDeclarationsDelegate.NestedClass(); MoveDeclarationsDescriptor descriptor = new MoveDeclarationsDescriptor( - myProject, elementsToMove, target, delegate, false, false, false, false, moveCallback, openInEditorCheckBox.isSelected() + myProject, + MoveSource(elementsToMove), + target, + delegate, + false, + false, + false, + moveCallback, + openInEditorCheckBox.isSelected() ); invokeRefactoring(new MoveKotlinDeclarationsProcessor(descriptor, Mover.Default.INSTANCE)); } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java index b292da292c5..3f803fba9f6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinNestedClassesToUpperLevelDialog.java @@ -39,7 +39,6 @@ import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.ui.EditorTextField; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; -import kotlin.collections.CollectionsKt; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -72,6 +71,8 @@ import java.awt.event.ItemListener; import java.util.Collections; import java.util.List; +import static org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessorKt.MoveSource; + public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { @NonNls private static final String RECENTS_KEY = MoveKotlinNestedClassesToUpperLevelDialog.class.getName() + ".RECENTS_KEY"; @@ -416,13 +417,12 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase { MoveDeclarationsDelegate delegate = new MoveDeclarationsDelegate.NestedClass(newClassName, outerInstanceParameterName); MoveDeclarationsDescriptor moveDescriptor = new MoveDeclarationsDescriptor( project, - CollectionsKt.listOf(innerClass), + MoveSource(innerClass), moveTarget, delegate, isSearchInComments(), isSearchInNonJavaFiles(), false, - false, null, isOpenInEditor() ); diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java index 0e37d272c63..c8cf2abd187 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java @@ -63,6 +63,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPan import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable; import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt; import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*; +import static org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessorKt.MoveSource; import org.jetbrains.kotlin.idea.refactoring.ui.KotlinFileChooserDialog; import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt; import org.jetbrains.kotlin.name.FqName; @@ -774,12 +775,11 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { MoveDeclarationsDescriptor options = new MoveDeclarationsDescriptor( myProject, - elementsToMove, + MoveSource(elementsToMove), target, MoveDeclarationsDelegate.TopLevel.INSTANCE, isSearchInComments(), isSearchInNonJavaFiles(), - false, deleteSourceFile, moveCallback, false, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt index 9dd34706fa2..df25f4ef01d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt @@ -38,7 +38,6 @@ import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.* import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.UserDataProperty internal var KtFile.allElementsToMove: List? by UserDataProperty(Key.create("SCOPE_TO_MOVE")) @@ -92,16 +91,14 @@ class MoveKotlinFileHandler : MoveFileHandler() { } return MoveKotlinDeclarationsProcessor( - MoveDeclarationsDescriptor( - project = project, - elementsToMove = psiFile.declarations.filterIsInstance(), - moveTarget = moveTarget, - delegate = MoveDeclarationsDelegate.TopLevel, - scanEntireFile = true, - allElementsToMove = psiFile.allElementsToMove, - analyzeConflicts = withConflicts - ), - Mover.Idle + MoveDeclarationsDescriptor( + project = project, + moveSource = MoveSource(psiFile), + moveTarget = moveTarget, + delegate = MoveDeclarationsDelegate.TopLevel, + allElementsToMove = psiFile.allElementsToMove, + analyzeConflicts = withConflicts + ) ) } diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt index 83e02087d1b..b2e296d272b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt @@ -244,7 +244,7 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { KotlinMoveTargetForExistingElement(PsiManager.getInstance(project).findFile(rootDir.findFileByRelativePath(filePath)!!) as KtFile) } - val descriptor = MoveDeclarationsDescriptor(project, elementsToMove, moveTarget, MoveDeclarationsDelegate.TopLevel) + val descriptor = MoveDeclarationsDescriptor(project, MoveSource(elementsToMove), moveTarget, MoveDeclarationsDelegate.TopLevel) MoveKotlinDeclarationsProcessor(descriptor).run() } }, @@ -288,7 +288,7 @@ enum class MoveAction : AbstractMultifileRefactoringTest.RefactoringAction { createKotlinFile(fileName, targetDir, targetPackageFqName.asString()) } } - val descriptor = MoveDeclarationsDescriptor(project, listOf(elementToMove), moveTarget, delegate) + val descriptor = MoveDeclarationsDescriptor(project, MoveSource(elementToMove), moveTarget, delegate) MoveKotlinDeclarationsProcessor(descriptor).run() } };