fix broken merge; support for renaming primary constructor parameter which declares an overridden property

This commit is contained in:
Dmitry Jemerov
2015-08-27 15:41:31 +02:00
parent 3e5c687e9d
commit 63d477e355
10 changed files with 114 additions and 28 deletions
@@ -151,6 +151,12 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
return null
}
private fun searchPropertyMethods(queryParameters: ReferencesSearch.SearchParameters, parameter: JetParameter) {
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(parameter) }
searchNamedElement(queryParameters, propertyMethods.getter)
searchNamedElement(queryParameters, propertyMethods.setter)
}
private fun searchLightElements(queryParameters: ReferencesSearch.SearchParameters, element: PsiElement) {
when (element) {
is JetClassOrObject -> processJetClassOrObject(element, queryParameters)
@@ -167,17 +173,18 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
searchNamedElement(queryParameters, staticFromCompanionObject)
}
}
is JetProperty -> {
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(element) }
searchNamedElement(queryParameters, propertyMethods.getGetter())
searchNamedElement(queryParameters, propertyMethods.getSetter())
searchNamedElement(queryParameters, propertyMethods.getter)
searchNamedElement(queryParameters, propertyMethods.setter)
searchNamedElement(queryParameters, propertyMethods.backingField)
}
is JetParameter -> {
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(element) }
searchNamedElement(queryParameters, propertyMethods.getGetter())
searchNamedElement(queryParameters, propertyMethods.getSetter())
searchNamedElement(queryParameters, propertyMethods.getBackingField())
searchPropertyMethods(queryParameters, element)
}
is KotlinLightMethod -> {
val declaration = element.getOrigin()
if (declaration is JetProperty || (declaration is JetParameter && declaration.hasValOrVar())) {
@@ -193,6 +200,7 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
}
}
}
is KotlinLightParameter -> {
val origin = element.getOrigin() ?: return
val componentFunctionDescriptor = origin.dataClassComponentFunction()
@@ -206,9 +214,7 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
}
}
val propertyMethods = runReadAction { LightClassUtil.getLightClassPropertyMethods(origin) }
searchNamedElement(queryParameters, propertyMethods.getGetter())
searchNamedElement(queryParameters, propertyMethods.getSetter())
searchPropertyMethods(queryParameters, origin)
}
}
}
@@ -33,11 +33,13 @@ import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetCallableDeclaration
import org.jetbrains.kotlin.psi.JetClassOrObject
import org.jetbrains.kotlin.psi.JetParameter
import org.jetbrains.kotlin.psi.JetProperty
@@ -56,35 +58,32 @@ public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
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()")
val callableDeclaration = namedUnwrappedElement as? JetCallableDeclaration
if (callableDeclaration == null) throw IllegalStateException("Can't be for element $element there because of canProcessElement()")
val deepestSuperProperty = findDeepestOverriddenProperty(jetProperty)
if (deepestSuperProperty == null || deepestSuperProperty == jetProperty) {
return jetProperty
val deepestSuperDeclaration = findDeepestOverriddenDeclaration(callableDeclaration)
if (deepestSuperDeclaration == null || deepestSuperDeclaration == callableDeclaration) {
return callableDeclaration
}
if (ApplicationManager.getApplication()!!.isUnitTestMode()) {
return deepestSuperProperty
return deepestSuperDeclaration
}
val containsText: String? =
deepestSuperProperty.getFqName()?.parent()?.asString() ?:
(deepestSuperProperty.getParent() as? JetClassOrObject)?.getName()
deepestSuperDeclaration.getFqName()?.parent()?.asString() ?:
(deepestSuperDeclaration.getParent() as? JetClassOrObject)?.getName()
val result = Messages.showYesNoCancelDialog(
deepestSuperProperty.getProject(),
deepestSuperDeclaration.getProject(),
if (containsText != null) "Do you want to rename base property from \n$containsText" else "Do you want to rename base property",
"Rename warning",
Messages.getQuestionIcon())
return when (result) {
Messages.YES -> deepestSuperProperty
Messages.NO -> jetProperty
Messages.YES -> deepestSuperDeclaration
Messages.NO -> callableDeclaration
else -> /* Cancel rename */ null
}
}
@@ -177,10 +176,14 @@ public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
}
}
private fun findDeepestOverriddenProperty(jetProperty: JetProperty): JetProperty? {
if (jetProperty.getModifierList()?.hasModifier(JetTokens.OVERRIDE_KEYWORD) == true) {
val bindingContext = jetProperty.analyze()
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, jetProperty]
private fun findDeepestOverriddenDeclaration(declaration: JetCallableDeclaration): JetCallableDeclaration? {
if (declaration.getModifierList()?.hasModifier(JetTokens.OVERRIDE_KEYWORD) == true) {
val bindingContext = declaration.analyze()
var descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
if (descriptor is ValueParameterDescriptor) {
descriptor = bindingContext[BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor]
?: return declaration
}
if (descriptor != null) {
assert(descriptor is PropertyDescriptor, "Property descriptor is expected")
@@ -191,7 +194,7 @@ public class RenameKotlinPropertyProcessor : RenamePsiElementProcessor() {
val deepest = supers.first()
if (deepest != descriptor) {
val superPsiElement = DescriptorToSourceUtils.descriptorToDeclaration(deepest)
return superPsiElement as? JetProperty
return superPsiElement as? JetCallableDeclaration
}
}
}
@@ -0,0 +1,10 @@
package testing.rename
public open class Foo(public open val second: String)
public class Bar(public override val /*rename*/second: String) : Foo(second) {
}
fun usages(f: Foo, b: Bar): String {
return f.second + b.second
}
@@ -0,0 +1,9 @@
package testing;
import testing.rename.*;
class JavaClient {
public String foo(Foo f) {
return f.getSecond();
}
}
@@ -0,0 +1,14 @@
package testng;
import testing.rename.Foo;
public class FooImpl extends Foo {
public FooImpl(String first) {
super(first);
}
@Override
public int getSecond() {
return "abc";
}
}
@@ -0,0 +1,10 @@
package testing.rename
public open class Foo(public open val first: String)
public class Bar(public override val /*rename*/first: String) : Foo(first) {
}
fun usages(f: Foo, b: Bar): String {
return f.first + b.first
}
@@ -0,0 +1,9 @@
package testing;
import testing.rename.*;
class JavaClient {
public String foo(Foo f) {
return f.getFirst();
}
}
@@ -0,0 +1,14 @@
package testng;
import testing.rename.Foo;
public class FooImpl extends Foo {
public FooImpl(String first) {
super(first);
}
@Override
public int getFirst() {
return "abc";
}
}
@@ -0,0 +1,5 @@
{
"type": "MARKED_ELEMENT",
"newName": "second",
"mainFile": "RenameKotlinPrimaryConstructorPropertyFromOverride.kt"
}
@@ -317,6 +317,12 @@ public class RenameTestGenerated extends AbstractRenameTest {
doTest(fileName);
}
@TestMetadata("renameKotlinPrimaryConstructorPropertyFromOverride/renameKotlinPrimaryConstructorPropertyFromOverride.test")
public void testRenameKotlinPrimaryConstructorPropertyFromOverride_RenameKotlinPrimaryConstructorPropertyFromOverride() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinPrimaryConstructorPropertyFromOverride/renameKotlinPrimaryConstructorPropertyFromOverride.test");
doTest(fileName);
}
@TestMetadata("renameKotlinStaticMethod/renameKotlinStaticMethod.test")
public void testRenameKotlinStaticMethod_RenameKotlinStaticMethod() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinStaticMethod/renameKotlinStaticMethod.test");