Refactor: Introduce MoveSource class

This commit is contained in:
Alexey Sedunov
2018-07-03 22:03:26 +03:00
parent 2131a314b0
commit aa4e87fc4b
13 changed files with 75 additions and 61 deletions
@@ -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()
)
@@ -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) })
@@ -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) {
@@ -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) {
@@ -102,7 +102,7 @@ class MoveDeclarationToSeparateFileIntention :
}
val descriptor = MoveDeclarationsDescriptor(
project = project,
elementsToMove = listOf(element),
moveSource = MoveSource(element),
moveTarget = moveTarget,
delegate = MoveDeclarationsDelegate.TopLevel,
searchInCommentsAndStrings = false,
@@ -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) {
@@ -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) {
@@ -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
@@ -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));
}
@@ -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()
);
@@ -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,
@@ -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()
}
};