mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix: replace usage of Map with SparseArray
This commit is contained in:
@@ -21,9 +21,11 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.SparseArray
|
||||
import android.view.Menu
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
import androidx.core.util.forEach
|
||||
import androidx.core.view.GravityCompat
|
||||
import com.blankj.utilcode.util.ImageUtils
|
||||
import com.blankj.utilcode.util.ThreadUtils
|
||||
@@ -605,7 +607,7 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
|
||||
executeAsyncProvideError({
|
||||
val files = editorViewModel.getOpenedFiles()
|
||||
val dupliCount = mutableMapOf<String, Int>()
|
||||
val names = mutableMapOf<Int, String>()
|
||||
val names = SparseArray<String>()
|
||||
val nameBuilder = UniqueNameBuilder<File>("", File.separator)
|
||||
|
||||
files.forEach {
|
||||
@@ -633,7 +635,9 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
|
||||
}
|
||||
|
||||
ThreadUtils.runOnUiThread {
|
||||
result.forEach { (index, name) -> binding.tabs.getTabAt(index)?.text = name }
|
||||
result.forEach { index, name ->
|
||||
binding.tabs.getTabAt(index)?.text = name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.utils
|
||||
|
||||
/**
|
||||
* Parses the given [hex color string][hexColor] and returns the [Long] representing
|
||||
* the color.
|
||||
*
|
||||
* @param hexColor The color string.
|
||||
* @return The parsed color value.
|
||||
* @throws IllegalArgumentException If there was an error parsing the hex color.
|
||||
*/
|
||||
fun parseHexColor(hexColor: String) : Long {
|
||||
var str = hexColor
|
||||
if (str[0] == '#') {
|
||||
str = str.substring(1)
|
||||
}
|
||||
return try {
|
||||
if (str.length == 3) {
|
||||
// HEX color is in the form of #FFF
|
||||
// convert it to #FFFFFF format (6 character long)
|
||||
val r = str[0]
|
||||
val g = str[1]
|
||||
val b = str[2]
|
||||
str = "$r$r$g$g$b$b"
|
||||
}
|
||||
|
||||
if (str.length == 6) {
|
||||
// Prepend alpha value
|
||||
str = "FF${str}"
|
||||
}
|
||||
|
||||
java.lang.Long.parseLong(str, 16)
|
||||
} catch (e: Exception) {
|
||||
throw IllegalArgumentException("Failed to parse hex color. color=$hexColor, processedColorString=$str", e)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.utils
|
||||
|
||||
import android.util.SparseIntArray
|
||||
|
||||
/**
|
||||
* Get the value associated with the given key or `null`.
|
||||
*/
|
||||
fun SparseIntArray.getOrNull(key: Int) : Int? {
|
||||
val keyIdx = indexOfKey(key)
|
||||
if (keyIdx >= 0) {
|
||||
return valueAt(keyIdx)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
+4
-19
@@ -23,6 +23,7 @@ import com.itsaky.androidide.editor.schemes.LanguageScheme
|
||||
import com.itsaky.androidide.treesitter.TSQuery
|
||||
import com.itsaky.androidide.treesitter.TSQueryCapture
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.parseHexColor
|
||||
import io.github.rosemoe.sora.editor.ts.spans.DefaultSpanFactory
|
||||
import io.github.rosemoe.sora.editor.ts.spans.TsSpanFactory
|
||||
import io.github.rosemoe.sora.lang.styling.Span
|
||||
@@ -95,28 +96,12 @@ class TreeSitterSpanFactory(
|
||||
}
|
||||
e = result.range.last
|
||||
|
||||
var str = ""
|
||||
val color = try {
|
||||
str = result.groupValues[1]
|
||||
if (str.length == 3) {
|
||||
// HEX color is in the form of #FFF
|
||||
// convert it to #FFFFFF format (6 character long)
|
||||
val r = str[0]
|
||||
val g = str[1]
|
||||
val b = str[2]
|
||||
str = "$r$r$g$g$b$b"
|
||||
}
|
||||
|
||||
if (str.length == 6) {
|
||||
// Prepend alpha value
|
||||
str = "FF${str}"
|
||||
}
|
||||
|
||||
java.lang.Long.parseLong(str, 16)
|
||||
parseHexColor(result.groupValues[1]).toInt()
|
||||
} catch (e: Exception) {
|
||||
log.error("Failed to parse hex color. color=$str text=$text", e)
|
||||
log.error("An error occurred parsing hex color. text=$text", e)
|
||||
return@forEach
|
||||
}.toInt()
|
||||
}
|
||||
|
||||
val textColor = if (ColorUtils.calculateLuminance(color) > 0.5f) {
|
||||
Color.BLACK
|
||||
|
||||
@@ -17,8 +17,12 @@
|
||||
|
||||
package com.itsaky.androidide.editor.schemes
|
||||
|
||||
import android.util.SparseIntArray
|
||||
import androidx.core.util.containsKey
|
||||
import androidx.core.util.set
|
||||
import com.itsaky.androidide.editor.schemes.internal.parser.SchemeParser
|
||||
import com.itsaky.androidide.syntax.colorschemes.DynamicColorScheme
|
||||
import com.itsaky.androidide.utils.getOrNull
|
||||
import io.github.rosemoe.sora.lang.styling.TextStyle
|
||||
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
|
||||
import java.io.File
|
||||
@@ -26,8 +30,8 @@ import java.util.TreeSet
|
||||
|
||||
class IDEColorScheme(internal val file: File, val key: String) : DynamicColorScheme() {
|
||||
|
||||
internal val colorIds = mutableMapOf<Int, Int>()
|
||||
internal val editorScheme = mutableMapOf<Int, Int>()
|
||||
internal val colorIds = SparseIntArray()
|
||||
internal val editorScheme = SparseIntArray()
|
||||
internal val languages = mutableMapOf<String, LanguageScheme>()
|
||||
|
||||
var name: String = ""
|
||||
@@ -64,7 +68,7 @@ class IDEColorScheme(internal val file: File, val key: String) : DynamicColorSch
|
||||
override fun getColor(type: Int): Int {
|
||||
// getColor is called in superclass constructor
|
||||
// in this case, the below properties will be null
|
||||
return editorScheme?.get(type) ?: colorIds?.get(type) ?: super.getColor(type)
|
||||
return editorScheme?.getOrNull(type) ?: colorIds?.getOrNull(type) ?: super.getColor(type)
|
||||
}
|
||||
|
||||
override fun isDark(): Boolean {
|
||||
|
||||
+1
@@ -17,6 +17,7 @@
|
||||
|
||||
package com.itsaky.androidide.editor.schemes.internal.parser
|
||||
|
||||
import androidx.core.util.set
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.itsaky.androidide.editor.schemes.IDEColorScheme
|
||||
import com.itsaky.androidide.editor.schemes.internal.parser.SchemeParser.EditorColors
|
||||
|
||||
+4
-2
@@ -24,5 +24,7 @@ import com.google.gson.JsonParseException
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class ParseException(msg: String?) : JsonParseException(msg) {
|
||||
}
|
||||
class ParseException @JvmOverloads constructor(
|
||||
msg: String?,
|
||||
cause: Throwable? = null
|
||||
) : JsonParseException(msg, cause)
|
||||
@@ -23,6 +23,7 @@ import com.google.gson.stream.JsonToken.STRING
|
||||
import com.itsaky.androidide.editor.schemes.IDEColorScheme
|
||||
import com.itsaky.androidide.editor.schemes.LanguageScheme
|
||||
import com.itsaky.androidide.editor.schemes.StyleDef
|
||||
import com.itsaky.androidide.utils.parseHexColor
|
||||
import java.io.File
|
||||
|
||||
/** @author Akash Yadav */
|
||||
@@ -47,17 +48,16 @@ fun IDEColorScheme.parseColorValue(value: String?, colorId: Boolean = true): Int
|
||||
val refName = value.substring(1)
|
||||
val refValue =
|
||||
definitions[refName] ?: throw ParseException("Referenced color '$value' not found")
|
||||
return if (colorId) refValue else colorIds[refValue]!!
|
||||
return if (colorId) refValue else colorIds.get(refValue)
|
||||
}
|
||||
|
||||
if (value[0] == '#') {
|
||||
val color =
|
||||
try {
|
||||
Color.parseColor(value)
|
||||
parseHexColor(value).toInt()
|
||||
} catch (err: Throwable) {
|
||||
throw ParseException("Invalid hex color code: '$value'")
|
||||
throw ParseException("Invalid hex color code: '$value'", err)
|
||||
}
|
||||
|
||||
return if (colorId) putColor(color) else color
|
||||
}
|
||||
|
||||
|
||||
+20
-18
@@ -18,6 +18,8 @@
|
||||
package com.itsaky.androidide.editor.schemes.internal.parser
|
||||
|
||||
import android.graphics.Color
|
||||
import android.util.SparseIntArray
|
||||
import androidx.core.util.size
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.itsaky.androidide.editor.schemes.IDEColorScheme
|
||||
import com.itsaky.androidide.editor.schemes.internal.parser.SchemeParser
|
||||
@@ -36,11 +38,11 @@ class SchemeParserTest {
|
||||
val scheme = parseSyntaxJson()
|
||||
assertThat(scheme.isDarkScheme).isFalse()
|
||||
assertThat(scheme.definitions).hasSize(12)
|
||||
assertThat(scheme.colorIds[scheme.definitions["black"]]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[scheme.definitions["white"]]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[scheme.definitions["9e"]]).isEqualTo(Color.parseColor("#9e9e9e"))
|
||||
assertThat(scheme.colorIds[scheme.definitions["black"] ?: -1]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[scheme.definitions["white"] ?: -1]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[scheme.definitions["9e"] ?: -1]).isEqualTo(Color.parseColor("#9e9e9e"))
|
||||
|
||||
assertThat(scheme.editorScheme).hasSize(27)
|
||||
assertThat(scheme.editorScheme.size).isEqualTo(27)
|
||||
assertThat(scheme.editorScheme[EditorColorScheme.WHOLE_BACKGROUND])
|
||||
.isEqualTo(Color.parseColor("#212121"))
|
||||
}
|
||||
@@ -63,12 +65,12 @@ class SchemeParserTest {
|
||||
this.styles["text.debug"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.parseColor("#f5f5f5"))
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["f5"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["f5"] ?: -1])
|
||||
}
|
||||
this.styles["priority.debug"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["white"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["white"] ?: -1])
|
||||
assertThat(scheme.colorIds[this.bg]).isEqualTo(Color.parseColor("#9e9d24"))
|
||||
assertThat(this.bold || this.italic || this.strikeThrough).isFalse()
|
||||
assertThat(this.completion).isTrue()
|
||||
@@ -76,7 +78,7 @@ class SchemeParserTest {
|
||||
this.styles["priority.error"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["black"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["black"] ?: -1])
|
||||
assertThat(scheme.colorIds[this.bg]).isEqualTo(Color.parseColor("#f44336"))
|
||||
assertThat(this.bold || this.italic || this.strikeThrough).isFalse()
|
||||
assertThat(this.completion).isFalse()
|
||||
@@ -114,12 +116,12 @@ class SchemeParserTest {
|
||||
this.styles["text.debug"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.parseColor("#f5f5f5"))
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["f5"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["f5"] ?: -1])
|
||||
}
|
||||
this.styles["priority.debug"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["white"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["white"] ?: -1])
|
||||
assertThat(scheme.colorIds[this.bg]).isEqualTo(Color.parseColor("#9e9d24"))
|
||||
assertThat(this.bold || this.italic || this.strikeThrough).isFalse()
|
||||
assertThat(this.completion).isTrue()
|
||||
@@ -127,7 +129,7 @@ class SchemeParserTest {
|
||||
this.styles["priority.error"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["black"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["black"] ?: -1])
|
||||
assertThat(scheme.colorIds[this.bg]).isEqualTo(Color.parseColor("#f44336"))
|
||||
assertThat(this.bold || this.italic || this.strikeThrough).isFalse()
|
||||
assertThat(this.completion).isFalse()
|
||||
@@ -160,12 +162,12 @@ class SchemeParserTest {
|
||||
this.styles["text.debug"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.parseColor("#f5f5f5"))
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["f5"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["f5"] ?: -1])
|
||||
}
|
||||
this.styles["priority.debug"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["white"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["white"] ?: -1])
|
||||
assertThat(scheme.colorIds[this.bg]).isEqualTo(Color.parseColor("#9e9d24"))
|
||||
assertThat(this.bold || this.italic || this.strikeThrough).isFalse()
|
||||
assertThat(this.completion).isTrue()
|
||||
@@ -173,7 +175,7 @@ class SchemeParserTest {
|
||||
this.styles["priority.error"].apply {
|
||||
assertThat(this).isNotNull()
|
||||
assertThat(scheme.colorIds[this!!.fg]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["black"]])
|
||||
assertThat(scheme.colorIds[this.fg]).isEqualTo(scheme.colorIds[scheme.definitions["black"] ?: -1])
|
||||
assertThat(scheme.colorIds[this.bg]).isEqualTo(Color.parseColor("#f44336"))
|
||||
assertThat(this.bold || this.italic || this.strikeThrough).isFalse()
|
||||
assertThat(this.completion).isFalse()
|
||||
@@ -193,11 +195,11 @@ class SchemeParserTest {
|
||||
val scheme = parseSyntaxJson("editor-ref.json")
|
||||
assertThat(scheme.isDarkScheme).isFalse()
|
||||
assertThat(scheme.definitions).hasSize(12)
|
||||
assertThat(scheme.colorIds[scheme.definitions["black"]]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[scheme.definitions["white"]]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[scheme.definitions["9e"]]).isEqualTo(Color.parseColor("#9e9e9e"))
|
||||
assertThat(scheme.colorIds[scheme.definitions["black"] ?: -1]).isEqualTo(Color.BLACK)
|
||||
assertThat(scheme.colorIds[scheme.definitions["white"] ?: -1]).isEqualTo(Color.WHITE)
|
||||
assertThat(scheme.colorIds[scheme.definitions["9e"] ?: -1]).isEqualTo(Color.parseColor("#9e9e9e"))
|
||||
|
||||
assertThat(scheme.editorScheme).hasSize(27)
|
||||
assertThat(scheme.editorScheme.size).isEqualTo(27)
|
||||
assertThat(scheme.editorScheme[EditorColorScheme.WHOLE_BACKGROUND])
|
||||
.isEqualTo(Color.parseColor("#212121"))
|
||||
}
|
||||
@@ -209,4 +211,4 @@ class SchemeParserTest {
|
||||
assertThat(scheme).isNotNull()
|
||||
return scheme
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.aaptcompiler
|
||||
|
||||
import android.util.SparseArray
|
||||
import com.android.aapt.Resources
|
||||
import com.itsaky.androidide.layoutlib.resources.ResourceVisibility
|
||||
import java.io.File
|
||||
@@ -16,6 +17,7 @@ import java.util.TreeMap
|
||||
* resources from libraries and are not validated.
|
||||
*/
|
||||
class ResourceTable(val validateResources: Boolean = false, val logger: BlameLogger? = null) {
|
||||
|
||||
/**
|
||||
* The string pool used by this resource table. Values that reference strings must use this pool
|
||||
* to create their strings.
|
||||
@@ -29,7 +31,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
* Set of dynamic packages that this table may reference. Their package names get encoded into the
|
||||
* resources.arsc along with their compile-time assigned IDs.
|
||||
*/
|
||||
private val includedPackages = mutableMapOf<Int, String>()
|
||||
private val includedPackages = SparseArray<String>()
|
||||
|
||||
enum class CollisionResult {
|
||||
KEEP_ORIGINAL,
|
||||
@@ -258,6 +260,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
tablePackage.id = id
|
||||
return tablePackage
|
||||
}
|
||||
|
||||
tablePackage.id != id -> return null
|
||||
}
|
||||
}
|
||||
@@ -288,6 +291,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
packages.add(newPackage)
|
||||
newPackage
|
||||
}
|
||||
|
||||
else -> tablePackage
|
||||
}
|
||||
}
|
||||
@@ -320,7 +324,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(source),
|
||||
"Resource '$name' has invalid entry name '${name.entry}'. " +
|
||||
"Invalid character '$badCodePoint'."
|
||||
"Invalid character '$badCodePoint'."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -349,7 +353,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(value.source),
|
||||
"Failed to add resource '$name' with ID ${id.toString(16)} because " +
|
||||
"package '${tablePackage.name}' already has ID ${packageId.toString(16)}."
|
||||
"package '${tablePackage.name}' already has ID ${packageId.toString(16)}."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -364,7 +368,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(value.source),
|
||||
"Failed to add resource '$name' with ID ${id.toString(16)} because type " +
|
||||
"'${resourceGroup.type.tagName}' already has ID ${groupId.toString(16)}."
|
||||
"'${resourceGroup.type.tagName}' already has ID ${groupId.toString(16)}."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -376,7 +380,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(value.source),
|
||||
"Failed to add resource '$name' with ID ${id.toString(16)}, because resource already" +
|
||||
" has ID ${resourceIdFromParts(packageId!!, groupId!!, entryId).toString(16)}."
|
||||
" has ID ${resourceIdFromParts(packageId!!, groupId!!, entryId).toString(16)}."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -395,10 +399,11 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(value.source),
|
||||
"Duplicate value for resource '$name' with config '$config' and product '$product'. " +
|
||||
"Resource was previously defined here: $previousSource."
|
||||
"Resource was previously defined here: $previousSource."
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
CollisionResult.KEEP_ORIGINAL -> {}
|
||||
}
|
||||
}
|
||||
@@ -451,7 +456,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(source),
|
||||
"Failed to add resource '$name' with ID ${id.toString(16)} because package " +
|
||||
"'${tablePackage.name}' already has ID ${packageId.toString(16)}."
|
||||
"'${tablePackage.name}' already has ID ${packageId.toString(16)}."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -466,7 +471,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(source),
|
||||
"Failed to add resource '$name' with ID ${id.toString(16)} because type " +
|
||||
"'${resourceGroup.type.tagName}' already has ID ${groupId.toString(16)}."
|
||||
"'${resourceGroup.type.tagName}' already has ID ${groupId.toString(16)}."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -478,7 +483,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(source),
|
||||
"Failed to add resource '$name' with ID ${id.toString(16)}, because resource already " +
|
||||
"has ID ${resourceIdFromParts(packageId!!, groupId!!, entryId).toString(16)}."
|
||||
"has ID ${resourceIdFromParts(packageId!!, groupId!!, entryId).toString(16)}."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -496,27 +501,30 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
|
||||
when {
|
||||
visibility.level == ResourceVisibility.UNDEFINED &&
|
||||
resourceEntry.visibility.level != ResourceVisibility.UNDEFINED -> {
|
||||
resourceEntry.visibility.level != ResourceVisibility.UNDEFINED -> {
|
||||
// We can't undefine a symbol. Ignore
|
||||
}
|
||||
|
||||
visibility.level == ResourceVisibility.PRIVATE &&
|
||||
resourceEntry.visibility.level == ResourceVisibility.PUBLIC -> {
|
||||
resourceEntry.visibility.level == ResourceVisibility.PUBLIC -> {
|
||||
logError(
|
||||
blameSource(source),
|
||||
"Failed to add resource '$name' as private (java-symbol) because it was " +
|
||||
"previously defined as public."
|
||||
"previously defined as public."
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
visibility.level == ResourceVisibility.PUBLIC &&
|
||||
resourceEntry.visibility.level == ResourceVisibility.PRIVATE -> {
|
||||
resourceEntry.visibility.level == ResourceVisibility.PRIVATE -> {
|
||||
logError(
|
||||
blameSource(source),
|
||||
"Failed to add resource '$name' as public because it was previously defined as " +
|
||||
"private (java-symbol)."
|
||||
"private (java-symbol)."
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
else -> {
|
||||
// This symbol definition takes precedence.
|
||||
resourceEntry.visibility = visibility
|
||||
@@ -562,7 +570,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
logError(
|
||||
blameSource(overlayable.source),
|
||||
"Failed to add overlayable declaration for resource '$name', because resource already " +
|
||||
"has an overlayable defined here: $previousSource."
|
||||
"has an overlayable defined here: $previousSource."
|
||||
)
|
||||
return false
|
||||
}
|
||||
@@ -571,6 +579,7 @@ class ResourceTable(val validateResources: Boolean = false, val logger: BlameLog
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun resolveValueCollision(existing: Value, incoming: Value): CollisionResult {
|
||||
val existingAttr = existing as? AttributeResource
|
||||
val incomingAttr = incoming as? AttributeResource
|
||||
@@ -633,6 +642,7 @@ class Overlayable(val name: String, val actor: String, val source: Source) {
|
||||
constructor() : this("", "", Source(""))
|
||||
|
||||
companion object {
|
||||
|
||||
const val ACTOR_SCHEME = "overlay"
|
||||
const val ACTOR_SCHEME_URI = "$ACTOR_SCHEME://"
|
||||
}
|
||||
@@ -661,19 +671,27 @@ class OverlayableItem(
|
||||
|
||||
/** Represents the types of overlays that are allowed to overlay the resource. */
|
||||
object Policy {
|
||||
|
||||
const val NONE = 0
|
||||
|
||||
/** The resource can be overlaid by any overlay. */
|
||||
const val PUBLIC = 1 shl 0
|
||||
|
||||
/** The resource can be overlaid by any overlay on the system partition. */
|
||||
const val SYSTEM = 1 shl 1
|
||||
|
||||
/** The resource can be overlaid by any overlay on the vendor partition. */
|
||||
const val VENDOR = 1 shl 2
|
||||
|
||||
/** The resource can be overlaid by any overlay on the product partition. */
|
||||
const val PRODUCT = 1 shl 3
|
||||
|
||||
/** The resource can be overlaid by any overlay signed with the same signature as its actor. */
|
||||
const val SIGNATURE = 1 shl 4
|
||||
|
||||
/** The resource can be overlaid by any overlay on the odm partition. */
|
||||
const val ODM = 1 shl 5
|
||||
|
||||
/** The resource can be overlaid by any overlay on the oem partition. */
|
||||
const val OEM = 1 shl 6
|
||||
}
|
||||
@@ -700,6 +718,7 @@ class ResourceTablePackage(var name: String = "", var id: Byte? = null) {
|
||||
groups.add(newGroup)
|
||||
newGroup
|
||||
}
|
||||
|
||||
else -> group
|
||||
}
|
||||
}
|
||||
@@ -710,6 +729,7 @@ class ResourceTablePackage(var name: String = "", var id: Byte? = null) {
|
||||
* etc.).
|
||||
*/
|
||||
class ResourceGroup(val type: AaptResourceType) {
|
||||
|
||||
var id: Byte? = null
|
||||
var visibility = ResourceVisibility.UNDEFINED
|
||||
|
||||
@@ -746,6 +766,7 @@ class ResourceGroup(val type: AaptResourceType) {
|
||||
entries.getOrPut(name) { TreeMap(nullsFirst()) }[entryId] = newEntry
|
||||
newEntry
|
||||
}
|
||||
|
||||
else -> entry
|
||||
}
|
||||
}
|
||||
@@ -753,6 +774,7 @@ class ResourceGroup(val type: AaptResourceType) {
|
||||
|
||||
/** Represents a resource entry, which may have varying values for each defined configuration. */
|
||||
class ResourceEntry(val name: String) {
|
||||
|
||||
var id: Short? = null
|
||||
var visibility = Visibility(Source(""), "", ResourceVisibility.UNDEFINED)
|
||||
|
||||
@@ -773,6 +795,7 @@ class ResourceEntry(val name: String) {
|
||||
values.add(newConfigValue)
|
||||
newConfigValue
|
||||
}
|
||||
|
||||
else -> configValue
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -42,6 +42,7 @@ import com.android.aaptcompiler.resourceIdFromParts
|
||||
import com.android.aaptcompiler.resourceTypeFromTag
|
||||
import com.itsaky.androidide.layoutlib.resources.ResourceVisibility
|
||||
import com.android.utils.ILogger
|
||||
import com.android.utils.SparseArray
|
||||
|
||||
fun deserializeConfigFromPb(
|
||||
config: ConfigurationOuterClass.Configuration, logger: ILogger?): ConfigDescription? {
|
||||
@@ -638,7 +639,7 @@ fun deserializePackageFromPb(
|
||||
val packageId =
|
||||
if (original.hasPackageId()) original.getPackageId().getId().toByte() else 0.toByte()
|
||||
|
||||
val idIndex = mutableMapOf<Int, ResourceName>()
|
||||
val idIndex = SparseArray<ResourceName>()
|
||||
|
||||
val resourcePackage =
|
||||
table.createPackageAllowingDuplicateNames(original.getPackageName(), packageId)
|
||||
@@ -725,8 +726,7 @@ fun deserializePackageFromPb(
|
||||
group.getTypeId().getId().toByte(),
|
||||
entry.getEntryId().getId().toShort())
|
||||
if (resourceId.isValidId()) {
|
||||
idIndex[resourceId] =
|
||||
ResourceName(resourcePackage.name, resourceGroup.type, resourceEntry.name)
|
||||
idIndex.put(resourceId, ResourceName(resourcePackage.name, resourceGroup.type, resourceEntry.name))
|
||||
}
|
||||
|
||||
for (configValue in entry.getConfigValueList()) {
|
||||
|
||||
Reference in New Issue
Block a user