Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f9ba206 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AAPT2: Allow compatible duplicate Attributes"

parents da6e6356 73bff1e8
Loading
Loading
Loading
Loading
+13 −24
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "ResourceParser.h"

#include <functional>
#include <limits>
#include <sstream>

#include "android-base/logging.h"
@@ -987,8 +988,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
    type_mask = ParseFormatAttribute(maybe_format.value());
    if (type_mask == 0) {
      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
                   << "invalid attribute format '" << maybe_format.value()
                   << "'");
                   << "invalid attribute format '" << maybe_format.value() << "'");
      return false;
    }
  }
@@ -1000,8 +1000,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
    if (!min_str.empty()) {
      std::u16string min_str16 = util::Utf8ToUtf16(min_str);
      android::Res_value value;
      if (android::ResTable::stringToInt(min_str16.data(), min_str16.size(),
                                         &value)) {
      if (android::ResTable::stringToInt(min_str16.data(), min_str16.size(), &value)) {
        maybe_min = static_cast<int32_t>(value.data);
      }
    }
@@ -1018,8 +1017,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
    if (!max_str.empty()) {
      std::u16string max_str16 = util::Utf8ToUtf16(max_str);
      android::Res_value value;
      if (android::ResTable::stringToInt(max_str16.data(), max_str16.size(),
                                         &value)) {
      if (android::ResTable::stringToInt(max_str16.data(), max_str16.size(), &value)) {
        maybe_max = static_cast<int32_t>(value.data);
      }
    }
@@ -1061,8 +1059,7 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
    const Source item_source = source_.WithLine(parser->line_number());
    const std::string& element_namespace = parser->element_namespace();
    const std::string& element_name = parser->element_name();
    if (element_namespace.empty() &&
        (element_name == "flag" || element_name == "enum")) {
    if (element_namespace.empty() && (element_name == "flag" || element_name == "enum")) {
      if (element_name == "enum") {
        if (type_mask & android::ResTable_map::TYPE_FLAGS) {
          diag_->Error(DiagMessage(item_source)
@@ -1120,17 +1117,12 @@ bool ResourceParser::ParseAttrImpl(xml::XmlPullParser* parser,
    return false;
  }

  std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(weak);
  std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(
      type_mask ? type_mask : uint32_t{android::ResTable_map::TYPE_ANY});
  attr->SetWeak(weak);
  attr->symbols = std::vector<Attribute::Symbol>(items.begin(), items.end());
  attr->type_mask =
      type_mask ? type_mask : uint32_t(android::ResTable_map::TYPE_ANY);
  if (maybe_min) {
    attr->min_int = maybe_min.value();
  }

  if (maybe_max) {
    attr->max_int = maybe_max.value();
  }
  attr->min_int = maybe_min.value_or_default(std::numeric_limits<int32_t>::min());
  attr->max_int = maybe_max.value_or_default(std::numeric_limits<int32_t>::max());
  out_resource->value = std::move(attr);
  return true;
}
@@ -1445,11 +1437,9 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
    const std::string& element_namespace = parser->element_namespace();
    const std::string& element_name = parser->element_name();
    if (element_namespace.empty() && element_name == "attr") {
      Maybe<StringPiece> maybe_name =
          xml::FindNonEmptyAttribute(parser, "name");
      Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
      if (!maybe_name) {
        diag_->Error(DiagMessage(item_source)
                     << "<attr> tag must have a 'name' attribute");
        diag_->Error(DiagMessage(item_source) << "<attr> tag must have a 'name' attribute");
        error = true;
        continue;
      }
@@ -1457,8 +1447,7 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser,
      // If this is a declaration, the package name may be in the name. Separate
      // these out.
      // Eg. <attr name="android:text" />
      Maybe<Reference> maybe_ref =
          ResourceUtils::ParseXmlAttributeName(maybe_name.value());
      Maybe<Reference> maybe_ref = ResourceUtils::ParseXmlAttributeName(maybe_name.value());
      if (!maybe_ref) {
        diag_->Error(DiagMessage(item_source) << "<attr> tag has invalid name '"
                                              << maybe_name.value() << "'");
+2 −3
Original line number Diff line number Diff line
@@ -262,9 +262,8 @@ ResourceTable::CollisionResult ResourceTable::ResolveValueCollision(Value* exist
  // attributes all-over, we do special handling to see
  // which definition sticks.
  //
  if (existing_attr->type_mask == incoming_attr->type_mask) {
    // The two attributes are both DECLs, but they are plain attributes
    // with the same formats.
  if (existing_attr->IsCompatibleWith(*incoming_attr)) {
    // The two attributes are both DECLs, but they are plain attributes with compatible formats.
    // Keep the strongest one.
    return existing_attr->IsWeak() ? CollisionResult::kTakeNew : CollisionResult::kKeepOriginal;
  }
+1 −4
Original line number Diff line number Diff line
@@ -81,10 +81,7 @@ class ResourceConfigValue {
  DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
};

/**
 * Represents a resource entry, which may have
 * varying values for each defined configuration.
 */
// Represents a resource entry, which may have varying values for each defined configuration.
class ResourceEntry {
 public:
  // The name of the resource. Immutable, as this determines the order of this resource
+20 −6
Original line number Diff line number Diff line
@@ -102,23 +102,37 @@ TEST(ResourceTableTest, AddMultipleResources) {
TEST(ResourceTableTest, OverrideWeakResourceValue) {
  ResourceTable table;

  ASSERT_TRUE(table.AddResource(
      test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
      util::make_unique<Attribute>(true), test::GetDiagnostics()));
  ASSERT_TRUE(table.AddResource(test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
                                test::AttributeBuilder().SetWeak(true).Build(),
                                test::GetDiagnostics()));

  Attribute* attr = test::GetValue<Attribute>(&table, "android:attr/foo");
  ASSERT_THAT(attr, NotNull());
  EXPECT_TRUE(attr->IsWeak());

  ASSERT_TRUE(table.AddResource(
      test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
      util::make_unique<Attribute>(false), test::GetDiagnostics()));
  ASSERT_TRUE(table.AddResource(test::ParseNameOrDie("android:attr/foo"), ConfigDescription{}, "",
                                util::make_unique<Attribute>(), test::GetDiagnostics()));

  attr = test::GetValue<Attribute>(&table, "android:attr/foo");
  ASSERT_THAT(attr, NotNull());
  EXPECT_FALSE(attr->IsWeak());
}

TEST(ResourceTableTest, AllowCompatibleDuplicateAttributes) {
  ResourceTable table;

  const ResourceName name = test::ParseNameOrDie("android:attr/foo");
  Attribute attr_one(android::ResTable_map::TYPE_STRING);
  attr_one.SetWeak(true);
  Attribute attr_two(android::ResTable_map::TYPE_STRING | android::ResTable_map::TYPE_REFERENCE);
  attr_two.SetWeak(true);

  ASSERT_TRUE(table.AddResource(name, ConfigDescription{}, "",
                                util::make_unique<Attribute>(attr_one), test::GetDiagnostics()));
  ASSERT_TRUE(table.AddResource(name, ConfigDescription{}, "",
                                util::make_unique<Attribute>(attr_two), test::GetDiagnostics()));
}

TEST(ResourceTableTest, ProductVaryingValues) {
  ResourceTable table;

+5 −6
Original line number Diff line number Diff line
@@ -179,8 +179,7 @@ TEST(ResourceUtilsTest, ParseStyleParentReference) {
}

TEST(ResourceUtilsTest, ParseEmptyFlag) {
  std::unique_ptr<Attribute> attr =
      test::AttributeBuilder(false)
  std::unique_ptr<Attribute> attr = test::AttributeBuilder()
                                        .SetTypeMask(ResTable_map::TYPE_FLAGS)
                                        .AddItem("one", 0x01)
                                        .AddItem("two", 0x02)
Loading