Fix Android layout widget redeclarations
This commit is contained in:
+4
-3
@@ -33,9 +33,9 @@ public abstract class AndroidResourceManager(val project: Project) {
|
||||
|
||||
public open fun idToXmlAttribute(id: String): PsiElement? = null
|
||||
|
||||
open fun getLayoutXmlFiles(): List<PsiFile> {
|
||||
public fun getLayoutXmlFiles(): Map<String, List<PsiFile>> {
|
||||
val info = androidModuleInfo
|
||||
if (info == null) return listOf()
|
||||
if (info == null) return mapOf()
|
||||
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val fileManager = VirtualFileManager.getInstance()
|
||||
@@ -61,7 +61,8 @@ public abstract class AndroidResourceManager(val project: Project) {
|
||||
.filter { it.getParent().getName().startsWith("layout") && it.getName().toLowerCase().endsWith(".xml") }
|
||||
.map { psiManager.findFile(it) }
|
||||
.filterNotNull()
|
||||
.sortBy { it.getName() }
|
||||
.groupBy { it.getName().substringBeforeLast('.') }
|
||||
.mapValues { it.getValue().sortBy { it.getParent().getName().length() } }
|
||||
}
|
||||
|
||||
fun getMainResDirectory(): VirtualFile? {
|
||||
|
||||
+21
-5
@@ -69,7 +69,7 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) {
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
val applicationPackage = resourceManager.androidModuleInfo?.applicationPackage
|
||||
|
||||
val jetFiles = cachedSources.getValue().mapIndexed { (index, text) ->
|
||||
val jetFiles = cachedSources.getValue().mapIndexed { index, text ->
|
||||
val virtualFile = LightVirtualFile(AndroidConst.SYNTHETIC_FILENAME + index + ".kt", text)
|
||||
val jetFile = psiManager.findFile(virtualFile) as JetFile
|
||||
if (applicationPackage != null) {
|
||||
@@ -89,10 +89,11 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) {
|
||||
listOf(clearCacheFile, FLEXIBLE_TYPE_FILE)
|
||||
} else listOf()
|
||||
|
||||
return resourceManager.getLayoutXmlFiles().flatMap { file ->
|
||||
val widgets = parseSingleFile(file)
|
||||
return resourceManager.getLayoutXmlFiles().flatMap { entry ->
|
||||
val files = entry.getValue()
|
||||
val widgets = parseLayout(files)
|
||||
if (widgets.isNotEmpty()) {
|
||||
val layoutPackage = file.genSyntheticPackageName()
|
||||
val layoutPackage = files[0].genSyntheticPackageName()
|
||||
|
||||
val mainLayoutFile = renderLayoutFile(layoutPackage, widgets) {
|
||||
writeSyntheticProperty("Activity", it, "findViewById(0)")
|
||||
@@ -110,7 +111,7 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) {
|
||||
|
||||
public fun parseToPsi(): List<JetFile>? = cachedJetFiles.getValue()
|
||||
|
||||
protected abstract fun parseSingleFile(file: PsiFile): List<AndroidWidget>
|
||||
protected abstract fun parseLayout(files: List<PsiFile>): List<AndroidWidget>
|
||||
|
||||
private fun renderLayoutFile(
|
||||
packageName: String,
|
||||
@@ -150,6 +151,21 @@ public abstract class AndroidUIXmlProcessor(protected val project: Project) {
|
||||
return CachedValuesManager.getManager(project).createCachedValue(result, false)
|
||||
}
|
||||
|
||||
protected fun removeDuplicates(widgets: List<AndroidWidget>): List<AndroidWidget> {
|
||||
val widgetMap = linkedMapOf<String, AndroidWidget>()
|
||||
for (widget in widgets) {
|
||||
if (widgetMap.contains(widget.id)) {
|
||||
val existingElement = widgetMap.get(widget.id)
|
||||
if (existingElement.className != widget.className) {
|
||||
// Widgets with the same id but different types exist.
|
||||
widgetMap.put(widget.id, widget.copy(className = "View"))
|
||||
}
|
||||
}
|
||||
else widgetMap.put(widget.id, widget)
|
||||
}
|
||||
return widgetMap.values().toList()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val EXPLICIT_FLEXIBLE_PACKAGE = Flexibility.FLEXIBLE_TYPE_CLASSIFIER.getPackageFqName().asString()
|
||||
private val EXPLICIT_FLEXIBLE_CLASS_NAME = Flexibility.FLEXIBLE_TYPE_CLASSIFIER.getRelativeClassName().asString()
|
||||
|
||||
+7
-5
@@ -43,14 +43,16 @@ public class CliAndroidUIXmlProcessor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun parseSingleFile(file: PsiFile): List<AndroidWidget> {
|
||||
override fun parseLayout(files: List<PsiFile>): List<AndroidWidget> {
|
||||
val widgets = arrayListOf<AndroidWidget>()
|
||||
val handler = AndroidXmlHandler { id, clazz -> widgets.add(AndroidWidget(id, clazz)) }
|
||||
val handler = AndroidXmlHandler { id, widgetType -> widgets.add(AndroidWidget(id, widgetType)) }
|
||||
|
||||
try {
|
||||
val inputStream = ByteArrayInputStream(file.getVirtualFile().contentsToByteArray())
|
||||
resourceManager.saxParser.parse(inputStream, handler)
|
||||
return widgets
|
||||
for (file in files) {
|
||||
val inputStream = ByteArrayInputStream(file.getVirtualFile().contentsToByteArray())
|
||||
resourceManager.saxParser.parse(inputStream, handler)
|
||||
}
|
||||
return removeDuplicates(widgets)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
|
||||
+1
-1
@@ -20,4 +20,4 @@ public data class AndroidModuleInfo(val applicationPackage: String, val mainResD
|
||||
|
||||
trait AndroidResource
|
||||
|
||||
public class AndroidWidget(val id: String, val className: String) : AndroidResource
|
||||
public data class AndroidWidget(val id: String, val className: String) : AndroidResource
|
||||
Reference in New Issue
Block a user