diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt index 08b7252300d..c8aa07ccf33 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler -import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinPropertyProcessor +import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinPropertyProcessorCompat import org.jetbrains.kotlin.idea.util.string.collapseSpaces import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name @@ -148,7 +148,7 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider { is KtImportAlias -> KotlinBundle.message("find.usages.import.alias") is RenameJavaSyntheticPropertyHandler.SyntheticPropertyWrapper -> KotlinBundle.message("find.usages.property") is KtLightClassForFacade -> KotlinBundle.message("find.usages.facade.class") - is RenameKotlinPropertyProcessor.PropertyMethodWrapper -> KotlinBundle.message("find.usages.property.accessor") + is RenameKotlinPropertyProcessorCompat.PropertyMethodWrapper -> KotlinBundle.message("find.usages.property.accessor") else -> null } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessor.kt new file mode 100644 index 00000000000..a16e0dfb342 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessor.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import com.intellij.psi.search.SearchScope + +// BUNCH 191 +class RenameKotlinClassifierProcessor : RenameKotlinClassifierProcessorCompat() { + + override fun findReferences( + element: PsiElement, + searchScope: SearchScope, + searchInCommentsAndStrings: Boolean + ): Collection { + val references = super.findReferences(element, searchScope, searchInCommentsAndStrings) + return processFoundReferences(element, references) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessor.kt.191 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessor.kt.191 new file mode 100644 index 00000000000..e72bf9c6d5f --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessor.kt.191 @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import com.intellij.psi.search.SearchScope + +// BUNCH 191 +class RenameKotlinClassifierProcessor : RenameKotlinClassifierProcessorCompat() { + + override fun findReferences(element: PsiElement): Collection { + val references = super.findReferences(element) + return processFoundReferences(element, references) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessorCompat.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessorCompat.kt index eab42a9fe53..04a09f72ce2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessorCompat.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassifierProcessorCompat.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.utils.SmartList import java.util.* // BUNCH 191 -class RenameKotlinClassifierProcessor : RenameKotlinPsiProcessor() { +abstract class RenameKotlinClassifierProcessorCompat : RenameKotlinPsiProcessor() { override fun canProcessElement(element: PsiElement): Boolean { return element is KtClassOrObject || element is KtLightClass || element is KtConstructor<*> || element is KtTypeAlias } @@ -63,11 +63,14 @@ class RenameKotlinClassifierProcessor : RenameKotlinPsiProcessor() { } } - override fun findReferences(element: PsiElement): Collection { + protected fun processFoundReferences( + element: PsiElement, + references: Collection + ): Collection { if (element is KtObjectDeclaration && element.isCompanion()) { - return super.findReferences(element).filter { !it.isCompanionObjectClassReference() } + return references.filter { !it.isCompanionObjectClassReference() } } - return super.findReferences(element) + return references } private fun PsiReference.isCompanionObjectClassReference(): Boolean { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt new file mode 100644 index 00000000000..16ba879b1ff --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import com.intellij.psi.search.SearchScope + +// BUNCH 191 +class RenameKotlinFunctionProcessor : RenameKotlinFunctionProcessorCompat() { + + override fun findReferences( + element: PsiElement, + searchScope: SearchScope, + searchInCommentsAndStrings: Boolean + ): Collection { + val references = super.findReferences(element, searchScope, searchInCommentsAndStrings) + return processFoundReferences(element, references) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt.191 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt.191 new file mode 100644 index 00000000000..f9c65610ca7 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt.191 @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference + +// BUNCH 191 +class RenameKotlinFunctionProcessor : RenameKotlinFunctionProcessorCompat() { + + override fun findReferences(element: PsiElement): Collection { + val references = super.findReferences(element) + return processFoundReferences(element, references) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessorCompat.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessorCompat.kt index 40f7a88f470..45304175293 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessorCompat.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessorCompat.kt @@ -40,7 +40,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import java.util.* // BUNCH 191 -class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() { +abstract class RenameKotlinFunctionProcessorCompat : RenameKotlinPsiProcessor() { private val javaMethodProcessorInstance = RenameJavaMethodProcessor() override fun canProcessElement(element: PsiElement): Boolean { @@ -64,8 +64,10 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() { return DescriptorUtils.getJvmName(descriptor) } - override fun findReferences(element: PsiElement): Collection { - val allReferences = super.findReferences(element) + protected fun processFoundReferences( + element: PsiElement, + allReferences: Collection + ): Collection { return when { getJvmName(element) == null -> allReferences element is KtElement -> allReferences.filterIsInstance() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt index 96793372519..21cfa559853 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt @@ -46,7 +46,7 @@ class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() { element: PsiElement, searchScope: SearchScope, searchInCommentsAndStrings: Boolean - ): MutableCollection { + ): Collection { if (element !is KtParameter) return super.findReferences(element, searchScope, searchInCommentsAndStrings) val ownerFunction = element.ownerFunction ?: return super.findReferences(element, searchScope, searchInCommentsAndStrings) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt new file mode 100644 index 00000000000..875faa911f9 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt @@ -0,0 +1,137 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiReference +import com.intellij.psi.search.SearchScope +import com.intellij.refactoring.listeners.RefactoringElementListener +import com.intellij.refactoring.util.MoveRenameUsageInfo +import com.intellij.usageView.UsageInfo +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.asJava.propertyNameByAccessor +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.idea.core.isEnumCompanionPropertyWithEntryConflict +import org.jetbrains.kotlin.idea.core.unquote +import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary +import org.jetbrains.kotlin.idea.references.KtReference +import org.jetbrains.kotlin.idea.references.KtSimpleNameReference +import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded +import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver +import org.jetbrains.kotlin.resolve.DescriptorUtils + +// BUNCH 191 +class RenameKotlinPropertyProcessor : RenameKotlinPropertyProcessorCompat() { + + override fun findReferences( + element: PsiElement, + searchScope: SearchScope, + searchInCommentsAndStrings: Boolean + ): Collection { + val references = super.findReferences(element, searchScope, searchInCommentsAndStrings) + return processFoundReferences(element, references) + } + + //TODO: a very long and complicated method, even recursive. mb refactor it somehow? at least split by PsiElement types? + override tailrec fun renameElement( + element: PsiElement, + newName: String, + usages: Array, + listener: RefactoringElementListener? + ) { + val newNameUnquoted = newName.unquote() + if (element is KtLightMethod) { + if (element.modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString()) != null) { + return super.renameElement(element, newName, usages, listener) + } + + val origin = element.kotlinOrigin + val newPropertyName = propertyNameByAccessor(newNameUnquoted, element) + // Kotlin references to Kotlin property should not use accessor name + if (newPropertyName != null && (origin is KtProperty || origin is KtParameter)) { + val (ktUsages, otherUsages) = usages.partition { it.reference is KtSimpleNameReference } + super.renameElement(element, newName, otherUsages.toTypedArray(), listener) + renameElement(origin, newPropertyName.quoteIfNeeded(), ktUsages.toTypedArray(), listener) + return + } + } + + if (element !is KtProperty && element !is KtParameter) { + super.renameElement(element, newName, usages, listener) + return + } + + val name = (element as KtNamedDeclaration).name!! + val oldGetterName = JvmAbi.getterName(name) + val oldSetterName = JvmAbi.setterName(name) + + if (isEnumCompanionPropertyWithEntryConflict(element, newNameUnquoted)) { + for ((i, usage) in usages.withIndex()) { + if (usage !is MoveRenameUsageInfo) continue + val ref = usage.reference ?: continue + // TODO: Enum value can't be accessed from Java in case of conflict with companion member + if (ref is KtReference) { + val newRef = (ref.bindToElement(element) as? KtSimpleNameExpression)?.mainReference ?: continue + usages[i] = MoveRenameUsageInfo(newRef, usage.referencedElement) + } + } + } + + val adjustedUsages = if (element is KtParameter) usages.filterNot { + val refTarget = it.reference?.resolve() + refTarget is KtLightMethod && DataClassDescriptorResolver.isComponentLike(Name.guessByFirstCharacter(refTarget.name)) + } else usages.toList() + + val refKindUsages = adjustedUsages.groupBy { usage: UsageInfo -> + val refElement = usage.reference?.resolve() + if (refElement is PsiMethod) { + val refElementName = refElement.name + val refElementNameToCheck = + (if (usage is MangledJavaRefUsageInfo) KotlinTypeMapper.InternalNameMapper.demangleInternalName(refElementName) else null) ?: refElementName + when (refElementNameToCheck) { + oldGetterName -> UsageKind.GETTER_USAGE + oldSetterName -> UsageKind.SETTER_USAGE + else -> UsageKind.SIMPLE_PROPERTY_USAGE + } + } else { + UsageKind.SIMPLE_PROPERTY_USAGE + } + } + + super.renameElement( + element.copy(), JvmAbi.setterName(newNameUnquoted).quoteIfNeeded(), + refKindUsages[UsageKind.SETTER_USAGE]?.toTypedArray() ?: arrayOf(), + null + ) + + super.renameElement( + element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(), + refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf(), + null + ) + + super.renameElement( + element, newName, + refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf(), + null + ) + + usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() } + + dropOverrideKeywordIfNecessary(element) + + listener?.elementRenamed(element) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt.191 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt.191 new file mode 100644 index 00000000000..c0e8bfaaaa4 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt.191 @@ -0,0 +1,132 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiReference +import com.intellij.refactoring.listeners.RefactoringElementListener +import com.intellij.refactoring.util.MoveRenameUsageInfo +import com.intellij.usageView.UsageInfo +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.asJava.propertyNameByAccessor +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.idea.core.isEnumCompanionPropertyWithEntryConflict +import org.jetbrains.kotlin.idea.core.unquote +import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary +import org.jetbrains.kotlin.idea.references.KtReference +import org.jetbrains.kotlin.idea.references.KtSimpleNameReference +import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded +import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver +import org.jetbrains.kotlin.resolve.DescriptorUtils + +// BUNCH 191 +class RenameKotlinPropertyProcessor : RenameKotlinPropertyProcessorCompat() { + + override fun findReferences(element: PsiElement): Collection { + val references = super.findReferences(element) + return processFoundReferences(element, references) + } + + //TODO: a very long and complicated method, even recursive. mb refactor it somehow? at least split by PsiElement types? + override tailrec fun renameElement( + element: PsiElement, + newName: String, + usages: Array, + listener: RefactoringElementListener? + ) { + val newNameUnquoted = newName.unquote() + if (element is KtLightMethod) { + if (element.modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString()) != null) { + return super.renameElement(element, newName, usages, listener) + } + + val origin = element.kotlinOrigin + val newPropertyName = propertyNameByAccessor(newNameUnquoted, element) + // Kotlin references to Kotlin property should not use accessor name + if (newPropertyName != null && (origin is KtProperty || origin is KtParameter)) { + val (ktUsages, otherUsages) = usages.partition { it.reference is KtSimpleNameReference } + super.renameElement(element, newName, otherUsages.toTypedArray(), listener) + renameElement(origin, newPropertyName.quoteIfNeeded(), ktUsages.toTypedArray(), listener) + return + } + } + + if (element !is KtProperty && element !is KtParameter) { + super.renameElement(element, newName, usages, listener) + return + } + + val name = (element as KtNamedDeclaration).name!! + val oldGetterName = JvmAbi.getterName(name) + val oldSetterName = JvmAbi.setterName(name) + + if (isEnumCompanionPropertyWithEntryConflict(element, newNameUnquoted)) { + for ((i, usage) in usages.withIndex()) { + if (usage !is MoveRenameUsageInfo) continue + val ref = usage.reference ?: continue + // TODO: Enum value can't be accessed from Java in case of conflict with companion member + if (ref is KtReference) { + val newRef = (ref.bindToElement(element) as? KtSimpleNameExpression)?.mainReference ?: continue + usages[i] = MoveRenameUsageInfo(newRef, usage.referencedElement) + } + } + } + + val adjustedUsages = if (element is KtParameter) usages.filterNot { + val refTarget = it.reference?.resolve() + refTarget is KtLightMethod && DataClassDescriptorResolver.isComponentLike(Name.guessByFirstCharacter(refTarget.name)) + } else usages.toList() + + val refKindUsages = adjustedUsages.groupBy { usage: UsageInfo -> + val refElement = usage.reference?.resolve() + if (refElement is PsiMethod) { + val refElementName = refElement.name + val refElementNameToCheck = + (if (usage is MangledJavaRefUsageInfo) KotlinTypeMapper.InternalNameMapper.demangleInternalName(refElementName) else null) ?: refElementName + when (refElementNameToCheck) { + oldGetterName -> UsageKind.GETTER_USAGE + oldSetterName -> UsageKind.SETTER_USAGE + else -> UsageKind.SIMPLE_PROPERTY_USAGE + } + } else { + UsageKind.SIMPLE_PROPERTY_USAGE + } + } + + super.renameElement( + element.copy(), JvmAbi.setterName(newNameUnquoted).quoteIfNeeded(), + refKindUsages[UsageKind.SETTER_USAGE]?.toTypedArray() ?: arrayOf(), + null + ) + + super.renameElement( + element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(), + refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf(), + null + ) + + super.renameElement( + element, newName, + refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf(), + null + ) + + usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() } + + dropOverrideKeywordIfNecessary(element) + + listener?.elementRenamed(element) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessorCompat.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessorCompat.kt index bcfb2423439..c3ae72e7167 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessorCompat.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessorCompat.kt @@ -64,7 +64,7 @@ import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.SmartList // BUNCH 191 -class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() { +abstract class RenameKotlinPropertyProcessorCompat : RenameKotlinPsiProcessor() { override fun canProcessElement(element: PsiElement): Boolean { val namedUnwrappedElement = element.namedUnwrappedElement return namedUnwrappedElement is KtProperty || (namedUnwrappedElement is KtParameter && namedUnwrappedElement.hasValOrVar()) @@ -89,17 +89,20 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() { return getterName to setterName } - override fun findReferences(element: PsiElement): Collection { - val allReferences = super.findReferences(element).filterNot { it is KtDestructuringDeclarationReference } + protected fun processFoundReferences( + element: PsiElement, + allReferences: Collection + ): Collection { + val references = allReferences.filterNot { it is KtDestructuringDeclarationReference } val (getterJvmName, setterJvmName) = getJvmNames(element) return when { - getterJvmName == null && setterJvmName == null -> allReferences - element is KtElement -> allReferences.filter { + getterJvmName == null && setterJvmName == null -> references + element is KtElement -> references.filter { it is KtReference || (getterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != setterJvmName) || (setterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != getterJvmName) } element is KtLightDeclaration<*, *> -> { val name = element.name - if (name == getterJvmName || name == setterJvmName) allReferences.filterNot { it is KtReference } else allReferences + if (name == getterJvmName || name == setterJvmName) references.filterNot { it is KtReference } else references } else -> emptyList() } @@ -343,103 +346,12 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() { } } - private enum class UsageKind { + protected enum class UsageKind { SIMPLE_PROPERTY_USAGE, GETTER_USAGE, SETTER_USAGE } - //TODO: a very long and complicated method, even recursive. mb refactor it somehow? at least split by PsiElement types? - override tailrec fun renameElement( - element: PsiElement, - newName: String, - usages: Array, - listener: RefactoringElementListener? - ) { - val newNameUnquoted = newName.unquote() - if (element is KtLightMethod) { - if (element.modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString()) != null) { - return super.renameElement(element, newName, usages, listener) - } - - val origin = element.kotlinOrigin - val newPropertyName = propertyNameByAccessor(newNameUnquoted, element) - // Kotlin references to Kotlin property should not use accessor name - if (newPropertyName != null && (origin is KtProperty || origin is KtParameter)) { - val (ktUsages, otherUsages) = usages.partition { it.reference is KtSimpleNameReference } - super.renameElement(element, newName, otherUsages.toTypedArray(), listener) - renameElement(origin, newPropertyName.quoteIfNeeded(), ktUsages.toTypedArray(), listener) - return - } - } - - if (element !is KtProperty && element !is KtParameter) { - super.renameElement(element, newName, usages, listener) - return - } - - val name = (element as KtNamedDeclaration).name!! - val oldGetterName = JvmAbi.getterName(name) - val oldSetterName = JvmAbi.setterName(name) - - if (isEnumCompanionPropertyWithEntryConflict(element, newNameUnquoted)) { - for ((i, usage) in usages.withIndex()) { - if (usage !is MoveRenameUsageInfo) continue - val ref = usage.reference ?: continue - // TODO: Enum value can't be accessed from Java in case of conflict with companion member - if (ref is KtReference) { - val newRef = (ref.bindToElement(element) as? KtSimpleNameExpression)?.mainReference ?: continue - usages[i] = MoveRenameUsageInfo(newRef, usage.referencedElement) - } - } - } - - val adjustedUsages = if (element is KtParameter) usages.filterNot { - val refTarget = it.reference?.resolve() - refTarget is KtLightMethod && DataClassDescriptorResolver.isComponentLike(Name.guessByFirstCharacter(refTarget.name)) - } else usages.toList() - - val refKindUsages = adjustedUsages.groupBy { usage: UsageInfo -> - val refElement = usage.reference?.resolve() - if (refElement is PsiMethod) { - val refElementName = refElement.name - val refElementNameToCheck = - (if (usage is MangledJavaRefUsageInfo) demangleInternalName(refElementName) else null) ?: refElementName - when (refElementNameToCheck) { - oldGetterName -> UsageKind.GETTER_USAGE - oldSetterName -> UsageKind.SETTER_USAGE - else -> UsageKind.SIMPLE_PROPERTY_USAGE - } - } else { - UsageKind.SIMPLE_PROPERTY_USAGE - } - } - - super.renameElement( - element.copy(), JvmAbi.setterName(newNameUnquoted).quoteIfNeeded(), - refKindUsages[UsageKind.SETTER_USAGE]?.toTypedArray() ?: arrayOf(), - null - ) - - super.renameElement( - element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(), - refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf(), - null - ) - - super.renameElement( - element, newName, - refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf(), - null - ) - - usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() } - - dropOverrideKeywordIfNecessary(element) - - listener?.elementRenamed(element) - } - private fun addRenameElements( psiMethod: PsiMethod?, oldName: String?, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessor.kt new file mode 100644 index 00000000000..56cf72a2168 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessor.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import com.intellij.psi.search.SearchScope +import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions +import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters + +// BUNCH 191 +abstract class RenameKotlinPsiProcessor : RenameKotlinPsiProcessorCompat() { + + override fun findReferences( + element: PsiElement, + searchScope: SearchScope, + searchInCommentsAndStrings: Boolean + ): Collection { + val searchParameters = KotlinReferencesSearchParameters( + element, + searchScope, + kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false) + ) + return findReferences(element, searchParameters) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessor.kt.191 b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessor.kt.191 new file mode 100644 index 00000000000..2d2b8922bf6 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessor.kt.191 @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference +import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions +import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters +import org.jetbrains.kotlin.idea.search.or +import org.jetbrains.kotlin.idea.search.projectScope + +// BUNCH 191 +abstract class RenameKotlinPsiProcessor : RenameKotlinPsiProcessorCompat() { + + override fun findReferences(element: PsiElement): Collection { + val searchParameters = KotlinReferencesSearchParameters( + element, + element.project.projectScope() or element.useScope, + kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false) + ) + return findReferences(element, searchParameters) + } + +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessorCompat.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessorCompat.kt index a95d0ea9801..a98bea1bbcb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessorCompat.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPsiProcessorCompat.kt @@ -39,7 +39,7 @@ import java.util.ArrayList import kotlin.collections.* // BUNCH 191 -abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() { +abstract class RenameKotlinPsiProcessorCompat : RenamePsiElementProcessor() { class MangledJavaRefUsageInfo( val manglingSuffix: String, element: PsiElement, @@ -56,13 +56,11 @@ abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() { override fun canProcessElement(element: PsiElement): Boolean = element is KtNamedDeclaration - override fun findReferences(element: PsiElement): Collection { - val searchParameters = KotlinReferencesSearchParameters( - element, - element.project.projectScope() or element.useScope, - kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false) - ) - val references = ReferencesSearch.search(searchParameters).toMutableList() + protected fun findReferences( + element: PsiElement, + searchParameters: KotlinReferencesSearchParameters + ): MutableSet { + val references = ReferencesSearch.search(searchParameters).toMutableSet() if (element is KtNamedFunction || (element is KtProperty && !element.isLocal) || (element is KtParameter && element.hasValOrVar())) { element.toLightMethods().flatMapTo(references) { MethodReferencesSearch.search(it) } }