Move: Fix exception on moving top-level declaration from/to script file
#KT-20260 Fixed
This commit is contained in:
@@ -578,4 +578,13 @@ fun KtNamedDeclaration.safeFqNameForLazyResolve(): FqName? {
|
||||
//NOTE: should only create special names for package level declarations, so we can safely rely on real fq name for parent
|
||||
val parentFqName = KtNamedDeclarationUtil.getParentFqName(this)
|
||||
return parentFqName?.child(safeNameForLazyResolve())
|
||||
}
|
||||
|
||||
fun isTopLevelInFileOrScript(element: PsiElement): Boolean {
|
||||
val parent = element.parent
|
||||
return when (parent) {
|
||||
is KtFile -> true
|
||||
is KtBlockExpression -> parent.parent is KtScript
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -43,12 +43,13 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isTopLevelInFileOrScript
|
||||
import java.util.*
|
||||
|
||||
class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() {
|
||||
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
||||
val getContainer: (PsiElement) -> PsiElement? =
|
||||
if (elements.any { it.parent !is KtFile }) { e ->
|
||||
if (elements.any { !isTopLevelInFileOrScript(it) }) { e ->
|
||||
when (e) {
|
||||
is KtNamedDeclaration -> e.containingClassOrObject ?: e.parent
|
||||
is KtFile -> e.parent
|
||||
|
||||
+2
-1
@@ -43,12 +43,13 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isTopLevelInFileOrScript
|
||||
import java.util.*
|
||||
|
||||
class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() {
|
||||
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
||||
val getContainer: (PsiElement) -> PsiElement? =
|
||||
if (elements.any { it.parent !is KtFile }) { e ->
|
||||
if (elements.any { !isTopLevelInFileOrScript(it) }) { e ->
|
||||
when (e) {
|
||||
is KtNamedDeclaration -> e.containingClassOrObject ?: e.parent
|
||||
is KtFile -> e.parent
|
||||
|
||||
+5
-1
@@ -71,7 +71,11 @@ interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
|
||||
object Default : Mover {
|
||||
override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement): KtNamedDeclaration {
|
||||
return when (targetContainer) {
|
||||
is KtFile -> targetContainer.add(originalElement) as KtNamedDeclaration
|
||||
is KtFile -> {
|
||||
val declarationContainer: KtElement =
|
||||
if (targetContainer.isScript()) targetContainer.script!!.blockExpression else targetContainer
|
||||
declarationContainer.add(originalElement) as KtNamedDeclaration
|
||||
}
|
||||
is KtClassOrObject -> targetContainer.addDeclaration(originalElement)
|
||||
else -> error("Unexpected element: ${targetContainer.getElementTextWithContext()}")
|
||||
}.apply {
|
||||
|
||||
+6
-2
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*;
|
||||
import org.jetbrains.kotlin.idea.refactoring.ui.KotlinFileChooserDialog;
|
||||
import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationContainer;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
||||
|
||||
@@ -77,6 +78,8 @@ import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
||||
private static final String RECENTS_KEY = "MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY";
|
||||
private final MoveCallback moveCallback;
|
||||
@@ -169,7 +172,8 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
||||
new Function1<KtFile, Iterable<?>>() {
|
||||
@Override
|
||||
public Iterable<?> invoke(KtFile jetFile) {
|
||||
return jetFile.getDeclarations();
|
||||
KtDeclarationContainer container = jetFile.isScript() ? jetFile.getScript() : jetFile;
|
||||
return container != null ? container.getDeclarations() : emptyList();
|
||||
}
|
||||
}
|
||||
),
|
||||
@@ -190,7 +194,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
||||
@Nullable String targetFileName,
|
||||
@Nullable final PsiDirectory targetDirectory
|
||||
) {
|
||||
if (targetDirectory == null) return Collections.emptyList();
|
||||
if (targetDirectory == null) return emptyList();
|
||||
|
||||
List<String> fileNames =
|
||||
targetFileName != null
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class Foo
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
class Bar
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Foo
|
||||
|
||||
class <caret>Bar
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/test.kt",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetFile": "source/testNew.kts"
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class Foo
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
class Bar
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Foo
|
||||
|
||||
class <caret>Bar
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/test.kts",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetFile": "source/testNew.kt"
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class Foo
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
class Bar
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Foo
|
||||
|
||||
class <caret>Bar
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"mainFile": "source/test.kts",
|
||||
"type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS",
|
||||
"targetFile": "source/testNew.kts"
|
||||
}
|
||||
+15
@@ -479,6 +479,21 @@ public class MoveTestGenerated extends AbstractMoveTest {
|
||||
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/implicitInvokeCalls/differentTarget/differentTarget.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/classFromKtsToKt/classFromKtsToKt.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_classFromKtsToKt_ClassFromKtsToKt() throws Exception {
|
||||
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/classFromKtsToKt/classFromKtsToKt.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/classFromKtsToKts/classFromKtsToKts.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_classFromKtsToKts_ClassFromKtsToKts() throws Exception {
|
||||
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/classFromKtsToKts/classFromKtsToKts.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/classFromKtToKts/classFromKtToKts.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_classFromKtToKts_ClassFromKtToKts() throws Exception {
|
||||
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/classFromKtToKts/classFromKtToKts.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/classWithInitializer/delegateInObject.test")
|
||||
public void testKotlin_moveTopLevelDeclarations_misc_classWithInitializer_DelegateInObject() throws Exception {
|
||||
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/classWithInitializer/delegateInObject.test");
|
||||
|
||||
Reference in New Issue
Block a user