Loading tools/aapt2/java/AnnotationProcessor.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace aapt { void AnnotationProcessor::appendCommentLine(const std::string& comment) { void AnnotationProcessor::appendCommentLine(std::string& comment) { static const std::string sDeprecated = "@deprecated"; static const std::string sSystemApi = "@SystemApi"; Loading @@ -29,8 +29,14 @@ void AnnotationProcessor::appendCommentLine(const std::string& comment) { mAnnotationBitMask |= kDeprecated; } if (comment.find(sSystemApi) != std::string::npos) { std::string::size_type idx = comment.find(sSystemApi); if (idx != std::string::npos) { mAnnotationBitMask |= kSystemApi; comment.erase(comment.begin() + idx, comment.begin() + idx + sSystemApi.size()); } if (util::trimWhitespace(comment).empty()) { return; } if (!mHasComments) { Loading @@ -46,7 +52,8 @@ void AnnotationProcessor::appendComment(const StringPiece16& comment) { for (StringPiece16 line : util::tokenize(comment, u'\n')) { line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(util::utf16ToUtf8(line)); std::string utf8Line = util::utf16ToUtf8(line); appendCommentLine(utf8Line); } } } Loading @@ -55,7 +62,8 @@ void AnnotationProcessor::appendComment(const StringPiece& comment) { for (StringPiece line : util::tokenize(comment, '\n')) { line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(line.toString()); std::string utf8Line = line.toString(); appendCommentLine(utf8Line); } } } Loading tools/aapt2/java/AnnotationProcessor.h +1 −2 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ namespace aapt { * /\* * * This is meant to be hidden because * * It is system api. Also it is @deprecated * * @SystemApi * *\/ * * Output Annotations: Loading Loading @@ -79,7 +78,7 @@ private: bool mHasComments = false; uint32_t mAnnotationBitMask = 0; void appendCommentLine(const std::string& line); void appendCommentLine(std::string& line); }; } // namespace aapt Loading tools/aapt2/java/AnnotationProcessor_test.cpp +17 −45 Original line number Diff line number Diff line Loading @@ -14,65 +14,37 @@ * limitations under the License. */ #include "ResourceParser.h" #include "ResourceTable.h" #include "ResourceValues.h" #include "java/AnnotationProcessor.h" #include "test/Builders.h" #include "test/Context.h" #include "xml/XmlPullParser.h" #include <gtest/gtest.h> #include "test/Test.h" namespace aapt { struct AnnotationProcessorTest : public ::testing::Test { std::unique_ptr<IAaptContext> mContext; ResourceTable mTable; void SetUp() override { mContext = test::ContextBuilder().build(); } TEST(AnnotationProcessorTest, EmitsDeprecated) { const char* comment = "Some comment, and it should contain a marker word, " "something that marks this resource as nor needed. " "{@deprecated That's the marker! }"; ::testing::AssertionResult parse(const StringPiece& str) { ResourceParserOptions options; ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{}, ConfigDescription{}, options); std::stringstream in; in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str; xml::XmlPullParser xmlParser(in); if (parser.parse(&xmlParser)) { return ::testing::AssertionSuccess(); } return ::testing::AssertionFailure(); } }; TEST_F(AnnotationProcessorTest, EmitsDeprecated) { const char* xmlInput = R"EOF( <resources> <declare-styleable name="foo"> <!-- Some comment, and it should contain a marker word, something that marks this resource as nor needed. {@deprecated That's the marker! } --> <attr name="autoText" format="boolean" /> </declare-styleable> </resources>)EOF"; AnnotationProcessor processor; processor.appendComment(comment); ASSERT_TRUE(parse(xmlInput)); std::stringstream result; processor.writeToStream(&result, ""); std::string annotations = result.str(); Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText"); ASSERT_NE(nullptr, attr); EXPECT_NE(std::string::npos, annotations.find("@Deprecated")); } TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) { AnnotationProcessor processor; processor.appendComment(attr->getComment()); processor.appendComment("@SystemApi This is a system API"); std::stringstream result; processor.writeToStream(&result, ""); std::string annotations = result.str(); EXPECT_NE(std::string::npos, annotations.find("@Deprecated")); EXPECT_NE(std::string::npos, annotations.find("@android.annotation.SystemApi")); EXPECT_EQ(std::string::npos, annotations.find("@SystemApi")); EXPECT_NE(std::string::npos, annotations.find("This is a system API")); } } // namespace aapt Loading tools/aapt2/java/ClassDefinition.h +1 −1 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ public: void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override { ClassMember::writeToStream(prefix, final, out); *out << "public static final int[] " << mName << "={"; *out << prefix << "public static final int[] " << mName << "={"; const auto begin = mElements.begin(); const auto end = mElements.end(); Loading tools/aapt2/java/JavaClassGenerator.cpp +48 −12 Original line number Diff line number Diff line Loading @@ -188,8 +188,8 @@ bool JavaClassGenerator::skipSymbol(SymbolState state) { struct StyleableAttr { const Reference* attrRef; std::shared_ptr<Attribute> attribute; std::string fieldName; std::unique_ptr<SymbolTable::Symbol> symbol; }; static bool lessStyleableAttr(const StyleableAttr& lhs, const StyleableAttr& rhs) { Loading Loading @@ -245,8 +245,9 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package // legal values for this attribute. const SymbolTable::Symbol* symbol = mContext->getExternalSymbols()->findByReference( mangledReference); if (symbol) { styleableAttr.attribute = symbol->attribute; if (symbol && symbol->attribute) { // Copy the symbol data structure because the returned instance can be destroyed. styleableAttr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol); } sortedAttributes.push_back(std::move(styleableAttr)); } Loading @@ -273,6 +274,16 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package "<tr><th>Attribute</th><th>Description</th></tr>\n"; for (const StyleableAttr& entry : sortedAttributes) { if (!entry.symbol) { continue; } if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && !entry.symbol->isPublic) { // Don't write entries for non-public attributes. continue; } const ResourceName& attrName = entry.attrRef->name.value(); styleableComment << "<tr><td>"; styleableComment << "<code>{@link #" Loading @@ -284,14 +295,30 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package styleableComment << "</td>"; styleableComment << "<td>"; if (entry.attribute) { styleableComment << entry.attribute->getComment(); // Only use the comment up until the first '.'. This is to stay compatible with // the way old AAPT did it (presumably to keep it short and to avoid including // annotations like @hide which would affect this Styleable). StringPiece16 attrCommentLine = entry.symbol->attribute->getComment(); auto iter = std::find(attrCommentLine.begin(), attrCommentLine.end(), u'.'); if (iter != attrCommentLine.end()) { attrCommentLine = attrCommentLine.substr( 0, (iter - attrCommentLine.begin()) + 1); } styleableComment << "</td></tr>\n"; styleableComment << attrCommentLine << "</td></tr>\n"; } styleableComment << "</table>\n"; for (const StyleableAttr& entry : sortedAttributes) { if (!entry.symbol) { continue; } if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && !entry.symbol->isPublic) { // Don't write entries for non-public attributes. continue; } styleableComment << "@see #" << entry.fieldName << "\n"; } Loading @@ -310,6 +337,17 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package // Now we emit the indices into the array. for (size_t i = 0; i < attrCount; i++) { const StyleableAttr& styleableAttr = sortedAttributes[i]; if (!styleableAttr.symbol) { continue; } if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && !styleableAttr.symbol->isPublic) { // Don't write entries for non-public attributes. continue; } const ResourceName& attrName = styleableAttr.attrRef->name.value(); StringPiece16 packageName = attrName.package; Loading @@ -323,8 +361,8 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder(); StringPiece16 comment = styleableAttr.attrRef->getComment(); if (styleableAttr.attribute && comment.empty()) { comment = styleableAttr.attribute->getComment(); if (styleableAttr.symbol->attribute && comment.empty()) { comment = styleableAttr.symbol->attribute->getComment(); } if (!comment.empty()) { Loading @@ -342,10 +380,8 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package attrProcessor->appendNewLine(); if (styleableAttr.attribute) { addAttributeFormatDoc(attrProcessor, styleableAttr.attribute.get()); addAttributeFormatDoc(attrProcessor, styleableAttr.symbol->attribute.get()); attrProcessor->appendNewLine(); } std::stringstream doclavaName; doclavaName << "@attr name " << packageName << ":" << attrName.entry;; Loading Loading
tools/aapt2/java/AnnotationProcessor.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ namespace aapt { void AnnotationProcessor::appendCommentLine(const std::string& comment) { void AnnotationProcessor::appendCommentLine(std::string& comment) { static const std::string sDeprecated = "@deprecated"; static const std::string sSystemApi = "@SystemApi"; Loading @@ -29,8 +29,14 @@ void AnnotationProcessor::appendCommentLine(const std::string& comment) { mAnnotationBitMask |= kDeprecated; } if (comment.find(sSystemApi) != std::string::npos) { std::string::size_type idx = comment.find(sSystemApi); if (idx != std::string::npos) { mAnnotationBitMask |= kSystemApi; comment.erase(comment.begin() + idx, comment.begin() + idx + sSystemApi.size()); } if (util::trimWhitespace(comment).empty()) { return; } if (!mHasComments) { Loading @@ -46,7 +52,8 @@ void AnnotationProcessor::appendComment(const StringPiece16& comment) { for (StringPiece16 line : util::tokenize(comment, u'\n')) { line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(util::utf16ToUtf8(line)); std::string utf8Line = util::utf16ToUtf8(line); appendCommentLine(utf8Line); } } } Loading @@ -55,7 +62,8 @@ void AnnotationProcessor::appendComment(const StringPiece& comment) { for (StringPiece line : util::tokenize(comment, '\n')) { line = util::trimWhitespace(line); if (!line.empty()) { appendCommentLine(line.toString()); std::string utf8Line = line.toString(); appendCommentLine(utf8Line); } } } Loading
tools/aapt2/java/AnnotationProcessor.h +1 −2 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ namespace aapt { * /\* * * This is meant to be hidden because * * It is system api. Also it is @deprecated * * @SystemApi * *\/ * * Output Annotations: Loading Loading @@ -79,7 +78,7 @@ private: bool mHasComments = false; uint32_t mAnnotationBitMask = 0; void appendCommentLine(const std::string& line); void appendCommentLine(std::string& line); }; } // namespace aapt Loading
tools/aapt2/java/AnnotationProcessor_test.cpp +17 −45 Original line number Diff line number Diff line Loading @@ -14,65 +14,37 @@ * limitations under the License. */ #include "ResourceParser.h" #include "ResourceTable.h" #include "ResourceValues.h" #include "java/AnnotationProcessor.h" #include "test/Builders.h" #include "test/Context.h" #include "xml/XmlPullParser.h" #include <gtest/gtest.h> #include "test/Test.h" namespace aapt { struct AnnotationProcessorTest : public ::testing::Test { std::unique_ptr<IAaptContext> mContext; ResourceTable mTable; void SetUp() override { mContext = test::ContextBuilder().build(); } TEST(AnnotationProcessorTest, EmitsDeprecated) { const char* comment = "Some comment, and it should contain a marker word, " "something that marks this resource as nor needed. " "{@deprecated That's the marker! }"; ::testing::AssertionResult parse(const StringPiece& str) { ResourceParserOptions options; ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{}, ConfigDescription{}, options); std::stringstream in; in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str; xml::XmlPullParser xmlParser(in); if (parser.parse(&xmlParser)) { return ::testing::AssertionSuccess(); } return ::testing::AssertionFailure(); } }; TEST_F(AnnotationProcessorTest, EmitsDeprecated) { const char* xmlInput = R"EOF( <resources> <declare-styleable name="foo"> <!-- Some comment, and it should contain a marker word, something that marks this resource as nor needed. {@deprecated That's the marker! } --> <attr name="autoText" format="boolean" /> </declare-styleable> </resources>)EOF"; AnnotationProcessor processor; processor.appendComment(comment); ASSERT_TRUE(parse(xmlInput)); std::stringstream result; processor.writeToStream(&result, ""); std::string annotations = result.str(); Attribute* attr = test::getValue<Attribute>(&mTable, u"@attr/autoText"); ASSERT_NE(nullptr, attr); EXPECT_NE(std::string::npos, annotations.find("@Deprecated")); } TEST(AnnotationProcessorTest, EmitsSystemApiAnnotationAndRemovesFromComment) { AnnotationProcessor processor; processor.appendComment(attr->getComment()); processor.appendComment("@SystemApi This is a system API"); std::stringstream result; processor.writeToStream(&result, ""); std::string annotations = result.str(); EXPECT_NE(std::string::npos, annotations.find("@Deprecated")); EXPECT_NE(std::string::npos, annotations.find("@android.annotation.SystemApi")); EXPECT_EQ(std::string::npos, annotations.find("@SystemApi")); EXPECT_NE(std::string::npos, annotations.find("This is a system API")); } } // namespace aapt Loading
tools/aapt2/java/ClassDefinition.h +1 −1 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ public: void writeToStream(const StringPiece& prefix, bool final, std::ostream* out) const override { ClassMember::writeToStream(prefix, final, out); *out << "public static final int[] " << mName << "={"; *out << prefix << "public static final int[] " << mName << "={"; const auto begin = mElements.begin(); const auto end = mElements.end(); Loading
tools/aapt2/java/JavaClassGenerator.cpp +48 −12 Original line number Diff line number Diff line Loading @@ -188,8 +188,8 @@ bool JavaClassGenerator::skipSymbol(SymbolState state) { struct StyleableAttr { const Reference* attrRef; std::shared_ptr<Attribute> attribute; std::string fieldName; std::unique_ptr<SymbolTable::Symbol> symbol; }; static bool lessStyleableAttr(const StyleableAttr& lhs, const StyleableAttr& rhs) { Loading Loading @@ -245,8 +245,9 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package // legal values for this attribute. const SymbolTable::Symbol* symbol = mContext->getExternalSymbols()->findByReference( mangledReference); if (symbol) { styleableAttr.attribute = symbol->attribute; if (symbol && symbol->attribute) { // Copy the symbol data structure because the returned instance can be destroyed. styleableAttr.symbol = util::make_unique<SymbolTable::Symbol>(*symbol); } sortedAttributes.push_back(std::move(styleableAttr)); } Loading @@ -273,6 +274,16 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package "<tr><th>Attribute</th><th>Description</th></tr>\n"; for (const StyleableAttr& entry : sortedAttributes) { if (!entry.symbol) { continue; } if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && !entry.symbol->isPublic) { // Don't write entries for non-public attributes. continue; } const ResourceName& attrName = entry.attrRef->name.value(); styleableComment << "<tr><td>"; styleableComment << "<code>{@link #" Loading @@ -284,14 +295,30 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package styleableComment << "</td>"; styleableComment << "<td>"; if (entry.attribute) { styleableComment << entry.attribute->getComment(); // Only use the comment up until the first '.'. This is to stay compatible with // the way old AAPT did it (presumably to keep it short and to avoid including // annotations like @hide which would affect this Styleable). StringPiece16 attrCommentLine = entry.symbol->attribute->getComment(); auto iter = std::find(attrCommentLine.begin(), attrCommentLine.end(), u'.'); if (iter != attrCommentLine.end()) { attrCommentLine = attrCommentLine.substr( 0, (iter - attrCommentLine.begin()) + 1); } styleableComment << "</td></tr>\n"; styleableComment << attrCommentLine << "</td></tr>\n"; } styleableComment << "</table>\n"; for (const StyleableAttr& entry : sortedAttributes) { if (!entry.symbol) { continue; } if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && !entry.symbol->isPublic) { // Don't write entries for non-public attributes. continue; } styleableComment << "@see #" << entry.fieldName << "\n"; } Loading @@ -310,6 +337,17 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package // Now we emit the indices into the array. for (size_t i = 0; i < attrCount; i++) { const StyleableAttr& styleableAttr = sortedAttributes[i]; if (!styleableAttr.symbol) { continue; } if (mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic && !styleableAttr.symbol->isPublic) { // Don't write entries for non-public attributes. continue; } const ResourceName& attrName = styleableAttr.attrRef->name.value(); StringPiece16 packageName = attrName.package; Loading @@ -323,8 +361,8 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package AnnotationProcessor* attrProcessor = indexMember->getCommentBuilder(); StringPiece16 comment = styleableAttr.attrRef->getComment(); if (styleableAttr.attribute && comment.empty()) { comment = styleableAttr.attribute->getComment(); if (styleableAttr.symbol->attribute && comment.empty()) { comment = styleableAttr.symbol->attribute->getComment(); } if (!comment.empty()) { Loading @@ -342,10 +380,8 @@ void JavaClassGenerator::addMembersToStyleableClass(const StringPiece16& package attrProcessor->appendNewLine(); if (styleableAttr.attribute) { addAttributeFormatDoc(attrProcessor, styleableAttr.attribute.get()); addAttributeFormatDoc(attrProcessor, styleableAttr.symbol->attribute.get()); attrProcessor->appendNewLine(); } std::stringstream doclavaName; doclavaName << "@attr name " << packageName << ":" << attrName.entry;; Loading