From 5924d8c9ab7bd8614e8bd99864903ce9d50f3bf7 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Tue, 30 May 2017 15:15:58 -0700 Subject: AAPT2: Allow merging of Style attributes from overlays Previously style overlays would completely override an existing style. To be compatible with AAPT, styles now merge with the overlay, allowing the overlay's attributes and parent to take precedence. Bug: 38355988 Test: make aapt2_tests Change-Id: Id25c7240050a43e6a4a177c6e3d51e048d0cceb5 --- tools/aapt2/ResourceValues.cpp | 183 +++++++++++++++++++++++++++++------------ 1 file changed, 129 insertions(+), 54 deletions(-) (limited to 'tools/aapt2/ResourceValues.cpp') diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index 34bd2b4361ca..abfdec48df67 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -29,6 +29,11 @@ namespace aapt { +std::ostream& operator<<(std::ostream& out, const Value& value) { + value.Print(&out); + return out; +} + template void BaseValue::Accept(RawValueVisitor* visitor) { visitor->Visit(static_cast(this)); @@ -346,6 +351,15 @@ Attribute::Attribute(bool w, uint32_t t) weak_ = w; } +std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) { + if (s.symbol.name) { + out << s.symbol.name.value().entry; + } else { + out << "???"; + } + return out << "=" << s.value; +} + template constexpr T* add_pointer(T& val) { return &val; @@ -361,31 +375,27 @@ bool Attribute::Equals(const Value* value) const { return false; } - if (type_mask != other->type_mask || min_int != other->min_int || - max_int != other->max_int) { + if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) { return false; } std::vector sorted_a; std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a), add_pointer); - std::sort(sorted_a.begin(), sorted_a.end(), - [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.name < b->symbol.name; - }); + std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.name < b->symbol.name; + }); std::vector sorted_b; - std::transform(other->symbols.begin(), other->symbols.end(), - std::back_inserter(sorted_b), add_pointer); - std::sort(sorted_b.begin(), sorted_b.end(), - [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.name < b->symbol.name; - }); + std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b), + add_pointer); + std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool { + return a->symbol.name < b->symbol.name; + }); return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(), [](const Symbol* a, const Symbol* b) -> bool { - return a->symbol.Equals(&b->symbol) && - a->value == b->value; + return a->symbol.Equals(&b->symbol) && a->value == b->value; }); } @@ -588,14 +598,50 @@ bool Attribute::Matches(const Item* item, DiagMessage* out_msg) const { return true; } +std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) { + if (entry.key.name) { + out << entry.key.name.value(); + } else if (entry.key.id) { + out << entry.key.id.value(); + } else { + out << "???"; + } + out << " = " << entry.value; + return out; +} + +template +std::vector ToPointerVec(std::vector& src) { + std::vector dst; + dst.reserve(src.size()); + for (T& in : src) { + dst.push_back(&in); + } + return dst; +} + +template +std::vector ToPointerVec(const std::vector& src) { + std::vector dst; + dst.reserve(src.size()); + for (const T& in : src) { + dst.push_back(&in); + } + return dst; +} + +static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) { + return a->key.name < b->key.name; +} + bool Style::Equals(const Value* value) const { const Style* other = ValueCast