diff options
Diffstat (limited to 'tools/aapt2/ResourceTable.cpp')
-rw-r--r-- | tools/aapt2/ResourceTable.cpp | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index f9707e41bb3d..bdc6a8c5d4f9 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -35,11 +35,11 @@ static bool lessThanType(const std::unique_ptr<ResourceTableType>& lhs, Resource template <typename T> static bool lessThanStructWithName(const std::unique_ptr<T>& lhs, - const StringPiece16& rhs) { + const StringPiece& rhs) { return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0; } -ResourceTablePackage* ResourceTable::findPackage(const StringPiece16& name) { +ResourceTablePackage* ResourceTable::findPackage(const StringPiece& name) { const auto last = packages.end(); auto iter = std::lower_bound(packages.begin(), last, name, lessThanStructWithName<ResourceTablePackage>); @@ -58,7 +58,7 @@ ResourceTablePackage* ResourceTable::findPackageById(uint8_t id) { return nullptr; } -ResourceTablePackage* ResourceTable::createPackage(const StringPiece16& name, Maybe<uint8_t> id) { +ResourceTablePackage* ResourceTable::createPackage(const StringPiece& name, Maybe<uint8_t> id) { ResourceTablePackage* package = findOrCreatePackage(name); if (id && !package->id) { package->id = id; @@ -71,7 +71,7 @@ ResourceTablePackage* ResourceTable::createPackage(const StringPiece16& name, Ma return package; } -ResourceTablePackage* ResourceTable::findOrCreatePackage(const StringPiece16& name) { +ResourceTablePackage* ResourceTable::findOrCreatePackage(const StringPiece& name) { const auto last = packages.end(); auto iter = std::lower_bound(packages.begin(), last, name, lessThanStructWithName<ResourceTablePackage>); @@ -102,7 +102,7 @@ ResourceTableType* ResourceTablePackage::findOrCreateType(ResourceType type) { return types.emplace(iter, new ResourceTableType(type))->get(); } -ResourceEntry* ResourceTableType::findEntry(const StringPiece16& name) { +ResourceEntry* ResourceTableType::findEntry(const StringPiece& name) { const auto last = entries.end(); auto iter = std::lower_bound(entries.begin(), last, name, lessThanStructWithName<ResourceEntry>); @@ -112,7 +112,7 @@ ResourceEntry* ResourceTableType::findEntry(const StringPiece16& name) { return nullptr; } -ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece16& name) { +ResourceEntry* ResourceTableType::findOrCreateEntry(const StringPiece& name) { auto last = entries.end(); auto iter = std::lower_bound(entries.begin(), last, name, lessThanStructWithName<ResourceEntry>); @@ -201,36 +201,51 @@ std::vector<ResourceConfigValue*> ResourceEntry::findValuesIf( } /** - * The default handler for collisions. A return value of -1 means keep the - * existing value, 0 means fail, and +1 means take the incoming value. + * The default handler for collisions. + * + * Typically, a weak value will be overridden by a strong value. An existing weak + * value will not be overridden by an incoming weak value. + * + * There are some exceptions: + * + * Attributes: There are two types of Attribute values: USE and DECL. + * + * USE is anywhere an Attribute is declared without a format, and in a place that would + * be legal to declare if the Attribute already existed. This is typically in a + * <declare-styleable> tag. Attributes defined in a <declare-styleable> are also weak. + * + * DECL is an absolute declaration of an Attribute and specifies an explicit format. + * + * A DECL will override a USE without error. Two DECLs must match in their format for there to be + * no error. */ -int ResourceTable::resolveValueCollision(Value* existing, Value* incoming) { +ResourceTable::CollisionResult ResourceTable::resolveValueCollision( + Value* existing, Value* incoming) { Attribute* existingAttr = valueCast<Attribute>(existing); Attribute* incomingAttr = valueCast<Attribute>(incoming); - if (!incomingAttr) { if (incoming->isWeak()) { // We're trying to add a weak resource but a resource // already exists. Keep the existing. - return -1; + return CollisionResult::kKeepOriginal; } else if (existing->isWeak()) { // Override the weak resource with the new strong resource. - return 1; + return CollisionResult::kTakeNew; } // The existing and incoming values are strong, this is an error // if the values are not both attributes. - return 0; + return CollisionResult::kConflict; } if (!existingAttr) { if (existing->isWeak()) { // The existing value is not an attribute and it is weak, // so take the incoming attribute value. - return 1; + return CollisionResult::kTakeNew; } // The existing value is not an attribute and it is strong, // so the incoming attribute value is an error. - return 0; + return CollisionResult::kConflict; } assert(incomingAttr && existingAttr); @@ -245,24 +260,24 @@ int ResourceTable::resolveValueCollision(Value* existing, Value* incoming) { // The two attributes are both DECLs, but they are plain attributes // with the same formats. // Keep the strongest one. - return existingAttr->isWeak() ? 1 : -1; + return existingAttr->isWeak() ? CollisionResult::kTakeNew : CollisionResult::kKeepOriginal; } if (existingAttr->isWeak() && existingAttr->typeMask == android::ResTable_map::TYPE_ANY) { // Any incoming attribute is better than this. - return 1; + return CollisionResult::kTakeNew; } if (incomingAttr->isWeak() && incomingAttr->typeMask == android::ResTable_map::TYPE_ANY) { // The incoming attribute may be a USE instead of a DECL. // Keep the existing attribute. - return -1; + return CollisionResult::kKeepOriginal; } - return 0; + return CollisionResult::kConflict; } -static constexpr const char16_t* kValidNameChars = u"._-"; -static constexpr const char16_t* kValidNameMangledChars = u"._-$"; +static constexpr const char* kValidNameChars = "._-"; +static constexpr const char* kValidNameMangledChars = "._-$"; bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config, @@ -286,7 +301,7 @@ bool ResourceTable::addResource(const ResourceNameRef& name, bool ResourceTable::addFileReference(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, - const StringPiece16& path, + const StringPiece& path, IDiagnostics* diag) { return addFileReferenceImpl(name, config, source, path, nullptr, kValidNameChars, diag); } @@ -294,7 +309,7 @@ bool ResourceTable::addFileReference(const ResourceNameRef& name, bool ResourceTable::addFileReferenceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, - const StringPiece16& path, + const StringPiece& path, io::IFile* file, IDiagnostics* diag) { return addFileReferenceImpl(name, config, source, path, file, kValidNameMangledChars, diag); @@ -303,16 +318,16 @@ bool ResourceTable::addFileReferenceAllowMangled(const ResourceNameRef& name, bool ResourceTable::addFileReferenceImpl(const ResourceNameRef& name, const ConfigDescription& config, const Source& source, - const StringPiece16& path, + const StringPiece& path, io::IFile* file, - const char16_t* validChars, + const char* validChars, IDiagnostics* diag) { std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>( stringPool.makeRef(path)); fileRef->setSource(source); fileRef->file = file; return addResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef), - kValidNameChars, resolveValueCollision, diag); + validChars, resolveValueCollision, diag); } bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name, @@ -339,8 +354,8 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, - const char16_t* validChars, - std::function<int(Value*,Value*)> conflictResolver, + const char* validChars, + const CollisionResolverFunc& conflictResolver, IDiagnostics* diag) { assert(value && "value can't be nullptr"); assert(diag && "diagnostics can't be nullptr"); @@ -353,7 +368,7 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name, << "' has invalid entry name '" << name.entry << "'. Invalid character '" - << StringPiece16(badCharIter, 1) + << StringPiece(badCharIter, 1) << "'"); return false; } @@ -404,17 +419,22 @@ bool ResourceTable::addResourceImpl(const ResourceNameRef& name, configValue->value = std::move(value); } else { - int collisionResult = conflictResolver(configValue->value.get(), value.get()); - if (collisionResult > 0) { + switch (conflictResolver(configValue->value.get(), value.get())) { + case CollisionResult::kTakeNew: // Take the incoming value. configValue->value = std::move(value); - } else if (collisionResult == 0) { + break; + + case CollisionResult::kConflict: diag->error(DiagMessage(value->getSource()) - << "duplicate value for resource '" << name << "' " - << "with config '" << config << "'"); + << "duplicate value for resource '" << name << "' " + << "with config '" << config << "'"); diag->error(DiagMessage(configValue->value->getSource()) - << "resource previously defined here"); + << "resource previously defined here"); return false; + + case CollisionResult::kKeepOriginal: + break; } } @@ -438,7 +458,7 @@ bool ResourceTable::setSymbolStateAllowMangled(const ResourceNameRef& name, } bool ResourceTable::setSymbolStateImpl(const ResourceNameRef& name, const ResourceId& resId, - const Symbol& symbol, const char16_t* validChars, + const Symbol& symbol, const char* validChars, IDiagnostics* diag) { assert(diag && "diagnostics can't be nullptr"); @@ -450,7 +470,7 @@ bool ResourceTable::setSymbolStateImpl(const ResourceNameRef& name, const Resour << "' has invalid entry name '" << name.entry << "'. Invalid character '" - << StringPiece16(badCharIter, 1) + << StringPiece(badCharIter, 1) << "'"); return false; } |