diff options
author | Adam Lesinski <adamlesinski@google.com> | 2017-11-09 11:29:39 -0800 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2017-11-16 12:06:17 -0800 |
commit | a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2 (patch) | |
tree | 902f4d5abd493ccb8087b941676e2562c8db128b /tools/aapt2/java | |
parent | 60303333dc8ad61e640992cee2b5c601be73faf8 (diff) |
AAPT2: Move all file output to FileOutputStream
FileOutputStream is safe to use on Windows, as it opens
files using our compatibility API.
Bug: 68262818
Test: make aapt2_tests
Change-Id: Ib0b27e93edd609b49b1327db7d9867a002198ebb
Diffstat (limited to 'tools/aapt2/java')
-rw-r--r-- | tools/aapt2/java/AnnotationProcessor.cpp | 12 | ||||
-rw-r--r-- | tools/aapt2/java/AnnotationProcessor.h | 6 | ||||
-rw-r--r-- | tools/aapt2/java/AnnotationProcessor_test.cpp | 28 | ||||
-rw-r--r-- | tools/aapt2/java/ClassDefinition.cpp | 49 | ||||
-rw-r--r-- | tools/aapt2/java/ClassDefinition.h | 62 | ||||
-rw-r--r-- | tools/aapt2/java/JavaClassGenerator.cpp | 83 | ||||
-rw-r--r-- | tools/aapt2/java/JavaClassGenerator.h | 22 | ||||
-rw-r--r-- | tools/aapt2/java/JavaClassGenerator_test.cpp | 77 | ||||
-rw-r--r-- | tools/aapt2/java/ManifestClassGenerator.h | 3 | ||||
-rw-r--r-- | tools/aapt2/java/ManifestClassGenerator_test.cpp | 11 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules.cpp | 36 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules.h | 13 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules_test.cpp | 49 |
13 files changed, 248 insertions, 203 deletions
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp index c93461a66899..8d91b0098c1f 100644 --- a/tools/aapt2/java/AnnotationProcessor.cpp +++ b/tools/aapt2/java/AnnotationProcessor.cpp @@ -23,6 +23,7 @@ #include "text/Utf8Iterator.h" #include "util/Util.h" +using ::aapt::text::Printer; using ::aapt::text::Utf8Iterator; using ::android::StringPiece; @@ -109,23 +110,22 @@ void AnnotationProcessor::AppendNewLine() { } } -void AnnotationProcessor::WriteToStream(const StringPiece& prefix, std::ostream* out) const { +void AnnotationProcessor::Print(Printer* printer) const { if (has_comments_) { std::string result = comment_.str(); for (StringPiece line : util::Tokenize(result, '\n')) { - *out << prefix << line << "\n"; + printer->Println(line); } - *out << prefix << " */" - << "\n"; + printer->Println(" */"); } if (annotation_bit_mask_ & AnnotationRule::kDeprecated) { - *out << prefix << "@Deprecated\n"; + printer->Println("@Deprecated"); } for (const AnnotationRule& rule : sAnnotationRules) { if (annotation_bit_mask_ & rule.bit_mask) { - *out << prefix << rule.annotation << "\n"; + printer->Println(rule.annotation); } } } diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h index a7bf73f50de5..ae7bdb0c3ae2 100644 --- a/tools/aapt2/java/AnnotationProcessor.h +++ b/tools/aapt2/java/AnnotationProcessor.h @@ -22,6 +22,8 @@ #include "androidfw/StringPiece.h" +#include "text/Printer.h" + namespace aapt { // Builds a JavaDoc comment from a set of XML comments. @@ -61,8 +63,8 @@ class AnnotationProcessor { void AppendNewLine(); - // Writes the comments and annotations to the stream, with the given prefix before each line. - void WriteToStream(const android::StringPiece& prefix, std::ostream* out) const; + // Writes the comments and annotations to the Printer. + void Print(text::Printer* printer) const; private: std::stringstream comment_; diff --git a/tools/aapt2/java/AnnotationProcessor_test.cpp b/tools/aapt2/java/AnnotationProcessor_test.cpp index 856f4ccbd7f0..69f49c8b97c3 100644 --- a/tools/aapt2/java/AnnotationProcessor_test.cpp +++ b/tools/aapt2/java/AnnotationProcessor_test.cpp @@ -16,8 +16,12 @@ #include "java/AnnotationProcessor.h" +#include "io/StringStream.h" #include "test/Test.h" +#include "text/Printer.h" +using ::aapt::io::StringOutputStream; +using ::aapt::text::Printer; using ::testing::Eq; using ::testing::HasSubstr; using ::testing::Not; @@ -33,9 +37,11 @@ TEST(AnnotationProcessorTest, EmitsDeprecated) { AnnotationProcessor processor; processor.AppendComment(comment); - std::stringstream result; - processor.WriteToStream("", &result); - std::string annotations = result.str(); + std::string annotations; + StringOutputStream out(&annotations); + Printer printer(&out); + processor.Print(&printer); + out.Flush(); EXPECT_THAT(annotations, HasSubstr("@Deprecated")); } @@ -44,9 +50,11 @@ TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) { AnnotationProcessor processor; processor.AppendComment("@SystemApi This is a system API"); - std::stringstream result; - processor.WriteToStream("", &result); - std::string annotations = result.str(); + std::string annotations; + StringOutputStream out(&annotations); + Printer printer(&out); + processor.Print(&printer); + out.Flush(); EXPECT_THAT(annotations, HasSubstr("@android.annotation.SystemApi")); EXPECT_THAT(annotations, Not(HasSubstr("@SystemApi"))); @@ -57,9 +65,11 @@ TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) { AnnotationProcessor processor; processor.AppendComment("@TestApi This is a test API"); - std::stringstream result; - processor.WriteToStream("", &result); - std::string annotations = result.str(); + std::string annotations; + StringOutputStream out(&annotations); + Printer printer(&out); + processor.Print(&printer); + out.Flush(); EXPECT_THAT(annotations, HasSubstr("@android.annotation.TestApi")); EXPECT_THAT(annotations, Not(HasSubstr("@TestApi"))); diff --git a/tools/aapt2/java/ClassDefinition.cpp b/tools/aapt2/java/ClassDefinition.cpp index 0c57e7e06128..b692ccf7e52d 100644 --- a/tools/aapt2/java/ClassDefinition.cpp +++ b/tools/aapt2/java/ClassDefinition.cpp @@ -18,25 +18,27 @@ #include "androidfw/StringPiece.h" +using ::aapt::text::Printer; using ::android::StringPiece; namespace aapt { -void ClassMember::WriteToStream(const StringPiece& prefix, bool final, std::ostream* out) const { - processor_.WriteToStream(prefix, out); +void ClassMember::Print(bool /*final*/, Printer* printer) const { + processor_.Print(printer); } void MethodDefinition::AppendStatement(const StringPiece& statement) { statements_.push_back(statement.to_string()); } -void MethodDefinition::WriteToStream(const StringPiece& prefix, bool final, - std::ostream* out) const { - *out << prefix << signature_ << " {\n"; +void MethodDefinition::Print(bool final, Printer* printer) const { + printer->Print(signature_).Println(" {"); + printer->Indent(); for (const auto& statement : statements_) { - *out << prefix << " " << statement << "\n"; + printer->Println(statement); } - *out << prefix << "}"; + printer->Undent(); + printer->Print("}"); } ClassDefinition::Result ClassDefinition::AddMember(std::unique_ptr<ClassMember> member) { @@ -62,34 +64,32 @@ bool ClassDefinition::empty() const { return true; } -void ClassDefinition::WriteToStream(const StringPiece& prefix, bool final, - std::ostream* out) const { +void ClassDefinition::Print(bool final, Printer* printer) const { if (empty() && !create_if_empty_) { return; } - ClassMember::WriteToStream(prefix, final, out); + ClassMember::Print(final, printer); - *out << prefix << "public "; + printer->Print("public "); if (qualifier_ == ClassQualifier::kStatic) { - *out << "static "; + printer->Print("static "); } - *out << "final class " << name_ << " {\n"; - - std::string new_prefix = prefix.to_string(); - new_prefix.append(kIndent); + printer->Print("final class ").Print(name_).Println(" {"); + printer->Indent(); for (const std::unique_ptr<ClassMember>& member : ordered_members_) { // There can be nullptr members when a member is added to the ClassDefinition // and takes precedence over a previous member with the same name. The overridden member is // set to nullptr. if (member != nullptr) { - member->WriteToStream(new_prefix, final, out); - *out << "\n"; + member->Print(final, printer); + printer->Println(); } } - *out << prefix << "}"; + printer->Undent(); + printer->Print("}"); } constexpr static const char* sWarningHeader = @@ -100,11 +100,12 @@ constexpr static const char* sWarningHeader = " * should not be modified by hand.\n" " */\n\n"; -bool ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package, - bool final, std::ostream* out) { - *out << sWarningHeader << "package " << package << ";\n\n"; - def->WriteToStream("", final, out); - return bool(*out); +void ClassDefinition::WriteJavaFile(const ClassDefinition* def, const StringPiece& package, + bool final, io::OutputStream* out) { + Printer printer(out); + printer.Print(sWarningHeader).Print("package ").Print(package).Println(";"); + printer.Println(); + def->Print(final, &printer); } } // namespace aapt diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h index 28a3489e71a4..fb11266f1761 100644 --- a/tools/aapt2/java/ClassDefinition.h +++ b/tools/aapt2/java/ClassDefinition.h @@ -17,7 +17,6 @@ #ifndef AAPT_JAVA_CLASSDEFINITION_H #define AAPT_JAVA_CLASSDEFINITION_H -#include <ostream> #include <string> #include <unordered_map> #include <vector> @@ -27,6 +26,7 @@ #include "Resource.h" #include "java/AnnotationProcessor.h" +#include "text/Printer.h" #include "util/Util.h" namespace aapt { @@ -47,11 +47,10 @@ class ClassMember { virtual const std::string& GetName() const = 0; - // Writes the class member to the out stream. Subclasses should derive this method + // Writes the class member to the Printer. Subclasses should derive this method // to write their own data. Call this base method from the subclass to write out // this member's comments/annotations. - virtual void WriteToStream(const android::StringPiece& prefix, bool final, - std::ostream* out) const; + virtual void Print(bool final, text::Printer* printer) const; private: AnnotationProcessor processor_; @@ -71,11 +70,16 @@ class PrimitiveMember : public ClassMember { return name_; } - void WriteToStream(const android::StringPiece& prefix, bool final, - std::ostream* out) const override { - ClassMember::WriteToStream(prefix, final, out); - *out << prefix << "public static " << (final ? "final " : "") << "int " << name_ << "=" << val_ - << ";"; + void Print(bool final, text::Printer* printer) const override { + using std::to_string; + + ClassMember::Print(final, printer); + + printer->Print("public static "); + if (final) { + printer->Print("final "); + } + printer->Print("int ").Print(name_).Print("=").Print(to_string(val_)).Print(";"); } private: @@ -100,12 +104,14 @@ class PrimitiveMember<std::string> : public ClassMember { return name_; } - void WriteToStream(const android::StringPiece& prefix, bool final, - std::ostream* out) const override { - ClassMember::WriteToStream(prefix, final, out); + void Print(bool final, text::Printer* printer) const override { + ClassMember::Print(final, printer); - *out << prefix << "public static " << (final ? "final " : "") << "String " - << name_ << "=\"" << val_ << "\";"; + printer->Print("public static "); + if (final) { + printer->Print("final "); + } + printer->Print("String ").Print(name_).Print("=\"").Print(val_).Print("\";"); } private: @@ -136,25 +142,27 @@ class PrimitiveArrayMember : public ClassMember { return name_; } - void WriteToStream(const android::StringPiece& prefix, bool final, - std::ostream* out) const override { - ClassMember::WriteToStream(prefix, final, out); + void Print(bool final, text::Printer* printer) const override { + ClassMember::Print(final, printer); - *out << prefix << "public static final int[] " << name_ << "={"; + printer->Print("public static final int[] ").Print(name_).Print("={"); + printer->Indent(); const auto begin = elements_.begin(); const auto end = elements_.end(); for (auto current = begin; current != end; ++current) { if (std::distance(begin, current) % kAttribsPerLine == 0) { - *out << "\n" << prefix << kIndent << kIndent; + printer->Println(); } - *out << *current; + printer->Print(to_string(*current)); if (std::distance(current, end) > 1) { - *out << ", "; + printer->Print(", "); } } - *out << "\n" << prefix << kIndent << "};"; + printer->Println(); + printer->Undent(); + printer->Print("};"); } private: @@ -187,8 +195,7 @@ class MethodDefinition : public ClassMember { return false; } - void WriteToStream(const android::StringPiece& prefix, bool final, - std::ostream* out) const override; + void Print(bool final, text::Printer* printer) const override; private: DISALLOW_COPY_AND_ASSIGN(MethodDefinition); @@ -201,8 +208,8 @@ enum class ClassQualifier { kNone, kStatic }; class ClassDefinition : public ClassMember { public: - static bool WriteJavaFile(const ClassDefinition* def, const android::StringPiece& package, - bool final, std::ostream* out); + static void WriteJavaFile(const ClassDefinition* def, const android::StringPiece& package, + bool final, io::OutputStream* out); ClassDefinition(const android::StringPiece& name, ClassQualifier qualifier, bool createIfEmpty) : name_(name.to_string()), qualifier_(qualifier), create_if_empty_(createIfEmpty) {} @@ -220,8 +227,7 @@ class ClassDefinition : public ClassMember { return name_; } - void WriteToStream(const android::StringPiece& prefix, bool final, - std::ostream* out) const override; + void Print(bool final, text::Printer* printer) const override; private: DISALLOW_COPY_AND_ASSIGN(ClassDefinition); diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index 91cef642fc3f..9861770083a2 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -37,8 +37,10 @@ #include "java/ClassDefinition.h" #include "process/SymbolTable.h" -using android::StringPiece; -using android::base::StringPrintf; +using ::aapt::io::OutputStream; +using ::aapt::text::Printer; +using ::android::StringPiece; +using ::android::base::StringPrintf; namespace aapt { @@ -230,7 +232,7 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res const StringPiece& package_name_to_generate, ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method, - std::ostream* out_r_txt) { + Printer* r_txt_printer) { const std::string array_field_name = TransformToFieldName(name.entry); std::unique_ptr<ResourceArrayMember> array_def = util::make_unique<ResourceArrayMember>(array_field_name); @@ -323,8 +325,8 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res array_def->GetCommentBuilder()->AppendComment(styleable_comment.str()); } - if (out_r_txt != nullptr) { - *out_r_txt << "int[] styleable " << array_field_name << " {"; + if (r_txt_printer != nullptr) { + r_txt_printer->Print("int[] styleable ").Print(array_field_name).Print(" {"); } // Add the ResourceIds to the array member. @@ -332,16 +334,16 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res const ResourceId id = sorted_attributes[i].attr_ref->id.value_or_default(ResourceId(0)); array_def->AddElement(id); - if (out_r_txt != nullptr) { + if (r_txt_printer != nullptr) { if (i != 0) { - *out_r_txt << ","; + r_txt_printer->Print(","); } - *out_r_txt << " " << id; + r_txt_printer->Print(" ").Print(id.to_string()); } } - if (out_r_txt != nullptr) { - *out_r_txt << " }\n"; + if (r_txt_printer != nullptr) { + r_txt_printer->Println(" }"); } // Add the Styleable array to the Styleable class. @@ -396,9 +398,9 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res attr_processor->AppendComment( StringPrintf("@attr name %s:%s", package_name.data(), attr_name.entry.data())); - if (out_r_txt != nullptr) { - *out_r_txt << StringPrintf("int styleable %s %d\n", sorted_attributes[i].field_name.data(), - (int)i); + 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)); @@ -422,10 +424,12 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const ResourceId& id, const ResourceEntry& entry, ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method, - std::ostream* out_r_txt) { + text::Printer* r_txt_printer) { ResourceId real_id = id; if (context_->GetMinSdkVersion() < SDK_O && name.type == ResourceType::kId && id.package_id() > kAppPackageId) { + // Workaround for feature splits using package IDs > 0x7F. + // See b/37498913. real_id = ResourceId(kAppPackageId, id.package_id(), id.entry_id()); } @@ -456,8 +460,13 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso out_class_def->AddMember(std::move(resource_member)); - if (out_r_txt != nullptr) { - *out_r_txt << "int " << name.type << " " << field_name << " " << real_id << "\n"; + if (r_txt_printer != nullptr) { + r_txt_printer->Print("int ") + .Print(to_string(name.type)) + .Print(" ") + .Print(field_name) + .Print(" ") + .Println(real_id.to_string()); } if (out_rewrite_method != nullptr) { @@ -497,7 +506,7 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate const ResourceTableType& type, ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def, - std::ostream* out_r_txt) { + Printer* r_txt_printer) { for (const auto& entry : type.entries) { const Maybe<std::string> unmangled_name = UnmangleResource(package.name, package_name_to_generate, *entry); @@ -532,18 +541,18 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate 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, out_r_txt); + out_rewrite_method_def, r_txt_printer); } else { ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def, - out_r_txt); + r_txt_printer); } } return true; } -bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out, - std::ostream* out_r_txt) { - return Generate(package_name_to_generate, package_name_to_generate, out); +bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, OutputStream* out, + OutputStream* out_r_txt) { + return Generate(package_name_to_generate, package_name_to_generate, out, out_r_txt); } static void AppendJavaDocAnnotations(const std::vector<std::string>& annotations, @@ -556,11 +565,16 @@ static void AppendJavaDocAnnotations(const std::vector<std::string>& annotations } bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, - const StringPiece& out_package_name, std::ostream* out, - std::ostream* out_r_txt) { + const StringPiece& out_package_name, OutputStream* out, + OutputStream* out_r_txt) { ClassDefinition r_class("R", ClassQualifier::kNone, true); std::unique_ptr<MethodDefinition> rewrite_method; + std::unique_ptr<Printer> r_txt_printer; + if (out_r_txt != nullptr) { + r_txt_printer = util::make_unique<Printer>(out_r_txt); + } + // Generate an onResourcesLoaded() callback if requested. if (options_.rewrite_callback_options) { rewrite_method = @@ -586,7 +600,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::unique_ptr<ClassDefinition> 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(), out_r_txt)) { + rewrite_method.get(), r_txt_printer.get())) { return false; } @@ -595,7 +609,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate); if (priv_type) { if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(), - rewrite_method.get(), out_r_txt)) { + rewrite_method.get(), r_txt_printer.get())) { return false; } } @@ -619,22 +633,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, } AppendJavaDocAnnotations(options_.javadoc_annotations, r_class.GetCommentBuilder()); - - if (!ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, out)) { - return false; - } - - out->flush(); - - if (out_r_txt != nullptr) { - out_r_txt->flush(); - - if (!*out_r_txt) { - error_ = android::base::SystemErrorCodeToString(errno); - return false; - } - } - + ClassDefinition::WriteJavaFile(&r_class, out_package_name, options_.use_final, out); return true; } diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h index 2541749750a6..4992f077c566 100644 --- a/tools/aapt2/java/JavaClassGenerator.h +++ b/tools/aapt2/java/JavaClassGenerator.h @@ -17,16 +17,16 @@ #ifndef AAPT_JAVA_CLASS_GENERATOR_H #define AAPT_JAVA_CLASS_GENERATOR_H -#include <ostream> #include <string> #include "androidfw/StringPiece.h" #include "ResourceTable.h" #include "ResourceValues.h" -#include "androidfw/StringPiece.h" +#include "io/Io.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" +#include "text/Printer.h" namespace aapt { @@ -70,14 +70,14 @@ class JavaClassGenerator { // All symbols technically belong to a single package, but linked libraries will // have their names mangled, denoting that they came from a different package. // We need to generate these symbols in a separate file. Returns true on success. - bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out, - std::ostream* out_r_txt = nullptr); + bool Generate(const android::StringPiece& package_name_to_generate, io::OutputStream* out, + io::OutputStream* out_r_txt = nullptr); bool Generate(const android::StringPiece& package_name_to_generate, - const android::StringPiece& output_package_name, std::ostream* out, - std::ostream* out_r_txt = nullptr); + const android::StringPiece& output_package_name, io::OutputStream* out, + io::OutputStream* out_r_txt = nullptr); - const std::string& getError() const; + const std::string& GetError() const; static std::string TransformToFieldName(const android::StringPiece& symbol); @@ -94,13 +94,13 @@ class JavaClassGenerator { bool ProcessType(const android::StringPiece& package_name_to_generate, const ResourceTablePackage& package, const ResourceTableType& type, ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def, - std::ostream* out_r_txt); + text::Printer* r_txt_printer); // Writes a resource to the R.java file, optionally writing out a rewrite rule for its package // ID if `out_rewrite_method` is not nullptr. void ProcessResource(const ResourceNameRef& name, const ResourceId& id, const ResourceEntry& entry, ClassDefinition* out_class_def, - MethodDefinition* out_rewrite_method, std::ostream* out_r_txt); + MethodDefinition* out_rewrite_method, text::Printer* r_txt_printer); // 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. @@ -109,7 +109,7 @@ class JavaClassGenerator { const Styleable& styleable, const android::StringPiece& package_name_to_generate, ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method, - std::ostream* out_r_txt); + text::Printer* r_txt_printer); IAaptContext* context_; ResourceTable* table_; @@ -117,7 +117,7 @@ class JavaClassGenerator { std::string error_; }; -inline const std::string& JavaClassGenerator::getError() const { +inline const std::string& JavaClassGenerator::GetError() const { return error_; } diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp index 668e4340e839..02f4cb14eb41 100644 --- a/tools/aapt2/java/JavaClassGenerator_test.cpp +++ b/tools/aapt2/java/JavaClassGenerator_test.cpp @@ -16,12 +16,13 @@ #include "java/JavaClassGenerator.h" -#include <sstream> #include <string> +#include "io/StringStream.h" #include "test/Test.h" #include "util/Util.h" +using ::aapt::io::StringOutputStream; using ::android::StringPiece; using ::testing::HasSubstr; using ::testing::Lt; @@ -45,7 +46,8 @@ TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) { .Build(); JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + std::string result; + StringOutputStream out(&result); EXPECT_FALSE(generator.Generate("android", &out)); } @@ -69,10 +71,10 @@ TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) { .Build(); JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + std::string output; + StringOutputStream out(&output); EXPECT_TRUE(generator.Generate("android", &out)); - - std::string output = out.str(); + out.Flush(); EXPECT_THAT(output, HasSubstr("public static final int hey_man=0x01020000;")); EXPECT_THAT(output, HasSubstr("public static final int[] hey_dude={")); @@ -93,10 +95,12 @@ TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) { .SetNameManglerPolicy(NameManglerPolicy{"android"}) .Build(); JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", "com.android.internal", &out)); + out.Flush(); - std::string output = out.str(); EXPECT_THAT(output, HasSubstr("package com.android.internal;")); EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;")); EXPECT_THAT(output, Not(HasSubstr("two"))); @@ -117,10 +121,12 @@ TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) { .SetNameManglerPolicy(NameManglerPolicy{"android"}) .Build(); JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); + out.Flush(); - std::string output = out.str(); EXPECT_THAT(output, HasSubstr("public static final class attr")); EXPECT_THAT(output, Not(HasSubstr("public static final class ^attr-private"))); } @@ -147,9 +153,11 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic; { JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); + EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;")); EXPECT_THAT(output, Not(HasSubstr("two"))); EXPECT_THAT(output, Not(HasSubstr("three"))); @@ -158,9 +166,11 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate; { JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); + EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;")); EXPECT_THAT(output, HasSubstr("public static final int two=0x01020001;")); EXPECT_THAT(output, Not(HasSubstr("three"))); @@ -169,9 +179,11 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; { JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); + EXPECT_THAT(output, HasSubstr("public static final int one=0x01020000;")); EXPECT_THAT(output, HasSubstr("public static final int two=0x01020001;")); EXPECT_THAT(output, HasSubstr("public static final int three=0x01020002;")); @@ -235,10 +247,11 @@ TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) { .Build(); JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + std::string output; + StringOutputStream out(&output); EXPECT_TRUE(generator.Generate("android", &out)); + out.Flush(); - std::string output = out.str(); EXPECT_THAT(output, HasSubstr("int foo_bar=")); EXPECT_THAT(output, HasSubstr("int foo_com_lib_bar=")); } @@ -258,9 +271,11 @@ TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) { .SetNameManglerPolicy(NameManglerPolicy{"android"}) .Build(); JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); const char* expected_text = R"EOF(/** @@ -298,9 +313,11 @@ TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) JavaClassGeneratorOptions options; options.use_final = false; JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; + + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); EXPECT_THAT(output, HasSubstr("attr name android:one")); EXPECT_THAT(output, HasSubstr("attr description")); @@ -332,9 +349,11 @@ TEST(JavaClassGeneratorTest, StyleableAndIndicesAreColocated) { JavaClassGeneratorOptions options; JavaClassGenerator generator(context.get(), table.get(), {}); - std::stringstream out; + + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); std::string::size_type actionbar_pos = output.find("int[] ActionBar"); ASSERT_THAT(actionbar_pos, Ne(std::string::npos)); @@ -373,9 +392,11 @@ TEST(JavaClassGeneratorTest, CommentsForRemovedAttributesAreNotPresentInClass) { JavaClassGeneratorOptions options; options.use_final = false; JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; + + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - std::string output = out.str(); + out.Flush(); EXPECT_THAT(output, Not(HasSubstr("@attr name android:one"))); EXPECT_THAT(output, Not(HasSubstr("@attr description"))); @@ -409,10 +430,10 @@ TEST(JavaClassGeneratorTest, GenerateOnResourcesLoadedCallbackForSharedLibrary) options.rewrite_callback_options = OnResourcesLoadedCallbackOptions{{"com.foo", "com.boo"}}; JavaClassGenerator generator(context.get(), table.get(), options); - std::stringstream out; + std::string output; + StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); - - std::string output = out.str(); + out.Flush(); EXPECT_THAT(output, HasSubstr("void onResourcesLoaded")); EXPECT_THAT(output, HasSubstr("com.foo.R.onResourcesLoaded")); diff --git a/tools/aapt2/java/ManifestClassGenerator.h b/tools/aapt2/java/ManifestClassGenerator.h index b12202a8d137..3f6645facaa2 100644 --- a/tools/aapt2/java/ManifestClassGenerator.h +++ b/tools/aapt2/java/ManifestClassGenerator.h @@ -23,8 +23,7 @@ namespace aapt { -std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag, - xml::XmlResource* res); +std::unique_ptr<ClassDefinition> GenerateManifestClass(IDiagnostics* diag, xml::XmlResource* res); } // namespace aapt diff --git a/tools/aapt2/java/ManifestClassGenerator_test.cpp b/tools/aapt2/java/ManifestClassGenerator_test.cpp index ada563409d19..c324238d3ecb 100644 --- a/tools/aapt2/java/ManifestClassGenerator_test.cpp +++ b/tools/aapt2/java/ManifestClassGenerator_test.cpp @@ -16,8 +16,10 @@ #include "java/ManifestClassGenerator.h" +#include "io/StringStream.h" #include "test/Test.h" +using ::aapt::io::StringOutputStream; using ::testing::HasSubstr; using ::testing::Not; @@ -144,12 +146,9 @@ static ::testing::AssertionResult GetManifestClassText(IAaptContext* context, xm return ::testing::AssertionFailure() << "manifest_class == nullptr"; } - std::stringstream out; - if (!manifest_class->WriteJavaFile(manifest_class.get(), "android", true, &out)) { - return ::testing::AssertionFailure() << "failed to write java file"; - } - - *out_str = out.str(); + StringOutputStream out(out_str); + manifest_class->WriteJavaFile(manifest_class.get(), "android", true, &out); + out.Flush(); return ::testing::AssertionSuccess(); } diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index b214d2169f50..132b234ab1e4 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -20,14 +20,18 @@ #include <string> #include "android-base/macros.h" +#include "androidfw/StringPiece.h" #include "JavaClassGenerator.h" #include "ResourceUtils.h" #include "ValueVisitor.h" -#include "androidfw/StringPiece.h" +#include "text/Printer.h" #include "util/Util.h" #include "xml/XmlDom.h" +using ::aapt::io::OutputStream; +using ::aapt::text::Printer; + namespace aapt { namespace proguard { @@ -326,12 +330,13 @@ bool CollectProguardRules(xml::XmlResource* res, KeepSet* keep_set) { return true; } -bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set) { +void WriteKeepSet(const KeepSet& keep_set, OutputStream* out) { + Printer printer(out); for (const auto& entry : keep_set.manifest_class_set_) { for (const UsageLocation& location : entry.second) { - *out << "# Referenced at " << location.source << "\n"; + printer.Print("# Referenced at ").Println(location.source.to_string()); } - *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl; + printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }"); } for (const auto& entry : keep_set.conditional_class_set_) { @@ -342,26 +347,31 @@ bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set) { } for (const UsageLocation& location : entry.second) { - *out << "# Referenced at " << location.source << "\n"; + printer.Print("# Referenced at ").Println(location.source.to_string()); } if (keep_set.conditional_keep_rules_ && can_be_conditional) { - *out << "-if class **.R$layout {\n"; + printer.Println("-if class **.R$layout {"); + printer.Indent(); for (const UsageLocation& location : locations) { - auto transformed_name = JavaClassGenerator::TransformToFieldName(location.name.entry); - *out << " int " << transformed_name << ";\n"; + printer.Print("int ") + .Print(JavaClassGenerator::TransformToFieldName(location.name.entry)) + .Println(";"); } - *out << "}\n"; + printer.Undent(); + printer.Println("}"); + printer.Println(); } - *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl; + printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }"); + printer.Println(); } for (const auto& entry : keep_set.method_set_) { for (const UsageLocation& location : entry.second) { - *out << "# Referenced at " << location.source << "\n"; + printer.Print("# Referenced at ").Println(location.source.to_string()); } - *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" << std::endl; + printer.Print("-keepclassmembers class * { *** ").Print(entry.first).Println("(...); }"); + printer.Println(); } - return true; } bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set, diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h index 8dbe3c2bd1e8..46827ee7cf93 100644 --- a/tools/aapt2/java/ProguardRules.h +++ b/tools/aapt2/java/ProguardRules.h @@ -22,11 +22,13 @@ #include <set> #include <string> +#include "androidfw/StringPiece.h" + #include "Resource.h" #include "ResourceTable.h" #include "Source.h" #include "ValueVisitor.h" -#include "androidfw/StringPiece.h" +#include "io/Io.h" #include "process/IResourceTableConsumer.h" #include "xml/XmlDom.h" @@ -62,7 +64,7 @@ class KeepSet { } private: - friend bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set); + friend void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out); friend bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set, std::set<UsageLocation>* locations); @@ -76,11 +78,12 @@ class KeepSet { bool CollectProguardRulesForManifest(xml::XmlResource* res, KeepSet* keep_set, bool main_dex_only = false); + bool CollectProguardRules(xml::XmlResource* res, KeepSet* keep_set); -bool CollectResourceReferences(aapt::IAaptContext* context, ResourceTable* table, - KeepSet* keep_set); -bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set); +bool CollectResourceReferences(IAaptContext* context, ResourceTable* table, KeepSet* keep_set); + +void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out); bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set, std::set<UsageLocation>* locations); diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp index 802c56a47de4..37d1a5fbaeb8 100644 --- a/tools/aapt2/java/ProguardRules_test.cpp +++ b/tools/aapt2/java/ProguardRules_test.cpp @@ -17,13 +17,23 @@ #include "java/ProguardRules.h" #include "link/Linkers.h" +#include "io/StringStream.h" #include "test/Test.h" +using ::aapt::io::StringOutputStream; using ::testing::HasSubstr; using ::testing::Not; namespace aapt { +std::string GetKeepSetString(const proguard::KeepSet& set) { + std::string out; + StringOutputStream sout(&out); + proguard::WriteKeepSet(set, &sout); + sout.Flush(); + return out; +} + TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) { std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( @@ -34,10 +44,8 @@ TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) { proguard::KeepSet set; ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); } @@ -50,10 +58,8 @@ TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { proguard::KeepSet set; ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); } @@ -68,10 +74,8 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { proguard::KeepSet set; ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); EXPECT_THAT(actual, HasSubstr("com.foo.Baz")); } @@ -87,10 +91,8 @@ TEST(ProguardRulesTest, CustomViewRulesAreEmitted) { proguard::KeepSet set; ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); } @@ -126,11 +128,10 @@ TEST(ProguardRulesTest, IncludedLayoutRulesAreConditional) { ASSERT_TRUE(proguard::CollectProguardRules(bar_layout.get(), &set)); ASSERT_TRUE(proguard::CollectProguardRules(foo_layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("-if class **.R$layout")); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("int foo")); EXPECT_THAT(actual, HasSubstr("int bar")); EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); @@ -148,10 +149,9 @@ TEST(ProguardRulesTest, AliasedLayoutRulesAreConditional) { set.AddReference({test::ParseNameOrDie("layout/bar"), {}}, layout->file.name); ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-if class **.R$layout")); EXPECT_THAT(actual, HasSubstr("int foo")); EXPECT_THAT(actual, HasSubstr("int bar")); @@ -170,11 +170,10 @@ TEST(ProguardRulesTest, NonLayoutReferencesAreUnconditional) { set.AddReference({test::ParseNameOrDie("style/MyStyle"), {}}, layout->file.name); ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, Not(HasSubstr("-if"))); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); } TEST(ProguardRulesTest, ViewOnClickRuleIsEmitted) { @@ -187,10 +186,8 @@ TEST(ProguardRulesTest, ViewOnClickRuleIsEmitted) { proguard::KeepSet set; ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("bar_method")); } @@ -208,10 +205,8 @@ TEST(ProguardRulesTest, MenuRulesAreEmitted) { proguard::KeepSet set; ASSERT_TRUE(proguard::CollectProguardRules(menu.get(), &set)); - std::stringstream out; - ASSERT_TRUE(proguard::WriteKeepSet(&out, set)); + std::string actual = GetKeepSetString(set); - std::string actual = out.str(); EXPECT_THAT(actual, HasSubstr("on_click")); EXPECT_THAT(actual, HasSubstr("com.foo.Bar")); EXPECT_THAT(actual, HasSubstr("com.foo.Baz")); |