diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt index 9cda2eb287a..9ea11a45295 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt @@ -19,14 +19,12 @@ package org.jetbrains.kotlin.idea.refactoring.copy import com.intellij.ide.util.EditorHelper import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.ui.Messages import com.intellij.openapi.util.Key import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.psi.PsiNamedElement import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.copy.CopyFilesOrDirectoriesDialog @@ -74,7 +72,13 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { } override fun canCopy(elements: Array, fromUpdate: Boolean): Boolean { - return elements.flatMap { it.getElementsToCopy().ifEmpty { return false } }.distinctBy { it.containingFile }.size == 1 + val containingFile = + elements + .flatMap { it.getElementsToCopy().ifEmpty { return false } } + .distinctBy { it.containingFile } + .singleOrNull() + ?.containingFile ?: return false + return containingFile.sourceRoot != null } enum class ExistingFilePolicy { diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/A.iml b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/A.iml new file mode 100644 index 00000000000..c90834f2d60 --- /dev/null +++ b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/A.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/bar/dummy.txt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/bar/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/bar/test.kt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/bar/test.kt new file mode 100644 index 00000000000..81faec63931 --- /dev/null +++ b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/bar/test.kt @@ -0,0 +1,5 @@ +package foo + +fun test() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/foo/test.kt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/foo/test.kt new file mode 100644 index 00000000000..81faec63931 --- /dev/null +++ b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +fun test() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/src/dummy.kt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/after/A/src/dummy.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/A.iml b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/A.iml new file mode 100644 index 00000000000..c90834f2d60 --- /dev/null +++ b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/A.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/bar/dummy.txt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/bar/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/foo/test.kt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/foo/test.kt new file mode 100644 index 00000000000..81faec63931 --- /dev/null +++ b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +fun test() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/src/dummy.kt b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/before/A/src/dummy.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/fileNotUnderSourceRoot.test b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/fileNotUnderSourceRoot.test new file mode 100644 index 00000000000..4808870688e --- /dev/null +++ b/idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/fileNotUnderSourceRoot.test @@ -0,0 +1,4 @@ +{ + "mainFile": "A/foo/test.kt", + "targetDirectory": "A/bar" +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/MultiModuleCopyTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/MultiModuleCopyTestGenerated.java index 5d9e2ef1dcf..c2de4b583f9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/MultiModuleCopyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/MultiModuleCopyTestGenerated.java @@ -36,6 +36,12 @@ public class MultiModuleCopyTestGenerated extends AbstractMultiModuleCopyTest { KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClass(this.getClass(), new File("idea/testData/refactoring/copyMultiModule"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY); } + @TestMetadata("fileNotUnderSourceRoot/fileNotUnderSourceRoot.test") + public void testFileNotUnderSourceRoot_FileNotUnderSourceRoot() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copyMultiModule/fileNotUnderSourceRoot/fileNotUnderSourceRoot.test"); + doTest(fileName); + } + @TestMetadata("internalReferencesToAnotherModule2/internalReferencesToAnotherModule.test") public void testInternalReferencesToAnotherModule2_InternalReferencesToAnotherModule() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copyMultiModule/internalReferencesToAnotherModule2/internalReferencesToAnotherModule.test");