aboutsummaryrefslogtreecommitdiff
path: root/comments.cpp
diff options
context:
space:
mode:
authorJooyung Han <jooyung@google.com>2021-01-21 12:30:16 +0900
committerJooyung Han <jooyung@google.com>2021-01-21 19:41:43 +0900
commit161bb0f56b3ac9559c7c87d64b48be329256cf9d (patch)
treeacd0b558fce6d3e8b205f1c885e9da2aaf60bee8 /comments.cpp
parent8451a20b41819e4648d332b61b330fcf3b391a81 (diff)
downloadaidl-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.cpp64
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};