diff options
Diffstat (limited to 'tools/aapt2/ResourceParser.cpp')
-rw-r--r-- | tools/aapt2/ResourceParser.cpp | 128 |
1 files changed, 101 insertions, 27 deletions
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 1c3ac2ad4f17..4cc60a8dbb07 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -392,6 +392,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, {"declare-styleable", std::mem_fn(&ResourceParser::ParseDeclareStyleable)}, {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)}, {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)}, + {"overlayable", std::mem_fn(&ResourceParser::ParseOverlayable)}, {"plurals", std::mem_fn(&ResourceParser::ParsePlural)}, {"public", std::mem_fn(&ResourceParser::ParsePublic)}, {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)}, @@ -498,7 +499,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, const auto bag_iter = elToBagMap.find(resource_type); if (bag_iter != elToBagMap.end()) { // Ensure we have a name (unless this is a <public-group>). - if (resource_type != "public-group") { + if (resource_type != "public-group" && resource_type != "overlayable") { if (!maybe_name) { diag_->Error(DiagMessage(out_resource->source) << "<" << parser->element_name() << "> missing 'name' attribute"); @@ -605,7 +606,7 @@ std::unique_ptr<Item> ResourceParser::ParseXml(xml::XmlPullParser* parser, if (processed_item) { // Fix up the reference. if (Reference* ref = ValueCast<Reference>(processed_item.get())) { - TransformReferenceFromNamespace(parser, "", ref); + ResolvePackage(parser, ref); } return processed_item; } @@ -690,6 +691,11 @@ bool ResourceParser::ParseString(xml::XmlPullParser* parser, bool ResourceParser::ParsePublic(xml::XmlPullParser* parser, ParsedResource* out_resource) { + if (out_resource->config != ConfigDescription::DefaultConfig()) { + diag_->Warn(DiagMessage(out_resource->source) + << "ignoring configuration '" << out_resource->config << "' for <public> tag"); + } + Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type"); if (!maybe_type) { diag_->Error(DiagMessage(out_resource->source) @@ -726,8 +732,13 @@ bool ResourceParser::ParsePublic(xml::XmlPullParser* parser, return true; } -bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, - ParsedResource* out_resource) { +bool ResourceParser::ParsePublicGroup(xml::XmlPullParser* parser, ParsedResource* out_resource) { + if (out_resource->config != ConfigDescription::DefaultConfig()) { + diag_->Warn(DiagMessage(out_resource->source) + << "ignoring configuration '" << out_resource->config + << "' for <public-group> tag"); + } + Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type"); if (!maybe_type) { diag_->Error(DiagMessage(out_resource->source) @@ -842,13 +853,83 @@ bool ResourceParser::ParseSymbolImpl(xml::XmlPullParser* parser, return true; } -bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser, - ParsedResource* out_resource) { - if (ParseSymbolImpl(parser, out_resource)) { - out_resource->symbol_state = SymbolState::kPrivate; - return true; +bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource) { + if (out_resource->config != ConfigDescription::DefaultConfig()) { + diag_->Warn(DiagMessage(out_resource->source) + << "ignoring configuration '" << out_resource->config << "' for <" + << parser->element_name() << "> tag"); } - return false; + + if (!ParseSymbolImpl(parser, out_resource)) { + return false; + } + + out_resource->symbol_state = SymbolState::kPrivate; + return true; +} + +bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource* out_resource) { + if (out_resource->config != ConfigDescription::DefaultConfig()) { + diag_->Warn(DiagMessage(out_resource->source) + << "ignoring configuration '" << out_resource->config << "' for <overlayable> tag"); + } + + if (Maybe<StringPiece> maybe_policy = xml::FindNonEmptyAttribute(parser, "policy")) { + const StringPiece& policy = maybe_policy.value(); + if (policy != "system") { + diag_->Error(DiagMessage(out_resource->source) + << "<overlayable> has invalid policy '" << policy << "'"); + return false; + } + } + + bool error = false; + const size_t depth = parser->depth(); + while (xml::XmlPullParser::NextChildNode(parser, depth)) { + if (parser->event() != xml::XmlPullParser::Event::kStartElement) { + // Skip text/comments. + continue; + } + + 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 == "item") { + Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name"); + if (!maybe_name) { + diag_->Error(DiagMessage(item_source) + << "<item> within an <overlayable> tag must have a 'name' attribute"); + error = true; + continue; + } + + Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type"); + if (!maybe_type) { + diag_->Error(DiagMessage(item_source) + << "<item> within an <overlayable> tag must have a 'type' attribute"); + error = true; + continue; + } + + const ResourceType* type = ParseResourceType(maybe_type.value()); + if (type == nullptr) { + diag_->Error(DiagMessage(out_resource->source) + << "invalid resource type '" << maybe_type.value() + << "' in <item> within an <overlayable>"); + error = true; + continue; + } + + // TODO(b/64980941): Mark the symbol as overlayable and allow marking which entity can overlay + // the resource (system/app). + + xml::XmlPullParser::SkipCurrentElement(parser); + } else if (!ShouldIgnoreElement(element_namespace, element_name)) { + diag_->Error(DiagMessage(item_source) << ":" << element_name << ">"); + error = true; + } + } + return !error; } bool ResourceParser::ParseAddResource(xml::XmlPullParser* parser, @@ -1074,15 +1155,13 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) { return false; } - Maybe<Reference> maybe_key = - ResourceUtils::ParseXmlAttributeName(maybe_name.value()); + Maybe<Reference> maybe_key = ResourceUtils::ParseXmlAttributeName(maybe_name.value()); if (!maybe_key) { - diag_->Error(DiagMessage(source) << "invalid attribute name '" - << maybe_name.value() << "'"); + diag_->Error(DiagMessage(source) << "invalid attribute name '" << maybe_name.value() << "'"); return false; } - TransformReferenceFromNamespace(parser, "", &maybe_key.value()); + ResolvePackage(parser, &maybe_key.value()); maybe_key.value().SetSource(source); std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString); @@ -1091,8 +1170,7 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) { return false; } - style->entries.push_back( - Style::Entry{std::move(maybe_key.value()), std::move(value)}); + style->entries.push_back(Style::Entry{std::move(maybe_key.value()), std::move(value)}); return true; } @@ -1104,21 +1182,18 @@ bool ResourceParser::ParseStyle(const ResourceType type, xml::XmlPullParser* par Maybe<StringPiece> maybe_parent = xml::FindAttribute(parser, "parent"); if (maybe_parent) { - // If the parent is empty, we don't have a parent, but we also don't infer - // either. + // If the parent is empty, we don't have a parent, but we also don't infer either. if (!maybe_parent.value().empty()) { std::string err_str; - style->parent = ResourceUtils::ParseStyleParentReference( - maybe_parent.value(), &err_str); + style->parent = ResourceUtils::ParseStyleParentReference(maybe_parent.value(), &err_str); if (!style->parent) { diag_->Error(DiagMessage(out_resource->source) << err_str); return false; } - // Transform the namespace prefix to the actual package name, and mark the - // reference as + // Transform the namespace prefix to the actual package name, and mark the reference as // private if appropriate. - TransformReferenceFromNamespace(parser, "", &style->parent.value()); + ResolvePackage(parser, &style->parent.value()); } } else { @@ -1127,8 +1202,7 @@ bool ResourceParser::ParseStyle(const ResourceType type, xml::XmlPullParser* par size_t pos = style_name.find_last_of(u'.'); if (pos != std::string::npos) { style->parent_inferred = true; - style->parent = Reference( - ResourceName({}, ResourceType::kStyle, style_name.substr(0, pos))); + style->parent = Reference(ResourceName({}, ResourceType::kStyle, style_name.substr(0, pos))); } } @@ -1373,7 +1447,7 @@ bool ResourceParser::ParseDeclareStyleable(xml::XmlPullParser* parser, } Reference& child_ref = maybe_ref.value(); - xml::TransformReferenceFromNamespace(parser, "", &child_ref); + xml::ResolvePackage(parser, &child_ref); // Create the ParsedResource that will add the attribute to the table. ParsedResource child_resource; |