fix double renaming issue

- rebuild resource mapping cache on external layout file changes
- move duplicated code to AndroidResourceManager
This commit is contained in:
Mikhail Mutcianko
2014-07-31 17:18:26 +04:00
committed by Yan Zhulanow
parent 1b50b226ae
commit b5e267ed56
3 changed files with 16 additions and 22 deletions
@@ -21,8 +21,12 @@ import com.intellij.psi.PsiElement
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
abstract class AndroidResourceManager(val project: Project, val searchPath: String?) { abstract class AndroidResourceManager(val project: Project, val searchPath: String?) {
private val idPrefix = "@+id/"
abstract fun getLayoutXmlFiles(): Collection<PsiFile> abstract fun getLayoutXmlFiles(): Collection<PsiFile>
abstract fun idToXmlAttribute(id: String): PsiElement? abstract fun idToXmlAttribute(id: String): PsiElement?
abstract fun renameXmlAttr(elem: PsiElement, newName: String) abstract fun renameXmlAttr(elem: PsiElement, newName: String)
abstract fun renameProperty(oldName: String, newName: String) abstract fun renameProperty(oldName: String, newName: String)
public fun nameToId(name: String): String = idPrefix + name
public fun idToName(id: String): String = id.replace(idPrefix, "")
public fun isResourceId(str: String?): Boolean = str?.startsWith(idPrefix) ?: false
} }
@@ -52,24 +52,8 @@ public class AndroidRenameProcessor : RenamePsiElementProcessor() {
val processor = ServiceManager.getService(jetProperty.getProject(), javaClass<AndroidUIXmlProcessor>()) val processor = ServiceManager.getService(jetProperty.getProject(), javaClass<AndroidUIXmlProcessor>())
val resourceManager = processor!!.resourceManager val resourceManager = processor!!.resourceManager
val attr = resourceManager.idToXmlAttribute(oldName) as XmlAttribute val attr = resourceManager.idToXmlAttribute(oldName) as XmlAttribute
for (file in resourceManager.getLayoutXmlFiles()) { allRenames[XmlAttributeValueWrapper(attr.getValueElement()!!)] = resourceManager.nameToId(newName!!)
if (file is XmlFile) { val name = AndroidResourceUtil.getResourceNameByReferenceText(newName)
file.accept(object : XmlElementVisitor() {
override fun visitElement(element: PsiElement) {
element.acceptChildren(this)
}
override fun visitXmlTag(tag: XmlTag?) {
val idPrefix = "@+id/"
val attribute = tag?.getAttribute("android:id")
if (attribute != null && attribute.getValue() == idPrefix + oldName) {
allRenames[XmlAttributeValueWrapper(attribute.getValueElement()!!)] = idPrefix + newName
}
tag?.acceptChildren(this)
}
})
}
}
val name = AndroidResourceUtil.getResourceNameByReferenceText(newName!!)
for (resField in AndroidResourceUtil.findIdFields(attr)) { for (resField in AndroidResourceUtil.findIdFields(attr)) {
allRenames.put(resField, AndroidResourceUtil.getFieldNameByResourceName(name!!)) allRenames.put(resField, AndroidResourceUtil.getFieldNameByResourceName(name!!))
} }
@@ -34,6 +34,7 @@ public class IDEAndroidResourceManager(project: Project, searchPath: String?) :
} }
private fun setupElementCache() { private fun setupElementCache() {
idToXmlAttributeCache.clear()
for (file in getLayoutXmlFiles()) { for (file in getLayoutXmlFiles()) {
if (file is XmlFile) { if (file is XmlFile) {
file.accept(object : XmlElementVisitor() { file.accept(object : XmlElementVisitor() {
@@ -41,11 +42,10 @@ public class IDEAndroidResourceManager(project: Project, searchPath: String?) :
element.acceptChildren(this) element.acceptChildren(this)
} }
override fun visitXmlTag(tag: XmlTag?) { override fun visitXmlTag(tag: XmlTag?) {
val idPrefix = "@+id/"
val attribute = tag?.getAttribute("android:id") val attribute = tag?.getAttribute("android:id")
val s = attribute?.getValue() val s = attribute?.getValue()
if (attribute != null && (s?.startsWith(idPrefix) ?: false)) { if (attribute != null && s != null && isResourceId(s)) {
idToXmlAttributeCache[s!!.replace(idPrefix, "")] = attribute idToXmlAttributeCache[idToName(s)] = attribute
} }
tag?.acceptChildren(this) tag?.acceptChildren(this)
} }
@@ -55,7 +55,13 @@ public class IDEAndroidResourceManager(project: Project, searchPath: String?) :
} }
override fun idToXmlAttribute(id: String): PsiElement? { override fun idToXmlAttribute(id: String): PsiElement? {
return idToXmlAttributeCache[id] val element = idToXmlAttributeCache[id]
// element not in cache - files might have changed
if (element == null) {
setupElementCache()
return idToXmlAttributeCache[id]
}
return element
} }
override fun renameXmlAttr(elem: PsiElement, newName: String) { override fun renameXmlAttr(elem: PsiElement, newName: String) {
val xmlAttr = elem as XmlAttribute val xmlAttr = elem as XmlAttribute