Move: Warn about accessibility conflicts due to moving to unrelated module

#KT-13174 Fixed
This commit is contained in:
Alexey Sedunov
2016-08-12 16:10:49 +03:00
parent 6a42802240
commit baa549e7c8
19 changed files with 204 additions and 21 deletions

View File

@@ -264,6 +264,7 @@ Using 'this' as function argument in constructor of non-final class
- [`KT-13254`](https://youtrack.jetbrains.com/issue/KT-13254) Rename: Conflict detection for type parameters
- [`KT-13282`](https://youtrack.jetbrains.com/issue/KT-13282), [`KT-13283`](https://youtrack.jetbrains.com/issue/KT-13283) Rename: Fix name quoting for automatic renamers
- [`KT-13239`](https://youtrack.jetbrains.com/issue/KT-13239) Rename: Warn about function name conflicts
- [`KT-13174`](https://youtrack.jetbrains.com/issue/KT-13174) Move: Warn about accessibility conflicts due to moving to unrelated module
##### New features

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.refactoring.move.changePackage
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
@@ -47,6 +48,8 @@ class KotlinChangePackageRefactoring(val file: KtFile) {
override val directory: PsiDirectory = file.containingDirectory!!
override val targetFile: VirtualFile? = directory.virtualFile
override fun getOrCreateTargetPsi(originalPsi: PsiElement) = originalPsi.containingFile as? KtFile
override fun getTargetPsiIfExists(originalPsi: PsiElement) = null

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
@@ -30,6 +31,8 @@ import java.util.*
interface KotlinMoveTarget {
val targetContainerFqName: FqName?
val targetFile: VirtualFile?
fun getOrCreateTargetPsi(originalPsi: PsiElement): KtElement?
fun getTargetPsiIfExists(originalPsi: PsiElement): KtElement?
@@ -43,6 +46,8 @@ interface KotlinDirectoryBasedMoveTarget : KotlinMoveTarget {
object EmptyKotlinMoveTarget: KotlinMoveTarget {
override val targetContainerFqName = null
override val targetFile = null
override fun getOrCreateTargetPsi(originalPsi: PsiElement) = null
override fun getTargetPsiIfExists(originalPsi: PsiElement) = null
override fun verify(file: PsiFile) = null
@@ -51,6 +56,8 @@ object EmptyKotlinMoveTarget: KotlinMoveTarget {
class KotlinMoveTargetForExistingElement(val targetElement: KtElement): KotlinMoveTarget {
override val targetContainerFqName = targetElement.getContainingKtFile().packageFqName
override val targetFile: VirtualFile? = targetElement.getContainingKtFile().virtualFile
override fun getOrCreateTargetPsi(originalPsi: PsiElement) = targetElement
override fun getTargetPsiIfExists(originalPsi: PsiElement) = targetElement
@@ -63,6 +70,8 @@ class KotlinMoveTargetForCompanion(val targetClass: KtClass): KotlinMoveTarget {
override val targetContainerFqName = targetClass.getCompanionObjects().firstOrNull()?.fqName
?: targetClass.fqName!!.child(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT)
override val targetFile: VirtualFile? = targetClass.getContainingKtFile().virtualFile
override fun getOrCreateTargetPsi(originalPsi: PsiElement) = targetClass.getOrCreateCompanionObject()
override fun getTargetPsiIfExists(originalPsi: PsiElement) = targetClass.getCompanionObjects().firstOrNull()
@@ -74,6 +83,7 @@ class KotlinMoveTargetForCompanion(val targetClass: KtClass): KotlinMoveTarget {
class KotlinMoveTargetForDeferredFile(
override val targetContainerFqName: FqName,
override val directory: PsiDirectory?,
override val targetFile: VirtualFile? = directory?.virtualFile,
private val createFile: (KtFile) -> KtFile?
): KotlinDirectoryBasedMoveTarget {
private val createdFiles = HashMap<KtFile, KtFile?>()

View File

@@ -90,7 +90,7 @@ class MoveDeclarationToSeparateFileIntention :
}
return
}
val moveTarget = KotlinMoveTargetForDeferredFile(packageName, directory) {
val moveTarget = KotlinMoveTargetForDeferredFile(packageName, directory, null) {
createKotlinFile(targetFileName, directory, packageName.asString())
}
val moveOptions = MoveDeclarationsDescriptor(

View File

@@ -22,20 +22,16 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMember
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.PsiReference
import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.refactoring.BaseRefactoringProcessor
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.move.MoveCallback
import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler
import com.intellij.refactoring.rename.RenameUtil
import com.intellij.refactoring.util.MoveRenameUsageInfo
import com.intellij.refactoring.util.NonCodeUsageInfo
import com.intellij.refactoring.util.RefactoringUIUtil
import com.intellij.refactoring.util.TextOccurrencesUtil
import com.intellij.refactoring.util.*
import com.intellij.usageView.UsageInfo
import com.intellij.usageView.UsageViewBundle
import com.intellij.usageView.UsageViewDescriptor
@@ -48,6 +44,7 @@ import gnu.trove.TObjectHashingStrategy
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.asJava.toLightElements
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
@@ -64,13 +61,11 @@ import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode
import org.jetbrains.kotlin.idea.search.projectScope
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.isInsideOf
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.keysToMap
import java.util.*
@@ -253,6 +248,39 @@ class MoveKotlinDeclarationsProcessor(
fun render(declaration: PsiElement) = RefactoringUIUtil.getDescription(declaration, false)
fun checkModuleConflictsInUsages(usages: List<UsageInfo>) {
val sourceRoot = descriptor.moveTarget.targetFile ?: return
RefactoringConflictsUtil.analyzeModuleConflicts(project, elementsToMove, usages.toTypedArray(), sourceRoot, conflicts)
}
fun checkModuleConflictsInDeclarations() {
val sourceRoot = descriptor.moveTarget.targetFile ?: return
val targetModule = ModuleUtilCore.findModuleForFile(sourceRoot, project) ?: return
val resolveScope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(targetModule)
for (declaration in elementsToMove) {
declaration.forEachDescendantOfType<KtReferenceExpression> { refExpr ->
refExpr.references
.forEach { ref ->
val target = ref.resolve() ?: return@forEach
if (target.isInsideOf(elementsToMove)) return@forEach
if (target in resolveScope) return@forEach
val superMethods = SmartSet.create<PsiMethod>()
target.toLightMethods().forEach { superMethods += it.findDeepestSuperMethods() }
if (superMethods.any { it in resolveScope }) return@forEach
val refContainer = ref.element.getStrictParentOfType<KtNamedDeclaration>() ?: return@forEach
val scopeDescription = RefactoringUIUtil.getDescription(refContainer, true)
val message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.in.module.2",
RefactoringUIUtil.getDescription(target, true),
scopeDescription,
CommonRefactoringUtil.htmlEmphasize(targetModule.name))
conflicts.putValue(target, CommonRefactoringUtil.capitalize(message))
}
}
}
}
fun checkVisibilityInUsages(usages: List<UsageInfo>) {
val declarationToContainers = HashMap<KtNamedDeclaration, MutableSet<PsiElement>>()
for (usage in usages) {
@@ -319,6 +347,8 @@ class MoveKotlinDeclarationsProcessor(
usages += descriptor.delegate.findUsages(descriptor)
collectUsages(kotlinToLightElements, usages)
checkModuleConflictsInUsages(usages)
checkModuleConflictsInDeclarations()
checkVisibilityInUsages(usages)
checkVisibilityInDeclarations()
descriptor.delegate.collectConflicts(descriptor, usages, conflicts)

View File

@@ -375,6 +375,7 @@ public class MoveKotlinNestedClassesToUpperLevelDialog extends MoveDialogBase {
moveTarget = new KotlinMoveTargetForDeferredFile(
targetPackageFqName,
targetDir,
null,
new Function1<KtFile, KtFile>() {
@Override
public KtFile invoke(@NotNull KtFile originalFile) {

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui;
import com.intellij.ide.util.DirectoryChooser;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -25,9 +26,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.JavaProjectRootsUtil;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.MoveDestination;
@@ -38,7 +42,10 @@ import com.intellij.refactoring.classMembers.MemberInfoChange;
import com.intellij.refactoring.classMembers.MemberInfoChangeListener;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveHandler;
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil;
import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination;
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.ui.RefactoringDialog;
@@ -59,8 +66,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinFileType;
import org.jetbrains.kotlin.idea.core.PackageUtilsKt;
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtilKt;
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle;
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtilKt;
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo;
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel;
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable;
@@ -103,6 +110,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
private KotlinMemberSelectionTable memberTable;
private final MoveCallback moveCallback;
private final PsiDirectory initialTargetDirectory;
public MoveKotlinTopLevelDeclarationsDialog(
@NotNull Project project,
@@ -120,6 +128,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
List<KtFile> sourceFiles = getSourceFiles(elementsToMove);
this.moveCallback = moveCallback;
this.initialTargetDirectory = targetDirectory;
init();
@@ -440,7 +449,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
}
@Nullable
private MoveDestination selectPackageBasedMoveDestination(boolean askIfDoesNotExist) {
private Pair<VirtualFile, ? extends MoveDestination> selectPackageBasedTargetDirAndDestination(boolean askIfDoesNotExist) {
String packageName = getTargetPackage();
RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, packageName);
@@ -451,7 +460,18 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
if (ret != Messages.YES) return null;
}
return ((DestinationFolderComboBox) destinationFolderCB).selectDirectory(targetPackage, false);
DirectoryChooser.ItemWrapper selectedItem = (DirectoryChooser.ItemWrapper)destinationFolderCB.getComboBox().getSelectedItem();
PsiDirectory selectedPsiDirectory = selectedItem.getDirectory();
if (selectedPsiDirectory == null) return Pair.create(null, new MultipleRootsMoveDestination(targetPackage));
VirtualFile targetDirectory = selectedPsiDirectory.getVirtualFile();
List<VirtualFile> sourceRoots = JavaProjectRootsUtil.getSuitableDestinationSourceRoots(getProject());
if (initialTargetDirectory != null && Comparing.equal(targetDirectory, initialTargetDirectory.getVirtualFile()) &&
sourceRoots.size() > 1) {
targetDirectory = MoveClassesOrPackagesUtil.chooseSourceRoot(targetPackage, sourceRoots, initialTargetDirectory);
}
if (targetDirectory == null) return null;
return Pair.create(targetDirectory, new AutocreatingSingleSourceRootMoveDestination(targetPackage, targetDirectory));
}
private boolean checkTargetFileName(String fileName) {
@@ -508,8 +528,11 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
PsiDirectory sourceDirectory = getSourceDirectory(sourceFiles);
if (isMoveToPackage()) {
final MoveDestination moveDestination = selectPackageBasedMoveDestination(true);
if (moveDestination == null) return null;
Pair<VirtualFile, ? extends MoveDestination> targetDirWithMoveDestination = selectPackageBasedTargetDirAndDestination(true);
if (targetDirWithMoveDestination == null) return null;
VirtualFile targetDir = targetDirWithMoveDestination.getFirst();
final MoveDestination moveDestination = targetDirWithMoveDestination.getSecond();
final String targetFileName = sourceFiles.size() > 1 ? null : tfFileNameInPackage.getText();
if (targetFileName != null && !checkTargetFileName(targetFileName)) return null;
@@ -555,6 +578,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
return new KotlinMoveTargetForDeferredFile(
new FqName(getTargetPackage()),
moveDestination.getTargetIfExists(sourceFiles.get(0)),
targetDir,
new Function1<KtFile, KtFile>() {
@Override
public KtFile invoke(@NotNull KtFile originalFile) {
@@ -610,6 +634,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
return new KotlinMoveTargetForDeferredFile(
targetPackageFqName,
psiDirectory,
null,
new Function1<KtFile, KtFile>() {
@Override
public KtFile invoke(@NotNull KtFile originalFile) {
@@ -705,8 +730,10 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
if (isFullFileMove()) {
if (isMoveToPackage()) {
final MoveDestination moveDestination = selectPackageBasedMoveDestination(false);
Pair<VirtualFile, ? extends MoveDestination> sourceRootWithMoveDestination = selectPackageBasedTargetDirAndDestination(false);
//noinspection ConstantConditions
final MoveDestination moveDestination = sourceRootWithMoveDestination.getSecond();
PsiDirectory targetDir = moveDestination.getTargetIfExists(sourceDirectory);
final String targetFileName = sourceFiles.size() > 1 ? null : tfFileNameInPackage.getText();
List<PsiFile> filesExistingInTargetDir = getFilesExistingInTargetDir(sourceFiles, targetFileName, targetDir);

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,4 @@
package a
val val1 = 0
val val2 = val1

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,4 @@
package a
val <caret>val1 = 0
val val2 = val1

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,2 @@
Property a.val1, referenced in file test.kt, will not be accessible from module A
Property a.val1, referenced in file test.kt, will not be accessible from module A

View File

@@ -0,0 +1,8 @@
{
"mainFile": "A/src/a/test.kt",
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
"targetPackage": "target",
"targetSourceRoot": "B/src",
"isMultiModule": "true",
"withRuntime": "true"
}

View File

@@ -19,11 +19,15 @@ package org.jetbrains.kotlin.idea.refactoring.move
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.intellij.codeInsight.TargetElementUtilBase
import com.intellij.ide.highlighter.ModuleFileType
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileVisitor
import com.intellij.psi.*
import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException
import com.intellij.refactoring.PackageWrapper
@@ -36,6 +40,7 @@ import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectori
import com.intellij.refactoring.move.moveInner.MoveInnerProcessor
import com.intellij.refactoring.move.moveMembers.MockMoveMembersOptions
import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor
import com.intellij.testFramework.PsiTestUtil
import com.intellij.util.ActionRunner
import org.jetbrains.kotlin.idea.jsonUtils.getNullableString
import org.jetbrains.kotlin.idea.jsonUtils.getString
@@ -59,6 +64,8 @@ import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractMoveTest : KotlinMultiFileTestCase() {
private var isMultiModule = false
protected fun doTest(path: String) {
val config = JsonParser().parse(FileUtil.loadFile(File(path), true)) as JsonObject
@@ -73,6 +80,7 @@ abstract class AbstractMoveTest : KotlinMultiFileTestCase() {
if (withRuntime) {
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk())
}
isMultiModule = config["isMultiModule"]?.asBoolean ?: false
doTest({ rootDir, rootAfter ->
val mainFile = rootDir.findFileByRelativePath(mainFilePath)!!
@@ -112,6 +120,27 @@ abstract class AbstractMoveTest : KotlinMultiFileTestCase() {
getTestDirName(true))
}
override fun prepareProject(rootDir: VirtualFile) {
if (isMultiModule) {
VfsUtilCore.visitChildrenRecursively(
rootDir,
object : VirtualFileVisitor<Any>() {
override fun visitFile(file: VirtualFile): Boolean {
if (!file.isDirectory && file.name.endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) {
createModule(File(file.path), StdModuleTypes.JAVA)
return false
}
return true
}
}
)
}
else {
PsiTestUtil.addSourceContentToRoots(myModule, rootDir)
}
}
protected fun getTestDirName(lowercaseFirstLetter : Boolean) : String {
val testName = getTestName(lowercaseFirstLetter)
return testName.substring(0, testName.lastIndexOf('_')).replace('_', '/')
@@ -250,8 +279,16 @@ enum class MoveAction {
val elementToMove = elementAtCaret!!.getNonStrictParentOfType<KtNamedDeclaration>()!!
val moveTarget = config.getNullableString("targetPackage")?.let { packageName ->
val targetSourceRootPath = config["targetSourceRoot"]?.asString
val moveDestination = MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), packageName))
KotlinMoveTargetForDeferredFile(FqName(packageName), moveDestination.getTargetIfExists(mainFile)) {
val targetDir = moveDestination.getTargetIfExists(mainFile)
val targetSourceRoot = if (targetSourceRootPath != null) {
rootDir.findFileByRelativePath(targetSourceRootPath)!!
} else {
targetDir?.virtualFile
}
KotlinMoveTargetForDeferredFile(FqName(packageName), targetDir, targetSourceRoot) {
createKotlinFile(guessNewFileName(listOf(elementToMove))!!, moveDestination.getTargetDirectory(mainFile))
}
} ?: config.getString("targetFile").let { filePath ->
@@ -298,7 +335,7 @@ enum class MoveAction {
val fileName = (delegate.newClassName ?: elementToMove.name!!) + ".kt"
val targetPackageFqName = (mainFile as KtFile).packageFqName
val targetDir = mainFile.containingDirectory!!
KotlinMoveTargetForDeferredFile(targetPackageFqName, targetDir) {
KotlinMoveTargetForDeferredFile(targetPackageFqName, targetDir, null) {
createKotlinFile(fileName, targetDir, targetPackageFqName.asString())
}
}

View File

@@ -437,6 +437,12 @@ public class MoveTestGenerated extends AbstractMoveTest {
doTest(fileName);
}
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/moveToUnrelatedModuleConflict/moveToUnrelatedModuleConflict.test")
public void testKotlin_moveTopLevelDeclarations_misc_moveToUnrelatedModuleConflict_MoveToUnrelatedModuleConflict() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/moveToUnrelatedModuleConflict/moveToUnrelatedModuleConflict.test");
doTest(fileName);
}
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/selfReferences/selfReferences.test")
public void testKotlin_moveTopLevelDeclarations_misc_selfReferences_SelfReferences() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/selfReferences/selfReferences.test");