diff options
author | 2024-08-23 17:29:03 -0700 | |
---|---|---|
committer | 2024-09-25 14:50:54 -0700 | |
commit | 3d8d4a18c2bd4d697692ea30471852c90e7a3775 (patch) | |
tree | 19f6ae00972e306ed53d18712bc3893f2b973b42 /tools/aapt2/ResourceParser.cpp | |
parent | b7ab38e10e1f0d3088153f070e681e34263d393c (diff) |
Error on duplicate resource with same disabled flag
Also realized I hadn't handled flag negation so added that as well.
Test: Automated
Bug: 329436914
Flag: EXEMPT Aconfig not supported on host tools
Change-Id: If90ae71070306f8e0c367be7e652da9c7bd0bb22
Diffstat (limited to 'tools/aapt2/ResourceParser.cpp')
-rw-r--r-- | tools/aapt2/ResourceParser.cpp | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index a5aecc855707..773edc3e3c22 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -107,9 +107,10 @@ struct ParsedResource { Visibility::Level visibility_level = Visibility::Level::kUndefined; bool staged_api = false; bool allow_new = false; - FlagStatus flag_status = FlagStatus::NoFlag; std::optional<OverlayableItem> overlayable_item; std::optional<StagedId> staged_alias; + std::optional<FeatureFlagAttribute> flag; + FlagStatus flag_status; std::string comment; std::unique_ptr<Value> value; @@ -151,6 +152,7 @@ static bool AddResourcesToTable(ResourceTable* table, android::IDiagnostics* dia } if (res->value != nullptr) { + res->value->SetFlag(res->flag); res->value->SetFlagStatus(res->flag_status); // Attach the comment, source and config to the value. res->value->SetComment(std::move(res->comment)); @@ -162,8 +164,6 @@ static bool AddResourcesToTable(ResourceTable* table, android::IDiagnostics* dia res_builder.SetStagedId(res->staged_alias.value()); } - res_builder.SetFlagStatus(res->flag_status); - bool error = false; if (!res->name.entry.empty()) { if (!table->AddResource(res_builder.Build(), diag)) { @@ -547,11 +547,15 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, }); std::string resource_type = parser->element_name(); - auto flag_status = GetFlagStatus(parser); - if (!flag_status) { + out_resource->flag = GetFlag(parser); + std::string error; + auto flag_status = GetFlagStatus(out_resource->flag, options_.feature_flag_values, &error); + if (flag_status) { + out_resource->flag_status = flag_status.value(); + } else { + diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) << error); return false; } - out_resource->flag_status = flag_status.value(); // The value format accepted for this resource. uint32_t resource_format = 0u; @@ -733,31 +737,20 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, return false; } -std::optional<FlagStatus> ResourceParser::GetFlagStatus(xml::XmlPullParser* parser) { - auto flag_status = FlagStatus::NoFlag; - - std::optional<StringPiece> flag = xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"); - if (flag) { - auto flag_it = options_.feature_flag_values.find(flag.value()); - if (flag_it == options_.feature_flag_values.end()) { - diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) - << "Resource flag value undefined"); - return {}; - } - const auto& flag_properties = flag_it->second; - if (!flag_properties.read_only) { - diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) - << "Only read only flags may be used with resources"); - return {}; - } - if (!flag_properties.enabled.has_value()) { - diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) - << "Only flags with a value may be used with resources"); - return {}; +std::optional<FeatureFlagAttribute> ResourceParser::GetFlag(xml::XmlPullParser* parser) { + auto name = xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"); + if (name) { + FeatureFlagAttribute flag; + if (name->starts_with('!')) { + flag.negated = true; + flag.name = name->substr(1); + } else { + flag.name = name.value(); } - flag_status = flag_properties.enabled.value() ? FlagStatus::Enabled : FlagStatus::Disabled; + return flag; + } else { + return {}; } - return flag_status; } bool ResourceParser::ParseItem(xml::XmlPullParser* parser, @@ -1666,21 +1659,25 @@ bool ResourceParser::ParseArrayImpl(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 == "item") { - auto flag_status = GetFlagStatus(parser); - if (!flag_status) { - error = true; - continue; - } + auto flag = GetFlag(parser); std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString); if (!item) { diag_->Error(android::DiagMessage(item_source) << "could not parse array item"); error = true; continue; } - item->SetFlagStatus(flag_status.value()); + item->SetFlag(flag); + std::string err; + auto status = GetFlagStatus(flag, options_.feature_flag_values, &err); + if (status) { + item->SetFlagStatus(status.value()); + } else { + diag_->Error(android::DiagMessage(item_source) << err); + error = true; + continue; + } item->SetSource(item_source); array->elements.emplace_back(std::move(item)); - } else if (!ShouldIgnoreElement(element_namespace, element_name)) { diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) << "unknown tag <" << element_namespace << ":" << element_name << ">"); |