Rename: Fix Find Usages/Rename for parameter references in XML files

#KT-11967 Fixed
This commit is contained in:
Alexey Sedunov
2016-04-20 17:25:42 +03:00
parent 6a1387b9b9
commit d456aa6ba8
18 changed files with 114 additions and 5 deletions
+1
View File
@@ -36,6 +36,7 @@ Issues fixed:
- [KT-11817](https://youtrack.jetbrains.com/issue/KT-11817) Fixed rename of Kotlin enum constants through Java references - [KT-11817](https://youtrack.jetbrains.com/issue/KT-11817) Fixed rename of Kotlin enum constants through Java references
- [KT-11816](https://youtrack.jetbrains.com/issue/KT-11816) Fixed usages search for Safe Delete on simple enum entries - [KT-11816](https://youtrack.jetbrains.com/issue/KT-11816) Fixed usages search for Safe Delete on simple enum entries
- [KT-11282](https://youtrack.jetbrains.com/issue/KT-11282) Delete interface reference from super-type list when applying Safe Delete to Java interface - [KT-11282](https://youtrack.jetbrains.com/issue/KT-11282) Delete interface reference from super-type list when applying Safe Delete to Java interface
- [KT-11967](https://youtrack.jetbrains.com/issue/KT-11967) Fix Find Usages/Rename for parameter references in XML files
#### Debugger #### Debugger
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT
import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.search.allScope
import org.jetbrains.kotlin.idea.search.effectiveSearchScope
import org.jetbrains.kotlin.idea.search.usagesSearch.* import org.jetbrains.kotlin.idea.search.usagesSearch.*
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
@@ -69,7 +70,10 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
(if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList()) (if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList())
} }
val effectiveSearchScope = runReadAction { queryParameters.effectiveSearchScope } val effectiveSearchScope = runReadAction {
val elements = if (unwrappedElement is KtDeclaration) unwrappedElement.toLightElements() else listOf(unwrappedElement)
elements.fold(queryParameters.effectiveSearchScope) { scope, e -> scope.union(queryParameters.effectiveSearchScope(e)) }
}
val refFilter: (PsiReference) -> Boolean = when { val refFilter: (PsiReference) -> Boolean = when {
unwrappedElement is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ }) unwrappedElement is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
@@ -314,7 +318,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
element: PsiNamedElement?, element: PsiNamedElement?,
name: String? = element?.name) { name: String? = element?.name) {
if (name != null && element != null) { if (name != null && element != null) {
val scope = runReadAction { queryParameters.effectiveSearchScope } val scope = runReadAction { queryParameters.effectiveSearchScope(element) }
val context = UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES + UsageSearchContext.IN_COMMENTS val context = UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES + UsageSearchContext.IN_COMMENTS
val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions
?: KotlinReferencesSearchOptions.Empty ?: KotlinReferencesSearchOptions.Empty
@@ -17,10 +17,13 @@
package org.jetbrains.kotlin.idea.search package org.jetbrains.kotlin.idea.search
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.PsiSearchHelper
import com.intellij.psi.search.SearchScope import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -50,4 +53,12 @@ fun SearchScope.restrictToKotlinSources(): SearchScope {
} }
else -> this else -> this
} }
}
// Copied from SearchParameters.getEffectiveSearchScope()
fun ReferencesSearch.SearchParameters.effectiveSearchScope(element: PsiElement): SearchScope {
if (element == elementToSearch) return effectiveSearchScope
if (isIgnoreAccessScope) return scopeDeterminedByUser
val accessScope = PsiSearchHelper.SERVICE.getInstance(element.project).getUseScope(element)
return scopeDeterminedByUser.intersectWith(accessScope)
} }
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.refactoring.listeners.RefactoringElementListener import com.intellij.refactoring.listeners.RefactoringElementListener
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import com.intellij.util.xml.impl.GenericDomValueReference
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration
@@ -36,6 +37,12 @@ class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() {
} }
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?) {
// Workaround for usages in XML files
// TODO: Do not use Change Signature for parameter rename as it's less efficient and loses some usages
for (usage in usages) {
(usage.reference as? GenericDomValueReference<*>)?.handleElementRename(newName)
}
val function = (element as KtParameter).parent.parent as KtNamedFunction val function = (element as KtParameter).parent.parent as KtNamedFunction
val paramIndex = function.valueParameters.indexOf(element) val paramIndex = function.valueParameters.indexOf(element)
assert(paramIndex != -1, { "couldn't find parameter in parent ${element.getElementTextWithContext()}" }) assert(paramIndex != -1, { "couldn't find parameter in parent ${element.getElementTextWithContext()}" })
@@ -1 +1 @@
Function call 8 open fun processRequest() = doProcessRequest() Function call 8 open fun processRequest() = doProcessRequest()
@@ -1 +1,2 @@
Value read 8 open fun processRequest() = foo Value read 12 override fun processRequest() = "foo" + foo
Value read 8 open fun processRequest() = foo
@@ -1,3 +1,3 @@
[kotlinPrivatePropertyUsages2.0.kt] Named argument 9 public class ServerEx(): Server(foo = "!") { [kotlinPrivatePropertyUsages2.0.kt] Named argument 9 public class ServerEx(): Server(foo = "!") {
[kotlinPrivatePropertyUsages2.0.kt] Value read 6 open fun processRequest() = foo [kotlinPrivatePropertyUsages2.0.kt] Value read 6 open fun processRequest() = foo
[kotlinPrivatePropertyUsages2.1.kt] Named argument 5 println(Server(foo = "!").foo) [kotlinPrivatePropertyUsages2.1.kt] Named argument 5 println(Server(foo = "!").foo)
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="a.FactoryObject" factory-method="buildObject" name="fmKotlin">
<constructor-arg name="param2" value="1"/>
</bean>
</beans>
@@ -0,0 +1,6 @@
package a
class Construction(param: Int)
object FactoryObject {
@JvmStatic fun buildObject(param2: Int) = Construction(param2)
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="a.FactoryObject" factory-method="buildObject" name="fmKotlin">
<constructor-arg name="param" value="1"/>
</bean>
</beans>
@@ -0,0 +1,6 @@
package a
class Construction(param: Int)
object FactoryObject {
@JvmStatic fun buildObject(/*rename*/param: Int) = Construction(param)
}
@@ -0,0 +1,8 @@
{
"fixtureClasses": ["org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension"],
"type": "MARKED_ELEMENT",
"mainFile": "test.kt",
"springFileSet": ["spring-config.xml"],
"newName": "param2",
"withRuntime": "true"
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="a.FactoryObject" factory-method="buildObject" name="fmKotlin">
<constructor-arg name="param2" value="1"/>
</bean>
</beans>
@@ -0,0 +1,6 @@
package a
class Construction(param: Int)
object FactoryObject {
@JvmStatic fun buildObject(param2: Int) = Construction(param2)
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="a.FactoryObject" factory-method="buildObject" name="fmKotlin">
<constructor-arg name="/*rename*/param" value="1"/>
</bean>
</beans>
@@ -0,0 +1,6 @@
package a
class Construction(param: Int)
object FactoryObject {
@JvmStatic fun buildObject(param: Int) = Construction(param)
}
@@ -0,0 +1,9 @@
{
"fixtureClasses": ["org.jetbrains.kotlin.idea.spring.tests.SpringTestFixtureExtension"],
"type": "MARKED_ELEMENT",
"mainFile": "spring-config.xml",
"springFileSet": ["spring-config.xml"],
"newName": "param2",
"byRef": "true",
"withRuntime": "true"
}
@@ -47,6 +47,18 @@ public class SpringRenameTestGenerated extends AbstractSpringRenameTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("factoryMethodParam/factoryMethodParam.test")
public void testFactoryMethodParam_FactoryMethodParam() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/factoryMethodParam/factoryMethodParam.test");
doTest(fileName);
}
@TestMetadata("factoryMethodParamByXmlRef/factoryMethodParamByXmlRef.test")
public void testFactoryMethodParamByXmlRef_FactoryMethodParamByXmlRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/factoryMethodParamByXmlRef/factoryMethodParamByXmlRef.test");
doTest(fileName);
}
@TestMetadata("isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test") @TestMetadata("isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test")
public void testIsPropertyWithXmlRefsBySpelRef_IsPropertyWithXmlRefBySpelRef() throws Exception { public void testIsPropertyWithXmlRefsBySpelRef_IsPropertyWithXmlRefBySpelRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test"); String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test");