Light Classes: Support property accessors with non-conventional names

#KT-13032 Fixed
This commit is contained in:
Alexey Sedunov
2016-08-15 20:13:01 +03:00
parent 94c4b426f5
commit fbd6edce92
16 changed files with 126 additions and 5 deletions
+1
View File
@@ -270,6 +270,7 @@ Using 'this' as function argument in constructor of non-final class
- [`KT-13253`](https://youtrack.jetbrains.com/issue/KT-13253) Rename: Report conflicts for constructor parameters
- [`KT-12971`](https://youtrack.jetbrains.com/issue/KT-12971) Push Down: Do not specifiy visibility on generated overriding members
- [`KT-13124`](https://youtrack.jetbrains.com/issue/KT-13124) Pull Up: Skip super members without explicit declarations
- [`KT-13032`](https://youtrack.jetbrains.com/issue/KT-13032) Rename: Support accessors with non-conventional names
##### New features
@@ -198,7 +198,9 @@ object LightClassUtil {
val additionalAccessors = arrayListOf<PsiMethod>()
for (wrapper in getPsiMethodWrappers(ktDeclaration, true)) {
if (JvmAbi.isSetterName(wrapper.name)) {
if (wrapper !is KtLightMethod) continue
if (wrapper.isSetter) {
if (setterWrapper == null || setterWrapper === specialSetter) {
setterWrapper = wrapper
}
@@ -232,3 +232,16 @@ fun KtLightMethod.isTraitFakeOverride(): Boolean {
// Method was generated from declaration in some other trait
return (parentOfMethodOrigin != null && thisClassDeclaration !== parentOfMethodOrigin && KtPsiUtil.isTrait(parentOfMethodOrigin))
}
fun KtLightMethod.isAccessor(getter: Boolean): Boolean {
val origin = kotlinOrigin as? KtCallableDeclaration ?: return false
if (origin !is KtProperty && origin !is KtParameter) return false
val expectedParametersCount = (if (getter) 0 else 1) + (if (origin.receiverTypeReference != null) 1 else 0)
return parameterList.parametersCount == expectedParametersCount
}
val KtLightMethod.isGetter: Boolean
get() = isAccessor(true)
val KtLightMethod.isSetter: Boolean
get() = isAccessor(false)
@@ -28,7 +28,6 @@ import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
@@ -100,8 +99,8 @@ internal fun computeAnnotations(lightElement: PsiModifierList,
val descriptor = declaration?.let { LightClassGenerationSupport.getInstance(lightElement.project).resolveToDescriptor(it) }
val annotatedDescriptor = when {
descriptor !is PropertyDescriptor || lightOwner !is KtLightMethod -> descriptor
JvmAbi.isGetterName(lightOwner.name) -> descriptor.getter
JvmAbi.isSetterName(lightOwner.name) -> descriptor.setter
lightOwner.isGetter -> descriptor.getter
lightOwner.isSetter -> descriptor.setter
else -> descriptor
}
val ktAnnotations = annotatedDescriptor?.annotations?.getAllAnnotations() ?: emptyList()
@@ -171,7 +171,7 @@ fun propertyNameByAccessor(name: String, accessor: KtLightMethod): String? {
return when {
JvmAbi.isGetterName(name) -> propertyNameByGetMethodName(methodName)
JvmAbi.isSetterName(name) -> propertyNameBySetMethodName(methodName, propertyName.startsWith("is"))
else -> null
else -> methodName
}?.asString()
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().fooNew();
new A().bar(1);
}
}
@@ -0,0 +1,12 @@
package test
class A {
@get:JvmName("fooNew")
@set:JvmName("bar")
var first = 1
}
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A()./*rename*/foo();
new A().bar(1);
}
}
@@ -0,0 +1,12 @@
package test
class A {
@get:JvmName("foo")
@set:JvmName("bar")
var first = 1
}
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "fooNew",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().foo();
new A().barNew(1);
}
}
@@ -0,0 +1,12 @@
package test
class A {
@get:JvmName("foo")
@set:JvmName("barNew")
var first = 1
}
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().foo();
new A()./*rename*/bar(1);
}
}
@@ -0,0 +1,12 @@
package test
class A {
@get:JvmName("foo")
@set:JvmName("bar")
var first = 1
}
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "barNew",
"withRuntime": "true",
"byRef": "true"
}
@@ -785,6 +785,18 @@ public class RenameTestGenerated extends AbstractRenameTest {
doTest(fileName);
}
@TestMetadata("renameKotlinPropertyWithCustomGetterSetterJvmNameByGetterRef/renameKotlinPropertyWithCustomGetterSetterJvmNameByGetterRef.test")
public void testRenameKotlinPropertyWithCustomGetterSetterJvmNameByGetterRef_RenameKotlinPropertyWithCustomGetterSetterJvmNameByGetterRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinPropertyWithCustomGetterSetterJvmNameByGetterRef/renameKotlinPropertyWithCustomGetterSetterJvmNameByGetterRef.test");
doTest(fileName);
}
@TestMetadata("renameKotlinPropertyWithCustomGetterSetterJvmNameBySetterRef/renameKotlinPropertyWithCustomGetterSetterJvmNameBySetterRef.test")
public void testRenameKotlinPropertyWithCustomGetterSetterJvmNameBySetterRef_RenameKotlinPropertyWithCustomGetterSetterJvmNameBySetterRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinPropertyWithCustomGetterSetterJvmNameBySetterRef/renameKotlinPropertyWithCustomGetterSetterJvmNameBySetterRef.test");
doTest(fileName);
}
@TestMetadata("renameKotlinPropertyWithGetterJvmName/renameKotlinPropertyWithGetterJvmName.test")
public void testRenameKotlinPropertyWithGetterJvmName_RenameKotlinPropertyWithGetterJvmName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinPropertyWithGetterJvmName/renameKotlinPropertyWithGetterJvmName.test");