From: y Date: Wed, 18 Apr 2018 18:29:09 +0000 (-0700) Subject: AAPT2: Support id reference chaining from AAPT X-Git-Tag: android-x86-9.0-r1~133^2~56^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=9efbbef2e060cd5e05f5b652ba5c7aaf687f64d6;p=android-x86%2Fframeworks-base.git AAPT2: Support id reference chaining from AAPT AAPT would allow for ids to be declared in the form: + + @id/middle_ref + @id/low_ref + diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 1b6f8827291b..19c6c3107e7c 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -586,7 +586,29 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, out_resource->name.type = ResourceType::kId; out_resource->name.entry = maybe_name.value().to_string(); - out_resource->value = util::make_unique(); + + // Ids either represent a unique resource id or reference another resource id + auto item = ParseItem(parser, out_resource, resource_format); + if (!item) { + return false; + } + + String* empty = ValueCast(out_resource->value.get()); + if (empty && *empty->value == "") { + // If no inner element exists, represent a unique identifier + out_resource->value = util::make_unique(); + } else { + // If an inner element exists, the inner element must be a reference to + // another resource id + Reference* ref = ValueCast(out_resource->value.get()); + if (!ref || ref->name.value().type != ResourceType::kId) { + diag_->Error(DiagMessage(out_resource->source) + << "<" << parser->element_name() + << "> inner element must either be a resource reference or empty"); + return false; + } + } + return true; } diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index fc1aeaa58fe2..c12b9fac5704 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -933,4 +933,32 @@ TEST_F(ResourceParserTest, DuplicateOverlayableIsError) { EXPECT_FALSE(TestParse(input)); } +TEST_F(ResourceParserTest, ParseIdItem) { + std::string input = R"( + @id/bar + + )"; + ASSERT_TRUE(TestParse(input)); + + ASSERT_THAT(test::GetValue(&table_, "id/foo"), NotNull()); + ASSERT_THAT(test::GetValue(&table_, "id/bar"), NotNull()); + ASSERT_THAT(test::GetValue(&table_, "id/baz"), NotNull()); + + // Reject attribute references + input = R"(?attr/bar")"; + ASSERT_FALSE(TestParse(input)); + + // Reject non-references + input = R"(0x7f010001)"; + ASSERT_FALSE(TestParse(input)); + input = R"(@drawable/my_image)"; + ASSERT_FALSE(TestParse(input)); + input = R"()"; + ASSERT_FALSE(TestParse(input)); + + // Ids that reference other resource ids cannot be public + input = R"(@id/bar6)"; + ASSERT_FALSE(TestParse(input)); +} + } // namespace aapt