diff options
author | Adam Lesinski <adamlesinski@google.com> | 2017-12-08 16:06:10 -0800 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2018-01-11 13:54:11 -0800 |
commit | 73bff1e8519bb73f17a801f45977d41b69b5b0d0 (patch) | |
tree | 9ac5f4e491ed617b6cefe118b91edb637c6c35a4 /tools/aapt2/ResourceValues.cpp | |
parent | 14c2ae4a6e62b78f2c994112d08dbe3d4de64695 (diff) |
AAPT2: Allow compatible duplicate Attributes
If a resource XML file defines two compatible Attributes, they should
be merged without throwing an error. Ex:
<declare-styleable>
<attr name="conflict" format="string" />
</declare-styleable>
<declare-styleable>
<attr name="conflict" format="string|reference" />
</declare-styleable>
In this case, string|reference and string are the same, so these should
merge correctly.
Bug: 65699599
Test: make aapt2_tests
Test: make AaptBasicTest
Change-Id: I7b0f956d2332f7f0b458acd59ca0a606b2cfdf95
Diffstat (limited to 'tools/aapt2/ResourceValues.cpp')
-rw-r--r-- | tools/aapt2/ResourceValues.cpp | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index a782cd3672d1..77cee0683f3e 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -507,17 +507,10 @@ void BinaryPrimitive::PrettyPrint(Printer* printer) const { } } -Attribute::Attribute() - : type_mask(0u), - min_int(std::numeric_limits<int32_t>::min()), - max_int(std::numeric_limits<int32_t>::max()) { -} - -Attribute::Attribute(bool w, uint32_t t) +Attribute::Attribute(uint32_t t) : type_mask(t), min_int(std::numeric_limits<int32_t>::min()), max_int(std::numeric_limits<int32_t>::max()) { - weak_ = w; } std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) { @@ -568,6 +561,20 @@ bool Attribute::Equals(const Value* value) const { }); } +bool Attribute::IsCompatibleWith(const Attribute& attr) const { + // If the high bits are set on any of these attribute type masks, then they are incompatible. + // We don't check that flags and enums are identical. + if ((type_mask & ~android::ResTable_map::TYPE_ANY) != 0 || + (attr.type_mask & ~android::ResTable_map::TYPE_ANY) != 0) { + return false; + } + + // Every attribute accepts a reference. + uint32_t this_type_mask = type_mask | android::ResTable_map::TYPE_REFERENCE; + uint32_t that_type_mask = attr.type_mask | android::ResTable_map::TYPE_REFERENCE; + return this_type_mask == that_type_mask; +} + Attribute* Attribute::Clone(StringPool* /*new_pool*/) const { return new Attribute(*this); } |