Loading tools/aapt2/java/AnnotationProcessor.cpp +25 −6 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <algorithm> #include <algorithm> #include <array> #include <array> #include <regex> #include "text/Unicode.h" #include "text/Unicode.h" #include "text/Utf8Iterator.h" #include "text/Utf8Iterator.h" Loading Loading @@ -65,16 +66,28 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) { // Treat deprecated specially, since we don't remove it from the source comment. // Treat deprecated specially, since we don't remove it from the source comment. if (comment.find(sDeprecated) != std::string::npos) { if (comment.find(sDeprecated) != std::string::npos) { annotation_bit_mask_ |= AnnotationRule::kDeprecated; annotation_parameter_map_[AnnotationRule::kDeprecated] = ""; } } for (const AnnotationRule& rule : sAnnotationRules) { for (const AnnotationRule& rule : sAnnotationRules) { std::string::size_type idx = comment.find(rule.doc_str.data()); std::string::size_type idx = comment.find(rule.doc_str.data()); if (idx != std::string::npos) { if (idx != std::string::npos) { annotation_bit_mask_ |= rule.bit_mask; // Captures all parameters associated with the specified annotation rule // by matching the first pair of parantheses after the rule. std::regex re(rule.doc_str.to_string() + "\\s*\\((.+)\\)"); std::smatch match_result; const bool is_match = std::regex_search(comment, match_result, re); // We currently only capture and preserve parameters for SystemApi. if (is_match && rule.bit_mask == AnnotationRule::kSystemApi) { annotation_parameter_map_[rule.bit_mask] = match_result[1].str(); comment.erase(comment.begin() + match_result.position(), comment.begin() + match_result.position() + match_result.length()); } else { annotation_parameter_map_[rule.bit_mask] = ""; comment.erase(comment.begin() + idx, comment.begin() + idx + rule.doc_str.size()); comment.erase(comment.begin() + idx, comment.begin() + idx + rule.doc_str.size()); } } } } } // Check if after removal of annotations the line is empty. // Check if after removal of annotations the line is empty. const StringPiece trimmed = util::TrimWhitespace(comment); const StringPiece trimmed = util::TrimWhitespace(comment); Loading Loading @@ -119,13 +132,19 @@ void AnnotationProcessor::Print(Printer* printer) const { printer->Println(" */"); printer->Println(" */"); } } if (annotation_bit_mask_ & AnnotationRule::kDeprecated) { if (annotation_parameter_map_.find(AnnotationRule::kDeprecated) != annotation_parameter_map_.end()) { printer->Println("@Deprecated"); printer->Println("@Deprecated"); } } for (const AnnotationRule& rule : sAnnotationRules) { for (const AnnotationRule& rule : sAnnotationRules) { if (annotation_bit_mask_ & rule.bit_mask) { const auto& it = annotation_parameter_map_.find(rule.bit_mask); printer->Println(rule.annotation); if (it != annotation_parameter_map_.end()) { printer->Print(rule.annotation); if (!it->second.empty()) { printer->Print("(").Print(it->second).Print(")"); } printer->Print("\n"); } } } } } } Loading tools/aapt2/java/AnnotationProcessor.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <sstream> #include <sstream> #include <string> #include <string> #include <unordered_map> #include "androidfw/StringPiece.h" #include "androidfw/StringPiece.h" Loading Loading @@ -70,7 +71,7 @@ class AnnotationProcessor { std::stringstream comment_; std::stringstream comment_; std::stringstream mAnnotations; std::stringstream mAnnotations; bool has_comments_ = false; bool has_comments_ = false; uint32_t annotation_bit_mask_ = 0; std::unordered_map<uint32_t, std::string> annotation_parameter_map_; void AppendCommentLine(std::string line); void AppendCommentLine(std::string line); }; }; Loading tools/aapt2/java/AnnotationProcessor_test.cpp +15 −0 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,21 @@ TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) { EXPECT_THAT(annotations, HasSubstr("This is a system API")); EXPECT_THAT(annotations, HasSubstr("This is a system API")); } } TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationParamsAndRemovesFromComment) { AnnotationProcessor processor; processor.AppendComment("@SystemApi (p1=k1,p2=k2) This is a system API"); std::string annotations; StringOutputStream out(&annotations); Printer printer(&out); processor.Print(&printer); out.Flush(); EXPECT_THAT(annotations, HasSubstr("@android.annotation.SystemApi(p1=k1,p2=k2)")); EXPECT_THAT(annotations, Not(HasSubstr("@SystemApi"))); EXPECT_THAT(annotations, HasSubstr("This is a system API")); } TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) { TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) { AnnotationProcessor processor; AnnotationProcessor processor; processor.AppendComment("@TestApi This is a test API"); processor.AppendComment("@TestApi This is a test API"); Loading Loading
tools/aapt2/java/AnnotationProcessor.cpp +25 −6 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <algorithm> #include <algorithm> #include <array> #include <array> #include <regex> #include "text/Unicode.h" #include "text/Unicode.h" #include "text/Utf8Iterator.h" #include "text/Utf8Iterator.h" Loading Loading @@ -65,16 +66,28 @@ void AnnotationProcessor::AppendCommentLine(std::string comment) { // Treat deprecated specially, since we don't remove it from the source comment. // Treat deprecated specially, since we don't remove it from the source comment. if (comment.find(sDeprecated) != std::string::npos) { if (comment.find(sDeprecated) != std::string::npos) { annotation_bit_mask_ |= AnnotationRule::kDeprecated; annotation_parameter_map_[AnnotationRule::kDeprecated] = ""; } } for (const AnnotationRule& rule : sAnnotationRules) { for (const AnnotationRule& rule : sAnnotationRules) { std::string::size_type idx = comment.find(rule.doc_str.data()); std::string::size_type idx = comment.find(rule.doc_str.data()); if (idx != std::string::npos) { if (idx != std::string::npos) { annotation_bit_mask_ |= rule.bit_mask; // Captures all parameters associated with the specified annotation rule // by matching the first pair of parantheses after the rule. std::regex re(rule.doc_str.to_string() + "\\s*\\((.+)\\)"); std::smatch match_result; const bool is_match = std::regex_search(comment, match_result, re); // We currently only capture and preserve parameters for SystemApi. if (is_match && rule.bit_mask == AnnotationRule::kSystemApi) { annotation_parameter_map_[rule.bit_mask] = match_result[1].str(); comment.erase(comment.begin() + match_result.position(), comment.begin() + match_result.position() + match_result.length()); } else { annotation_parameter_map_[rule.bit_mask] = ""; comment.erase(comment.begin() + idx, comment.begin() + idx + rule.doc_str.size()); comment.erase(comment.begin() + idx, comment.begin() + idx + rule.doc_str.size()); } } } } } // Check if after removal of annotations the line is empty. // Check if after removal of annotations the line is empty. const StringPiece trimmed = util::TrimWhitespace(comment); const StringPiece trimmed = util::TrimWhitespace(comment); Loading Loading @@ -119,13 +132,19 @@ void AnnotationProcessor::Print(Printer* printer) const { printer->Println(" */"); printer->Println(" */"); } } if (annotation_bit_mask_ & AnnotationRule::kDeprecated) { if (annotation_parameter_map_.find(AnnotationRule::kDeprecated) != annotation_parameter_map_.end()) { printer->Println("@Deprecated"); printer->Println("@Deprecated"); } } for (const AnnotationRule& rule : sAnnotationRules) { for (const AnnotationRule& rule : sAnnotationRules) { if (annotation_bit_mask_ & rule.bit_mask) { const auto& it = annotation_parameter_map_.find(rule.bit_mask); printer->Println(rule.annotation); if (it != annotation_parameter_map_.end()) { printer->Print(rule.annotation); if (!it->second.empty()) { printer->Print("(").Print(it->second).Print(")"); } printer->Print("\n"); } } } } } } Loading
tools/aapt2/java/AnnotationProcessor.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <sstream> #include <sstream> #include <string> #include <string> #include <unordered_map> #include "androidfw/StringPiece.h" #include "androidfw/StringPiece.h" Loading Loading @@ -70,7 +71,7 @@ class AnnotationProcessor { std::stringstream comment_; std::stringstream comment_; std::stringstream mAnnotations; std::stringstream mAnnotations; bool has_comments_ = false; bool has_comments_ = false; uint32_t annotation_bit_mask_ = 0; std::unordered_map<uint32_t, std::string> annotation_parameter_map_; void AppendCommentLine(std::string line); void AppendCommentLine(std::string line); }; }; Loading
tools/aapt2/java/AnnotationProcessor_test.cpp +15 −0 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,21 @@ TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) { EXPECT_THAT(annotations, HasSubstr("This is a system API")); EXPECT_THAT(annotations, HasSubstr("This is a system API")); } } TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationParamsAndRemovesFromComment) { AnnotationProcessor processor; processor.AppendComment("@SystemApi (p1=k1,p2=k2) This is a system API"); std::string annotations; StringOutputStream out(&annotations); Printer printer(&out); processor.Print(&printer); out.Flush(); EXPECT_THAT(annotations, HasSubstr("@android.annotation.SystemApi(p1=k1,p2=k2)")); EXPECT_THAT(annotations, Not(HasSubstr("@SystemApi"))); EXPECT_THAT(annotations, HasSubstr("This is a system API")); } TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) { TEST(AnnotationProcessorTest, EmitsTestApiAnnotationAndRemovesFromComment) { AnnotationProcessor processor; AnnotationProcessor processor; processor.AppendComment("@TestApi This is a test API"); processor.AppendComment("@TestApi This is a test API"); Loading