Move top level declaration refactoring
This commit is contained in:
+19
-26
@@ -17,13 +17,11 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.refactoring.PackageWrapper
|
import com.intellij.refactoring.PackageWrapper
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil
|
|
||||||
import com.intellij.refactoring.util.RefactoringMessageUtil
|
import com.intellij.refactoring.util.RefactoringMessageUtil
|
||||||
import com.intellij.refactoring.util.RefactoringUtil
|
import com.intellij.refactoring.util.RefactoringUtil
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
|
import org.jetbrains.kotlin.idea.refactoring.createKotlinFile
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.getTargetPackageFqName
|
import org.jetbrains.kotlin.idea.refactoring.move.getTargetPackageFqName
|
||||||
@@ -57,13 +55,13 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
initialDir: PsiDirectory?
|
initialDir: PsiDirectory?
|
||||||
): VirtualFile?
|
): VirtualFile?
|
||||||
|
|
||||||
private val innerClassDescriptor = innerClass.unsafeResolveToDescriptor(BodyResolveMode.FULL) as ClassDescriptor
|
private val innerClassDescriptor = innerClass.resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
||||||
|
|
||||||
private fun getTargetContainer(): PsiElement? {
|
private fun getTargetContainer(): PsiElement? {
|
||||||
if (target is PsiDirectory) {
|
if (target is PsiDirectory) {
|
||||||
val oldPackageFqName = getTargetPackageFqName(target)
|
val oldPackageFqName = getTargetPackageFqName(target)
|
||||||
val targetName = packageName
|
val targetName = packageName
|
||||||
if (!Comparing.equal(oldPackageFqName?.asString(), targetName)) {
|
if (oldPackageFqName?.asString() != targetName) {
|
||||||
val projectRootManager = ProjectRootManager.getInstance(project)
|
val projectRootManager = ProjectRootManager.getInstance(project)
|
||||||
|
|
||||||
val contentSourceRoots = getSuitableDestinationSourceRoots(project)
|
val contentSourceRoots = getSuitableDestinationSourceRoots(project)
|
||||||
@@ -88,24 +86,21 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
targetSourceRoot = contentSourceRoots[0]
|
targetSourceRoot = contentSourceRoots[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var directory = RefactoringUtil.findPackageDirectoryInSourceRoot(newPackage, targetSourceRoot);
|
RefactoringUtil.findPackageDirectoryInSourceRoot(newPackage, targetSourceRoot)?.let { return it }
|
||||||
if (directory === null) {
|
|
||||||
runWriteAction {
|
return runWriteAction {
|
||||||
try {
|
try {
|
||||||
directory = RefactoringUtil.createPackageDirectoryInSourceRoot(newPackage, targetSourceRoot)
|
RefactoringUtil.createPackageDirectoryInSourceRoot(newPackage, targetSourceRoot)
|
||||||
} catch (e: IncorrectOperationException) {
|
} catch (e: IncorrectOperationException) {
|
||||||
directory = null;
|
null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return directory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (target is KtFile || target is KtClassOrObject) target else null
|
return target as? KtFile ?: target as? KtClassOrObject
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ConfigurationException::class)
|
@Throws(ConfigurationException::class)
|
||||||
@@ -142,11 +137,10 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
val targetPackageFqName = getTargetPackageFqName(target)
|
val targetPackageFqName = getTargetPackageFqName(target)
|
||||||
?: throw ConfigurationException("No package corresponds to this directory")
|
?: throw ConfigurationException("No package corresponds to this directory")
|
||||||
|
|
||||||
val existingClass = DescriptorUtils
|
val existingClass = innerClassDescriptor?.let { DescriptorUtils.getContainingModule(it) }
|
||||||
.getContainingModule(innerClassDescriptor)
|
?.getPackage(targetPackageFqName)
|
||||||
.getPackage(targetPackageFqName)
|
?.memberScope
|
||||||
.memberScope
|
?.getContributedClassifier(Name.identifier(className), NoLookupLocation.FROM_IDE)
|
||||||
.getContributedClassifier(Name.identifier(className), NoLookupLocation.FROM_IDE)
|
|
||||||
if (existingClass != null) {
|
if (existingClass != null) {
|
||||||
throw ConfigurationException("Class $className already exists in package $targetPackageFqName")
|
throw ConfigurationException("Class $className already exists in package $targetPackageFqName")
|
||||||
}
|
}
|
||||||
@@ -163,21 +157,20 @@ internal abstract class MoveKotlinNestedClassesToUpperLevelModel(
|
|||||||
private fun getMoveTarget(): KotlinMoveTarget {
|
private fun getMoveTarget(): KotlinMoveTarget {
|
||||||
val target = getTargetContainerWithValidation()
|
val target = getTargetContainerWithValidation()
|
||||||
if (target is PsiDirectory) {
|
if (target is PsiDirectory) {
|
||||||
val targetDir = target
|
|
||||||
|
|
||||||
val targetPackageFqName = getTargetPackageFqName(target)
|
val targetPackageFqName = getTargetPackageFqName(target)
|
||||||
?: throw ConfigurationException("Cannot find target package name")
|
?: throw ConfigurationException("Cannot find target package name")
|
||||||
|
|
||||||
val suggestedName = KotlinNameSuggester.suggestNameByName(className) {
|
val suggestedName = KotlinNameSuggester.suggestNameByName(className) {
|
||||||
targetDir.findFile(it + "." + KotlinFileType.EXTENSION) == null
|
target.findFile(it + "." + KotlinFileType.EXTENSION) == null
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetFileName = suggestedName + "." + KotlinFileType.EXTENSION
|
val targetFileName = suggestedName + "." + KotlinFileType.EXTENSION
|
||||||
|
|
||||||
return KotlinMoveTargetForDeferredFile(
|
return KotlinMoveTargetForDeferredFile(
|
||||||
targetPackageFqName,
|
targetPackageFqName,
|
||||||
targetDir, null
|
target,
|
||||||
) { createKotlinFile(targetFileName, targetDir, targetPackageFqName.asString()) }
|
targetFile = null
|
||||||
|
) { createKotlinFile(targetFileName, target, targetPackageFqName.asString()) }
|
||||||
} else {
|
} else {
|
||||||
return KotlinMoveTargetForExistingElement(target as KtElement)
|
return KotlinMoveTargetForExistingElement(target as KtElement)
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-70
@@ -7,26 +7,23 @@ package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui
|
|||||||
|
|
||||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.openapi.options.ConfigurationException
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
import com.intellij.refactoring.MoveDestination
|
import com.intellij.refactoring.MoveDestination
|
||||||
import com.intellij.refactoring.PackageWrapper
|
import com.intellij.refactoring.PackageWrapper
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
|
||||||
import com.intellij.refactoring.move.MoveCallback
|
import com.intellij.refactoring.move.MoveCallback
|
||||||
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination
|
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination
|
||||||
import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination
|
import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination
|
||||||
import com.intellij.util.IncorrectOperationException
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.idea.core.getPackage
|
||||||
|
import org.jetbrains.kotlin.idea.core.util.toPsiDirectory
|
||||||
import org.jetbrains.kotlin.idea.core.util.toPsiFile
|
import org.jetbrains.kotlin.idea.core.util.toPsiFile
|
||||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
|
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
|
||||||
import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile
|
import org.jetbrains.kotlin.idea.refactoring.getOrCreateKotlinFile
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
import org.jetbrains.kotlin.idea.refactoring.move.getOrCreateDirectory
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
|
||||||
import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective
|
import org.jetbrains.kotlin.idea.refactoring.move.updatePackageDirective
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
@@ -51,29 +48,24 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
val moveCallback: MoveCallback?
|
val moveCallback: MoveCallback?
|
||||||
) : Model<BaseRefactoringProcessor> {
|
) : Model<BaseRefactoringProcessor> {
|
||||||
|
|
||||||
private inline fun <T, K> List<T>.mapToSingleOrNull(transform: (T) -> K?): K? =
|
private inline fun <T, K> Set<T>.mapToSingleOrNull(transform: (T) -> K?): K? =
|
||||||
mapTo(mutableSetOf(), transform).singleOrNull()
|
mapTo(mutableSetOf(), transform).singleOrNull()
|
||||||
|
|
||||||
private val sourceDirectory by lazy {
|
private fun checkedGetSourceDirectory() =
|
||||||
sourceFiles.mapToSingleOrNull { it.parent } ?: throw ConfigurationException("Can't determine sources directory")
|
sourceFiles.mapToSingleOrNull { it.parent } ?: throw ConfigurationException("Can't determine sources directory")
|
||||||
}
|
|
||||||
|
|
||||||
private val sourceFiles = elementsToMove.map { it.containingKtFile }.distinct()
|
private val sourceFiles: Set<KtFile> = elementsToMove.mapTo(mutableSetOf()) { it.containingKtFile }
|
||||||
|
|
||||||
private data class TargetDirAndDestination(val targetDir: VirtualFile?, val destination: MoveDestination)
|
private val singleSourceFileMode = sourceFiles.size == 1
|
||||||
|
|
||||||
private fun selectPackageBasedTargetDirAndDestination(): TargetDirAndDestination {
|
private fun selectPackageBasedDestination(): MoveDestination {
|
||||||
|
|
||||||
val targetPackageWrapper = PackageWrapper(PsiManager.getInstance(project), targetPackage)
|
val targetPackageWrapper = PackageWrapper(PsiManager.getInstance(project), targetPackage)
|
||||||
|
|
||||||
return if (selectedPsiDirectory == null)
|
return if (selectedPsiDirectory == null)
|
||||||
TargetDirAndDestination(null, MultipleRootsMoveDestination(targetPackageWrapper))
|
MultipleRootsMoveDestination(targetPackageWrapper)
|
||||||
else {
|
else
|
||||||
TargetDirAndDestination(
|
AutocreatingSingleSourceRootMoveDestination(targetPackageWrapper, selectedPsiDirectory.virtualFile)
|
||||||
selectedPsiDirectory.virtualFile,
|
|
||||||
AutocreatingSingleSourceRootMoveDestination(targetPackageWrapper, selectedPsiDirectory.virtualFile)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkTargetFileName(fileName: String) {
|
private fun checkTargetFileName(fileName: String) {
|
||||||
@@ -82,7 +74,7 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFilesExistingInTargetDir(
|
private fun getFilesExistingInTargetDirectory(
|
||||||
targetFileName: String?,
|
targetFileName: String?,
|
||||||
targetDirectory: PsiDirectory
|
targetDirectory: PsiDirectory
|
||||||
): Set<PsiFile> {
|
): Set<PsiFile> {
|
||||||
@@ -93,41 +85,43 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun tryMoveToPackageForExistingDirectory(targetFileName: String?, targetDirectory: PsiDirectory): KotlinMoveTarget? {
|
||||||
|
|
||||||
|
val filesExistingInTargetDir = getFilesExistingInTargetDirectory(targetFileName, targetDirectory)
|
||||||
|
|
||||||
|
if (filesExistingInTargetDir.isEmpty()) return null
|
||||||
|
|
||||||
|
if (singleSourceFileMode) {
|
||||||
|
val singeTargetFile = filesExistingInTargetDir.single() as? KtFile
|
||||||
|
if (singeTargetFile != null) {
|
||||||
|
return KotlinMoveTargetForExistingElement(singeTargetFile)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val filePathsToReport = filesExistingInTargetDir.joinToString(
|
||||||
|
separator = "\n",
|
||||||
|
prefix = "Cannot perform refactoring since the following files already exist:\n\n"
|
||||||
|
) { it.virtualFile.path }
|
||||||
|
throw ConfigurationException(filePathsToReport)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private fun selectMoveTargetToPackage(): KotlinMoveTarget {
|
private fun selectMoveTargetToPackage(): KotlinMoveTarget {
|
||||||
require(sourceFiles.isNotEmpty())
|
require(sourceFiles.isNotEmpty())
|
||||||
|
|
||||||
val (targetDir, moveDestination) = selectPackageBasedTargetDirAndDestination()
|
val moveDestination = selectPackageBasedDestination()
|
||||||
val targetDirectory = moveDestination.getTargetIfExists(sourceDirectory)
|
val targetDirectory: PsiDirectory? = moveDestination.getTargetIfExists(checkedGetSourceDirectory())
|
||||||
?: throw ConfigurationException("Can't get target directory for selected package")
|
|
||||||
|
|
||||||
val destination = sourceFiles
|
|
||||||
.mapToSingleOrNull { moveDestination.getTargetIfExists(it) }
|
|
||||||
?: throw ConfigurationException("Can't get target for all source elements")
|
|
||||||
|
|
||||||
val singleSourceFileMode = sourceFiles.size == 1
|
|
||||||
|
|
||||||
val targetFileName = if (singleSourceFileMode) fileNameInPackage.also(::checkTargetFileName) else null
|
val targetFileName = if (singleSourceFileMode) fileNameInPackage.also(::checkTargetFileName) else null
|
||||||
val filesExistingInTargetDir = getFilesExistingInTargetDir(targetFileName, targetDirectory)
|
|
||||||
|
|
||||||
if (filesExistingInTargetDir.isNotEmpty()) {
|
if (targetDirectory != null) {
|
||||||
if (singleSourceFileMode) {
|
tryMoveToPackageForExistingDirectory(targetFileName, targetDirectory)?.let { return it }
|
||||||
val singeTargetFile = filesExistingInTargetDir.single() as? KtFile
|
|
||||||
if (singeTargetFile != null) {
|
|
||||||
return KotlinMoveTargetForExistingElement(singeTargetFile)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val filePathsToReport = filesExistingInTargetDir.joinToString(
|
|
||||||
separator = "\n",
|
|
||||||
prefix = "Cannot perform refactoring since the following files already exist:\n\n"
|
|
||||||
) { it.virtualFile.path }
|
|
||||||
throw ConfigurationException(filePathsToReport)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return KotlinMoveTargetForDeferredFile(
|
return KotlinMoveTargetForDeferredFile(
|
||||||
FqName(targetPackage),
|
FqName(targetPackage),
|
||||||
destination,
|
targetDirectory
|
||||||
targetDir
|
|
||||||
) {
|
) {
|
||||||
val deferredFileName = if (singleSourceFileMode) fileNameInPackage else it.name
|
val deferredFileName = if (singleSourceFileMode) fileNameInPackage else it.name
|
||||||
val deferredFileDirectory = moveDestination.getTargetDirectory(it)
|
val deferredFileDirectory = moveDestination.getTargetDirectory(it)
|
||||||
@@ -137,51 +131,49 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
|
|
||||||
private fun selectMoveTargetToFile(): KotlinMoveTarget {
|
private fun selectMoveTargetToFile(): KotlinMoveTarget {
|
||||||
|
|
||||||
try {
|
val targetFile = try {
|
||||||
Paths.get(targetFilePath)
|
Paths.get(targetFilePath).toFile()
|
||||||
} catch (e: InvalidPathException) {
|
} catch (e: InvalidPathException) {
|
||||||
throw ConfigurationException("Invalid target path $targetFilePath")
|
throw ConfigurationException("Invalid target path $targetFilePath")
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetFile = File(targetFilePath)
|
|
||||||
checkTargetFileName(targetFile.name)
|
checkTargetFileName(targetFile.name)
|
||||||
|
|
||||||
val jetFile = targetFile.toPsiFile(project) as? KtFile
|
val jetFile = targetFile.toPsiFile(project) as? KtFile
|
||||||
if (jetFile != null) {
|
if (jetFile != null) {
|
||||||
if (sourceFiles.size == 1 && sourceFiles.contains(jetFile)) {
|
if (sourceFiles.singleOrNull() == jetFile) {
|
||||||
throw ConfigurationException("Can't move to the original file")
|
throw ConfigurationException("Can't move to the original file")
|
||||||
}
|
}
|
||||||
return KotlinMoveTargetForExistingElement(jetFile)
|
return KotlinMoveTargetForExistingElement(jetFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetDirPath = targetFile.toPath().parent
|
val targetDirectoryPath = targetFile.toPath().parent
|
||||||
?: throw ConfigurationException("Incorrect target path. Directory is not specified.")
|
?: throw ConfigurationException("Incorrect target path. Directory is not specified.")
|
||||||
|
|
||||||
val projectBasePath = project.basePath
|
val projectBasePath = project.basePath
|
||||||
?: throw ConfigurationException("Can't move for current project")
|
?: throw ConfigurationException("Can't move for current project")
|
||||||
|
|
||||||
if (!targetDirPath.startsWith(projectBasePath)) {
|
if (!targetDirectoryPath.startsWith(projectBasePath)) {
|
||||||
throw ConfigurationException("Incorrect target path. Directory $targetDirPath does not belong to current project.")
|
throw ConfigurationException("Incorrect target path. Directory $targetDirectoryPath does not belong to current project.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val absoluteTargetDirPath = targetDirPath.toString()
|
val psiDirectory = targetDirectoryPath.toFile().toPsiDirectory(project)
|
||||||
val psiDirectory: PsiDirectory
|
|
||||||
try {
|
|
||||||
psiDirectory = getOrCreateDirectory(absoluteTargetDirPath, project)
|
|
||||||
} catch (e: IncorrectOperationException) {
|
|
||||||
throw ConfigurationException("Failed to create parent directory: $absoluteTargetDirPath")
|
|
||||||
}
|
|
||||||
|
|
||||||
val targetPackageFqName = sourceFiles.singleOrNull()?.packageFqName
|
val targetPackageFqName = sourceFiles.singleOrNull()?.packageFqName
|
||||||
?: JavaDirectoryService.getInstance().getPackage(psiDirectory)?.let { FqName(it.qualifiedName) }
|
?: psiDirectory?.getPackage()?.let { FqName(it.qualifiedName) }
|
||||||
?: throw ConfigurationException("Could not find package corresponding to $absoluteTargetDirPath")
|
?: throw ConfigurationException("Could not find package corresponding to $targetDirectoryPath")
|
||||||
|
|
||||||
|
val targetDirectoryPathString = targetDirectoryPath.toString()
|
||||||
val finalTargetPackageFqName = targetPackageFqName.asString()
|
val finalTargetPackageFqName = targetPackageFqName.asString()
|
||||||
|
|
||||||
return KotlinMoveTargetForDeferredFile(
|
return KotlinMoveTargetForDeferredFile(
|
||||||
targetPackageFqName,
|
targetPackageFqName,
|
||||||
psiDirectory,
|
psiDirectory,
|
||||||
targetFile = null
|
targetFile = null
|
||||||
) { getOrCreateKotlinFile(targetFile.name, psiDirectory, finalTargetPackageFqName) }
|
) {
|
||||||
|
val actualPsiDirectory = psiDirectory ?: getOrCreateDirectory(targetDirectoryPathString, project)
|
||||||
|
getOrCreateKotlinFile(targetFile.name, actualPsiDirectory, finalTargetPackageFqName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun selectMoveTarget() =
|
private fun selectMoveTarget() =
|
||||||
@@ -191,7 +183,7 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
|
|
||||||
if (elementsToMove.isEmpty()) throw ConfigurationException("At least one member must be selected")
|
if (elementsToMove.isEmpty()) throw ConfigurationException("At least one member must be selected")
|
||||||
if (sourceFiles.isEmpty()) throw ConfigurationException("None elements were selected")
|
if (sourceFiles.isEmpty()) throw ConfigurationException("None elements were selected")
|
||||||
if (sourceFiles.size == 1 && fileNameInPackage.isBlank()) throw ConfigurationException("File name may not be empty")
|
if (singleSourceFileMode && fileNameInPackage.isBlank()) throw ConfigurationException("File name may not be empty")
|
||||||
|
|
||||||
if (isMoveToPackage) {
|
if (isMoveToPackage) {
|
||||||
if (targetPackage.isNotEmpty() && !PsiNameHelper.getInstance(project).isQualifiedName(targetPackage)) {
|
if (targetPackage.isNotEmpty() && !PsiNameHelper.getInstance(project).isQualifiedName(targetPackage)) {
|
||||||
@@ -225,20 +217,16 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
val targetFileName = if (sourceFiles.size > 1) null else fileNameInPackage
|
val targetFileName = if (sourceFiles.size > 1) null else fileNameInPackage
|
||||||
if (targetFileName != null) checkTargetFileName(targetFileName)
|
if (targetFileName != null) checkTargetFileName(targetFileName)
|
||||||
|
|
||||||
val moveDestination = selectPackageBasedTargetDirAndDestination().destination
|
val moveDestination = selectPackageBasedDestination()
|
||||||
val targetDir = moveDestination.getTargetIfExists(sourceDirectory) ?: return null
|
val targetDirectory = moveDestination.getTargetIfExists(checkedGetSourceDirectory()) ?: return null
|
||||||
|
|
||||||
val filesExistingInTargetDir = getFilesExistingInTargetDir(targetFileName, targetDir)
|
val filesExistingInTargetDir = getFilesExistingInTargetDirectory(targetFileName, targetDirectory)
|
||||||
|
|
||||||
val moveAsFile = filesExistingInTargetDir.isEmpty() ||
|
val moveAsFile = filesExistingInTargetDir.isEmpty() ||
|
||||||
filesExistingInTargetDir.singleOrNull()?.let { sourceFiles.contains(it) } == true
|
filesExistingInTargetDir.singleOrNull()?.let { sourceFiles.contains(it) } == true
|
||||||
|
|
||||||
if (!moveAsFile) return null
|
if (!moveAsFile) return null
|
||||||
|
|
||||||
val targetDirectory = project.executeCommand(RefactoringBundle.message("move.title"), null) {
|
|
||||||
runWriteAction<PsiDirectory> { moveDestination.getTargetDirectory(sourceDirectory) }
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceFiles.forEach { it.updatePackageDirective = isUpdatePackageDirective }
|
sourceFiles.forEach { it.updatePackageDirective = isUpdatePackageDirective }
|
||||||
|
|
||||||
return if (targetFileName != null)
|
return if (targetFileName != null)
|
||||||
@@ -255,7 +243,7 @@ internal class MoveKotlinTopLevelDeclarationsModel(
|
|||||||
else
|
else
|
||||||
KotlinAwareMoveFilesOrDirectoriesProcessor(
|
KotlinAwareMoveFilesOrDirectoriesProcessor(
|
||||||
project,
|
project,
|
||||||
sourceFiles,
|
sourceFiles.toList(),
|
||||||
targetDirectory,
|
targetDirectory,
|
||||||
isSearchReferences,
|
isSearchReferences,
|
||||||
searchInComments = isSearchInComments,
|
searchInComments = isSearchInComments,
|
||||||
|
|||||||
Reference in New Issue
Block a user