AAPT2: Merge Styleables instead of overriding them
Styleables merge in AAPT. Preserve this behavior.
Bug:30970091
Change-Id: Ie68ca675aeecd873c0648682182e2fc574e329a0
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 460de0e..ae5d299 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -203,11 +203,38 @@
/**
* The default handler for collisions. A return value of -1 means keep the
* existing value, 0 means fail, and +1 means take the incoming value.
+ *
+ * Typically, a weak value will be overridden by a strong value. An existing weak
+ * value will not be overridden by an incoming weak value.
+ *
+ * There are some exceptions:
+ *
+ * Attributes: There are two types of Attribute values: USE and DECL.
+ *
+ * USE is anywhere an Attribute is declared without a format, and in a place that would
+ * be legal to declare if the Attribute already existed. This is typically in a
+ * <declare-styleable> tag. Attributes defined in a <declare-styleable> are also weak.
+ *
+ * DECL is an absolute declaration of an Attribute and specifies an explicit format.
+ *
+ * A DECL will override a USE without error. Two DECLs must match in their format for there to be
+ * no error.
+ *
+ * Styleables: Styleables are not actual resources, but they are treated as such during the
+ * compilation phase. Styleables are allowed to override each other, and their definitions merge
+ * and accumulate. If both values are Styleables, we just merge them into the existing value.
*/
int ResourceTable::resolveValueCollision(Value* existing, Value* incoming) {
+ if (Styleable* existingStyleable = valueCast<Styleable>(existing)) {
+ if (Styleable* incomingStyleable = valueCast<Styleable>(incoming)) {
+ // Styleables get merged.
+ existingStyleable->mergeWith(incomingStyleable);
+ return -1;
+ }
+ }
+
Attribute* existingAttr = valueCast<Attribute>(existing);
Attribute* incomingAttr = valueCast<Attribute>(incoming);
-
if (!incomingAttr) {
if (incoming->isWeak()) {
// We're trying to add a weak resource but a resource