Refactor: Introduce MoveSource class
This commit is contained in:
@@ -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()
|
||||
)
|
||||
|
||||
+1
-1
@@ -271,7 +271,7 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention<KtNamed
|
||||
}
|
||||
}
|
||||
val moveDescriptor = MoveDeclarationsDescriptor(project,
|
||||
listOf(element),
|
||||
MoveSource(element),
|
||||
KotlinMoveTargetForCompanion(containingClass),
|
||||
MoveDeclarationsDelegate.NestedClass(null, outerInstanceName),
|
||||
moveCallback = MoveCallback { runTemplateForInstanceParam(movedClass!!, nameSuggestions, editor) })
|
||||
|
||||
+7
-7
@@ -111,13 +111,13 @@ class MoveDeclarationsProcessor(
|
||||
}
|
||||
|
||||
val declarationProcessor = MoveKotlinDeclarationsProcessor(
|
||||
MoveDeclarationsDescriptor(
|
||||
elementsToMove = stubDeclarations,
|
||||
moveTarget = KotlinMoveTargetForExistingElement(targetPsiFile),
|
||||
delegate = MoveDeclarationsDelegate.TopLevel,
|
||||
project = project
|
||||
),
|
||||
mover
|
||||
MoveDeclarationsDescriptor(
|
||||
moveSource = MoveSource(stubDeclarations),
|
||||
moveTarget = KotlinMoveTargetForExistingElement(targetPsiFile),
|
||||
delegate = MoveDeclarationsDelegate.TopLevel,
|
||||
project = project
|
||||
),
|
||||
mover
|
||||
)
|
||||
|
||||
val declarationUsages = project.runSynchronouslyWithProgress(RefactoringBundle.message("progress.text"), true) {
|
||||
|
||||
+6
-9
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
|
||||
class KotlinChangePackageRefactoring(val file: KtFile) {
|
||||
private val project = file.project
|
||||
@@ -39,14 +38,12 @@ class KotlinChangePackageRefactoring(val file: KtFile) {
|
||||
val currentFqName = packageDirective.fqName
|
||||
|
||||
val declarationProcessor = MoveKotlinDeclarationsProcessor(
|
||||
MoveDeclarationsDescriptor(
|
||||
project = project,
|
||||
elementsToMove = file.declarations.filterIsInstance<KtNamedDeclaration>(),
|
||||
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) {
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ class MoveDeclarationToSeparateFileIntention :
|
||||
}
|
||||
val descriptor = MoveDeclarationsDescriptor(
|
||||
project = project,
|
||||
elementsToMove = listOf(element),
|
||||
moveSource = MoveSource(element),
|
||||
moveTarget = moveTarget,
|
||||
delegate = MoveDeclarationsDelegate.TopLevel,
|
||||
searchInCommentsAndStrings = false,
|
||||
|
||||
+2
-2
@@ -79,7 +79,7 @@ sealed class MoveDeclarationsDelegate {
|
||||
}
|
||||
|
||||
override fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List<UsageInfo> {
|
||||
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) {
|
||||
|
||||
+2
-2
@@ -79,7 +79,7 @@ sealed class MoveDeclarationsDelegate {
|
||||
}
|
||||
|
||||
override fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List<UsageInfo> {
|
||||
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) {
|
||||
|
||||
+30
-19
@@ -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<KtNamedDeclaration>
|
||||
|
||||
class Elements(override val elementsToMove: Collection<KtNamedDeclaration>) : MoveSource()
|
||||
|
||||
class File(val file: KtFile) : MoveSource() {
|
||||
override val elementsToMove: Collection<KtNamedDeclaration>
|
||||
get() = file.declarations.filterIsInstance<KtNamedDeclaration>()
|
||||
}
|
||||
}
|
||||
|
||||
fun MoveSource(declaration: KtNamedDeclaration) = MoveSource.Elements(listOf(declaration))
|
||||
fun MoveSource(declarations: Collection<KtNamedDeclaration>) = MoveSource.Elements(declarations)
|
||||
fun MoveSource(file: KtFile) = MoveSource.File(file)
|
||||
|
||||
class MoveDeclarationsDescriptor @JvmOverloads constructor(
|
||||
val project: Project,
|
||||
val elementsToMove: Collection<KtNamedDeclaration>,
|
||||
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<PsiElement>? = 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<PsiElement>? = null,
|
||||
val analyzeConflicts: Boolean = true,
|
||||
val searchReferences: Boolean = true
|
||||
)
|
||||
|
||||
class ConflictUsageInfo(element: PsiElement, val messages: Collection<String>) : UsageInfo(element)
|
||||
@@ -144,7 +153,8 @@ class MoveKotlinDeclarationsProcessor(
|
||||
val project get() = descriptor.project
|
||||
|
||||
private var nonCodeUsages: Array<NonCodeUsageInfo>? = 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<UsageInfo>()
|
||||
val externalUsages = LinkedHashSet<UsageInfo>()
|
||||
|
||||
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<KtElement> = if (descriptor.scanEntireFile) {
|
||||
val internalUsageScopes: List<KtElement> = if (moveEntireFile) {
|
||||
newDeclarations.asSequence().map { it.containingKtFile }.distinct().toList()
|
||||
} else {
|
||||
newDeclarations
|
||||
|
||||
+10
-1
@@ -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));
|
||||
}
|
||||
|
||||
+3
-3
@@ -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()
|
||||
);
|
||||
|
||||
+2
-2
@@ -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,
|
||||
|
||||
+8
-11
@@ -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<PsiElement>? by UserDataProperty(Key.create("SCOPE_TO_MOVE"))
|
||||
@@ -92,16 +91,14 @@ class MoveKotlinFileHandler : MoveFileHandler() {
|
||||
}
|
||||
|
||||
return MoveKotlinDeclarationsProcessor(
|
||||
MoveDeclarationsDescriptor(
|
||||
project = project,
|
||||
elementsToMove = psiFile.declarations.filterIsInstance<KtNamedDeclaration>(),
|
||||
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
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user