diff options
author | Jooyung Han <jooyung@google.com> | 2021-01-16 10:24:03 +0900 |
---|---|---|
committer | Jooyung Han <jooyung@google.com> | 2021-01-19 02:08:10 +0000 |
commit | 24effbf65022ebdfd0803a5c1e4b645e907d555e (patch) | |
tree | e259b50ae2d750f3ad2286bed8d752877f4fe48b | |
parent | 6736ffbd592638003f44b4c449982091f93dc5ee (diff) | |
download | aidl-24effbf65022ebdfd0803a5c1e4b645e907d555e.tar.gz |
Parses @hide/@deprecated only in block comments
Comment annotations(or tags) should be in block comments. This is to
prevent ambiguous cases like following.
// /* @hide */
int foo;
Bug: 177616426
Test: aidl_unittests
Change-Id: Iaa6a344f6d206b643db031a007954d8e4797b1d2
-rw-r--r-- | aidl_language.cpp | 6 | ||||
-rw-r--r-- | aidl_unittest.cpp | 22 | ||||
-rw-r--r-- | comments.cpp | 34 | ||||
-rw-r--r-- | comments.h | 2 |
4 files changed, 39 insertions, 25 deletions
diff --git a/aidl_language.cpp b/aidl_language.cpp index e5da1605..a10a19ec 100644 --- a/aidl_language.cpp +++ b/aidl_language.cpp @@ -69,10 +69,6 @@ bool IsJavaKeyword(const char* str) { }; return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end(); } - -inline bool HasHideComment(const std::string& comment) { - return std::regex_search(comment, std::regex("@hide\\b")); -} } // namespace AidlNode::AidlNode(const AidlLocation& location) : location_(location) {} @@ -762,7 +758,7 @@ string AidlArgument::ToString() const { } bool AidlCommentable::IsHidden() const { - return HasHideComment(GetComments()); + return android::aidl::HasHideInComments(GetComments()); } bool AidlCommentable::IsDeprecated() const { diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp index 2ba03994..90e05d85 100644 --- a/aidl_unittest.cpp +++ b/aidl_unittest.cpp @@ -781,11 +781,11 @@ TEST_P(AidlTest, SupportDeprecated) { R"(#[deprecated = "a really long deprecation message which is really long"])"}}, }); - // In AIDL @deprecated can be in any style of comments + // In AIDL @deprecated can be in block comments as well as javadoc style CheckDeprecated( "IFoo.aidl", "interface IFoo {\n" - " // @deprecated use bar()\n" + " /* @deprecated use bar() */\n" " List<String> foo();\n" "}", { @@ -798,6 +798,11 @@ TEST_P(AidlTest, SupportDeprecated) { {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}}, }); + // but not in line comments + auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage()); + EXPECT_FALSE(parsed->IsDeprecated()); + + // parcelable CheckDeprecated("Foo.aidl", "parcelable Foo {\n" " /** @deprecated use bar*/\n" @@ -810,6 +815,7 @@ TEST_P(AidlTest, SupportDeprecated) { {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}}, }); + // interface constants CheckDeprecated("IFoo.aidl", "interface IFoo {\n" " /** @deprecated use bar*/\n" @@ -1418,7 +1424,7 @@ TEST_F(AidlTest, ApiDump) { "foo/bar/IFoo.aidl", "package foo.bar;\n" "import foo.bar.Data;\n" - "// comment @hide\n" + "// commented /* @hide */\n" "interface IFoo {\n" " /* @hide */\n" " int foo(out int[] a, String b, boolean c, inout List<String> d);\n" @@ -1430,7 +1436,7 @@ TEST_F(AidlTest, ApiDump) { " @deprecated\n" " reason why... */\n" " const int A = 1;\n" - " // @deprecated do not use\n" + " // @deprecated tags in line comments are ignored\n" " const String STR = \"Hello\";\n" "}\n"); io_delegate_.SetFileContents("foo/bar/Data.aidl", @@ -1444,7 +1450,7 @@ TEST_F(AidlTest, ApiDump) { " int y;\n" " /*@hide2*/\n" " IFoo foo;\n" - " // It should be @hide property\n" + " // Ignore @hide property in line comment\n" " @nullable String[] c;\n" "}\n"); io_delegate_.SetFileContents("api.aidl", ""); @@ -1456,17 +1462,14 @@ TEST_F(AidlTest, ApiDump) { string actual; EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual)); EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar; -/* @hide */ interface IFoo { /* @hide */ int foo(out int[] a, String b, boolean c, inout List<String> d); int foo2(@utf8InCpp String x, inout List<String> y); foo.bar.IFoo foo3(foo.bar.IFoo foo); foo.bar.Data getData(); - /* @hide */ /* @deprecated reason why... */ const int A = 1; - /* @deprecated do not use */ const String STR = "Hello"; } )")); @@ -1475,12 +1478,9 @@ interface IFoo { EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar; /* @hide */ parcelable Data { - /* @hide */ int x = 10; - /* @hide */ int y; foo.bar.IFoo foo; - /* @hide */ @nullable String[] c; } )")); diff --git a/comments.cpp b/comments.cpp index 5c25c671..1005c417 100644 --- a/comments.cpp +++ b/comments.cpp @@ -19,6 +19,7 @@ #include <android-base/strings.h> #include <optional> +#include <regex> #include <string> #include <vector> @@ -40,6 +41,8 @@ namespace { static const std::string_view kLineCommentBegin = "//"; static const std::string_view kBlockCommentBegin = "/*"; static const std::string_view kBlockCommentEnd = "*/"; +static const std::string kTagDeprecated = "@deprecated"; +static const std::regex kTagHideRegex{"@hide\\b"}; std::string ConsumePrefix(const std::string& s, std::string_view prefix) { AIDL_FATAL_IF(!StartsWith(s, prefix), AIDL_LOCATION_HERE); @@ -56,7 +59,7 @@ struct BlockTag { std::string description; }; -struct Comments { +struct Comment { enum class Type { LINE, BLOCK }; Type type; std::string body; @@ -65,10 +68,10 @@ struct Comments { std::vector<BlockTag> BlockTags() const; }; -// Removes comment markers: //, /*, /**, */, optional leading "*" in doc/block comments +// Removes comment markers: //, /*, */, optional leading "*" in doc/block comments // - keeps leading spaces, but trims trailing spaces // - keeps empty lines -std::vector<std::string> Comments::TrimmedLines() const { +std::vector<std::string> Comment::TrimmedLines() const { if (type == Type::LINE) return std::vector{ConsumePrefix(body, kLineCommentBegin)}; std::string stripped = ConsumeSuffix(ConsumePrefix(body, kBlockCommentBegin), kBlockCommentEnd); @@ -105,7 +108,7 @@ std::vector<std::string> Comments::TrimmedLines() const { return lines; } -std::vector<BlockTag> Comments::BlockTags() const { +std::vector<BlockTag> Comment::BlockTags() const { std::vector<BlockTag> tags; // current tag and paragraph @@ -158,7 +161,7 @@ std::vector<BlockTag> Comments::BlockTags() const { } // TODO(b/177276676) remove this when comments are kept as parsed in AST -Result<std::vector<Comments>> ParseComments(const std::string& comments) { +Result<std::vector<Comment>> ParseComments(const std::string& comments) { enum ParseState { INITIAL, SLASH, @@ -168,7 +171,7 @@ Result<std::vector<Comments>> ParseComments(const std::string& comments) { }; ParseState st = INITIAL; std::string body; - std::vector<Comments> result; + std::vector<Comment> result; for (const auto& c : comments) { switch (st) { case INITIAL: // trim ws & newlines @@ -195,7 +198,7 @@ Result<std::vector<Comments>> ParseComments(const std::string& comments) { case SLASHSLASH: if (c == '\n') { st = INITIAL; - result.push_back({Comments::Type::LINE, std::move(body)}); + result.push_back({Comment::Type::LINE, std::move(body)}); body.clear(); } else { body += c; @@ -211,7 +214,7 @@ Result<std::vector<Comments>> ParseComments(const std::string& comments) { body += c; if (c == '/') { // close! st = INITIAL; - result.push_back({Comments::Type::BLOCK, std::move(body)}); + result.push_back({Comment::Type::BLOCK, std::move(body)}); body.clear(); } else if (c == '*') { // about to close... @@ -228,13 +231,26 @@ Result<std::vector<Comments>> ParseComments(const std::string& comments) { } // namespace +bool HasHideInComments(const std::string& comments) { + auto result = ParseComments(comments); + AIDL_FATAL_IF(!result.ok(), AIDL_LOCATION_HERE) << result.error(); + + for (const auto& c : *result) { + if (c.type == Comment::Type::LINE) continue; + if (std::regex_search(c.body, kTagHideRegex)) { + return true; + } + } + return false; +} + // Finds @deprecated tag and returns it with optional note which follows the tag. std::optional<Deprecated> FindDeprecated(const std::string& comments) { auto result = ParseComments(comments); AIDL_FATAL_IF(!result.ok(), AIDL_LOCATION_HERE) << result.error(); - const std::string kTagDeprecated = "@deprecated"; for (const auto& c : *result) { + if (c.type == Comment::Type::LINE) continue; for (const auto& [name, description] : c.BlockTags()) { // take the first @deprecated if (kTagDeprecated == name) { @@ -21,6 +21,8 @@ namespace android { namespace aidl { +bool HasHideInComments(const std::string& comments); + struct Deprecated { std::string note; // can be empty("") }; |