Move: Extract MoveToKotlinFileProcessor class
This commit is contained in:
+1
-26
@@ -28,16 +28,14 @@ import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectori
|
|||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.usageView.UsageViewDescriptor
|
import com.intellij.usageView.UsageViewDescriptor
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import com.intellij.util.text.UniqueNameGenerator
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.allElementsToMove
|
import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.allElementsToMove
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.shouldFixFqName
|
import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.shouldFixFqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class MoveFilesWithDeclarationsProcessor @JvmOverloads constructor (
|
class KotlinAwareMoveFilesOrDirectoriesProcessor @JvmOverloads constructor (
|
||||||
project: Project,
|
project: Project,
|
||||||
private val elementsToMove: List<PsiElement>,
|
private val elementsToMove: List<PsiElement>,
|
||||||
private val targetDirectory: PsiDirectory,
|
private val targetDirectory: PsiDirectory,
|
||||||
private val targetFileName: String?,
|
|
||||||
searchInComments: Boolean,
|
searchInComments: Boolean,
|
||||||
searchInNonJavaFiles: Boolean,
|
searchInNonJavaFiles: Boolean,
|
||||||
moveCallback: MoveCallback?,
|
moveCallback: MoveCallback?,
|
||||||
@@ -50,10 +48,6 @@ class MoveFilesWithDeclarationsProcessor @JvmOverloads constructor (
|
|||||||
searchInNonJavaFiles,
|
searchInNonJavaFiles,
|
||||||
moveCallback,
|
moveCallback,
|
||||||
prepareSuccessfulCallback) {
|
prepareSuccessfulCallback) {
|
||||||
override fun getCommandName(): String {
|
|
||||||
return if (targetFileName != null) "Move " + (elementsToMove.single() as PsiFile).name else "Move"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>): UsageViewDescriptor {
|
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>): UsageViewDescriptor {
|
||||||
return MoveFilesWithDeclarationsViewDescriptor(elementsToMove.toTypedArray<PsiElement>(), targetDirectory)
|
return MoveFilesWithDeclarationsViewDescriptor(elementsToMove.toTypedArray<PsiElement>(), targetDirectory)
|
||||||
}
|
}
|
||||||
@@ -83,17 +77,6 @@ class MoveFilesWithDeclarationsProcessor @JvmOverloads constructor (
|
|||||||
return showConflicts(conflicts, usages)
|
return showConflicts(conflicts, usages)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign a temporary name to file-under-move to avoid naming conflict during the refactoring
|
|
||||||
private fun renameFileTemporarily() {
|
|
||||||
if (targetFileName == null || targetDirectory.findFile(targetFileName) == null) return
|
|
||||||
|
|
||||||
val sourceFile = elementsToMove.single() as PsiFile
|
|
||||||
val temporaryName = UniqueNameGenerator.generateUniqueName("temp", "", ".kt") {
|
|
||||||
sourceFile.containingDirectory!!.findFile(it) == null
|
|
||||||
}
|
|
||||||
sourceFile.name = temporaryName
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun markPsiFiles(mark: PsiFile.() -> Unit) {
|
private fun markPsiFiles(mark: PsiFile.() -> Unit) {
|
||||||
fun PsiElement.doMark(mark: PsiFile.() -> Unit) {
|
fun PsiElement.doMark(mark: PsiFile.() -> Unit) {
|
||||||
when (this) {
|
when (this) {
|
||||||
@@ -114,20 +97,12 @@ class MoveFilesWithDeclarationsProcessor @JvmOverloads constructor (
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun performRefactoring(usages: Array<UsageInfo>) {
|
override fun performRefactoring(usages: Array<UsageInfo>) {
|
||||||
val needTemporaryRename = targetFileName != null && targetDirectory.findFile(targetFileName) != null
|
|
||||||
if (needTemporaryRename) {
|
|
||||||
renameFileTemporarily()
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
markShouldFixFqName(true)
|
markShouldFixFqName(true)
|
||||||
super.performRefactoring(usages)
|
super.performRefactoring(usages)
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
markShouldFixFqName(false)
|
markShouldFixFqName(false)
|
||||||
if (needTemporaryRename) {
|
|
||||||
(elementsToMove.single() as PsiFile).name = targetFileName!!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+95
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.EmptyRunnable
|
||||||
|
import com.intellij.openapi.util.Ref
|
||||||
|
import com.intellij.psi.PsiDirectory
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
|
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor
|
||||||
|
import com.intellij.usageView.UsageInfo
|
||||||
|
import com.intellij.usageView.UsageViewDescriptor
|
||||||
|
import com.intellij.util.containers.MultiMap
|
||||||
|
import com.intellij.util.text.UniqueNameGenerator
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
|
class MoveToKotlinFileProcessor @JvmOverloads constructor (
|
||||||
|
project: Project,
|
||||||
|
private val sourceFile: KtFile,
|
||||||
|
private val targetDirectory: PsiDirectory,
|
||||||
|
private val targetFileName: String,
|
||||||
|
searchInComments: Boolean,
|
||||||
|
searchInNonJavaFiles: Boolean,
|
||||||
|
moveCallback: MoveCallback?,
|
||||||
|
prepareSuccessfulCallback: Runnable = EmptyRunnable.INSTANCE
|
||||||
|
) : MoveFilesOrDirectoriesProcessor(project,
|
||||||
|
arrayOf(sourceFile),
|
||||||
|
targetDirectory,
|
||||||
|
true,
|
||||||
|
searchInComments,
|
||||||
|
searchInNonJavaFiles,
|
||||||
|
moveCallback,
|
||||||
|
prepareSuccessfulCallback) {
|
||||||
|
override fun getCommandName() = "Move ${sourceFile.name}"
|
||||||
|
|
||||||
|
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>): UsageViewDescriptor {
|
||||||
|
return MoveFilesWithDeclarationsViewDescriptor(arrayOf(sourceFile), targetDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun preprocessUsages(refUsages: Ref<Array<UsageInfo>>): Boolean {
|
||||||
|
val usages = refUsages.get()
|
||||||
|
|
||||||
|
val (conflictUsages, usagesToProcess) = usages.partition { it is ConflictUsageInfo }
|
||||||
|
|
||||||
|
val conflicts = MultiMap<PsiElement, String>()
|
||||||
|
for (conflictUsage in conflictUsages) {
|
||||||
|
conflicts.putValues(conflictUsage.element, (conflictUsage as ConflictUsageInfo).messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
refUsages.set(usagesToProcess.toTypedArray())
|
||||||
|
|
||||||
|
return showConflicts(conflicts, usages)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign a temporary name to file-under-move to avoid naming conflict during the refactoring
|
||||||
|
private fun renameFileTemporarily() {
|
||||||
|
if (targetDirectory.findFile(targetFileName) == null) return
|
||||||
|
|
||||||
|
val temporaryName = UniqueNameGenerator.generateUniqueName("temp", "", ".kt") {
|
||||||
|
sourceFile.containingDirectory!!.findFile(it) == null
|
||||||
|
}
|
||||||
|
sourceFile.name = temporaryName
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun performRefactoring(usages: Array<UsageInfo>) {
|
||||||
|
val needTemporaryRename = targetDirectory.findFile(targetFileName) != null
|
||||||
|
if (needTemporaryRename) {
|
||||||
|
renameFileTemporarily()
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
super.performRefactoring(usages)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (needTemporaryRename) {
|
||||||
|
sourceFile.name = targetFileName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-13
@@ -31,10 +31,7 @@ import com.intellij.openapi.util.Pass;
|
|||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
import com.intellij.refactoring.*;
|
||||||
import com.intellij.refactoring.MoveDestination;
|
|
||||||
import com.intellij.refactoring.PackageWrapper;
|
|
||||||
import com.intellij.refactoring.RefactoringBundle;
|
|
||||||
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
|
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
|
||||||
import com.intellij.refactoring.classMembers.MemberInfoChange;
|
import com.intellij.refactoring.classMembers.MemberInfoChange;
|
||||||
import com.intellij.refactoring.classMembers.MemberInfoChangeListener;
|
import com.intellij.refactoring.classMembers.MemberInfoChangeListener;
|
||||||
@@ -738,15 +735,23 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
MoveUtilsKt.setUpdatePackageDirective(sourceFile, cbUpdatePackageDirective.isSelected());
|
MoveUtilsKt.setUpdatePackageDirective(sourceFile, cbUpdatePackageDirective.isSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeRefactoring(
|
BaseRefactoringProcessor processor;
|
||||||
new MoveFilesWithDeclarationsProcessor(myProject,
|
processor = sourceFiles.size() == 1 && targetFileName != null
|
||||||
sourceFiles,
|
? new MoveToKotlinFileProcessor(myProject,
|
||||||
targetDirectory,
|
CollectionsKt.single(sourceFiles),
|
||||||
targetFileName,
|
targetDirectory,
|
||||||
isSearchInComments(),
|
targetFileName,
|
||||||
isSearchInNonJavaFiles(),
|
isSearchInComments(),
|
||||||
moveCallback)
|
isSearchInNonJavaFiles(),
|
||||||
);
|
moveCallback)
|
||||||
|
: new KotlinAwareMoveFilesOrDirectoriesProcessor(myProject,
|
||||||
|
sourceFiles,
|
||||||
|
targetDirectory,
|
||||||
|
isSearchInComments(),
|
||||||
|
isSearchInNonJavaFiles(),
|
||||||
|
moveCallback);
|
||||||
|
|
||||||
|
invokeRefactoring(processor);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectori
|
|||||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isInJavaSourceRoot
|
import org.jetbrains.kotlin.idea.refactoring.isInJavaSourceRoot
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveFilesWithDeclarationsProcessor
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
@@ -78,11 +78,10 @@ fun invokeMoveFilesOrDirectoriesRefactoring(
|
|||||||
|
|
||||||
if (elementsToMove.isNotEmpty()) {
|
if (elementsToMove.isNotEmpty()) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val processor = MoveFilesWithDeclarationsProcessor(
|
val processor = KotlinAwareMoveFilesOrDirectoriesProcessor(
|
||||||
project,
|
project,
|
||||||
elementsToMove as List<KtFile>,
|
elementsToMove as List<KtFile>,
|
||||||
selectedDir,
|
selectedDir,
|
||||||
null,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
moveCallback,
|
moveCallback,
|
||||||
|
|||||||
@@ -296,11 +296,10 @@ enum class MoveAction {
|
|||||||
}
|
}
|
||||||
val targetDirPath = config.getString("targetDirectory")
|
val targetDirPath = config.getString("targetDirectory")
|
||||||
val targetDir = rootDir.findFileByRelativePath(targetDirPath)!!.toPsiDirectory(project)!!
|
val targetDir = rootDir.findFileByRelativePath(targetDirPath)!!.toPsiDirectory(project)!!
|
||||||
MoveFilesWithDeclarationsProcessor(
|
KotlinAwareMoveFilesOrDirectoriesProcessor(
|
||||||
project,
|
project,
|
||||||
elementsToMove,
|
elementsToMove,
|
||||||
targetDir,
|
targetDir,
|
||||||
(elementsToMove.singleOrNull() as? KtFile)?.name,
|
|
||||||
searchInComments = true,
|
searchInComments = true,
|
||||||
searchInNonJavaFiles = true,
|
searchInNonJavaFiles = true,
|
||||||
moveCallback = null
|
moveCallback = null
|
||||||
|
|||||||
Reference in New Issue
Block a user