summaryrefslogtreecommitdiff
path: root/tools/aapt2/java
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/java')
-rw-r--r--tools/aapt2/java/ClassDefinition.h29
-rw-r--r--tools/aapt2/java/JavaClassGenerator.cpp63
-rw-r--r--tools/aapt2/java/JavaClassGenerator.h2
-rw-r--r--tools/aapt2/java/JavaClassGenerator_test.cpp2
4 files changed, 61 insertions, 35 deletions
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index 1e4b6816075a..995495ac56a8 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -70,8 +70,8 @@ class PrimitiveMember : public ClassMember {
return name_;
}
- void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
- const override {
+ void Print(bool final, text::Printer* printer,
+ bool strip_api_annotations = false) const override {
using std::to_string;
ClassMember::Print(final, printer, strip_api_annotations);
@@ -127,13 +127,13 @@ using IntMember = PrimitiveMember<uint32_t>;
using ResourceMember = PrimitiveMember<ResourceId>;
using StringMember = PrimitiveMember<std::string>;
-template <typename T>
+template <typename T, typename StringConverter>
class PrimitiveArrayMember : public ClassMember {
public:
explicit PrimitiveArrayMember(const android::StringPiece& name) : name_(name.to_string()) {}
void AddElement(const T& val) {
- elements_.push_back(val);
+ elements_.emplace_back(val);
}
bool empty() const override {
@@ -158,7 +158,7 @@ class PrimitiveArrayMember : public ClassMember {
printer->Println();
}
- printer->Print(to_string(*current));
+ printer->Print(StringConverter::ToString(*current));
if (std::distance(current, end) > 1) {
printer->Print(", ");
}
@@ -175,7 +175,24 @@ class PrimitiveArrayMember : public ClassMember {
std::vector<T> elements_;
};
-using ResourceArrayMember = PrimitiveArrayMember<ResourceId>;
+struct FieldReference {
+ explicit FieldReference(std::string reference) : ref(std::move(reference)) {
+ }
+ std::string ref;
+};
+
+struct ResourceArrayMemberStringConverter {
+ static std::string ToString(const std::variant<ResourceId, FieldReference>& ref) {
+ if (auto id = std::get_if<ResourceId>(&ref)) {
+ return to_string(*id);
+ } else {
+ return std::get<FieldReference>(ref).ref;
+ }
+ }
+};
+
+using ResourceArrayMember = PrimitiveArrayMember<std::variant<ResourceId, FieldReference>,
+ ResourceArrayMemberStringConverter>;
// Represents a method in a class.
class MethodDefinition : public ClassMember {
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index f0f839d968d5..59dd481607e9 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -224,7 +224,16 @@ static bool operator<(const StyleableAttr& lhs, const StyleableAttr& rhs) {
return cmp_ids_dynamic_after_framework(lhs_id, rhs_id);
}
-void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
+static FieldReference GetRFieldReference(const ResourceName& name,
+ StringPiece fallback_package_name) {
+ const std::string package_name =
+ name.package.empty() ? fallback_package_name.to_string() : name.package;
+ const std::string entry = JavaClassGenerator::TransformToFieldName(name.entry);
+ return FieldReference(
+ StringPrintf("%s.R.%s.%s", package_name.c_str(), to_string(name.type).data(), entry.c_str()));
+}
+
+bool JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
const Styleable& styleable,
const StringPiece& package_name_to_generate,
ClassDefinition* out_class_def,
@@ -340,14 +349,29 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
// Add the ResourceIds to the array member.
for (size_t i = 0; i < attr_count; i++) {
- const ResourceId id = sorted_attributes[i].attr_ref->id.value_or_default(ResourceId(0));
- array_def->AddElement(id);
+ const StyleableAttr& attr = sorted_attributes[i];
+ std::string r_txt_contents;
+ if (attr.symbol && attr.symbol.value().is_dynamic) {
+ if (!attr.attr_ref->name) {
+ error_ = "unable to determine R.java field name of dynamic resource";
+ return false;
+ }
+
+ const FieldReference field_name =
+ GetRFieldReference(attr.attr_ref->name.value(), package_name_to_generate);
+ array_def->AddElement(field_name);
+ r_txt_contents = field_name.ref;
+ } else {
+ const ResourceId attr_id = attr.attr_ref->id.value_or_default(ResourceId(0));
+ array_def->AddElement(attr_id);
+ r_txt_contents = to_string(attr_id);
+ }
if (r_txt_printer != nullptr) {
if (i != 0) {
r_txt_printer->Print(",");
}
- r_txt_printer->Print(" ").Print(id.to_string());
+ r_txt_printer->Print(" ").Print(r_txt_contents);
}
}
@@ -419,19 +443,7 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
}
}
- // If there is a rewrite method to generate, add the statements that rewrite package IDs
- // for this styleable.
- if (out_rewrite_method != nullptr) {
- out_rewrite_method->AppendStatement(
- StringPrintf("for (int i = 0; i < styleable.%s.length; i++) {", array_field_name.data()));
- out_rewrite_method->AppendStatement(
- StringPrintf(" if ((styleable.%s[i] & 0xff000000) == 0) {", array_field_name.data()));
- out_rewrite_method->AppendStatement(
- StringPrintf(" styleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | packageIdBits;",
- array_field_name.data(), array_field_name.data()));
- out_rewrite_method->AppendStatement(" }");
- out_rewrite_method->AppendStatement("}");
- }
+ return true;
}
void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const ResourceId& id,
@@ -448,8 +460,7 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso
const std::string field_name = TransformToFieldName(name.entry);
if (out_class_def != nullptr) {
- std::unique_ptr<ResourceMember> resource_member =
- util::make_unique<ResourceMember>(field_name, real_id);
+ auto resource_member = util::make_unique<ResourceMember>(field_name, real_id);
// Build the comments and annotations for this entry.
AnnotationProcessor* processor = resource_member->GetCommentBuilder();
@@ -551,12 +562,11 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
if (resource_name.type == ResourceType::kStyleable) {
CHECK(!entry->values.empty());
-
- const Styleable* styleable =
- static_cast<const Styleable*>(entry->values.front()->value.get());
-
- ProcessStyleable(resource_name, id, *styleable, package_name_to_generate, out_type_class_def,
- out_rewrite_method_def, r_txt_printer);
+ const auto styleable = reinterpret_cast<const Styleable*>(entry->values.front()->value.get());
+ if (!ProcessStyleable(resource_name, id, *styleable, package_name_to_generate,
+ out_type_class_def, out_rewrite_method_def, r_txt_printer)) {
+ return false;
+ }
} else {
ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def,
r_txt_printer);
@@ -626,8 +636,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
if (type->type == ResourceType::kAttr) {
// Also include private attributes in this same class.
- const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate);
- if (priv_type) {
+ if (const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate)) {
if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
rewrite_method.get(), r_txt_printer.get())) {
return false;
diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h
index 853120b3cb98..d9d1b39805f9 100644
--- a/tools/aapt2/java/JavaClassGenerator.h
+++ b/tools/aapt2/java/JavaClassGenerator.h
@@ -105,7 +105,7 @@ class JavaClassGenerator {
// Writes a styleable resource to the R.java file, optionally writing out a rewrite rule for
// its package ID if `out_rewrite_method` is not nullptr.
// `package_name_to_generate` is the package
- void ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
+ bool ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
const Styleable& styleable,
const android::StringPiece& package_name_to_generate,
ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method,
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index 04e20101a0dd..ec5b4151b1a6 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -581,7 +581,7 @@ TEST(JavaClassGeneratorTest, SortsDynamicAttributesAfterFrameworkAttributes) {
out.Flush();
EXPECT_THAT(output, HasSubstr("public static final int[] MyStyleable={"));
- EXPECT_THAT(output, HasSubstr("0x01010000, 0x00010000"));
+ EXPECT_THAT(output, HasSubstr("0x01010000, lib.R.attr.dynamic_attr"));
EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_android_framework_attr=0;"));
EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_dynamic_attr=1;"));
}