Copy: Copy entire file if it contains just a selected declaration

This commit is contained in:
Alexey Sedunov
2017-09-19 19:18:24 +03:00
parent c8c0ab1647
commit 6e59cc2140
14 changed files with 94 additions and 4 deletions
@@ -187,6 +187,8 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() {
val originalFile = elementsToCopy.first().containingFile as KtFile val originalFile = elementsToCopy.first().containingFile as KtFile
val initialTargetDirectory = defaultTargetDirectory ?: originalFile.containingDirectory ?: return val initialTargetDirectory = defaultTargetDirectory ?: originalFile.containingDirectory ?: return
val isSingleDeclarationInFile = singleElementToCopy is KtNamedDeclaration && originalFile.declarations.singleOrNull() == singleElementToCopy
val project = initialTargetDirectory.project val project = initialTargetDirectory.project
val commandName = "Copy Declarations" val commandName = "Copy Declarations"
@@ -249,16 +251,24 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() {
val oldToNewElementsMapping = HashMap<PsiElement, PsiElement>() val oldToNewElementsMapping = HashMap<PsiElement, PsiElement>()
val fileToCopy = when {
singleElementToCopy is KtFile -> singleElementToCopy
isSingleDeclarationInFile -> originalFile
else -> null
}
val targetFile: KtFile val targetFile: KtFile
if (singleElementToCopy is KtFile) { val copiedDeclaration: KtNamedDeclaration?
if (fileToCopy != null) {
targetFile = runWriteAction { targetFile = runWriteAction {
val copiedFile = targetDirectory.copyFileFrom(targetFileName, singleElementToCopy) as KtFile val copiedFile = targetDirectory.copyFileFrom(targetFileName, fileToCopy) as KtFile
if (singleElementToCopy.packageMatchesDirectory()) { if (fileToCopy.packageMatchesDirectory()) {
targetDirectory.getPackage()?.qualifiedName?.let { copiedFile.packageFqName = FqName(it) } targetDirectory.getPackage()?.qualifiedName?.let { copiedFile.packageFqName = FqName(it) }
} }
performDelayedRefactoringRequests(project) performDelayedRefactoringRequests(project)
copiedFile copiedFile
} }
copiedDeclaration = if (isSingleDeclarationInFile) targetFile.declarations.singleOrNull() as? KtNamedDeclaration else null
} }
else { else {
targetFile = getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand targetFile = getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand
@@ -274,9 +284,10 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() {
performDelayedRefactoringRequests(project) performDelayedRefactoringRequests(project)
} }
copiedDeclaration = oldToNewElementsMapping.values.filterIsInstance<KtNamedDeclaration>().singleOrNull()
} }
(oldToNewElementsMapping.values.filterIsInstance<KtNamedDeclaration>().singleOrNull())?.let { newDeclaration -> copiedDeclaration?.let { newDeclaration ->
if (newName == newDeclaration.name) return@let if (newName == newDeclaration.name) return@let
val selfReferences = ReferencesSearch.search(newDeclaration, LocalSearchScope(newDeclaration)).findAll() val selfReferences = ReferencesSearch.search(newDeclaration, LocalSearchScope(newDeclaration)).findAll()
runWriteAction { runWriteAction {
@@ -0,0 +1,7 @@
package bar
// test
class A
// test2
@@ -0,0 +1,7 @@
package foo
// test
class A
// test2
@@ -0,0 +1,7 @@
package foo
// test
class <caret>A
// test2
@@ -0,0 +1,4 @@
{
"mainFile": "foo/A.kt",
"targetPackage": "bar"
}
@@ -0,0 +1,7 @@
package bar
// test
class B
// test2
@@ -0,0 +1,7 @@
package foo
// test
class A
// test2
@@ -0,0 +1,7 @@
package foo
// test
class <caret>A
// test2
@@ -0,0 +1,5 @@
{
"mainFile": "foo/A.kt",
"targetPackage": "bar",
"newName": "B"
}
@@ -5,3 +5,7 @@ import foo.J.JJJ
fun test() { fun test() {
val x = JJJ val x = JJJ
} }
fun dummy() {
}
@@ -5,3 +5,7 @@ import foo.J.JJJ
fun <caret>test() { fun <caret>test() {
val x = JJJ val x = JJJ
} }
fun dummy() {
}
@@ -5,3 +5,7 @@ import foo.J.jjj
fun test() { fun test() {
jjj() jjj()
} }
fun dummy() {
}
@@ -5,3 +5,7 @@ import foo.J.jjj
fun <caret>test() { fun <caret>test() {
jjj() jjj()
} }
fun dummy() {
}
@@ -168,12 +168,24 @@ public class CopyTestGenerated extends AbstractCopyTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("copySingleClass/copySingleClass.test")
public void testCopySingleClass_CopySingleClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copySingleClass/copySingleClass.test");
doTest(fileName);
}
@TestMetadata("copySingleClassFile/copySingleClassFile.test") @TestMetadata("copySingleClassFile/copySingleClassFile.test")
public void testCopySingleClassFile_CopySingleClassFile() throws Exception { public void testCopySingleClassFile_CopySingleClassFile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copySingleClassFile/copySingleClassFile.test"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copySingleClassFile/copySingleClassFile.test");
doTest(fileName); doTest(fileName);
} }
@TestMetadata("copySingleClassWithRename/copySingleClassWithRename.test")
public void testCopySingleClassWithRename_CopySingleClassWithRename() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copySingleClassWithRename/copySingleClassWithRename.test");
doTest(fileName);
}
@TestMetadata("copyTopLevelFunction/copyTopLevelFunction.test") @TestMetadata("copyTopLevelFunction/copyTopLevelFunction.test")
public void testCopyTopLevelFunction_CopyTopLevelFunction() throws Exception { public void testCopyTopLevelFunction_CopyTopLevelFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test");