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-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-11967](https://youtrack.jetbrains.com/issue/KT-11967) Fix Find Usages/Rename for parameter references in XML files
#### Debugger
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT
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.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.util.application.runReadAction
@@ -69,7 +70,10 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
(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 {
unwrappedElement is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
@@ -314,7 +318,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
element: PsiNamedElement?,
name: String? = element?.name) {
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 kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions
?: KotlinReferencesSearchOptions.Empty
@@ -17,10 +17,13 @@
package org.jetbrains.kotlin.idea.search
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.PsiSearchHelper
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.KtFile
@@ -50,4 +53,12 @@ fun SearchScope.restrictToKotlinSources(): SearchScope {
}
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.refactoring.listeners.RefactoringElementListener
import com.intellij.usageView.UsageInfo
import com.intellij.util.xml.impl.GenericDomValueReference
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
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?) {
// 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 paramIndex = function.valueParameters.indexOf(element)
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] 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);
}
@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")
public void testIsPropertyWithXmlRefsBySpelRef_IsPropertyWithXmlRefBySpelRef() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("ultimate/testData/spring/core/rename/isPropertyWithXmlRefsBySpelRef/isPropertyWithXmlRefBySpelRef.test");