diff options
author | Adam Lesinski <adamlesinski@google.com> | 2015-04-24 19:19:30 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2015-05-04 16:43:24 -0700 |
commit | 24aad163bc88cb10d2275385e9afc3de7f342d65 (patch) | |
tree | 361fc0b3fbef5f68a16f357ae9d2bed5e93efbf5 /tools/aapt2/ResourceParser.cpp | |
parent | ab2581398c812917145088590bd18eb83f3a2ea6 (diff) | |
download | frameworks_base-24aad163bc88cb10d2275385e9afc3de7f342d65.zip frameworks_base-24aad163bc88cb10d2275385e9afc3de7f342d65.tar.gz frameworks_base-24aad163bc88cb10d2275385e9afc3de7f342d65.tar.bz2 |
Add namespace handling in attribute values
Previously, you could only reference namespace prefixes in attribute names:
<View xmlns:appcompat="http://schemas.android.com/apk/res/android.support.v7.appcompat"
appcompat:name="hey"
...
Now you can also reference them in resource names within an attribute value:
...
android:text="@appcompat:string/confirm"
...
Which will be treated as "@android.support.v7.appcompat:string/confirm".
Change-Id: Ib076e867a990c80cf877a704eb77cd1ef0b23b52
Diffstat (limited to 'tools/aapt2/ResourceParser.cpp')
-rw-r--r-- | tools/aapt2/ResourceParser.cpp | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 943892d..e7e824c 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -175,23 +175,16 @@ bool ResourceParser::parseStyleParentReference(const StringPiece16& str, Referen } std::unique_ptr<Reference> ResourceParser::tryParseReference(const StringPiece16& str, - const StringPiece16& defaultPackage, bool* outCreate) { ResourceNameRef ref; bool privateRef = false; if (tryParseReference(str, &ref, outCreate, &privateRef)) { - if (ref.package.empty()) { - ref.package = defaultPackage; - } std::unique_ptr<Reference> value = util::make_unique<Reference>(ref); value->privateReference = privateRef; return value; } if (tryParseAttributeReference(str, &ref)) { - if (ref.package.empty()) { - ref.package = defaultPackage; - } *outCreate = false; return util::make_unique<Reference>(ref, Reference::Type::kAttribute); } @@ -330,7 +323,7 @@ std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseBool(const StringPiece1 StringPiece16 trimmedStr(util::trimWhitespace(str)); uint32_t data = 0; if (trimmedStr == u"true" || trimmedStr == u"TRUE") { - data = 1; + data = 0xffffffffu; } else if (trimmedStr != u"false" && trimmedStr != u"FALSE") { return {}; } @@ -397,7 +390,7 @@ uint32_t ResourceParser::androidTypeToAttributeTypeMask(uint16_t type) { } std::unique_ptr<Item> ResourceParser::parseItemForAttribute( - const StringPiece16& value, uint32_t typeMask, const StringPiece16& defaultPackage, + const StringPiece16& value, uint32_t typeMask, std::function<void(const ResourceName&)> onCreateReference) { std::unique_ptr<BinaryPrimitive> nullOrEmpty = tryParseNullOrEmpty(value); if (nullOrEmpty) { @@ -405,7 +398,7 @@ std::unique_ptr<Item> ResourceParser::parseItemForAttribute( } bool create = false; - std::unique_ptr<Reference> reference = tryParseReference(value, defaultPackage, &create); + std::unique_ptr<Reference> reference = tryParseReference(value, &create); if (reference) { if (create && onCreateReference) { onCreateReference(reference->name); @@ -457,11 +450,10 @@ std::unique_ptr<Item> ResourceParser::parseItemForAttribute( * allows. */ std::unique_ptr<Item> ResourceParser::parseItemForAttribute( - const StringPiece16& str, const Attribute& attr, const StringPiece16& defaultPackage, + const StringPiece16& str, const Attribute& attr, std::function<void(const ResourceName&)> onCreateReference) { const uint32_t typeMask = attr.typeMask; - std::unique_ptr<Item> value = parseItemForAttribute(str, typeMask, defaultPackage, - onCreateReference); + std::unique_ptr<Item> value = parseItemForAttribute(str, typeMask, onCreateReference); if (value) { return value; } @@ -770,14 +762,25 @@ std::unique_ptr<Item> ResourceParser::parseXml(XmlPullParser* parser, uint32_t t } auto onCreateReference = [&](const ResourceName& name) { + // name.package can be empty here, as it will assume the package name of the table. mTable->addResource(name, {}, mSource.line(beginXmlLine), util::make_unique<Id>()); }; // Process the raw value. std::unique_ptr<Item> processedItem = parseItemForAttribute(rawValue, typeMask, - mTable->getPackage(), onCreateReference); if (processedItem) { + // Fix up the reference. + visitFunc<Reference>(*processedItem, [&](Reference& ref) { + if (!ref.name.package.empty()) { + // The package name was set, so lookup its alias. + parser->applyPackageAlias(&ref.name.package, mTable->getPackage()); + } else { + // The package name was left empty, so it assumes the default package + // without alias lookup. + ref.name.package = mTable->getPackage(); + } + }); return processedItem; } @@ -1093,7 +1096,7 @@ bool ResourceParser::parseEnumOrFlagItem(XmlPullParser* parser, const StringPiec return true; } -static bool parseXmlAttributeName(StringPiece16 str, ResourceNameRef* outRef) { +static bool parseXmlAttributeName(StringPiece16 str, ResourceName* outName) { str = util::trimWhitespace(str); const char16_t* const start = str.data(); const char16_t* const end = start + str.size(); @@ -1110,12 +1113,12 @@ static bool parseXmlAttributeName(StringPiece16 str, ResourceNameRef* outRef) { p++; } - outRef->package = package; - outRef->type = ResourceType::kAttr; + outName->package = package.toString(); + outName->type = ResourceType::kAttr; if (name.size() == 0) { - outRef->entry = str; + outName->entry = str.toString(); } else { - outRef->entry = name; + outName->entry = name.toString(); } return true; } @@ -1130,8 +1133,8 @@ bool ResourceParser::parseUntypedItem(XmlPullParser* parser, Style& style) { return false; } - ResourceNameRef keyRef; - if (!parseXmlAttributeName(nameAttrIter->value, &keyRef)) { + ResourceName key; + if (!parseXmlAttributeName(nameAttrIter->value, &key)) { mLogger.error(parser->getLineNumber()) << "invalid attribute name '" << nameAttrIter->value @@ -1140,14 +1143,15 @@ bool ResourceParser::parseUntypedItem(XmlPullParser* parser, Style& style) { return false; } - if (keyRef.package.empty()) { - keyRef.package = mTable->getPackage(); + if (!key.package.empty()) { + // We have a package name set, so lookup its alias. + parser->applyPackageAlias(&key.package, mTable->getPackage()); + } else { + // The package name was omitted, so use the default package name with + // no alias lookup. + key.package = mTable->getPackage(); } - // Create a copy instead of a reference because we - // are about to invalidate keyRef when advancing the parser. - ResourceName key = keyRef.toResourceName(); - std::unique_ptr<Item> value = parseXml(parser, 0, kAllowRawString); if (!value) { return false; @@ -1170,7 +1174,11 @@ bool ResourceParser::parseStyle(XmlPullParser* parser, const ResourceNameRef& re return false; } - if (style->parent.name.package.empty()) { + if (!style->parent.name.package.empty()) { + // Try to interpret the package name as an alias. These take precedence. + parser->applyPackageAlias(&style->parent.name.package, mTable->getPackage()); + } else { + // If no package is specified, this can not be an alias and is the local package. style->parent.name.package = mTable->getPackage(); } } |