Move: Fix exception on moving top-level declaration from/to script file
#KT-20260 Fixed
This commit is contained in:
@@ -579,3 +579,12 @@ fun KtNamedDeclaration.safeFqNameForLazyResolve(): FqName? {
|
|||||||
val parentFqName = KtNamedDeclarationUtil.getParentFqName(this)
|
val parentFqName = KtNamedDeclarationUtil.getParentFqName(this)
|
||||||
return parentFqName?.child(safeNameForLazyResolve())
|
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isTopLevelInFileOrScript
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() {
|
class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() {
|
||||||
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
||||||
val getContainer: (PsiElement) -> PsiElement? =
|
val getContainer: (PsiElement) -> PsiElement? =
|
||||||
if (elements.any { it.parent !is KtFile }) { e ->
|
if (elements.any { !isTopLevelInFileOrScript(it) }) { e ->
|
||||||
when (e) {
|
when (e) {
|
||||||
is KtNamedDeclaration -> e.containingClassOrObject ?: e.parent
|
is KtNamedDeclaration -> e.containingClassOrObject ?: e.parent
|
||||||
is KtFile -> 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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isTopLevelInFileOrScript
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() {
|
class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() {
|
||||||
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
private fun getUniqueContainer(elements: Array<out PsiElement>): PsiElement? {
|
||||||
val getContainer: (PsiElement) -> PsiElement? =
|
val getContainer: (PsiElement) -> PsiElement? =
|
||||||
if (elements.any { it.parent !is KtFile }) { e ->
|
if (elements.any { !isTopLevelInFileOrScript(it) }) { e ->
|
||||||
when (e) {
|
when (e) {
|
||||||
is KtNamedDeclaration -> e.containingClassOrObject ?: e.parent
|
is KtNamedDeclaration -> e.containingClassOrObject ?: e.parent
|
||||||
is KtFile -> e.parent
|
is KtFile -> e.parent
|
||||||
|
|||||||
+5
-1
@@ -71,7 +71,11 @@ interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
|
|||||||
object Default : Mover {
|
object Default : Mover {
|
||||||
override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement): KtNamedDeclaration {
|
override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement): KtNamedDeclaration {
|
||||||
return when (targetContainer) {
|
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)
|
is KtClassOrObject -> targetContainer.addDeclaration(originalElement)
|
||||||
else -> error("Unexpected element: ${targetContainer.getElementTextWithContext()}")
|
else -> error("Unexpected element: ${targetContainer.getElementTextWithContext()}")
|
||||||
}.apply {
|
}.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.refactoring.ui.KotlinFileChooserDialog;
|
||||||
import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt;
|
import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclarationContainer;
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
||||||
|
|
||||||
@@ -77,6 +78,8 @@ import java.io.File;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
|
||||||
public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
||||||
private static final String RECENTS_KEY = "MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY";
|
private static final String RECENTS_KEY = "MoveKotlinTopLevelDeclarationsDialog.RECENTS_KEY";
|
||||||
private final MoveCallback moveCallback;
|
private final MoveCallback moveCallback;
|
||||||
@@ -169,7 +172,8 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
new Function1<KtFile, Iterable<?>>() {
|
new Function1<KtFile, Iterable<?>>() {
|
||||||
@Override
|
@Override
|
||||||
public Iterable<?> invoke(KtFile jetFile) {
|
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 String targetFileName,
|
||||||
@Nullable final PsiDirectory targetDirectory
|
@Nullable final PsiDirectory targetDirectory
|
||||||
) {
|
) {
|
||||||
if (targetDirectory == null) return Collections.emptyList();
|
if (targetDirectory == null) return emptyList();
|
||||||
|
|
||||||
List<String> fileNames =
|
List<String> fileNames =
|
||||||
targetFileName != null
|
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");
|
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")
|
@TestMetadata("kotlin/moveTopLevelDeclarations/misc/classWithInitializer/delegateInObject.test")
|
||||||
public void testKotlin_moveTopLevelDeclarations_misc_classWithInitializer_DelegateInObject() throws Exception {
|
public void testKotlin_moveTopLevelDeclarations_misc_classWithInitializer_DelegateInObject() throws Exception {
|
||||||
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/classWithInitializer/delegateInObject.test");
|
runTest("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/classWithInitializer/delegateInObject.test");
|
||||||
|
|||||||
Reference in New Issue
Block a user