fix find usages and rename for primary constructor properties

#KT-8807 Fixed
This commit is contained in:
Dmitry Jemerov
2015-08-24 18:48:59 +02:00
parent 0c87639514
commit ef4b32db0d
8 changed files with 69 additions and 14 deletions
@@ -169,10 +169,15 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
} }
is JetProperty -> { is JetProperty -> {
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(element) } val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(element) }
searchNamedElement(queryParameters, propertyMethods.getGetter()) searchNamedElement(queryParameters, propertyMethods.getGetter())
searchNamedElement(queryParameters, propertyMethods.getSetter()) searchNamedElement(queryParameters, propertyMethods.getSetter())
searchNamedElement(queryParameters, propertyMethods.getBackingField()) }
} is JetParameter -> {
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(element) }
searchNamedElement(queryParameters, propertyMethods.getGetter())
searchNamedElement(queryParameters, propertyMethods.getSetter())
searchNamedElement(queryParameters, propertyMethods.getBackingField())
}
is KotlinLightMethod -> { is KotlinLightMethod -> {
val declaration = element.getOrigin() val declaration = element.getOrigin()
if (declaration is JetProperty || (declaration is JetParameter && declaration.hasValOrVar())) { if (declaration is JetProperty || (declaration is JetParameter && declaration.hasValOrVar())) {
@@ -189,7 +194,8 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
} }
} }
is KotlinLightParameter -> { is KotlinLightParameter -> {
val componentFunctionDescriptor = element.getOrigin()?.dataClassComponentFunction() val origin = element.getOrigin() ?: return
val componentFunctionDescriptor = origin.dataClassComponentFunction()
if (componentFunctionDescriptor != null) { if (componentFunctionDescriptor != null) {
val containingClass = element.method.containingClass val containingClass = element.method.containingClass
val componentFunction = containingClass?.methods?.find { val componentFunction = containingClass?.methods?.find {
@@ -199,6 +205,10 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
searchNamedElement(queryParameters, componentFunction) searchNamedElement(queryParameters, componentFunction)
} }
} }
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(origin) }
searchNamedElement(queryParameters, propertyMethods.getGetter())
searchNamedElement(queryParameters, propertyMethods.getSetter())
} }
} }
} }
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.ui.Messages import com.intellij.openapi.ui.Messages
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.SyntheticElement import com.intellij.psi.SyntheticElement
import com.intellij.psi.search.SearchScope import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.OverridingMethodsSearch import com.intellij.psi.search.searches.OverridingMethodsSearch
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetClassOrObject import org.jetbrains.kotlin.psi.JetClassOrObject
import org.jetbrains.kotlin.psi.JetParameter
import org.jetbrains.kotlin.psi.JetProperty import org.jetbrains.kotlin.psi.JetProperty
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -45,14 +47,20 @@ import org.jetbrains.kotlin.resolve.OverrideResolver
public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() { public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
override fun canProcessElement(element: PsiElement): Boolean { override fun canProcessElement(element: PsiElement): Boolean {
return element.namedUnwrappedElement is JetProperty val namedUnwrappedElement = element.namedUnwrappedElement
return namedUnwrappedElement is JetProperty || (namedUnwrappedElement is JetParameter && namedUnwrappedElement.hasValOrVar())
} }
/* Can't properly update getters and setters in Java */ /* Can't properly update getters and setters in Java */
override fun isInplaceRenameSupported() = false override fun isInplaceRenameSupported() = false
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? { override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
val jetProperty = element?.namedUnwrappedElement as? JetProperty val namedUnwrappedElement = element?.namedUnwrappedElement
if (namedUnwrappedElement is JetParameter) {
return namedUnwrappedElement
}
val jetProperty = namedUnwrappedElement as? JetProperty
if (jetProperty == null) throw IllegalStateException("Can't be for element $element there because of canProcessElement()") if (jetProperty == null) throw IllegalStateException("Can't be for element $element there because of canProcessElement()")
val deepestSuperProperty = findDeepestOverriddenProperty(jetProperty) val deepestSuperProperty = findDeepestOverriddenProperty(jetProperty)
@@ -82,13 +90,15 @@ public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
} }
override fun prepareRenaming(element: PsiElement?, newName: String?, allRenames: MutableMap<PsiElement, String>, scope: SearchScope) { override fun prepareRenaming(element: PsiElement?, newName: String?, allRenames: MutableMap<PsiElement, String>, scope: SearchScope) {
val jetProperty = element?.namedUnwrappedElement as? JetProperty val namedUnwrappedElement = element?.namedUnwrappedElement
if (jetProperty == null) throw IllegalStateException("Can't be for element $element there because of canProcessElement()") val propertyMethods = when(namedUnwrappedElement) {
is JetProperty -> runReadAction { LightClassUtil.getLightClassPropertyMethods(namedUnwrappedElement) }
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(jetProperty) } is JetParameter -> runReadAction { LightClassUtil.getLightClassPropertyMethods(namedUnwrappedElement) }
else -> throw IllegalStateException("Can't be for element $element there because of canProcessElement()")
}
for (propertyMethod in propertyMethods) { for (propertyMethod in propertyMethods) {
addRenameElements(propertyMethod, jetProperty.getName(), newName, allRenames, scope) addRenameElements(propertyMethod, (element as PsiNamedElement).name, newName, allRenames, scope)
} }
} }
@@ -99,12 +109,12 @@ public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
} }
override fun renameElement(element: PsiElement?, newName: String?, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) { override fun renameElement(element: PsiElement?, newName: String?, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) {
if (element !is JetProperty) { if (element !is JetProperty && element !is JetParameter) {
super.renameElement(element, newName, usages, listener) super.renameElement(element, newName, usages, listener)
return return
} }
val name = element.getName()!! val name = (element as PsiNamedElement).getName()!!
val oldGetterName = JvmAbi.getterName(name) val oldGetterName = JvmAbi.getterName(name)
val oldSetterName = JvmAbi.setterName(name) val oldSetterName = JvmAbi.setterName(name)
@@ -0,0 +1,3 @@
package testing.rename
public class Foo(public val /*rename*/second: String)
@@ -0,0 +1,9 @@
package testing;
import testing.rename.*;
class JavaClient {
public String foo(Foo f) {
return f.getSecond();
}
}
@@ -0,0 +1,3 @@
package testing.rename
public class Foo(public val /*rename*/first: String)
@@ -0,0 +1,9 @@
package testing;
import testing.rename.*;
class JavaClient {
public String foo(Foo f) {
return f.getFirst();
}
}
@@ -0,0 +1,5 @@
{
"type": "MARKED_ELEMENT",
"newName": "second",
"mainFile": "RenameKotlinPrimaryConstructorProperty.kt"
}
@@ -311,6 +311,12 @@ public class RenameTestGenerated extends AbstractRenameTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("renameKotlinPrimaryConstructorProperty/renameKotlinPrimaryConstructorProperty.test")
public void testRenameKotlinPrimaryConstructorProperty_RenameKotlinPrimaryConstructorProperty() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinPrimaryConstructorProperty/renameKotlinPrimaryConstructorProperty.test");
doTest(fileName);
}
@TestMetadata("renameKotlinStaticMethod/renameKotlinStaticMethod.test") @TestMetadata("renameKotlinStaticMethod/renameKotlinStaticMethod.test")
public void testRenameKotlinStaticMethod_RenameKotlinStaticMethod() throws Exception { public void testRenameKotlinStaticMethod_RenameKotlinStaticMethod() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinStaticMethod/renameKotlinStaticMethod.test"); String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinStaticMethod/renameKotlinStaticMethod.test");