mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] Added ability to move nested declarations using K2 move refactoring
The nested declarations are first converted to be effectively static if they capture an outer class. ^KTIJ-28862 fixed GitOrigin-RevId: c035ba0350702f8934a1258b408521afc8736ea8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d3f50d6114
commit
e91c6650db
@@ -930,7 +930,7 @@ text.move.declaration.no.support.for.companion.objects=Move declaration is not s
|
||||
text.move.declaration.no.support.for.enums=Move declaration is not supported for enum entries
|
||||
text.move.file.no.support.for.file.target=Move files is not supported for non-directory target
|
||||
text.move.declaration.no.support.for.nested.declarations=Move declaration is not supported for nested declarations
|
||||
text.move.declaration.only.support.for.nested.classes=Move declaration is not supported for nested declarations other than nested classes
|
||||
text.move.declaration.only.support.for.some.nested.declarations=Move declaration is not supported for nested declarations other than nested classes, functions and properties
|
||||
text.move.declaration.only.support.for.single.elements=Move declaration is not supported for multiple nested declarations
|
||||
text.move.declaration.no.support.for.multi.file=Moving declarations from different files is not supported
|
||||
text.move.declaration.supports.only.top.levels.and.nested.classes=Move declaration is only supported for top-level declarations and nested classes
|
||||
|
||||
+60
@@ -1071,6 +1071,56 @@ public abstract class MoveTestGenerated extends AbstractMoveTest {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToObject/moveToObject.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/deepInnerToTopLevel/deepInnerToTopLevel.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_deepInnerToTopLevel_DeepInnerToTopLevel() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/deepInnerToTopLevel/deepInnerToTopLevel.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/dropEmptyCompanion/dropEmptyCompanion.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_dropEmptyCompanion_DropEmptyCompanion() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/dropEmptyCompanion/dropEmptyCompanion.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/externalFunctionUsageContextReceiver/externalFunctionUsageContextReceiver.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_externalFunctionUsageContextReceiver_ExternalFunctionUsageContextReceiver() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/externalFunctionUsageContextReceiver/externalFunctionUsageContextReceiver.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/externalFunctionUsageFromJava/externalFunctionUsageFromJava.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_externalFunctionUsageFromJava_ExternalFunctionUsageFromJava() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/externalFunctionUsageFromJava/externalFunctionUsageFromJava.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/externalFunctionUsage/externalFunctionUsage.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_externalFunctionUsage_ExternalFunctionUsage() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/externalFunctionUsage/externalFunctionUsage.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/implicitReceiver/implicitReceiver.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_implicitReceiver_ImplicitReceiver() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/implicitReceiver/implicitReceiver.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/implicitRefToCompanionObject/implicitRefToCompanionObject.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_implicitRefToCompanionObject_ImplicitRefToCompanionObject() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/implicitRefToCompanionObject/implicitRefToCompanionObject.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/nameClash/nameClash.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_nameClash_NameClash() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/nameClash/nameClash.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/outerInstanceAddParameter/outerInstanceAddParameter.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_outerInstanceAddParameter_OuterInstanceAddParameter() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/outerInstanceAddParameter/outerInstanceAddParameter.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/outerInstanceDontAddParameter/outerInstanceDontAddParameter.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_outerInstanceDontAddParameter_OuterInstanceDontAddParameter() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/outerInstanceDontAddParameter/outerInstanceDontAddParameter.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveNestedClass/callableReferences/nestedToAnotherClass/nestedToAnotherClass.test")
|
||||
public void testKotlin_moveNestedClass_callableReferences_nestedToAnotherClass_NestedToAnotherClass() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveNestedClass/callableReferences/nestedToAnotherClass/nestedToAnotherClass.test");
|
||||
@@ -1215,5 +1265,15 @@ public abstract class MoveTestGenerated extends AbstractMoveTest {
|
||||
public void testKotlin_moveNestedClass_protectedClass_ProtectedClass() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveNestedClass/protectedClass/protectedClass.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveProperty/moveToTopLevel/moveWithInstanceReference/moveWithInstanceReference.test")
|
||||
public void testKotlin_moveProperty_moveToTopLevel_moveWithInstanceReference_MoveWithInstanceReference() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveProperty/moveToTopLevel/moveWithInstanceReference/moveWithInstanceReference.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveProperty/moveToTopLevel/moveWithoutInstanceReference/moveWithoutInstanceReference.test")
|
||||
public void testKotlin_moveProperty_moveToTopLevel_moveWithoutInstanceReference_MoveWithoutInstanceReference() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveProperty/moveToTopLevel/moveWithoutInstanceReference/moveWithoutInstanceReference.test");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
|
||||
object A {
|
||||
}
|
||||
|
||||
private fun foo() = 1
|
||||
@@ -1,8 +1,10 @@
|
||||
// IGNORE_K1
|
||||
// "Propagate 'MyExperimentalAPI' opt-in requirement to containing class 'Derived'" "false"
|
||||
// COMPILER_ARGUMENTS: -opt-in=kotlin.RequiresOptIn
|
||||
// WITH_STDLIB
|
||||
// ACTION: Enable a trailing comma by default in the formatter
|
||||
// ACTION: Go To Super Method
|
||||
// ACTION: Move to top level
|
||||
// ACTION: Opt in for 'MyExperimentalAPI' in containing file 'override.kt'
|
||||
// ACTION: Opt in for 'MyExperimentalAPI' in module 'light_idea_test_case'
|
||||
// ACTION: Opt in for 'MyExperimentalAPI' on 'foo'
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test.Test2.Test3): Int {
|
||||
println(this@Test2)
|
||||
return Test.a + test.b
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
inner class Test2 {
|
||||
inner class Test3 {
|
||||
val b: Int = 5
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
inner class Test2 {
|
||||
inner class Test3 {
|
||||
val b: Int = 5
|
||||
fun foo<caret>(): Int {
|
||||
println(this@Test2)
|
||||
return a + b
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Indirect outer instances won't be extracted: a
|
||||
Indirect outer instances won't be extracted: this@Test2
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package bar
|
||||
|
||||
fun foo(): Int = 5
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
companion object {
|
||||
fun foo<caret>(): Int = 5
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test, b: Int): Int {
|
||||
return test.a + b
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
}
|
||||
|
||||
fun outside(test: Test): Int {
|
||||
return foo(test, 5)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
fun foo<caret>(b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
}
|
||||
|
||||
fun outside(test: Test): Int {
|
||||
return test.foo(5)
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test, b: Int): Int {
|
||||
return test.a + b
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
}
|
||||
|
||||
fun Test.outside(): Int {
|
||||
return foo(this, 5)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
fun foo<caret>(b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
}
|
||||
|
||||
fun Test.outside(): Int {
|
||||
return foo(5)
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package bar;
|
||||
|
||||
class JavaClass {
|
||||
public void test() {
|
||||
new Test().foo(5);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test, b: Int): Int {
|
||||
return test.a + b
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package bar;
|
||||
|
||||
class JavaClass {
|
||||
public void test() {
|
||||
new Test().foo(5);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
fun foo<caret>(b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "bar/test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test): Int {
|
||||
return test.test()
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
fun test(): Int = 5
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
fun test(): Int = 5
|
||||
|
||||
fun foo<caret>(): Int {
|
||||
return test()
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package bar
|
||||
|
||||
fun foo(): Int {
|
||||
// TODO: The .Companion parts here can be removed after KT-64842 is fixed
|
||||
return Test.Companion.a + Test.Companion.a
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
companion object {
|
||||
val a: Int = 5
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
companion object {
|
||||
val a: Int = 5
|
||||
fun foo<caret>(): Int {
|
||||
// TODO: The .Companion parts here can be removed after KT-64842 is fixed
|
||||
return a + a
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test, b: Int): Int {
|
||||
return test.a + test.a
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
}
|
||||
|
||||
fun foo(test: Test, b: Int): Int {
|
||||
return 5
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
fun foo<caret>(b: Int): Int {
|
||||
return a + a
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(test: Test, b: Int): Int {
|
||||
return 5
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Following declarations would clash: to move class test.A.C and destination class test.C declared in scope test
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(test: Test): Int {
|
||||
return test.a + test.a
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int = 5
|
||||
fun foo<caret>(): Int {
|
||||
return a + a
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
fun foo(): Int {
|
||||
return Test.a + Test.a
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a: Int
|
||||
fun foo<caret>(): Int {
|
||||
return a + a
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package bar
|
||||
|
||||
val foo: Int = Test.b + Test.b
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val b: Int = 5
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val b: Int = 5
|
||||
val foo<caret>: Int = b + b
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Usages of outer class instance inside of property 'foo' won't be processed
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package bar
|
||||
|
||||
val foo: Int = 5
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val foo<caret>: Int = 5
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mainFile": "test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+2
-2
@@ -46,7 +46,7 @@ abstract class K2BaseMoveDeclarationsRefactoringProcessor<T : DeclarationsMoveDe
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun collectConflicts(moveDescriptor: K2MoveDescriptor, allUsages: MutableSet<UsageInfo>) {}
|
||||
protected open fun collectConflicts(moveDescriptor: K2MoveDescriptor,allUsages: MutableSet<UsageInfo>) {}
|
||||
|
||||
override fun findUsages(): Array<UsageInfo> {
|
||||
if (!operationDescriptor.searchReferences) return emptyArray()
|
||||
@@ -97,7 +97,7 @@ abstract class K2BaseMoveDeclarationsRefactoringProcessor<T : DeclarationsMoveDe
|
||||
}
|
||||
}
|
||||
|
||||
protected val conflicts = MultiMap<PsiElement, String>()
|
||||
protected val conflicts: MultiMap<PsiElement, String> = MultiMap<PsiElement, String>()
|
||||
|
||||
override fun preprocessUsages(refUsages: Ref<Array<UsageInfo>>): Boolean {
|
||||
val usages = refUsages.get()
|
||||
|
||||
+89
-26
@@ -9,6 +9,7 @@ import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KaTypeRendererForSource
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KaClassSymbol
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.idea.base.analysis.api.utils.shortenReferences
|
||||
@@ -26,14 +27,35 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
operationDescriptor: K2MoveOperationDescriptor.NestedDeclarations,
|
||||
) : K2BaseMoveDeclarationsRefactoringProcessor<K2MoveOperationDescriptor.NestedDeclarations>(operationDescriptor) {
|
||||
private fun findInternalUsages(moveSource: K2MoveSourceDescriptor<*>): List<UsageInfo> {
|
||||
val classToMove = moveSource.elements.singleOrNull() as? KtClass ?: return emptyList()
|
||||
return collectOuterInstanceReferences(classToMove)
|
||||
val declarationToMove = moveSource.elements.singleOrNull() as? KtNamedDeclaration ?: return emptyList()
|
||||
return collectOuterInstanceReferences(declarationToMove)
|
||||
}
|
||||
|
||||
override fun getUsages(moveDescriptor: K2MoveDescriptor): List<UsageInfo> {
|
||||
return super.getUsages(moveDescriptor) + findInternalUsages(moveDescriptor.source)
|
||||
}
|
||||
|
||||
private enum class MoveType {
|
||||
CLASS, PROPERTY, FUNCTION, UNKNOWN
|
||||
}
|
||||
|
||||
private val moveType: MoveType by lazy {
|
||||
when (operationDescriptor.sourceElements.singleOrNull()) {
|
||||
is KtClass -> MoveType.CLASS
|
||||
is KtProperty -> MoveType.PROPERTY
|
||||
is KtNamedFunction -> MoveType.FUNCTION
|
||||
else -> MoveType.UNKNOWN
|
||||
}
|
||||
}
|
||||
private val elementToMove = operationDescriptor.sourceElements.single()
|
||||
|
||||
private fun willLoseOuterInstanceReference(): Boolean {
|
||||
// For properties, any outer instance reference is a conflict because we do not process them.
|
||||
val canReferenceOuterInstance = moveType != MoveType.PROPERTY && operationDescriptor.outerInstanceParameterName != null
|
||||
// For anything else, it is a conflict if it is contained in a class rather than an object
|
||||
return !canReferenceOuterInstance && elementToMove.containingClassOrObject !is KtObjectDeclaration
|
||||
}
|
||||
|
||||
override fun collectConflicts(
|
||||
moveDescriptor: K2MoveDescriptor,
|
||||
allUsages: MutableSet<UsageInfo>
|
||||
@@ -55,7 +77,18 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
true
|
||||
}
|
||||
|
||||
is OuterInstanceReferenceUsageInfo -> usage.reportConflictIfAny(conflicts)
|
||||
is OuterInstanceReferenceUsageInfo -> {
|
||||
if (moveType == MoveType.PROPERTY) {
|
||||
// For properties, any outer instance reference is a conflict because we do not process them.
|
||||
conflicts.putValue(
|
||||
element,
|
||||
KotlinBundle.message("usages.of.outer.class.instance.inside.of.property.0.won.t.be.processed", elementToMove.nameAsSafeName.asString())
|
||||
)
|
||||
true
|
||||
} else {
|
||||
usage.reportConflictIfAny(conflicts)
|
||||
}
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
@@ -73,17 +106,17 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
val outerInstanceParameterName = operationDescriptor.outerInstanceParameterName ?: return
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
val newOuterInstanceRef = psiFactory.createExpression(outerInstanceParameterName)
|
||||
val classToMove = moveSource.elements.singleOrNull() as? KtClass
|
||||
val declarationToMove = moveSource.elements.singleOrNull() as? KtNamedDeclaration
|
||||
|
||||
for (usage in usages) {
|
||||
if (usage is MoveRenameUsageInfo) {
|
||||
val referencedNestedClass = usage.referencedElement?.unwrapped as? KtClassOrObject
|
||||
if (referencedNestedClass == classToMove) {
|
||||
val outerClass = referencedNestedClass?.containingClassOrObject
|
||||
val referencedNestedDeclaration = usage.referencedElement?.unwrapped as? KtNamedDeclaration
|
||||
if (declarationToMove != null && referencedNestedDeclaration == declarationToMove) {
|
||||
val outerClass = referencedNestedDeclaration.containingClassOrObject
|
||||
val lightOuterClass = outerClass?.toLightClass()
|
||||
if (lightOuterClass != null) {
|
||||
MoveInnerClassUsagesHandler.EP_NAME
|
||||
.forLanguage(usage.element?.language ?: return)
|
||||
.forLanguage(usage.element?.language ?: continue)
|
||||
?.correctInnerClassUsage(usage, lightOuterClass, outerInstanceParameterName)
|
||||
}
|
||||
}
|
||||
@@ -106,26 +139,49 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
moveDescriptor: K2MoveDescriptor,
|
||||
originalDeclaration: KtNamedDeclaration
|
||||
) {
|
||||
val containingClass = originalDeclaration.containingClassOrObject
|
||||
val psiFactory = KtPsiFactory(originalDeclaration.project)
|
||||
val outerInstanceParameterName = operationDescriptor.outerInstanceParameterName
|
||||
with(originalDeclaration) {
|
||||
operationDescriptor.newClassName?.let { setName(it) }
|
||||
|
||||
if (this is KtClass) {
|
||||
// TODO: Potentially allow for moving into classes
|
||||
if (hasModifier(KtTokens.INNER_KEYWORD)) removeModifier(KtTokens.INNER_KEYWORD)
|
||||
if (hasModifier(KtTokens.PROTECTED_KEYWORD)) removeModifier(KtTokens.PROTECTED_KEYWORD)
|
||||
when (this) {
|
||||
is KtClass -> {
|
||||
// TODO: Potentially allow for moving into classes
|
||||
if (hasModifier(KtTokens.INNER_KEYWORD)) removeModifier(KtTokens.INNER_KEYWORD)
|
||||
if (hasModifier(KtTokens.PROTECTED_KEYWORD)) removeModifier(KtTokens.PROTECTED_KEYWORD)
|
||||
|
||||
operationDescriptor.outerInstanceParameterName?.let { outerInstanceParameterName ->
|
||||
val containingClass = containingClassOrObject ?: return
|
||||
analyze(originalDeclaration) {
|
||||
// Use the fully qualified type because we have not moved it to the new location yet
|
||||
val type = containingClass.classSymbol?.defaultType?.render(
|
||||
renderer = KaTypeRendererForSource.WITH_QUALIFIED_NAMES,
|
||||
position = Variance.INVARIANT
|
||||
) ?: return
|
||||
val parameter = KtPsiFactory(project).createParameter("private val $outerInstanceParameterName: $type")
|
||||
createPrimaryConstructorParameterListIfAbsent().addParameter(parameter)
|
||||
if (outerInstanceParameterName != null) {
|
||||
val containingClass = containingClassOrObject ?: return
|
||||
analyze(originalDeclaration) {
|
||||
// Use the fully qualified type because we have not moved it to the new location yet
|
||||
val type = containingClass.classSymbol?.defaultType?.render(
|
||||
renderer = KaTypeRendererForSource.WITH_QUALIFIED_NAMES,
|
||||
position = Variance.INVARIANT
|
||||
) ?: return
|
||||
val parameter = KtPsiFactory(project).createParameter("private val $outerInstanceParameterName: $type")
|
||||
createPrimaryConstructorParameterListIfAbsent().addParameter(parameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
is KtNamedFunction -> {
|
||||
if (outerInstanceParameterName != null) {
|
||||
val outerInstanceType = analyze(originalDeclaration) {
|
||||
val type = (containingClass?.symbol as? KaClassSymbol)?.defaultType ?: return@analyze null
|
||||
type.render(KaTypeRendererForSource.WITH_QUALIFIED_NAMES, Variance.INVARIANT)
|
||||
}
|
||||
if (outerInstanceType == null) return
|
||||
valueParameterList?.addParameterBefore(
|
||||
psiFactory.createParameter(
|
||||
"${outerInstanceParameterName}: $outerInstanceType"
|
||||
),
|
||||
valueParameterList?.parameters?.firstOrNull()
|
||||
)
|
||||
}
|
||||
}
|
||||
is KtProperty -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,9 +192,16 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
newDeclaration: PsiElement
|
||||
) {
|
||||
val outerInstanceParameterName = operationDescriptor.outerInstanceParameterName ?: return
|
||||
if (originalDeclaration !is KtClass || newDeclaration !is KtClass) return
|
||||
val primaryConstructor = newDeclaration.primaryConstructor ?: return
|
||||
val addedParameter = primaryConstructor.valueParameters.firstOrNull { it.name == outerInstanceParameterName } ?: return
|
||||
shortenReferences(addedParameter)
|
||||
when (newDeclaration) {
|
||||
is KtClass -> {
|
||||
val primaryConstructor = newDeclaration.primaryConstructor ?: return
|
||||
val addedParameter = primaryConstructor.valueParameters.firstOrNull { it.name == outerInstanceParameterName } ?: return
|
||||
shortenReferences(addedParameter)
|
||||
}
|
||||
is KtNamedFunction -> {
|
||||
val addedParameter = newDeclaration.valueParameterList?.parameters?.firstOrNull() ?: return
|
||||
shortenReferences(addedParameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -190,7 +190,7 @@ internal fun checkNameClashConflicts(
|
||||
"text.declarations.clash.move.0.destination.1.declared.in.scope.2",
|
||||
renderedDeclaration,
|
||||
conflictingSymbol.renderForConflict(),
|
||||
conflictingScope.renderForConflict(),
|
||||
conflictingScope.renderForConflict().ifBlank { "default" },
|
||||
)
|
||||
conflicts.putValue(declaration, message)
|
||||
}
|
||||
|
||||
+15
-12
@@ -229,7 +229,7 @@ sealed class K2MoveModel {
|
||||
override val target: K2MoveTargetModel.File,
|
||||
override val inSourceRoot: Boolean,
|
||||
outerClassName: String?,
|
||||
internal val isInnerClass: Boolean,
|
||||
internal val needsInstanceReference: Boolean,
|
||||
override val moveCallBack: MoveCallback? = null
|
||||
) : K2MoveModel() {
|
||||
|
||||
@@ -237,11 +237,11 @@ sealed class K2MoveModel {
|
||||
return super.isValidRefactoring() && isValidDeclarationsRefactoring(source, target)
|
||||
}
|
||||
|
||||
var passOuterClass: Boolean = isInnerClass
|
||||
private var passOuterClass: Boolean = needsInstanceReference
|
||||
var outerClassInstanceParameterName: String = outerClassName?.decapitalizeAsciiOnly() ?: "instance"
|
||||
|
||||
override fun buildPanel(panel: Panel) = with(panel) {
|
||||
if (isInnerClass) {
|
||||
if (needsInstanceReference) {
|
||||
lateinit var selected: ComponentPredicate
|
||||
row {
|
||||
selected = checkBox(KotlinBundle.message("pass.outer.class.instance.as.parameter"))
|
||||
@@ -270,7 +270,7 @@ sealed class K2MoveModel {
|
||||
searchReferences = searchReferences.state,
|
||||
dirStructureMatchesPkg = true,
|
||||
newClassName = null,
|
||||
outerInstanceParameterName = outerClassInstanceParameterName,
|
||||
outerInstanceParameterName = outerClassInstanceParameterName.takeIf { needsInstanceReference },
|
||||
moveCallBack = moveCallBack
|
||||
)
|
||||
}
|
||||
@@ -323,15 +323,16 @@ sealed class K2MoveModel {
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, elements.toList(), true)) return null
|
||||
|
||||
if (elementsToMove.any { it.parentOfType<KtNamedDeclaration>(withSelf = false) != null }) {
|
||||
if (elementsToMove.size != 1) {
|
||||
val singleElementToMove = elementsToMove.singleOrNull()
|
||||
if (singleElementToMove == null) {
|
||||
val message = RefactoringBundle.getCannotRefactorMessage(
|
||||
KotlinBundle.message("text.move.declaration.only.support.for.single.elements")
|
||||
)
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
||||
return null
|
||||
} else if (elementsToMove.single() !is KtClassOrObject) {
|
||||
} else if (singleElementToMove !is KtClassOrObject && singleElementToMove !is KtNamedFunction && singleElementToMove !is KtProperty) {
|
||||
val message = RefactoringBundle.getCannotRefactorMessage(
|
||||
KotlinBundle.message("text.move.declaration.only.support.for.nested.classes")
|
||||
KotlinBundle.message("text.move.declaration.only.support.for.some.nested.declarations")
|
||||
)
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, MOVE_DECLARATIONS, null)
|
||||
return null
|
||||
@@ -409,18 +410,20 @@ sealed class K2MoveModel {
|
||||
val psiDirectory = containingFile.containingDirectory ?: error("No directory found")
|
||||
K2MoveTargetModel.File(sourceFileName(), containingFile.packageFqName, psiDirectory)
|
||||
}
|
||||
val singleClassToMove = (elementsToMove.singleOrNull() as? KtClassOrObject)
|
||||
val singleDeclarationToMove = (elementsToMove.singleOrNull() as? KtNamedDeclaration)
|
||||
.takeIf { it !is KtObjectDeclaration || !it.isCompanion() }
|
||||
val outerClassName = (singleClassToMove?.parent?.parent as? KtClassOrObject?)?.name
|
||||
val outerClassName = (singleDeclarationToMove?.parent?.parent as? KtClassOrObject?)?.name
|
||||
|
||||
if (singleClassToMove?.containingClassOrObject != null) {
|
||||
if (singleDeclarationToMove?.containingClassOrObject != null) {
|
||||
val needsInstanceReference = (singleDeclarationToMove is KtClass && singleDeclarationToMove.isInner()) ||
|
||||
(singleDeclarationToMove is KtNamedFunction && singleDeclarationToMove.containingClassOrObject !is KtObjectDeclaration)
|
||||
NestedDeclarations(
|
||||
project = project,
|
||||
source = source,
|
||||
target = target,
|
||||
inSourceRoot = inSourceRoot,
|
||||
isInnerClass = singleClassToMove is KtClass && singleClassToMove.isInner(),
|
||||
outerClassName = outerClassName,
|
||||
needsInstanceReference = needsInstanceReference,
|
||||
outerClassName = outerClassName.takeIf { needsInstanceReference },
|
||||
moveCallBack = moveCallBack
|
||||
)
|
||||
} else {
|
||||
|
||||
+3
-3
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.K2MoveNestedDecla
|
||||
import org.jetbrains.kotlin.idea.refactoring.runRefactoringTest
|
||||
import org.jetbrains.kotlin.idea.util.sourceRoot
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
abstract class AbstractK2MoveNestedTest : AbstractMultifileMoveRefactoringTest() {
|
||||
@@ -37,9 +37,9 @@ internal object K2MoveNestedRefactoringAction : KotlinMoveRefactoringAction {
|
||||
val project = mainFile.project
|
||||
val type = config.getString("type")
|
||||
when (type) {
|
||||
"MOVE_KOTLIN_NESTED_CLASS" -> {
|
||||
"MOVE_KOTLIN_NESTED_CLASS", "MOVE_KOTLIN_NESTED_DECLARATION" -> {
|
||||
val project = mainFile.project
|
||||
val elementToMove = elementsAtCaret.single().getNonStrictParentOfType<KtClassOrObject>()!!
|
||||
val elementToMove = elementsAtCaret.single().getNonStrictParentOfType<KtNamedDeclaration>()!!
|
||||
val fileName = (elementToMove.name!!) + ".kt"
|
||||
val targetPackageFqName = config.getNullableString("targetPackage")?.let {
|
||||
FqName(it)
|
||||
|
||||
+117
-13
@@ -11,9 +11,7 @@ import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.move.ui.K2MoveModel
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
class K2MoveModelTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override val pluginMode: KotlinPluginMode
|
||||
@@ -336,6 +334,23 @@ class K2MoveModelTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
fun `test move multiple nested class should fail`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
class Outer<caret> {
|
||||
class Foo { }
|
||||
class Bar { }
|
||||
}
|
||||
""".trimIndent())
|
||||
val outerClass = myFixture.elementAtCaret as KtClass
|
||||
val nestedClasses = outerClass.declarations.filterIsInstance<KtClass>()
|
||||
assertEquals(2, nestedClasses.size)
|
||||
assertThrows(RefactoringErrorHintException::class.java) {
|
||||
K2MoveModel.create(nestedClasses.toTypedArray(), null)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test move nested class`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
@@ -354,8 +369,7 @@ class K2MoveModelTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
assert(sourceElement is KtClass && sourceElement.name == "Bar")
|
||||
val targetElement = moveDeclarationsModel.target.pkgName
|
||||
assertEquals("foo", targetElement.asString())
|
||||
assertEquals(false, moveDeclarationsModel.passOuterClass)
|
||||
assertEquals(false, moveDeclarationsModel.isInnerClass)
|
||||
assertEquals(false, moveDeclarationsModel.needsInstanceReference)
|
||||
}
|
||||
|
||||
fun `test move nested inner class`() {
|
||||
@@ -376,26 +390,71 @@ class K2MoveModelTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
assert(sourceElement is KtClass && sourceElement.name == "Bar")
|
||||
val targetElement = moveDeclarationsModel.target.pkgName
|
||||
assertEquals("foo", targetElement.asString())
|
||||
assertEquals(true, moveDeclarationsModel.passOuterClass)
|
||||
assertEquals("outerFoo", moveDeclarationsModel.outerClassInstanceParameterName)
|
||||
assertEquals(true, moveDeclarationsModel.isInnerClass)
|
||||
assertEquals(true, moveDeclarationsModel.needsInstanceReference)
|
||||
}
|
||||
|
||||
fun `test move instance method should fail`() {
|
||||
fun `test move instance method`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
class Foo {
|
||||
class OuterFoo {
|
||||
fun fo<caret>o() { }
|
||||
}
|
||||
""".trimIndent())
|
||||
val instanceMethod = myFixture.elementAtCaret as KtNamedDeclaration
|
||||
val moveModel = K2MoveModel.create(arrayOf(instanceMethod), null)
|
||||
assertInstanceOf<K2MoveModel.NestedDeclarations>(moveModel)
|
||||
assertTrue(moveModel!!.isValidRefactoring())
|
||||
val moveDeclarationsModel = moveModel as K2MoveModel.NestedDeclarations
|
||||
assertSize(1, moveDeclarationsModel.source.elements)
|
||||
val sourceElement = moveDeclarationsModel.source.elements.firstOrNull()
|
||||
assert(sourceElement is KtFunction && sourceElement.name == "foo")
|
||||
val targetElement = moveDeclarationsModel.target.pkgName
|
||||
assertEquals("foo", targetElement.asString())
|
||||
assertEquals("outerFoo", moveDeclarationsModel.outerClassInstanceParameterName)
|
||||
assertEquals(true, moveDeclarationsModel.needsInstanceReference)
|
||||
}
|
||||
|
||||
fun `test move multiple instance methods should fail`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
class Outer<caret> {
|
||||
fun foo() {}
|
||||
fun bar() {}
|
||||
}
|
||||
""".trimIndent())
|
||||
val outerClass = myFixture.elementAtCaret as KtClass
|
||||
val nestedFunctions = outerClass.declarations.filterIsInstance<KtFunction>()
|
||||
assertEquals(2, nestedFunctions.size)
|
||||
assertThrows(RefactoringErrorHintException::class.java) {
|
||||
K2MoveModel.create(arrayOf(instanceMethod), null)
|
||||
K2MoveModel.create(nestedFunctions.toTypedArray(), null)
|
||||
}
|
||||
}
|
||||
|
||||
fun `test move companion object method should fail`() {
|
||||
fun `test move object method`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
object OuterFoo {
|
||||
fun fo<caret>o() { }
|
||||
}
|
||||
""".trimIndent())
|
||||
val instanceMethod = myFixture.elementAtCaret as KtNamedDeclaration
|
||||
val moveModel = K2MoveModel.create(arrayOf(instanceMethod), null)
|
||||
assertInstanceOf<K2MoveModel.NestedDeclarations>(moveModel)
|
||||
assertTrue(moveModel!!.isValidRefactoring())
|
||||
val moveDeclarationsModel = moveModel as K2MoveModel.NestedDeclarations
|
||||
assertSize(1, moveDeclarationsModel.source.elements)
|
||||
val sourceElement = moveDeclarationsModel.source.elements.firstOrNull()
|
||||
assert(sourceElement is KtFunction && sourceElement.name == "foo")
|
||||
val targetElement = moveDeclarationsModel.target.pkgName
|
||||
assertEquals("foo", targetElement.asString())
|
||||
assertEquals(false, moveDeclarationsModel.needsInstanceReference)
|
||||
}
|
||||
|
||||
fun `test move companion object method`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
@@ -405,9 +464,54 @@ class K2MoveModelTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
}
|
||||
}
|
||||
""".trimIndent())
|
||||
val companionObjectMethod = myFixture.elementAtCaret as KtNamedDeclaration
|
||||
val instanceMethod = myFixture.elementAtCaret as KtNamedDeclaration
|
||||
val moveModel = K2MoveModel.create(arrayOf(instanceMethod), null)
|
||||
assertInstanceOf<K2MoveModel.NestedDeclarations>(moveModel)
|
||||
assertTrue(moveModel!!.isValidRefactoring())
|
||||
val moveDeclarationsModel = moveModel as K2MoveModel.NestedDeclarations
|
||||
assertSize(1, moveDeclarationsModel.source.elements)
|
||||
val sourceElement = moveDeclarationsModel.source.elements.firstOrNull()
|
||||
assert(sourceElement is KtFunction && sourceElement.name == "foo")
|
||||
val targetElement = moveDeclarationsModel.target.pkgName
|
||||
assertEquals("foo", targetElement.asString())
|
||||
assertEquals(false, moveDeclarationsModel.needsInstanceReference)
|
||||
}
|
||||
|
||||
fun `test move member property`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
class Foo {
|
||||
val foo<caret> = 5
|
||||
}
|
||||
""".trimIndent())
|
||||
val instanceProperty = myFixture.elementAtCaret as KtNamedDeclaration
|
||||
val moveModel = K2MoveModel.create(arrayOf(instanceProperty), null)
|
||||
assertInstanceOf<K2MoveModel.NestedDeclarations>(moveModel)
|
||||
assertTrue(moveModel!!.isValidRefactoring())
|
||||
val moveDeclarationsModel = moveModel as K2MoveModel.NestedDeclarations
|
||||
assertSize(1, moveDeclarationsModel.source.elements)
|
||||
val sourceElement = moveDeclarationsModel.source.elements.firstOrNull()
|
||||
assert(sourceElement is KtProperty && sourceElement.name == "foo")
|
||||
val targetElement = moveDeclarationsModel.target.pkgName
|
||||
assertEquals("foo", targetElement.asString())
|
||||
assertEquals(false, moveDeclarationsModel.needsInstanceReference)
|
||||
}
|
||||
|
||||
fun `test move multiple member properties should fal`() {
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, """
|
||||
package foo
|
||||
|
||||
class Outer<caret> {
|
||||
val foo = 5
|
||||
val bar = 5
|
||||
}
|
||||
""".trimIndent())
|
||||
val outerClass = myFixture.elementAtCaret as KtClass
|
||||
val nestedProperties = outerClass.declarations.filterIsInstance<KtProperty>()
|
||||
assertEquals(2, nestedProperties.size)
|
||||
assertThrows(RefactoringErrorHintException::class.java) {
|
||||
K2MoveModel.create(arrayOf(companionObjectMethod), null)
|
||||
K2MoveModel.create(nestedProperties.toTypedArray(), null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+60
@@ -195,6 +195,56 @@ public class K2MoveNestedTestGenerated extends AbstractK2MoveNestedTest {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToObject/moveToObject.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/deepInnerToTopLevel/deepInnerToTopLevel.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_deepInnerToTopLevel_DeepInnerToTopLevel() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/deepInnerToTopLevel/deepInnerToTopLevel.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/dropEmptyCompanion/dropEmptyCompanion.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_dropEmptyCompanion_DropEmptyCompanion() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/dropEmptyCompanion/dropEmptyCompanion.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/externalFunctionUsageContextReceiver/externalFunctionUsageContextReceiver.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_externalFunctionUsageContextReceiver_ExternalFunctionUsageContextReceiver() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/externalFunctionUsageContextReceiver/externalFunctionUsageContextReceiver.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/externalFunctionUsageFromJava/externalFunctionUsageFromJava.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_externalFunctionUsageFromJava_ExternalFunctionUsageFromJava() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/externalFunctionUsageFromJava/externalFunctionUsageFromJava.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/externalFunctionUsage/externalFunctionUsage.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_externalFunctionUsage_ExternalFunctionUsage() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/externalFunctionUsage/externalFunctionUsage.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/implicitReceiver/implicitReceiver.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_implicitReceiver_ImplicitReceiver() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/implicitReceiver/implicitReceiver.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/implicitRefToCompanionObject/implicitRefToCompanionObject.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_implicitRefToCompanionObject_ImplicitRefToCompanionObject() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/implicitRefToCompanionObject/implicitRefToCompanionObject.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/nameClash/nameClash.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_nameClash_NameClash() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/nameClash/nameClash.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/outerInstanceAddParameter/outerInstanceAddParameter.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_outerInstanceAddParameter_OuterInstanceAddParameter() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/outerInstanceAddParameter/outerInstanceAddParameter.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveMethod/moveToTopLevel/outerInstanceDontAddParameter/outerInstanceDontAddParameter.test")
|
||||
public void testKotlin_moveMethod_moveToTopLevel_outerInstanceDontAddParameter_OuterInstanceDontAddParameter() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveMethod/moveToTopLevel/outerInstanceDontAddParameter/outerInstanceDontAddParameter.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveNestedClass/callableReferences/nestedToAnotherClass/nestedToAnotherClass.test")
|
||||
public void testKotlin_moveNestedClass_callableReferences_nestedToAnotherClass_NestedToAnotherClass() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveNestedClass/callableReferences/nestedToAnotherClass/nestedToAnotherClass.test");
|
||||
@@ -339,4 +389,14 @@ public class K2MoveNestedTestGenerated extends AbstractK2MoveNestedTest {
|
||||
public void testKotlin_moveNestedClass_protectedClass_ProtectedClass() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveNestedClass/protectedClass/protectedClass.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveProperty/moveToTopLevel/moveWithInstanceReference/moveWithInstanceReference.test")
|
||||
public void testKotlin_moveProperty_moveToTopLevel_moveWithInstanceReference_MoveWithInstanceReference() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveProperty/moveToTopLevel/moveWithInstanceReference/moveWithInstanceReference.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveProperty/moveToTopLevel/moveWithoutInstanceReference/moveWithoutInstanceReference.test")
|
||||
public void testKotlin_moveProperty_moveToTopLevel_moveWithoutInstanceReference_MoveWithoutInstanceReference() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveProperty/moveToTopLevel/moveWithoutInstanceReference/moveWithoutInstanceReference.test");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ internal fun MutableTWorkspace.generateK2IntentionTests() {
|
||||
//model("${idea}intentions/loopToCallChain/filter", pattern = pattern, isIgnored = true)
|
||||
//model("${idea}intentions/loopToCallChain/introduceIndex", pattern = pattern, isIgnored = true)
|
||||
//model("${idea}intentions/loopToCallChain/indexOf", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/moveMemberToTopLevel", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/moveMemberToTopLevel", pattern = pattern)
|
||||
model("${idea}intentions/anonymousFunctionToLambda", pattern = pattern)
|
||||
model("${idea}intentions/copyConcatenatedStringToClipboard", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/inlayHints", pattern = pattern, isIgnored = true)
|
||||
|
||||
Reference in New Issue
Block a user