Do not resolve alias imported references on rename

#KT-38096 Fixed
This commit is contained in:
Vladimir Dolzhenko
2020-04-09 20:38:01 +00:00
parent ac0d34089a
commit b51ae78b84
9 changed files with 82 additions and 24 deletions
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.*
import com.intellij.psi.impl.cache.CacheManager
import com.intellij.psi.search.*
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.util.Processor
import com.intellij.util.containers.nullize
@@ -73,7 +74,7 @@ data class KotlinReferencesSearchOptions(
elementToSearch: PsiNamedElement,
parameters: ReferencesSearch.SearchParameters
): SearchScope {
val kotlinOptions = (parameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
val kotlinOptions = (parameters as? KotlinAwareReferencesSearchParameters)?.kotlinOptions ?: Empty
val elements = if (elementToSearch is KtDeclaration && !isOnlyKotlinSearch(parameters.scopeDeterminedByUser)) {
elementToSearch.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).nullize()
} else {
@@ -87,17 +88,28 @@ data class KotlinReferencesSearchOptions(
}
}
interface KotlinAwareReferencesSearchParameters {
val kotlinOptions: KotlinReferencesSearchOptions
}
class KotlinReferencesSearchParameters(
elementToSearch: PsiElement,
scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
ignoreAccessScope: Boolean = false,
optimizer: SearchRequestCollector? = null,
val kotlinOptions: KotlinReferencesSearchOptions = Empty
) : ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
override val kotlinOptions: KotlinReferencesSearchOptions = Empty
) : ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer), KotlinAwareReferencesSearchParameters
class KotlinMethodReferencesSearchParameters(
elementToSearch: PsiMethod,
scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
strictSignatureSearch: Boolean = true,
override val kotlinOptions: KotlinReferencesSearchOptions = Empty
) : MethodReferencesSearch.SearchParameters(elementToSearch, scope, strictSignatureSearch), KotlinAwareReferencesSearchParameters
class KotlinAliasedImportedElementSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>(true) {
override fun processQuery(parameters: ReferencesSearch.SearchParameters, consumer: Processor<in PsiReference?>) {
val kotlinOptions = (parameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
val kotlinOptions = (parameters as? KotlinAwareReferencesSearchParameters)?.kotlinOptions ?: Empty
if (!kotlinOptions.acceptImportAlias) return
val element = parameters.elementToSearch
if (!element.isValid) return
@@ -142,7 +154,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
private class QueryProcessor(val queryParameters: ReferencesSearch.SearchParameters, val consumer: Processor<in PsiReference>) {
private val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
private val kotlinOptions = (queryParameters as? KotlinAwareReferencesSearchParameters)?.kotlinOptions ?: Empty
private val longTasks = ArrayList<() -> Unit>()
@@ -15,9 +15,7 @@ import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.DirectClassInheritorsSearch
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.listeners.RefactoringElementListener
import com.intellij.refactoring.rename.RenameProcessor
import com.intellij.refactoring.util.MoveRenameUsageInfo
import com.intellij.refactoring.util.RefactoringUtil
import com.intellij.usageView.UsageInfo
import com.intellij.usageView.UsageViewUtil
@@ -37,15 +35,10 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
import org.jetbrains.kotlin.idea.core.isEnumCompanionPropertyWithEntryConflict
import org.jetbrains.kotlin.idea.core.unquote
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings
import org.jetbrains.kotlin.idea.refactoring.checkSuperMethodsWithPopup
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
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.idea.util.application.runReadAction
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -53,9 +46,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.findPropertyByName
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.source.getPsi
@@ -67,7 +58,8 @@ import org.jetbrains.kotlin.utils.SmartList
abstract class RenameKotlinPropertyProcessorCompat : RenameKotlinPsiProcessor() {
override fun canProcessElement(element: PsiElement): Boolean {
val namedUnwrappedElement = element.namedUnwrappedElement
return namedUnwrappedElement is KtProperty || (namedUnwrappedElement is KtParameter && namedUnwrappedElement.hasValOrVar())
return namedUnwrappedElement is KtProperty || namedUnwrappedElement is PropertyMethodWrapper ||
(namedUnwrappedElement is KtParameter && namedUnwrappedElement.hasValOrVar())
}
override fun isToSearchInComments(psiElement: PsiElement) = KotlinRefactoringSettings.instance.RENAME_SEARCH_IN_COMMENTS_FOR_FIELD
@@ -22,7 +22,10 @@ abstract class RenameKotlinPsiProcessor : RenameKotlinPsiProcessorCompat() {
val searchParameters = KotlinReferencesSearchParameters(
element,
searchScope,
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
kotlinOptions = KotlinReferencesSearchOptions(
searchForComponentConventions = false,
acceptImportAlias = false
)
)
return findReferences(element, searchParameters)
}
@@ -19,7 +19,10 @@ abstract class RenameKotlinPsiProcessor : RenameKotlinPsiProcessorCompat() {
val searchParameters = KotlinReferencesSearchParameters(
element,
element.project.projectScope() or element.useScope,
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
kotlinOptions = KotlinReferencesSearchOptions(
searchForComponentConventions = false,
acceptImportAlias = false
)
)
return findReferences(element, searchParameters)
}
@@ -22,15 +22,15 @@ import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.getImportAlias
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinMethodReferencesSearchParameters
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
import org.jetbrains.kotlin.idea.util.actualsForExpected
import org.jetbrains.kotlin.idea.util.liftToExpected
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.ImportPath
import java.util.ArrayList
import kotlin.collections.*
@@ -56,12 +56,26 @@ abstract class RenameKotlinPsiProcessorCompat : RenamePsiElementProcessor() {
protected fun findReferences(
element: PsiElement,
searchParameters: KotlinReferencesSearchParameters
): MutableSet<PsiReference> {
): Collection<PsiReference> {
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) }
element.toLightMethods().flatMapTo(references) { method ->
MethodReferencesSearch.search(
KotlinMethodReferencesSearchParameters(
method,
kotlinOptions = KotlinReferencesSearchOptions(
acceptImportAlias = false
)
)
)
}
}
return references.filter {
// have to filter so far as
// - text-matched reference could be named as imported alias and found in ReferencesSearch
// - MethodUsagesSearcher could create its own MethodReferencesSearchParameters regardless provided one
it.element.getNonStrictParentOfType<KtImportDirective>() != null || it.getImportAlias() == null
}
return references
}
override fun createUsageInfo(element: PsiElement, ref: PsiReference, referenceElement: PsiElement): UsageInfo {
@@ -0,0 +1,12 @@
import Some.referWithoutAlias
import Some.referWithAli as referWithAlias
fun referRenamed() {
println(referWithoutAlias)
println(referWithAlias)
}
object Some {
var referWithoutAlias = 0
var referWithAli = 0
}
@@ -0,0 +1,12 @@
import Some.referWithoutAlias
import Some.referWithAlias as referWithAlias
fun referRenamed() {
println(referWithoutAlias)
println(referWithAlias)
}
object Some {
var referWithoutAlias = 0
var referWithAlias/*rename*/ = 0
}
@@ -0,0 +1,5 @@
{
"type": "AUTO_DETECT",
"mainFile": "test.kt",
"newName": "referWithAli"
}
@@ -483,6 +483,11 @@ public class RenameTestGenerated extends AbstractRenameTest {
runTest("idea/testData/refactoring/rename/propertyAccidentalOverrideSuperclass/propertyAccidentalOverrideSuperclass.test");
}
@TestMetadata("propertyImportAliasByRef/propertyImportAliasByRef.test")
public void testPropertyImportAliasByRef_PropertyImportAliasByRef() throws Exception {
runTest("idea/testData/refactoring/rename/propertyImportAliasByRef/propertyImportAliasByRef.test");
}
@TestMetadata("propertyParameterAccidentalOverrideSubclass/propertyParameterAccidentalOverrideSubclass.test")
public void testPropertyParameterAccidentalOverrideSubclass_PropertyParameterAccidentalOverrideSubclass() throws Exception {
runTest("idea/testData/refactoring/rename/propertyParameterAccidentalOverrideSubclass/propertyParameterAccidentalOverrideSubclass.test");