diff options
author | Jooyung Han <jooyung@google.com> | 2021-01-21 12:30:16 +0900 |
---|---|---|
committer | Jooyung Han <jooyung@google.com> | 2021-01-21 19:41:43 +0900 |
commit | 161bb0f56b3ac9559c7c87d64b48be329256cf9d (patch) | |
tree | acd0b558fce6d3e8b205f1c885e9da2aaf60bee8 /comments.cpp | |
parent | 8451a20b41819e4648d332b61b330fcf3b391a81 (diff) | |
download | aidl-161bb0f56b3ac9559c7c87d64b48be329256cf9d.tar.gz |
Limit comment tags placement
Documentation comments are recognized only when placed immediately
before entities.
--dumpapi now generates a single block comment when an entity is
hidden/deprecated to comply with the change.
/* @hide
@deprecated */
AIDL entity;
Bug: 177276893
Bug: 177616426
Test: aidl_unittests
Change-Id: I2c00d8e234d1a1ec3fbbcf34f290e0b163d508c0
Diffstat (limited to 'comments.cpp')
-rw-r--r-- | comments.cpp | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/comments.cpp b/comments.cpp index 36f37e8b..4b724b2d 100644 --- a/comments.cpp +++ b/comments.cpp @@ -45,7 +45,8 @@ 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); + AIDL_FATAL_IF(!StartsWith(s, prefix), AIDL_LOCATION_HERE) + << "'" << s << "' has no prefix '" << prefix << "'"; return s.substr(prefix.size()); } @@ -63,7 +64,9 @@ struct BlockTag { // - keeps leading spaces, but trims trailing spaces // - keeps empty lines std::vector<std::string> TrimmedLines(const Comment& c) { - if (c.type == Comment::Type::LINE) return std::vector{ConsumePrefix(c.body, kLineCommentBegin)}; + if (c.type == Comment::Type::LINE) { + return std::vector{ConsumePrefix(c.body, kLineCommentBegin)}; + } std::string stripped = ConsumeSuffix(ConsumePrefix(c.body, kBlockCommentBegin), kBlockCommentEnd); @@ -99,7 +102,10 @@ std::vector<std::string> TrimmedLines(const Comment& c) { return lines; } +// Parses a block comment and returns block tags in the comment. std::vector<BlockTag> BlockTags(const Comment& c) { + AIDL_FATAL_IF(c.type != Comment::Type::BLOCK, AIDL_LOCATION_HERE); + std::vector<BlockTag> tags; // current tag and paragraph @@ -150,23 +156,55 @@ std::vector<BlockTag> BlockTags(const Comment& c) { return tags; } + +} // namespace + +Comment::Comment(const std::string& body) : body(body) { + if (StartsWith(body, kLineCommentBegin)) { + type = Type::LINE; + } else if (StartsWith(body, kBlockCommentBegin) && EndsWith(body, kBlockCommentEnd)) { + type = Type::BLOCK; + } else { + AIDL_FATAL(AIDL_LOCATION_HERE) << "invalid comments body:" << body; + } } -bool HasHideInComments(const Comments& comments) { - for (const auto& c : comments) { - if (c.type == Comment::Type::LINE) continue; - if (std::regex_search(c.body, kTagHideRegex)) { - return true; - } +// Returns the immediate block comment from the list of comments. +// Only the last/block comment can have the tag. +// +// /* @hide */ +// int x; +// +// But tags in line or distant comments don't count. In the following, +// the variable 'x' is not hidden. +// +// // @hide +// int x; +// +// /* @hide */ +// /* this is the immemediate comment to 'x' */ +// int x; +// +static std::optional<Comment> GetValidComment(const Comments& comments) { + if (!comments.empty() && comments.back().type == Comment::Type::BLOCK) { + return comments.back(); } - return false; + return std::nullopt; +} + +// Sees if comments have the @hide tag. +// Example: /** @hide */ +bool HasHideInComments(const Comments& comments) { + const auto valid_comment = GetValidComment(comments); + return valid_comment && std::regex_search(valid_comment->body, kTagHideRegex); } -// Finds @deprecated tag and returns it with optional note which follows the tag. +// Finds the @deprecated tag in comments and returns it with optional note which +// follows the tag. +// Example: /** @deprecated reason */ std::optional<Deprecated> FindDeprecated(const Comments& comments) { - for (const auto& c : comments) { - if (c.type == Comment::Type::LINE) continue; - for (const auto& [name, description] : BlockTags(c)) { + if (const auto valid_comment = GetValidComment(comments); valid_comment) { + for (const auto& [name, description] : BlockTags(comments.back())) { // take the first @deprecated if (kTagDeprecated == name) { return Deprecated{description}; |