AAPT2: allow to generate R.txt without R.java
Bug: 69956357
Test: manual
Change-Id: If2bc32bd4efb1ea17c6cba7a17f2b2300164ede0
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index d2aebfd..b8bcef3 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -975,25 +975,29 @@
bool WriteJavaFile(ResourceTable* table, const StringPiece& package_name_to_generate,
const StringPiece& out_package, const JavaClassGeneratorOptions& java_options,
const Maybe<std::string>& out_text_symbols_path = {}) {
- if (!options_.generate_java_class_path) {
+ if (!options_.generate_java_class_path && !out_text_symbols_path) {
return true;
}
- std::string out_path = options_.generate_java_class_path.value();
- file::AppendPath(&out_path, file::PackageToPath(out_package));
- if (!file::mkdirs(out_path)) {
- context_->GetDiagnostics()->Error(DiagMessage() << "failed to create directory '" << out_path
- << "'");
- return false;
- }
+ std::string out_path;
+ std::unique_ptr<io::FileOutputStream> fout;
+ if (options_.generate_java_class_path) {
+ out_path = options_.generate_java_class_path.value();
+ file::AppendPath(&out_path, file::PackageToPath(out_package));
+ if (!file::mkdirs(out_path)) {
+ context_->GetDiagnostics()->Error(DiagMessage()
+ << "failed to create directory '" << out_path << "'");
+ return false;
+ }
- file::AppendPath(&out_path, "R.java");
+ file::AppendPath(&out_path, "R.java");
- io::FileOutputStream fout(out_path);
- if (fout.HadError()) {
- context_->GetDiagnostics()->Error(DiagMessage() << "failed writing to '" << out_path
- << "': " << fout.GetError());
- return false;
+ fout = util::make_unique<io::FileOutputStream>(out_path);
+ if (fout->HadError()) {
+ context_->GetDiagnostics()->Error(DiagMessage() << "failed writing to '" << out_path
+ << "': " << fout->GetError());
+ return false;
+ }
}
std::unique_ptr<io::FileOutputStream> fout_text;
@@ -1008,18 +1012,11 @@
}
JavaClassGenerator generator(context_, table, java_options);
- if (!generator.Generate(package_name_to_generate, out_package, &fout, fout_text.get())) {
+ if (!generator.Generate(package_name_to_generate, out_package, fout.get(), fout_text.get())) {
context_->GetDiagnostics()->Error(DiagMessage(out_path) << generator.GetError());
return false;
}
- fout.Flush();
-
- if (fout.HadError()) {
- context_->GetDiagnostics()->Error(DiagMessage() << "failed writing to '" << out_path
- << "': " << fout.GetError());
- return false;
- }
return true;
}
@@ -1838,7 +1835,7 @@
return 1;
}
- if (options_.generate_java_class_path) {
+ if (options_.generate_java_class_path || options_.generate_text_symbols_path) {
if (!GenerateJavaClasses()) {
return 1;
}
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 9861770..8c8c254 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -272,7 +272,7 @@
// Build the JavaDoc comment for the Styleable array. This has references to child attributes
// and what possible values can be used for them.
const size_t attr_count = sorted_attributes.size();
- if (attr_count > 0) {
+ if (out_class_def != nullptr && attr_count > 0) {
std::stringstream styleable_comment;
if (!styleable.GetComment().empty()) {
styleable_comment << styleable.GetComment() << "\n";
@@ -356,54 +356,56 @@
continue;
}
- StringPiece comment = styleable_attr.attr_ref->GetComment();
- if (styleable_attr.symbol.value().attribute && comment.empty()) {
- comment = styleable_attr.symbol.value().attribute->GetComment();
+ if (out_class_def != nullptr) {
+ StringPiece comment = styleable_attr.attr_ref->GetComment();
+ if (styleable_attr.symbol.value().attribute && comment.empty()) {
+ comment = styleable_attr.symbol.value().attribute->GetComment();
+ }
+
+ if (comment.contains("@removed")) {
+ // Removed attributes are public but hidden from the documentation, so
+ // don't emit them as part of the class documentation.
+ continue;
+ }
+
+ const ResourceName& attr_name = styleable_attr.attr_ref->name.value();
+
+ StringPiece package_name = attr_name.package;
+ if (package_name.empty()) {
+ package_name = context_->GetCompilationPackage();
+ }
+
+ std::unique_ptr<IntMember> index_member =
+ util::make_unique<IntMember>(sorted_attributes[i].field_name, static_cast<uint32_t>(i));
+
+ AnnotationProcessor* attr_processor = index_member->GetCommentBuilder();
+
+ if (!comment.empty()) {
+ attr_processor->AppendComment("<p>\n@attr description");
+ attr_processor->AppendComment(comment);
+ } else {
+ std::stringstream default_comment;
+ default_comment << "<p>This symbol is the offset where the "
+ << "{@link " << package_name << ".R.attr#"
+ << TransformToFieldName(attr_name.entry) << "}\n"
+ << "attribute's value can be found in the "
+ << "{@link #" << array_field_name << "} array.";
+ attr_processor->AppendComment(default_comment.str());
+ }
+
+ attr_processor->AppendNewLine();
+ AddAttributeFormatDoc(attr_processor, styleable_attr.symbol.value().attribute.get());
+ attr_processor->AppendNewLine();
+ attr_processor->AppendComment(
+ StringPrintf("@attr name %s:%s", package_name.data(), attr_name.entry.data()));
+
+ out_class_def->AddMember(std::move(index_member));
}
- if (comment.contains("@removed")) {
- // Removed attributes are public but hidden from the documentation, so
- // don't emit them as part of the class documentation.
- continue;
- }
-
- const ResourceName& attr_name = styleable_attr.attr_ref->name.value();
-
- StringPiece package_name = attr_name.package;
- if (package_name.empty()) {
- package_name = context_->GetCompilationPackage();
- }
-
- std::unique_ptr<IntMember> index_member = util::make_unique<IntMember>(
- sorted_attributes[i].field_name, static_cast<uint32_t>(i));
-
- AnnotationProcessor* attr_processor = index_member->GetCommentBuilder();
-
- if (!comment.empty()) {
- attr_processor->AppendComment("<p>\n@attr description");
- attr_processor->AppendComment(comment);
- } else {
- std::stringstream default_comment;
- default_comment << "<p>This symbol is the offset where the "
- << "{@link " << package_name << ".R.attr#"
- << TransformToFieldName(attr_name.entry) << "}\n"
- << "attribute's value can be found in the "
- << "{@link #" << array_field_name << "} array.";
- attr_processor->AppendComment(default_comment.str());
- }
-
- attr_processor->AppendNewLine();
- AddAttributeFormatDoc(attr_processor, styleable_attr.symbol.value().attribute.get());
- attr_processor->AppendNewLine();
- attr_processor->AppendComment(
- StringPrintf("@attr name %s:%s", package_name.data(), attr_name.entry.data()));
-
if (r_txt_printer != nullptr) {
r_txt_printer->Println(
StringPrintf("int styleable %s %zd", sorted_attributes[i].field_name.c_str(), i));
}
-
- out_class_def->AddMember(std::move(index_member));
}
// If there is a rewrite method to generate, add the statements that rewrite package IDs
@@ -434,31 +436,33 @@
}
const std::string field_name = TransformToFieldName(name.entry);
- std::unique_ptr<ResourceMember> resource_member =
- util::make_unique<ResourceMember>(field_name, real_id);
+ if (out_class_def != nullptr) {
+ std::unique_ptr<ResourceMember> resource_member =
+ util::make_unique<ResourceMember>(field_name, real_id);
- // Build the comments and annotations for this entry.
- AnnotationProcessor* processor = resource_member->GetCommentBuilder();
+ // Build the comments and annotations for this entry.
+ AnnotationProcessor* processor = resource_member->GetCommentBuilder();
- // Add the comments from any <public> tags.
- if (entry.symbol_status.state != SymbolState::kUndefined) {
- processor->AppendComment(entry.symbol_status.comment);
- }
-
- // Add the comments from all configurations of this entry.
- for (const auto& config_value : entry.values) {
- processor->AppendComment(config_value->value->GetComment());
- }
-
- // If this is an Attribute, append the format Javadoc.
- if (!entry.values.empty()) {
- if (Attribute* attr = ValueCast<Attribute>(entry.values.front()->value.get())) {
- // We list out the available values for the given attribute.
- AddAttributeFormatDoc(processor, attr);
+ // Add the comments from any <public> tags.
+ if (entry.symbol_status.state != SymbolState::kUndefined) {
+ processor->AppendComment(entry.symbol_status.comment);
}
- }
- out_class_def->AddMember(std::move(resource_member));
+ // Add the comments from all configurations of this entry.
+ for (const auto& config_value : entry.values) {
+ processor->AppendComment(config_value->value->GetComment());
+ }
+
+ // If this is an Attribute, append the format Javadoc.
+ if (!entry.values.empty()) {
+ if (Attribute* attr = ValueCast<Attribute>(entry.values.front()->value.get())) {
+ // We list out the available values for the given attribute.
+ AddAttributeFormatDoc(processor, attr);
+ }
+ }
+
+ out_class_def->AddMember(std::move(resource_member));
+ }
if (r_txt_printer != nullptr) {
r_txt_printer->Print("int ")
@@ -576,7 +580,7 @@
}
// Generate an onResourcesLoaded() callback if requested.
- if (options_.rewrite_callback_options) {
+ if (out != nullptr && options_.rewrite_callback_options) {
rewrite_method =
util::make_unique<MethodDefinition>("public static void onResourcesLoaded(int p)");
for (const std::string& package_to_callback :
@@ -597,8 +601,12 @@
const bool force_creation_if_empty =
(options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic);
- std::unique_ptr<ClassDefinition> class_def = util::make_unique<ClassDefinition>(
- to_string(type->type), ClassQualifier::kStatic, force_creation_if_empty);
+ std::unique_ptr<ClassDefinition> class_def;
+ if (out != nullptr) {
+ class_def = util::make_unique<ClassDefinition>(
+ to_string(type->type), ClassQualifier::kStatic, force_creation_if_empty);
+ }
+
if (!ProcessType(package_name_to_generate, *package, *type, class_def.get(),
rewrite_method.get(), r_txt_printer.get())) {
return false;
@@ -615,16 +623,17 @@
}
}
- if (type->type == ResourceType::kStyleable &&
+ if (out != nullptr && type->type == ResourceType::kStyleable &&
options_.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) {
// When generating a public R class, we don't want Styleable to be part
// of the API. It is only emitted for documentation purposes.
class_def->GetCommentBuilder()->AppendComment("@doconly");
}
- AppendJavaDocAnnotations(options_.javadoc_annotations, class_def->GetCommentBuilder());
-
- r_class.AddMember(std::move(class_def));
+ if (out != nullptr) {
+ AppendJavaDocAnnotations(options_.javadoc_annotations, class_def->GetCommentBuilder());
+ r_class.AddMember(std::move(class_def));
+ }
}
}
@@ -632,8 +641,10 @@
r_class.AddMember(std::move(rewrite_method));
}
- AppendJavaDocAnnotations(options_.javadoc_annotations, r_class.GetCommentBuilder());
- ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, out);
+ if (out != nullptr) {
+ AppendJavaDocAnnotations(options_.javadoc_annotations, r_class.GetCommentBuilder());
+ ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, out);
+ }
return true;
}