mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] Add conflict if nested Kotlin properties/methods are moved that are referred to by Java code
KTIJ-28862 GitOrigin-RevId: 6f7de83360a718c2ee5957e85716bb3ad3e8c181
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d77e86c64a
commit
26340dea20
@@ -1850,6 +1850,8 @@ searching.for.0=Searching for {0}
|
||||
move.out.of.companion.object=Move out of companion object
|
||||
calls.with.explicit.extension.receiver.won.t.be.processed.0=Calls with explicit extension receiver won''t be processed: {0}
|
||||
usages.of.outer.class.instance.inside.of.property.0.won.t.be.processed=Usages of outer class instance inside of property ''{0}'' won''t be processed
|
||||
usages.of.outer.class.instance.inside.declaration.0.won.t.be.processed=Usages of outer class instance inside declaration ''{0}'' won''t be processed
|
||||
usages.of.nested.declarations.from.non.kotlin.code.won.t.be.processed=Usages of nested declarations from non-Kotlin code won't be processed
|
||||
companion.object.already.contains.0=Companion object already contains {0}
|
||||
0.references.type.parameters.of.the.containing.class={0} references type parameters of the containing class
|
||||
0.is.overridden.by.declaration.s.in.a.subclass={0} is overridden by declaration(s) in a subclass
|
||||
|
||||
+5
@@ -1266,6 +1266,11 @@ public abstract class MoveTestGenerated extends AbstractMoveTest {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveNestedClass/protectedClass/protectedClass.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveProperty/moveToTopLevel/externalPropertyUsageFromJava/externalPropertyUsageFromJava.test")
|
||||
public void testKotlin_moveProperty_moveToTopLevel_externalPropertyUsageFromJava_ExternalPropertyUsageFromJava() throws Exception {
|
||||
runTest("testData/refactoring/moveNested/kotlin/moveProperty/moveToTopLevel/externalPropertyUsageFromJava/externalPropertyUsageFromJava.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");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// IGNORE_K1
|
||||
// "Propagate 'MyExperimentalAPI' opt-in requirement to containing class 'Derived'" "false"
|
||||
// IGNORE_K1
|
||||
// COMPILER_ARGUMENTS: -opt-in=kotlin.RequiresOptIn
|
||||
// WITH_STDLIB
|
||||
// ACTION: Enable a trailing comma by default in the formatter
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
Usages of nested declarations from non-Kotlin code won't be processed
|
||||
+1
-1
@@ -4,5 +4,5 @@
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
"enabledInK2": "false"
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Usages of outer class instance inside declaration 'foo' won't be processed
|
||||
+1
@@ -0,0 +1 @@
|
||||
Usages of outer class instance inside declaration 'Inner' won't be processed
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package bar;
|
||||
|
||||
class JavaClass {
|
||||
public void test() {
|
||||
System.out.println(new Test().getA());
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package bar
|
||||
|
||||
val a: Int = 5
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package bar;
|
||||
|
||||
class JavaClass {
|
||||
public void test() {
|
||||
System.out.println(new Test().getA());
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package bar
|
||||
|
||||
class Test {
|
||||
val a<caret>: Int = 5
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
Usages of nested declarations from non-Kotlin code won't be processed
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"mainFile": "bar/test.kt",
|
||||
"type": "MOVE_KOTLIN_NESTED_DECLARATION",
|
||||
"outerInstanceParameter": "test",
|
||||
"withRuntime": "true",
|
||||
"enabledInK1": "false",
|
||||
"enabledInK2": "true"
|
||||
}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Usages of outer class instance inside of property 'foo' won't be processed
|
||||
Usages of outer class instance inside declaration 'foo' won't be processed
|
||||
|
||||
+28
-3
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2MoveOperationD
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2MoveSourceDescriptor
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.move.descriptor.K2MoveTargetDescriptor
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.usages.ImplicitCompanionAsDispatchReceiverUsageInfo
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.usages.K2MoveRenameUsageInfo
|
||||
import org.jetbrains.kotlin.idea.k2.refactoring.move.processor.usages.OuterInstanceReferenceUsageInfo
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -49,6 +50,10 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
else -> MoveType.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
require(operationDescriptor.sourceElements.size == 1) { "We can only move a single nested declaration at a time" }
|
||||
}
|
||||
private val elementToMove = operationDescriptor.sourceElements.single()
|
||||
|
||||
private fun willLoseOuterInstanceReference(): Boolean {
|
||||
@@ -68,6 +73,19 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
val element = usage.element ?: continue
|
||||
|
||||
val isConflict = when (usage) {
|
||||
is K2MoveRenameUsageInfo.Light -> {
|
||||
if (moveType != MoveType.CLASS && operationDescriptor.outerInstanceParameterName != null) {
|
||||
// We only have the facility to correct outer class usages if the moved declaration is a nested class.
|
||||
conflicts.putValue(
|
||||
element,
|
||||
KotlinBundle.message("usages.of.nested.declarations.from.non.kotlin.code.won.t.be.processed", element.text)
|
||||
)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
is ImplicitCompanionAsDispatchReceiverUsageInfo -> {
|
||||
val isValidTarget = isValidTargetForImplicitCompanionAsDispatchReceiver(moveDescriptor.target, usage.companionObject)
|
||||
if (!isValidTarget) {
|
||||
@@ -80,11 +98,13 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
}
|
||||
|
||||
is OuterInstanceReferenceUsageInfo -> {
|
||||
if (moveType == MoveType.PROPERTY) {
|
||||
// For properties, any outer instance reference is a conflict because we do not process them.
|
||||
if (willLoseOuterInstanceReference()) {
|
||||
conflicts.putValue(
|
||||
element,
|
||||
KotlinBundle.message("usages.of.outer.class.instance.inside.of.property.0.won.t.be.processed", elementToMove.nameAsSafeName.asString())
|
||||
KotlinBundle.message(
|
||||
"usages.of.outer.class.instance.inside.declaration.0.won.t.be.processed",
|
||||
elementToMove.nameAsSafeName.asString()
|
||||
)
|
||||
)
|
||||
true
|
||||
} else {
|
||||
@@ -117,6 +137,8 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
val outerClass = referencedNestedDeclaration.containingClassOrObject
|
||||
val lightOuterClass = outerClass?.toLightClass()
|
||||
if (lightOuterClass != null) {
|
||||
// While this is called the `MoveInnerClassUsagesHandler`, it will also correctly modify usages
|
||||
// of inner methods from Kotlin code (but not from Java code!).
|
||||
MoveInnerClassUsagesHandler.EP_NAME
|
||||
.forLanguage(usage.element?.language ?: continue)
|
||||
?.correctInnerClassUsage(usage, lightOuterClass, outerInstanceParameterName)
|
||||
@@ -166,6 +188,7 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is KtNamedFunction -> {
|
||||
if (outerInstanceParameterName != null) {
|
||||
val outerInstanceType = analyze(originalDeclaration) {
|
||||
@@ -181,6 +204,7 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is KtProperty -> {
|
||||
|
||||
}
|
||||
@@ -200,6 +224,7 @@ class K2MoveNestedDeclarationsRefactoringProcessor(
|
||||
val addedParameter = primaryConstructor.valueParameters.firstOrNull { it.name == outerInstanceParameterName } ?: return
|
||||
shortenReferences(addedParameter)
|
||||
}
|
||||
|
||||
is KtNamedFunction -> {
|
||||
val addedParameter = newDeclaration.valueParameterList?.parameters?.firstOrNull() ?: return
|
||||
shortenReferences(addedParameter)
|
||||
|
||||
+1
-1
@@ -270,7 +270,7 @@ sealed class K2MoveModel {
|
||||
searchReferences = searchReferences.state,
|
||||
dirStructureMatchesPkg = true,
|
||||
newClassName = null,
|
||||
outerInstanceParameterName = outerClassInstanceParameterName.takeIf { needsInstanceReference },
|
||||
outerInstanceParameterName = outerClassInstanceParameterName.takeIf { passOuterClass },
|
||||
moveCallBack = moveCallBack
|
||||
)
|
||||
}
|
||||
|
||||
+5
@@ -390,6 +390,11 @@ public class K2MoveNestedTestGenerated extends AbstractK2MoveNestedTest {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveNestedClass/protectedClass/protectedClass.test");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlin/moveProperty/moveToTopLevel/externalPropertyUsageFromJava/externalPropertyUsageFromJava.test")
|
||||
public void testKotlin_moveProperty_moveToTopLevel_externalPropertyUsageFromJava_ExternalPropertyUsageFromJava() throws Exception {
|
||||
runTest("../../idea/tests/testData/refactoring/moveNested/kotlin/moveProperty/moveToTopLevel/externalPropertyUsageFromJava/externalPropertyUsageFromJava.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");
|
||||
|
||||
Reference in New Issue
Block a user