Use scope-aware findReferences in RenameKotlinPsiProcessor
#KT-37801 Fixed
This commit is contained in:
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.asJava.unwrapped
|
|||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
import org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler
|
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.idea.util.string.collapseSpaces
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -148,7 +148,7 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
|
|||||||
is KtImportAlias -> KotlinBundle.message("find.usages.import.alias")
|
is KtImportAlias -> KotlinBundle.message("find.usages.import.alias")
|
||||||
is RenameJavaSyntheticPropertyHandler.SyntheticPropertyWrapper -> KotlinBundle.message("find.usages.property")
|
is RenameJavaSyntheticPropertyHandler.SyntheticPropertyWrapper -> KotlinBundle.message("find.usages.property")
|
||||||
is KtLightClassForFacade -> KotlinBundle.message("find.usages.facade.class")
|
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
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
@@ -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<PsiReference> {
|
||||||
|
val references = super.findReferences(element, searchScope, searchInCommentsAndStrings)
|
||||||
|
return processFoundReferences(element, references)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+20
@@ -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<PsiReference> {
|
||||||
|
val references = super.findReferences(element)
|
||||||
|
return processFoundReferences(element, references)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+7
-4
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.utils.SmartList
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// BUNCH 191
|
// BUNCH 191
|
||||||
class RenameKotlinClassifierProcessor : RenameKotlinPsiProcessor() {
|
abstract class RenameKotlinClassifierProcessorCompat : RenameKotlinPsiProcessor() {
|
||||||
override fun canProcessElement(element: PsiElement): Boolean {
|
override fun canProcessElement(element: PsiElement): Boolean {
|
||||||
return element is KtClassOrObject || element is KtLightClass || element is KtConstructor<*> || element is KtTypeAlias
|
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<PsiReference> {
|
protected fun processFoundReferences(
|
||||||
|
element: PsiElement,
|
||||||
|
references: Collection<PsiReference>
|
||||||
|
): Collection<PsiReference> {
|
||||||
if (element is KtObjectDeclaration && element.isCompanion()) {
|
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 {
|
private fun PsiReference.isCompanionObjectClassReference(): Boolean {
|
||||||
|
|||||||
+24
@@ -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<PsiReference> {
|
||||||
|
val references = super.findReferences(element, searchScope, searchInCommentsAndStrings)
|
||||||
|
return processFoundReferences(element, references)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+19
@@ -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<PsiReference> {
|
||||||
|
val references = super.findReferences(element)
|
||||||
|
return processFoundReferences(element, references)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
-3
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// BUNCH 191
|
// BUNCH 191
|
||||||
class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
abstract class RenameKotlinFunctionProcessorCompat : RenameKotlinPsiProcessor() {
|
||||||
private val javaMethodProcessorInstance = RenameJavaMethodProcessor()
|
private val javaMethodProcessorInstance = RenameJavaMethodProcessor()
|
||||||
|
|
||||||
override fun canProcessElement(element: PsiElement): Boolean {
|
override fun canProcessElement(element: PsiElement): Boolean {
|
||||||
@@ -64,8 +64,10 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
|||||||
return DescriptorUtils.getJvmName(descriptor)
|
return DescriptorUtils.getJvmName(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
protected fun processFoundReferences(
|
||||||
val allReferences = super.findReferences(element)
|
element: PsiElement,
|
||||||
|
allReferences: Collection<PsiReference>
|
||||||
|
): Collection<PsiReference> {
|
||||||
return when {
|
return when {
|
||||||
getJvmName(element) == null -> allReferences
|
getJvmName(element) == null -> allReferences
|
||||||
element is KtElement -> allReferences.filterIsInstance<KtReference>()
|
element is KtElement -> allReferences.filterIsInstance<KtReference>()
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() {
|
|||||||
element: PsiElement,
|
element: PsiElement,
|
||||||
searchScope: SearchScope,
|
searchScope: SearchScope,
|
||||||
searchInCommentsAndStrings: Boolean
|
searchInCommentsAndStrings: Boolean
|
||||||
): MutableCollection<PsiReference> {
|
): Collection<PsiReference> {
|
||||||
if (element !is KtParameter) return super.findReferences(element, searchScope, searchInCommentsAndStrings)
|
if (element !is KtParameter) return super.findReferences(element, searchScope, searchInCommentsAndStrings)
|
||||||
val ownerFunction = element.ownerFunction
|
val ownerFunction = element.ownerFunction
|
||||||
?: return super.findReferences(element, searchScope, searchInCommentsAndStrings)
|
?: return super.findReferences(element, searchScope, searchInCommentsAndStrings)
|
||||||
|
|||||||
+137
@@ -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<PsiReference> {
|
||||||
|
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<UsageInfo>,
|
||||||
|
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<UsageInfo>(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
super.renameElement(
|
||||||
|
element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(),
|
||||||
|
refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
super.renameElement(
|
||||||
|
element, newName,
|
||||||
|
refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() }
|
||||||
|
|
||||||
|
dropOverrideKeywordIfNecessary(element)
|
||||||
|
|
||||||
|
listener?.elementRenamed(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+132
@@ -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<PsiReference> {
|
||||||
|
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<UsageInfo>,
|
||||||
|
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<UsageInfo>(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
super.renameElement(
|
||||||
|
element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(),
|
||||||
|
refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
super.renameElement(
|
||||||
|
element, newName,
|
||||||
|
refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() }
|
||||||
|
|
||||||
|
dropOverrideKeywordIfNecessary(element)
|
||||||
|
|
||||||
|
listener?.elementRenamed(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+10
-98
@@ -64,7 +64,7 @@ import org.jetbrains.kotlin.utils.DFS
|
|||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
// BUNCH 191
|
// BUNCH 191
|
||||||
class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
|
abstract class RenameKotlinPropertyProcessorCompat : RenameKotlinPsiProcessor() {
|
||||||
override fun canProcessElement(element: PsiElement): Boolean {
|
override fun canProcessElement(element: PsiElement): Boolean {
|
||||||
val namedUnwrappedElement = element.namedUnwrappedElement
|
val namedUnwrappedElement = element.namedUnwrappedElement
|
||||||
return namedUnwrappedElement is KtProperty || (namedUnwrappedElement is KtParameter && namedUnwrappedElement.hasValOrVar())
|
return namedUnwrappedElement is KtProperty || (namedUnwrappedElement is KtParameter && namedUnwrappedElement.hasValOrVar())
|
||||||
@@ -89,17 +89,20 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
|
|||||||
return getterName to setterName
|
return getterName to setterName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
protected fun processFoundReferences(
|
||||||
val allReferences = super.findReferences(element).filterNot { it is KtDestructuringDeclarationReference }
|
element: PsiElement,
|
||||||
|
allReferences: Collection<PsiReference>
|
||||||
|
): Collection<PsiReference> {
|
||||||
|
val references = allReferences.filterNot { it is KtDestructuringDeclarationReference }
|
||||||
val (getterJvmName, setterJvmName) = getJvmNames(element)
|
val (getterJvmName, setterJvmName) = getJvmNames(element)
|
||||||
return when {
|
return when {
|
||||||
getterJvmName == null && setterJvmName == null -> allReferences
|
getterJvmName == null && setterJvmName == null -> references
|
||||||
element is KtElement -> allReferences.filter {
|
element is KtElement -> references.filter {
|
||||||
it is KtReference || (getterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != setterJvmName) || (setterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != getterJvmName)
|
it is KtReference || (getterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != setterJvmName) || (setterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != getterJvmName)
|
||||||
}
|
}
|
||||||
element is KtLightDeclaration<*, *> -> {
|
element is KtLightDeclaration<*, *> -> {
|
||||||
val name = element.name
|
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()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
@@ -343,103 +346,12 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class UsageKind {
|
protected enum class UsageKind {
|
||||||
SIMPLE_PROPERTY_USAGE,
|
SIMPLE_PROPERTY_USAGE,
|
||||||
GETTER_USAGE,
|
GETTER_USAGE,
|
||||||
SETTER_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<UsageInfo>,
|
|
||||||
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<UsageInfo>(),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
super.renameElement(
|
|
||||||
element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(),
|
|
||||||
refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
super.renameElement(
|
|
||||||
element, newName,
|
|
||||||
refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() }
|
|
||||||
|
|
||||||
dropOverrideKeywordIfNecessary(element)
|
|
||||||
|
|
||||||
listener?.elementRenamed(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addRenameElements(
|
private fun addRenameElements(
|
||||||
psiMethod: PsiMethod?,
|
psiMethod: PsiMethod?,
|
||||||
oldName: String?,
|
oldName: String?,
|
||||||
|
|||||||
@@ -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<PsiReference> {
|
||||||
|
val searchParameters = KotlinReferencesSearchParameters(
|
||||||
|
element,
|
||||||
|
searchScope,
|
||||||
|
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
|
||||||
|
)
|
||||||
|
return findReferences(element, searchParameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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<PsiReference> {
|
||||||
|
val searchParameters = KotlinReferencesSearchParameters(
|
||||||
|
element,
|
||||||
|
element.project.projectScope() or element.useScope,
|
||||||
|
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
|
||||||
|
)
|
||||||
|
return findReferences(element, searchParameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+6
-8
@@ -39,7 +39,7 @@ import java.util.ArrayList
|
|||||||
import kotlin.collections.*
|
import kotlin.collections.*
|
||||||
|
|
||||||
// BUNCH 191
|
// BUNCH 191
|
||||||
abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() {
|
abstract class RenameKotlinPsiProcessorCompat : RenamePsiElementProcessor() {
|
||||||
class MangledJavaRefUsageInfo(
|
class MangledJavaRefUsageInfo(
|
||||||
val manglingSuffix: String,
|
val manglingSuffix: String,
|
||||||
element: PsiElement,
|
element: PsiElement,
|
||||||
@@ -56,13 +56,11 @@ abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() {
|
|||||||
|
|
||||||
override fun canProcessElement(element: PsiElement): Boolean = element is KtNamedDeclaration
|
override fun canProcessElement(element: PsiElement): Boolean = element is KtNamedDeclaration
|
||||||
|
|
||||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
protected fun findReferences(
|
||||||
val searchParameters = KotlinReferencesSearchParameters(
|
element: PsiElement,
|
||||||
element,
|
searchParameters: KotlinReferencesSearchParameters
|
||||||
element.project.projectScope() or element.useScope,
|
): MutableSet<PsiReference> {
|
||||||
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
|
val references = ReferencesSearch.search(searchParameters).toMutableSet()
|
||||||
)
|
|
||||||
val references = ReferencesSearch.search(searchParameters).toMutableList()
|
|
||||||
if (element is KtNamedFunction || (element is KtProperty && !element.isLocal) || (element is KtParameter && element.hasValOrVar())) {
|
if (element is KtNamedFunction || (element is KtProperty && !element.isLocal) || (element is KtParameter && element.hasValOrVar())) {
|
||||||
element.toLightMethods().flatMapTo(references) { MethodReferencesSearch.search(it) }
|
element.toLightMethods().flatMapTo(references) { MethodReferencesSearch.search(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user