summaryrefslogtreecommitdiff
path: root/tools/aapt2/java
diff options
context:
space:
mode:
authorRyan Mitchell <rtmitchell@google.com>2018-07-20 15:18:05 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-07-20 15:18:05 +0000
commit848585e1a41c52fb723d17fe5e9eb98956c614d6 (patch)
treef053b51de3834bc85f89e0b189a0191cbf837ff1 /tools/aapt2/java
parentbc458577c9e7f6a65aeccbe2c1a7a4d224ff399b (diff)
parent23cc5d5dbecf34c205af40761ca762f3258f341f (diff)
Merge "AAPT2: Fix R.java for styleable in different package"
Diffstat (limited to 'tools/aapt2/java')
-rw-r--r--tools/aapt2/java/JavaClassGenerator.cpp17
-rw-r--r--tools/aapt2/java/JavaClassGenerator_test.cpp49
2 files changed, 63 insertions, 3 deletions
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index db1561e17f16..d1a70a75a44e 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -256,9 +256,20 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
styleable_attr.field_name =
TransformNestedAttr(attr.name.value(), array_field_name, package_name_to_generate);
+ Reference ref = attr;
+ if (attr.name.value().package.empty()) {
+
+ // If the resource does not have a package name, set the package to the unmangled package name
+ // of the styleable declaration because attributes without package names would have been
+ // declared in the same package as the styleable.
+ ref.name = ResourceName(package_name_to_generate, ref.name.value().type,
+ ref.name.value().entry);
+ }
+
// Look up the symbol so that we can write out in the comments what are possible legal values
// for this attribute.
- const SymbolTable::Symbol* symbol = context_->GetExternalSymbols()->FindByReference(attr);
+ const SymbolTable::Symbol* symbol = context_->GetExternalSymbols()->FindByReference(ref);
+
if (symbol && symbol->attribute) {
// Copy the symbol data structure because the returned instance can be destroyed.
styleable_attr.symbol = *symbol;
@@ -303,7 +314,7 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
const ResourceName& attr_name = entry.attr_ref->name.value();
styleable_comment << "<tr><td><code>{@link #" << entry.field_name << " "
<< (!attr_name.package.empty() ? attr_name.package
- : context_->GetCompilationPackage())
+ : package_name_to_generate)
<< ":" << attr_name.entry << "}</code></td>";
// Only use the comment up until the first '.'. This is to stay compatible with
@@ -374,7 +385,7 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
StringPiece package_name = attr_name.package;
if (package_name.empty()) {
- package_name = context_->GetCompilationPackage();
+ package_name = package_name_to_generate;
}
std::unique_ptr<IntMember> index_member =
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index 10a97d84f59d..fa208be120ed 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -107,6 +107,55 @@ TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) {
EXPECT_THAT(output, Not(HasSubstr("com_foo$two")));
}
+TEST(JavaClassGeneratorTest, StyleableAttributesWithDifferentPackageName) {
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .SetPackageId("android", 0x01)
+ .SetPackageId("app", 0x7f)
+ .AddValue("app:attr/foo", ResourceId(0x7f010000),
+ test::AttributeBuilder().Build())
+ .AddValue("app:attr/bar", ResourceId(0x7f010001),
+ test::AttributeBuilder().Build())
+ .AddValue("android:attr/baz", ResourceId(0x01010000),
+ test::AttributeBuilder().Build())
+ .AddValue("app:styleable/MyStyleable", ResourceId(0x7f030000),
+ test::StyleableBuilder()
+ .AddItem("app:attr/foo", ResourceId(0x7f010000))
+ .AddItem("attr/bar", ResourceId(0x7f010001))
+ .AddItem("android:attr/baz", ResourceId(0x01010000))
+ .Build())
+ .Build();
+
+ std::unique_ptr<IAaptContext> context =
+ test::ContextBuilder()
+ .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
+ .SetNameManglerPolicy(NameManglerPolicy{"custom"})
+ .SetCompilationPackage("custom")
+ .Build();
+ JavaClassGenerator generator(context.get(), table.get(), {});
+
+ std::string output;
+ StringOutputStream out(&output);
+ EXPECT_TRUE(generator.Generate("app", &out));
+ out.Flush();
+
+ EXPECT_THAT(output, Not(HasSubstr("public static final int baz=0x01010000;")));
+ EXPECT_THAT(output, HasSubstr("public static final int foo=0x7f010000;"));
+ EXPECT_THAT(output, HasSubstr("public static final int bar=0x7f010001;"));
+
+ EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_android_baz=0;"));
+ EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_foo=1;"));
+ EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_bar=2;"));
+
+ EXPECT_THAT(output, HasSubstr("@link #MyStyleable_android_baz android:baz"));
+ EXPECT_THAT(output, HasSubstr("@link #MyStyleable_foo app:foo"));
+ EXPECT_THAT(output, HasSubstr("@link #MyStyleable_bar app:bar"));
+
+ EXPECT_THAT(output, HasSubstr("@link android.R.attr#baz"));
+ EXPECT_THAT(output, HasSubstr("@link app.R.attr#foo"));
+ EXPECT_THAT(output, HasSubstr("@link app.R.attr#bar"));
+}
+
TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) {
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()