diff --git a/ChangeLog.md b/ChangeLog.md
index 394b80c40d8..ec8d8821be5 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -179,6 +179,7 @@ Issues fixed:
- Fix several issues leading to exceptions: [KT-11579](https://youtrack.jetbrains.com/issue/KT-11579), [KT-11580](https://youtrack.jetbrains.com/issue/KT-11580), [KT-11777](https://youtrack.jetbrains.com/issue/KT-11777), [KT-11868](https://youtrack.jetbrains.com/issue/KT-11868)
- Fixed NoSuchFieldException in Kotlin module settings on IDEA Ultimate
- [KT-11895](https://youtrack.jetbrains.com/issue/KT-11895) Fixed exception on highlighting of injected references
+- [KT-11880](https://youtrack.jetbrains.com/issue/KT-11880) Fixed renaming of Kotlin properties through SpEL references in XML files
#### Debugger
diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt
index eb18963d2f9..ad3685cade7 100644
--- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt
+++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt
@@ -24,6 +24,9 @@ import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.*
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.idea.KotlinLanguage
+import org.jetbrains.kotlin.load.java.propertyNameByGetMethodName
+import org.jetbrains.kotlin.load.java.propertyNameBySetMethodName
+import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
@@ -95,7 +98,19 @@ sealed class KtLightMethodImpl(
override fun setName(name: String): PsiElement? {
val toRename = kotlinOrigin as? PsiNamedElement ?: throwCanNotModify()
- toRename.setName(name)
+
+ val newName = if (toRename is KtProperty || toRename is KtParameter) {
+ val methodName = Name.guessByFirstCharacter(name)
+ val propertyName = toRename.name ?: ""
+ when {
+ name.startsWith("get") -> propertyNameByGetMethodName(methodName)
+ name.startsWith("set") -> propertyNameBySetMethodName(methodName, propertyName.startsWith("is"))
+ else -> null
+ }?.asString() ?: name
+ }
+ else name
+
+ toRename.setName(newName)
return this
}
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/J.java b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/J.java
new file mode 100644
index 00000000000..becbee315a8
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/J.java
@@ -0,0 +1,9 @@
+package a;
+
+public class J {
+ static void test() {
+ KotlinSpringBean bean = new KotlinSpringBean(1);
+ bean.isFooNew();
+ bean.setFooNew(true);
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/spring-config.xml b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/spring-config.xml
new file mode 100644
index 00000000000..f0398ba8edb
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/spring-config.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/test.kt b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/test.kt
new file mode 100644
index 00000000000..09db585764b
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/after/a/test.kt
@@ -0,0 +1,11 @@
+package a
+
+class KotlinSpringBean(value: Int) {
+ var isFooNew: Boolean = false
+}
+
+fun test() {
+ val bean = KotlinSpringBean(1)
+ bean.isFooNew
+ bean.isFooNew = true
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/J.java b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/J.java
new file mode 100644
index 00000000000..22d19c4c6cf
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/J.java
@@ -0,0 +1,9 @@
+package a;
+
+public class J {
+ static void test() {
+ KotlinSpringBean bean = new KotlinSpringBean(1);
+ bean.isFoo();
+ bean.setFoo(true);
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/spring-config.xml b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/spring-config.xml
new file mode 100644
index 00000000000..7dc8b407a10
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/spring-config.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/test.kt b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/test.kt
new file mode 100644
index 00000000000..b4f5b4676e8
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/before/a/test.kt
@@ -0,0 +1,11 @@
+package a
+
+class KotlinSpringBean(value: Int) {
+ var isFoo: Boolean = false
+}
+
+fun test() {
+ val bean = KotlinSpringBean(1)
+ bean.isFoo
+ bean.isFoo = true
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test
new file mode 100644
index 00000000000..d7418b55207
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test
@@ -0,0 +1,10 @@
+{
+ "fixtureClasses": ["org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension"],
+ "type": "MARKED_ELEMENT",
+ "mainFile": "a/spring-config.xml",
+ "springFileSet": ["a/spring-config.xml"],
+ "newName": "isFooNew",
+ "byRef": "true",
+ "injected": "true",
+ "withRuntime": "true"
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/J.java b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/J.java
new file mode 100644
index 00000000000..0e1bcf11e4e
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/J.java
@@ -0,0 +1,9 @@
+package a;
+
+public class J {
+ static void test() {
+ KotlinSpringBean bean = new KotlinSpringBean(1);
+ bean.getFooNew();
+ bean.setFooNew(2);
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/spring-config.xml b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/spring-config.xml
new file mode 100644
index 00000000000..d396fccdee0
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/spring-config.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/test.kt b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/test.kt
new file mode 100644
index 00000000000..9beca296f4d
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/after/a/test.kt
@@ -0,0 +1,9 @@
+package a
+
+class KotlinSpringBean(var fooNew: Int)
+
+fun test() {
+ val bean = KotlinSpringBean(1)
+ bean.fooNew
+ bean.fooNew = 2
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/J.java b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/J.java
new file mode 100644
index 00000000000..5587ad4417d
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/J.java
@@ -0,0 +1,9 @@
+package a;
+
+public class J {
+ static void test() {
+ KotlinSpringBean bean = new KotlinSpringBean(1);
+ bean.getFoo();
+ bean.setFoo(2);
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/spring-config.xml b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/spring-config.xml
new file mode 100644
index 00000000000..b6774812251
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/spring-config.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/test.kt b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/test.kt
new file mode 100644
index 00000000000..519ac291368
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/before/a/test.kt
@@ -0,0 +1,9 @@
+package a
+
+class KotlinSpringBean(var foo: Int)
+
+fun test() {
+ val bean = KotlinSpringBean(1)
+ bean.foo
+ bean.foo = 2
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/parameterWithXmlRefBySpelRef.test b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/parameterWithXmlRefBySpelRef.test
new file mode 100644
index 00000000000..13075cf362d
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/parameterWithXmlRefBySpelRef.test
@@ -0,0 +1,10 @@
+{
+ "fixtureClasses": ["org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension"],
+ "type": "MARKED_ELEMENT",
+ "mainFile": "a/spring-config.xml",
+ "springFileSet": ["a/spring-config.xml"],
+ "newName": "fooNew",
+ "byRef": "true",
+ "injected": "true",
+ "withRuntime": "true"
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/J.java b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/J.java
new file mode 100644
index 00000000000..0e1bcf11e4e
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/J.java
@@ -0,0 +1,9 @@
+package a;
+
+public class J {
+ static void test() {
+ KotlinSpringBean bean = new KotlinSpringBean(1);
+ bean.getFooNew();
+ bean.setFooNew(2);
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/spring-config.xml b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/spring-config.xml
new file mode 100644
index 00000000000..f0398ba8edb
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/spring-config.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/test.kt b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/test.kt
new file mode 100644
index 00000000000..75d741b0b78
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/after/a/test.kt
@@ -0,0 +1,11 @@
+package a
+
+class KotlinSpringBean(value: Int) {
+ var fooNew: Int = 0
+}
+
+fun test() {
+ val bean = KotlinSpringBean(1)
+ bean.fooNew
+ bean.fooNew = 2
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/J.java b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/J.java
new file mode 100644
index 00000000000..5587ad4417d
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/J.java
@@ -0,0 +1,9 @@
+package a;
+
+public class J {
+ static void test() {
+ KotlinSpringBean bean = new KotlinSpringBean(1);
+ bean.getFoo();
+ bean.setFoo(2);
+ }
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/spring-config.xml b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/spring-config.xml
new file mode 100644
index 00000000000..7dc8b407a10
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/spring-config.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/test.kt b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/test.kt
new file mode 100644
index 00000000000..48dee5c2875
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/before/a/test.kt
@@ -0,0 +1,11 @@
+package a
+
+class KotlinSpringBean(value: Int) {
+ var foo: Int = 0
+}
+
+fun test() {
+ val bean = KotlinSpringBean(1)
+ bean.foo
+ bean.foo = 2
+}
\ No newline at end of file
diff --git a/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/propertyWithXmlRefBySpelRef.test b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/propertyWithXmlRefBySpelRef.test
new file mode 100644
index 00000000000..13075cf362d
--- /dev/null
+++ b/ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/propertyWithXmlRefBySpelRef.test
@@ -0,0 +1,10 @@
+{
+ "fixtureClasses": ["org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension"],
+ "type": "MARKED_ELEMENT",
+ "mainFile": "a/spring-config.xml",
+ "springFileSet": ["a/spring-config.xml"],
+ "newName": "fooNew",
+ "byRef": "true",
+ "injected": "true",
+ "withRuntime": "true"
+}
\ No newline at end of file
diff --git a/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/SpringRenameTestGenerated.java b/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/SpringRenameTestGenerated.java
index 3b5de54b109..7275dde4a3d 100644
--- a/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/SpringRenameTestGenerated.java
+++ b/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/SpringRenameTestGenerated.java
@@ -47,6 +47,12 @@ public class SpringRenameTestGenerated extends AbstractSpringRenameTest {
doTest(fileName);
}
+ @TestMetadata("isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test")
+ public void testIsPropertyWithXmlRefsBySpelRef_IsPropertyWithXmlRefBySpelRef() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test");
+ doTest(fileName);
+ }
+
@TestMetadata("javaSpelRefToJava/javaSpelRefToJava.test")
public void testJavaSpelRefToJava_JavaSpelRefToJava() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/javaSpelRefToJava/javaSpelRefToJava.test");
@@ -95,6 +101,12 @@ public class SpringRenameTestGenerated extends AbstractSpringRenameTest {
doTest(fileName);
}
+ @TestMetadata("parameterWithXmlRefsBySpelRef/parameterWithXmlRefBySpelRef.test")
+ public void testParameterWithXmlRefsBySpelRef_ParameterWithXmlRefBySpelRef() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/parameterWithXmlRefsBySpelRef/parameterWithXmlRefBySpelRef.test");
+ doTest(fileName);
+ }
+
@TestMetadata("primaryConstructorArgWithXmlRefs/primaryConstructorArgWithXmlRef.test")
public void testPrimaryConstructorArgWithXmlRefs_PrimaryConstructorArgWithXmlRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/primaryConstructorArgWithXmlRefs/primaryConstructorArgWithXmlRef.test");
@@ -125,6 +137,12 @@ public class SpringRenameTestGenerated extends AbstractSpringRenameTest {
doTest(fileName);
}
+ @TestMetadata("propertyWithXmlRefsBySpelRef/propertyWithXmlRefBySpelRef.test")
+ public void testPropertyWithXmlRefsBySpelRef_PropertyWithXmlRefBySpelRef() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/propertyWithXmlRefsBySpelRef/propertyWithXmlRefBySpelRef.test");
+ doTest(fileName);
+ }
+
@TestMetadata("setterFunWithXmlRefs/setterFunWithXmlRef.test")
public void testSetterFunWithXmlRefs_SetterFunWithXmlRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/setterFunWithXmlRefs/setterFunWithXmlRef.test");