AAPT2: Add library support
Change-Id: I307f56d9631784ab29ee4156d94886f9b2f25b30
diff --git a/tools/aapt2/JavaClassGenerator.cpp b/tools/aapt2/JavaClassGenerator.cpp
index 779a346..3f92f18 100644
--- a/tools/aapt2/JavaClassGenerator.cpp
+++ b/tools/aapt2/JavaClassGenerator.cpp
@@ -15,6 +15,7 @@
*/
#include "JavaClassGenerator.h"
+#include "NameMangler.h"
#include "Resource.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
@@ -31,7 +32,7 @@
// The number of attributes to emit per line in a Styleable array.
constexpr size_t kAttribsPerLine = 4;
-JavaClassGenerator::JavaClassGenerator(std::shared_ptr<const ResourceTable> table,
+JavaClassGenerator::JavaClassGenerator(const std::shared_ptr<const ResourceTable>& table,
Options options) :
mTable(table), mOptions(options) {
}
@@ -79,42 +80,18 @@
return output;
}
-bool JavaClassGenerator::generateType(std::ostream& out, const ResourceTableType& type,
- size_t packageId) {
- const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
-
- for (const auto& entry : type.entries) {
- ResourceId id = { packageId, type.typeId, entry->entryId };
- assert(id.isValid());
-
- if (!isValidSymbol(entry->name)) {
- std::stringstream err;
- err << "invalid symbol name '"
- << StringPiece16(entry->name)
- << "'";
- mError = err.str();
- return false;
- }
-
- out << " "
- << "public static" << finalModifier
- << " int " << transform(entry->name) << " = " << id << ";" << std::endl;
- }
- return true;
-}
-
struct GenArgs : ValueVisitorArgs {
- GenArgs(std::ostream& o, const ResourceEntry& e) : out(o), entry(e) {
+ GenArgs(std::ostream* o, std::u16string* e) : out(o), entryName(e) {
}
- std::ostream& out;
- const ResourceEntry& entry;
+ std::ostream* out;
+ std::u16string* entryName;
};
void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a) {
const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
- std::ostream& out = static_cast<GenArgs&>(a).out;
- const ResourceEntry& entry = static_cast<GenArgs&>(a).entry;
+ std::ostream* out = static_cast<GenArgs&>(a).out;
+ std::u16string* entryName = static_cast<GenArgs&>(a).entryName;
// This must be sorted by resource ID.
std::vector<std::pair<ResourceId, StringPiece16>> sortedAttributes;
@@ -127,59 +104,86 @@
std::sort(sortedAttributes.begin(), sortedAttributes.end());
// First we emit the array containing the IDs of each attribute.
- out << " "
- << "public static final int[] " << transform(entry.name) << " = {";
+ *out << " "
+ << "public static final int[] " << transform(*entryName) << " = {";
const size_t attrCount = sortedAttributes.size();
for (size_t i = 0; i < attrCount; i++) {
if (i % kAttribsPerLine == 0) {
- out << std::endl << " ";
+ *out << std::endl << " ";
}
- out << sortedAttributes[i].first;
+ *out << sortedAttributes[i].first;
if (i != attrCount - 1) {
- out << ", ";
+ *out << ", ";
}
}
- out << std::endl << " };" << std::endl;
+ *out << std::endl << " };" << std::endl;
// Now we emit the indices into the array.
for (size_t i = 0; i < attrCount; i++) {
- out << " "
- << "public static" << finalModifier
- << " int " << transform(entry.name) << "_" << transform(sortedAttributes[i].second)
- << " = " << i << ";" << std::endl;
+ *out << " "
+ << "public static" << finalModifier
+ << " int " << transform(*entryName) << "_" << transform(sortedAttributes[i].second)
+ << " = " << i << ";" << std::endl;
}
}
-bool JavaClassGenerator::generate(std::ostream& out) {
+bool JavaClassGenerator::generateType(const std::u16string& package, size_t packageId,
+ const ResourceTableType& type, std::ostream& out) {
+ const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
+
+ std::u16string unmangledPackage;
+ std::u16string unmangledName;
+ for (const auto& entry : type.entries) {
+ ResourceId id = { packageId, type.typeId, entry->entryId };
+ assert(id.isValid());
+
+ unmangledName = entry->name;
+ if (NameMangler::unmangle(&unmangledName, &unmangledPackage)) {
+ // The entry name was mangled, and we successfully unmangled it.
+ // Check that we want to emit this symbol.
+ if (package != unmangledPackage) {
+ // Skip the entry if it doesn't belong to the package we're writing.
+ continue;
+ }
+ } else {
+ if (package != mTable->getPackage()) {
+ // We are processing a mangled package name,
+ // but this is a non-mangled resource.
+ continue;
+ }
+ }
+
+ if (!isValidSymbol(unmangledName)) {
+ ResourceNameRef resourceName = { package, type.type, unmangledName };
+ std::stringstream err;
+ err << "invalid symbol name '" << resourceName << "'";
+ mError = err.str();
+ return false;
+ }
+
+ if (type.type == ResourceType::kStyleable) {
+ assert(!entry->values.empty());
+ entry->values.front().value->accept(*this, GenArgs{ &out, &unmangledName });
+ } else {
+ out << " " << "public static" << finalModifier
+ << " int " << transform(unmangledName) << " = " << id << ";" << std::endl;
+ }
+ }
+ return true;
+}
+
+bool JavaClassGenerator::generate(const std::u16string& package, std::ostream& out) {
const size_t packageId = mTable->getPackageId();
- generateHeader(out, mTable->getPackage());
+ generateHeader(out, package);
out << "public final class R {" << std::endl;
for (const auto& type : *mTable) {
out << " public static final class " << type->type << " {" << std::endl;
- bool result;
- if (type->type == ResourceType::kStyleable) {
- for (const auto& entry : type->entries) {
- assert(!entry->values.empty());
- if (!isValidSymbol(entry->name)) {
- std::stringstream err;
- err << "invalid symbol name '"
- << StringPiece16(entry->name)
- << "'";
- mError = err.str();
- return false;
- }
- entry->values.front().value->accept(*this, GenArgs{ out, *entry });
- }
- } else {
- result = generateType(out, *type, packageId);
- }
-
- if (!result) {
+ if (!generateType(package, packageId, *type, out)) {
return false;
}
out << " }" << std::endl;