Loading tools/aapt2/java/AnnotationProcessor.cpp +24 −22 Original line number Diff line number Diff line Loading @@ -64,9 +64,10 @@ static std::array<AnnotationRule, 3> sAnnotationRules = {{ {"@FlaggedApi", AnnotationRule::kFlaggedApi, "@android.annotation.FlaggedApi", true}, }}; void AnnotationProcessor::AppendCommentLine(std::string comment) { void AnnotationProcessor::AppendCommentLine(std::string comment, bool add_api_annotations) { static constexpr std::string_view sDeprecated = "@deprecated"; if (add_api_annotations) { // Treat deprecated specially, since we don't remove it from the source comment. if (comment.find(sDeprecated) != std::string::npos) { annotation_parameter_map_[AnnotationRule::kDeprecated] = ""; Loading @@ -90,6 +91,7 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) { } } } } // Check if after removal of annotations the line is empty. const StringPiece trimmed = util::TrimWhitespace(comment); Loading @@ -109,12 +111,12 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) { comment_ << "\n * " << std::move(comment); } void AnnotationProcessor::AppendComment(StringPiece comment) { void AnnotationProcessor::AppendComment(StringPiece comment, bool add_api_annotations) { // We need to process line by line to clean-up whitespace and append prefixes. for (StringPiece line : util::Tokenize(comment, '\n')) { line = util::TrimWhitespace(line); if (!line.empty()) { AppendCommentLine(std::string(line)); AppendCommentLine(std::string(line), add_api_annotations); } } } Loading tools/aapt2/java/AnnotationProcessor.h +5 −2 Original line number Diff line number Diff line Loading @@ -60,7 +60,10 @@ class AnnotationProcessor { // Adds more comments. Resources can have value definitions for various configurations, and // each of the definitions may have comments that need to be processed. void AppendComment(android::StringPiece comment); // // If add_api_annotations is false, annotations found in the comment (e.g., "@SystemApi") // will NOT be converted to Java annotations. void AppendComment(android::StringPiece comment, bool add_api_annotations = true); void AppendNewLine(); Loading @@ -73,7 +76,7 @@ class AnnotationProcessor { bool has_comments_ = false; std::unordered_map<uint32_t, std::string> annotation_parameter_map_; void AppendCommentLine(std::string line); void AppendCommentLine(std::string line, bool add_api_annotations); }; } // namespace aapt Loading tools/aapt2/java/AnnotationProcessor_test.cpp +22 −1 Original line number Diff line number Diff line Loading @@ -136,7 +136,28 @@ TEST(AnnotationProcessorTest, NotEmitSystemApiAnnotation) { EXPECT_THAT(annotations, HasSubstr("This is a system API")); } TEST(AnnotationProcessor, ExtractsFirstSentence) { TEST(AnnotationProcessorTest, DoNotAddApiAnnotations) { AnnotationProcessor processor; processor.AppendComment( "@SystemApi This is a system API\n" "@FlaggedApi This is a flagged API\n" "@TestApi This is a test API\n" "@deprecated Deprecate me\n", /*add_api_annotations=*/ false); std::string annotations; StringOutputStream out(&annotations); Printer printer(&out); processor.Print(&printer); out.Flush(); EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.SystemApi"))); EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.FlaggedApi"))); EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.TestApi"))); EXPECT_THAT(annotations, Not(HasSubstr("@Deprecated"))); } TEST(AnnotationProcessorTest, ExtractsFirstSentence) { EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence("This is the only sentence"), Eq("This is the only sentence")); EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence( Loading tools/aapt2/java/JavaClassGenerator.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,10 @@ static void AddAttributeFormatDoc(AnnotationProcessor* processor, Attribute* att << "<td>" << std::hex << symbol.value << std::dec << "</td>" << "<td>" << util::TrimWhitespace(symbol.symbol.GetComment()) << "</td></tr>"; processor->AppendComment(line.str()); // add_api_annotations is false since we don't want any annotations // (e.g., "@deprecated")/ found in the enum/flag values to be propagated // up to the attribute. processor->AppendComment(line.str(), /*add_api_annotations=*/false); } processor->AppendComment("</table>"); } Loading tools/aapt2/java/JavaClassGenerator_test.cpp +52 −1 Original line number Diff line number Diff line Loading @@ -324,7 +324,58 @@ TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) { EXPECT_THAT(output, HasSubstr(expected_text)); } TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {} TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) { std::unique_ptr<Attribute> flagAttr = test::AttributeBuilder() .SetTypeMask(android::ResTable_map::TYPE_FLAGS) .SetComment("Flag attribute") .AddItemWithComment("flagOne", 0x01, "Flag comment 1") .AddItemWithComment("flagTwo", 0x02, "@deprecated Flag comment 2") .Build(); std::unique_ptr<Attribute> enumAttr = test::AttributeBuilder() .SetTypeMask(android::ResTable_map::TYPE_ENUM) .SetComment("Enum attribute") .AddItemWithComment("enumOne", 0x01, "@TestApi Enum comment 1") .AddItemWithComment("enumTwo", 0x02, "Enum comment 2") .Build(); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .AddValue("android:attr/one", std::move(flagAttr)) .AddValue("android:attr/two", std::move(enumAttr)) .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) .SetNameManglerPolicy(NameManglerPolicy{"android"}) .Build(); JavaClassGeneratorOptions options; options.use_final = false; JavaClassGenerator generator(context.get(), table.get(), options); std::string output; StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); out.Flush(); // Special annotations from the enum/flag values should NOT generate // annotations for the attribute value. EXPECT_THAT(output, Not(HasSubstr("@Deprecated"))); EXPECT_THAT(output, Not(HasSubstr("@android.annotation.TestApi"))); EXPECT_THAT(output, HasSubstr("Flag attribute")); EXPECT_THAT(output, HasSubstr("flagOne")); EXPECT_THAT(output, HasSubstr("Flag comment 1")); EXPECT_THAT(output, HasSubstr("flagTwo")); EXPECT_THAT(output, HasSubstr("@deprecated Flag comment 2")); EXPECT_THAT(output, HasSubstr("Enum attribute")); EXPECT_THAT(output, HasSubstr("enumOne")); EXPECT_THAT(output, HasSubstr("@TestApi Enum comment 1")); EXPECT_THAT(output, HasSubstr("enumTwo")); EXPECT_THAT(output, HasSubstr("Enum comment 2")); } TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) { Attribute attr; Loading Loading
tools/aapt2/java/AnnotationProcessor.cpp +24 −22 Original line number Diff line number Diff line Loading @@ -64,9 +64,10 @@ static std::array<AnnotationRule, 3> sAnnotationRules = {{ {"@FlaggedApi", AnnotationRule::kFlaggedApi, "@android.annotation.FlaggedApi", true}, }}; void AnnotationProcessor::AppendCommentLine(std::string comment) { void AnnotationProcessor::AppendCommentLine(std::string comment, bool add_api_annotations) { static constexpr std::string_view sDeprecated = "@deprecated"; if (add_api_annotations) { // Treat deprecated specially, since we don't remove it from the source comment. if (comment.find(sDeprecated) != std::string::npos) { annotation_parameter_map_[AnnotationRule::kDeprecated] = ""; Loading @@ -90,6 +91,7 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) { } } } } // Check if after removal of annotations the line is empty. const StringPiece trimmed = util::TrimWhitespace(comment); Loading @@ -109,12 +111,12 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) { comment_ << "\n * " << std::move(comment); } void AnnotationProcessor::AppendComment(StringPiece comment) { void AnnotationProcessor::AppendComment(StringPiece comment, bool add_api_annotations) { // We need to process line by line to clean-up whitespace and append prefixes. for (StringPiece line : util::Tokenize(comment, '\n')) { line = util::TrimWhitespace(line); if (!line.empty()) { AppendCommentLine(std::string(line)); AppendCommentLine(std::string(line), add_api_annotations); } } } Loading
tools/aapt2/java/AnnotationProcessor.h +5 −2 Original line number Diff line number Diff line Loading @@ -60,7 +60,10 @@ class AnnotationProcessor { // Adds more comments. Resources can have value definitions for various configurations, and // each of the definitions may have comments that need to be processed. void AppendComment(android::StringPiece comment); // // If add_api_annotations is false, annotations found in the comment (e.g., "@SystemApi") // will NOT be converted to Java annotations. void AppendComment(android::StringPiece comment, bool add_api_annotations = true); void AppendNewLine(); Loading @@ -73,7 +76,7 @@ class AnnotationProcessor { bool has_comments_ = false; std::unordered_map<uint32_t, std::string> annotation_parameter_map_; void AppendCommentLine(std::string line); void AppendCommentLine(std::string line, bool add_api_annotations); }; } // namespace aapt Loading
tools/aapt2/java/AnnotationProcessor_test.cpp +22 −1 Original line number Diff line number Diff line Loading @@ -136,7 +136,28 @@ TEST(AnnotationProcessorTest, NotEmitSystemApiAnnotation) { EXPECT_THAT(annotations, HasSubstr("This is a system API")); } TEST(AnnotationProcessor, ExtractsFirstSentence) { TEST(AnnotationProcessorTest, DoNotAddApiAnnotations) { AnnotationProcessor processor; processor.AppendComment( "@SystemApi This is a system API\n" "@FlaggedApi This is a flagged API\n" "@TestApi This is a test API\n" "@deprecated Deprecate me\n", /*add_api_annotations=*/ false); std::string annotations; StringOutputStream out(&annotations); Printer printer(&out); processor.Print(&printer); out.Flush(); EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.SystemApi"))); EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.FlaggedApi"))); EXPECT_THAT(annotations, Not(HasSubstr("@android.annotation.TestApi"))); EXPECT_THAT(annotations, Not(HasSubstr("@Deprecated"))); } TEST(AnnotationProcessorTest, ExtractsFirstSentence) { EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence("This is the only sentence"), Eq("This is the only sentence")); EXPECT_THAT(AnnotationProcessor::ExtractFirstSentence( Loading
tools/aapt2/java/JavaClassGenerator.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,10 @@ static void AddAttributeFormatDoc(AnnotationProcessor* processor, Attribute* att << "<td>" << std::hex << symbol.value << std::dec << "</td>" << "<td>" << util::TrimWhitespace(symbol.symbol.GetComment()) << "</td></tr>"; processor->AppendComment(line.str()); // add_api_annotations is false since we don't want any annotations // (e.g., "@deprecated")/ found in the enum/flag values to be propagated // up to the attribute. processor->AppendComment(line.str(), /*add_api_annotations=*/false); } processor->AppendComment("</table>"); } Loading
tools/aapt2/java/JavaClassGenerator_test.cpp +52 −1 Original line number Diff line number Diff line Loading @@ -324,7 +324,58 @@ TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) { EXPECT_THAT(output, HasSubstr(expected_text)); } TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) {} TEST(JavaClassGeneratorTest, CommentsForEnumAndFlagAttributesArePresent) { std::unique_ptr<Attribute> flagAttr = test::AttributeBuilder() .SetTypeMask(android::ResTable_map::TYPE_FLAGS) .SetComment("Flag attribute") .AddItemWithComment("flagOne", 0x01, "Flag comment 1") .AddItemWithComment("flagTwo", 0x02, "@deprecated Flag comment 2") .Build(); std::unique_ptr<Attribute> enumAttr = test::AttributeBuilder() .SetTypeMask(android::ResTable_map::TYPE_ENUM) .SetComment("Enum attribute") .AddItemWithComment("enumOne", 0x01, "@TestApi Enum comment 1") .AddItemWithComment("enumTwo", 0x02, "Enum comment 2") .Build(); std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .AddValue("android:attr/one", std::move(flagAttr)) .AddValue("android:attr/two", std::move(enumAttr)) .Build(); std::unique_ptr<IAaptContext> context = test::ContextBuilder() .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) .SetNameManglerPolicy(NameManglerPolicy{"android"}) .Build(); JavaClassGeneratorOptions options; options.use_final = false; JavaClassGenerator generator(context.get(), table.get(), options); std::string output; StringOutputStream out(&output); ASSERT_TRUE(generator.Generate("android", &out)); out.Flush(); // Special annotations from the enum/flag values should NOT generate // annotations for the attribute value. EXPECT_THAT(output, Not(HasSubstr("@Deprecated"))); EXPECT_THAT(output, Not(HasSubstr("@android.annotation.TestApi"))); EXPECT_THAT(output, HasSubstr("Flag attribute")); EXPECT_THAT(output, HasSubstr("flagOne")); EXPECT_THAT(output, HasSubstr("Flag comment 1")); EXPECT_THAT(output, HasSubstr("flagTwo")); EXPECT_THAT(output, HasSubstr("@deprecated Flag comment 2")); EXPECT_THAT(output, HasSubstr("Enum attribute")); EXPECT_THAT(output, HasSubstr("enumOne")); EXPECT_THAT(output, HasSubstr("@TestApi Enum comment 1")); EXPECT_THAT(output, HasSubstr("enumTwo")); EXPECT_THAT(output, HasSubstr("Enum comment 2")); } TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) { Attribute attr; Loading