correct interpretation of android id usage mixed with id declarations
This commit is contained in:
committed by
Yan Zhulanow
parent
8e8b626994
commit
85e18a3d73
+19
-4
@@ -21,17 +21,32 @@ 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/"
|
private val idDeclarationPrefix = "@+id/"
|
||||||
|
private val idUsagePrefix = "@id/"
|
||||||
|
public val androidNamespace: String = "android"
|
||||||
|
public val idAttributeNoNamespace: String = "id"
|
||||||
|
public val idAttribute: String = androidNamespace + ":" + idAttributeNoNamespace
|
||||||
|
public val classAttributeNoNamespace: String = "class"
|
||||||
|
public val classAttribute: String = androidNamespace + ":" + classAttributeNoNamespace
|
||||||
|
|
||||||
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 nameToIdDeclaration(name: String): String = idDeclarationPrefix + name
|
||||||
public fun idToName(id: String): String = id.replace(idPrefix, "")
|
public fun nameToIdUsage(name: String): String = idUsagePrefix + name
|
||||||
public fun isResourceId(str: String?): Boolean = str?.startsWith(idPrefix) ?: false
|
public fun idToName(id: String?): String {
|
||||||
|
return if (isResourceIdDeclaration(id)) id!!.replace(idDeclarationPrefix, "")
|
||||||
|
else if (isResourceIdUsage(id)) id!!.replace(idUsagePrefix, "")
|
||||||
|
else throw WrongIdFormat(id)
|
||||||
|
}
|
||||||
|
public fun isResourceIdDeclaration(str: String?): Boolean = str?.startsWith(idDeclarationPrefix) ?: false
|
||||||
|
public fun isResourceIdUsage(str: String?): Boolean = str?.startsWith(idUsagePrefix) ?: false
|
||||||
|
public fun isResourceDeclarationOrUsage(id: String?): Boolean = isResourceIdDeclaration(id) || isResourceIdUsage(id)
|
||||||
|
|
||||||
abstract fun readManifest(): AndroidManifest
|
abstract fun readManifest(): AndroidManifest
|
||||||
|
|
||||||
inner class NoUIXMLsFound : Exception("No android UI xmls found in $searchPath")
|
inner class NoUIXMLsFound : Exception("No android UI xmls found in $searchPath")
|
||||||
|
inner class WrongIdFormat(id: String?) : Exception("Id \"$id\" has wrong format")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-5
@@ -20,7 +20,7 @@ import org.xml.sax.helpers.DefaultHandler
|
|||||||
import org.xml.sax.Attributes
|
import org.xml.sax.Attributes
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
|
|
||||||
class AndroidXmlHandler(val elementCallback: (String, String) -> Unit) : DefaultHandler() {
|
class AndroidXmlHandler(val resourceManager: AndroidResourceManager, val elementCallback: (String, String) -> Unit) : DefaultHandler() {
|
||||||
|
|
||||||
override fun startDocument() {
|
override fun startDocument() {
|
||||||
super<DefaultHandler>.startDocument()
|
super<DefaultHandler>.startDocument()
|
||||||
@@ -32,10 +32,9 @@ class AndroidXmlHandler(val elementCallback: (String, String) -> Unit) : Default
|
|||||||
|
|
||||||
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
|
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
|
||||||
val hashMap = attributes.toMap()
|
val hashMap = attributes.toMap()
|
||||||
val s = hashMap["id"]
|
val s = hashMap[resourceManager.idAttributeNoNamespace]
|
||||||
val idPrefix = "@+id/"
|
val className = hashMap[resourceManager.classAttributeNoNamespace] ?: localName
|
||||||
val className = hashMap["class"] ?: localName
|
if (resourceManager.isResourceDeclarationOrUsage(s)) elementCallback(resourceManager.idToName(s), className)
|
||||||
if (s != null && s.startsWith(idPrefix)) elementCallback(s.replace(idPrefix, ""), className)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun endElement(uri: String?, localName: String, qName: String) {
|
override fun endElement(uri: String?, localName: String, qName: String) {
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ class CliAndroidUIXmlProcessor(project: Project, override val searchPath: String
|
|||||||
|
|
||||||
override fun parseSingleFileImpl(file: PsiFile): String {
|
override fun parseSingleFileImpl(file: PsiFile): String {
|
||||||
val ids: MutableCollection<AndroidWidget> = ArrayList()
|
val ids: MutableCollection<AndroidWidget> = ArrayList()
|
||||||
val handler = AndroidXmlHandler({ id, wClass -> ids.add(AndroidWidget(id, wClass)) })
|
val handler = AndroidXmlHandler(resourceManager, { id, wClass -> ids.add(AndroidWidget(id, wClass)) })
|
||||||
try {
|
try {
|
||||||
resourceManager.saxParser.parse(file.getVirtualFile()?.getInputStream()!!, handler)
|
resourceManager.saxParser.parse(file.getVirtualFile()?.getInputStream()!!, handler)
|
||||||
return produceKotlinProperties(KotlinStringWriter(), ids).toString()
|
return produceKotlinProperties(KotlinStringWriter(), ids).toString()
|
||||||
|
|||||||
@@ -23,14 +23,10 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor
|
import org.jetbrains.jet.lang.resolve.android.AndroidUIXmlProcessor
|
||||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
|
||||||
import com.intellij.psi.PsiReferenceExpression
|
|
||||||
import org.jetbrains.jet.plugin.references.JetSimpleNameReference
|
import org.jetbrains.jet.plugin.references.JetSimpleNameReference
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||||
import org.jetbrains.jet.lang.psi.JetProperty
|
import org.jetbrains.jet.lang.psi.JetProperty
|
||||||
import com.intellij.psi.impl.light.LightElement
|
import com.intellij.psi.impl.light.LightElement
|
||||||
import org.jetbrains.android.augment.AndroidInternalRClass
|
|
||||||
import com.intellij.psi.xml.XmlAttributeValue
|
|
||||||
import com.intellij.psi.xml.XmlAttribute
|
import com.intellij.psi.xml.XmlAttribute
|
||||||
|
|
||||||
public class AndroidGotoDeclarationHandler : GotoDeclarationHandler {
|
public class AndroidGotoDeclarationHandler : GotoDeclarationHandler {
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ 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
|
||||||
allRenames[XmlAttributeValueWrapper(attr.getValueElement()!!)] = resourceManager.nameToId(newName!!)
|
allRenames[XmlAttributeValueWrapper(attr.getValueElement()!!)] = resourceManager.nameToIdDeclaration(newName!!)
|
||||||
val name = AndroidResourceUtil.getResourceNameByReferenceText(newName)
|
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!!))
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.xml.XmlElement
|
import com.intellij.psi.xml.XmlElement
|
||||||
import com.intellij.psi.xml.XmlTag
|
import com.intellij.psi.xml.XmlTag
|
||||||
import com.intellij.psi.xml.XmlAttribute
|
import com.intellij.psi.xml.XmlAttribute
|
||||||
|
import org.jetbrains.jet.lang.resolve.android.AndroidResourceManager
|
||||||
|
|
||||||
class AndroidXmlVisitor(val elementCallback: (String, String, XmlAttribute) -> Unit) : XmlElementVisitor() {
|
class AndroidXmlVisitor(val resourceManager: AndroidResourceManager, val elementCallback: (String, String, XmlAttribute) -> Unit) : XmlElementVisitor() {
|
||||||
|
|
||||||
override fun visitElement(element: PsiElement) {
|
override fun visitElement(element: PsiElement) {
|
||||||
element.acceptChildren(this)
|
element.acceptChildren(this)
|
||||||
@@ -33,10 +34,9 @@ class AndroidXmlVisitor(val elementCallback: (String, String, XmlAttribute) -> U
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitXmlTag(tag: XmlTag?) {
|
override fun visitXmlTag(tag: XmlTag?) {
|
||||||
val idPrefix = "@+id/"
|
val attribute = tag?.getAttribute(resourceManager.idAttribute)
|
||||||
val attribute = tag?.getAttribute("android:id")
|
|
||||||
if (attribute != null && attribute.getValue() != null) {
|
if (attribute != null && attribute.getValue() != null) {
|
||||||
elementCallback(attribute.getValue()!!.replace(idPrefix, ""), tag!!.getLocalName(), attribute)
|
elementCallback(resourceManager.idToName(attribute.getValue()), tag!!.getLocalName(), attribute)
|
||||||
}
|
}
|
||||||
tag?.acceptChildren(this)
|
tag?.acceptChildren(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class IDEAndroidUIXmlProcessor(project: Project) : AndroidUIXmlProcessor(project
|
|||||||
override fun parseSingleFileImpl(file: PsiFile): String {
|
override fun parseSingleFileImpl(file: PsiFile): String {
|
||||||
val ids: MutableCollection<AndroidWidget> = ArrayList()
|
val ids: MutableCollection<AndroidWidget> = ArrayList()
|
||||||
resourceManager.resetAttributeCache()
|
resourceManager.resetAttributeCache()
|
||||||
file.accept(AndroidXmlVisitor { id, wClass, valueElement ->
|
file.accept(AndroidXmlVisitor(resourceManager, { id, wClass, valueElement ->
|
||||||
ids.add(AndroidWidget(id, wClass))
|
ids.add(AndroidWidget(id, wClass))
|
||||||
resourceManager.addMapping(id, valueElement)
|
resourceManager.addMapping(id, valueElement)
|
||||||
})
|
}))
|
||||||
return produceKotlinProperties(KotlinStringWriter(), ids).toString()
|
return produceKotlinProperties(KotlinStringWriter(), ids).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user