diff --git a/libsolidity/analysis/DocStringTagParser.cpp b/libsolidity/analysis/DocStringTagParser.cpp index b7fef128db8e..8fd34a036f30 100644 --- a/libsolidity/analysis/DocStringTagParser.cpp +++ b/libsolidity/analysis/DocStringTagParser.cpp @@ -312,7 +312,7 @@ void DocStringTagParser::parseDocStrings( if (!_node.documentation()) return; - _annotation.docTags = DocStringParser{*_node.documentation(), m_errorReporter}.parse(); + _annotation.docTags = DocStringParser{*_node.documentation(), m_errorReporter, _validTags}.parse(); for (auto const& [tagName, tagValue]: _annotation.docTags) { diff --git a/libsolidity/parsing/DocStringParser.cpp b/libsolidity/parsing/DocStringParser.cpp index 13e43a9488ed..f29becd9908a 100644 --- a/libsolidity/parsing/DocStringParser.cpp +++ b/libsolidity/parsing/DocStringParser.cpp @@ -103,13 +103,17 @@ std::multimap DocStringParser::parse() currPos = parseDocTagLine(currPos, end, true); else if (currPos != end) { - // if it begins without a tag then consider it as @notice + // if it begins without a tag then consider it as @notice (only if @notice is valid for this node type) if (currPos == m_node.text()->begin()) { - currPos = parseDocTag(currPos, end, "notice"); - continue; + if (m_validTags.empty() || m_validTags.count("notice")) + { + currPos = parseDocTag(currPos, end, "notice"); + continue; + } + // If notice is not valid, fall through to skip this line } - else if (nlPos == end) //end of text + if (nlPos == end) //end of text break; // else skip the line if a newline was found and we get here currPos = nlPos + 1; diff --git a/libsolidity/parsing/DocStringParser.h b/libsolidity/parsing/DocStringParser.h index 22625a160c23..54f2890f8211 100644 --- a/libsolidity/parsing/DocStringParser.h +++ b/libsolidity/parsing/DocStringParser.h @@ -25,6 +25,7 @@ #include #include +#include #include namespace solidity::langutil @@ -41,9 +42,15 @@ class DocStringParser { public: /// @param _documentedNode the node whose documentation is parsed. - DocStringParser(StructuredDocumentation const& _documentedNode, langutil::ErrorReporter& _errorReporter): + /// @param _validTags set of valid tags for this node type (used to determine if implicit @notice should be added). + DocStringParser( + StructuredDocumentation const& _documentedNode, + langutil::ErrorReporter& _errorReporter, + std::set const& _validTags = {} + ): m_node(_documentedNode), - m_errorReporter(_errorReporter) + m_errorReporter(_errorReporter), + m_validTags(_validTags) {} std::multimap parse(); @@ -62,6 +69,7 @@ class DocStringParser StructuredDocumentation const& m_node; langutil::ErrorReporter& m_errorReporter; + std::set m_validTags; /// Mapping tag name -> content. std::multimap m_docTags; DocTag* m_lastTag = nullptr; diff --git a/test/libsolidity/syntaxTests/constants/constant_natspec_user.sol b/test/libsolidity/syntaxTests/constants/constant_natspec_user.sol index feb952860f4b..c5747841a541 100644 --- a/test/libsolidity/syntaxTests/constants/constant_natspec_user.sol +++ b/test/libsolidity/syntaxTests/constants/constant_natspec_user.sol @@ -1,4 +1,3 @@ /// Documentation uint constant x = 8; // ---- -// DocstringParsingError 6546: (0-18): Documentation tag @notice not valid for file-level variables. diff --git a/test/libsolidity/syntaxTests/natspec/file_level_dev_tag_allowed.sol b/test/libsolidity/syntaxTests/natspec/file_level_dev_tag_allowed.sol new file mode 100644 index 000000000000..a881cafc6bbe --- /dev/null +++ b/test/libsolidity/syntaxTests/natspec/file_level_dev_tag_allowed.sol @@ -0,0 +1,5 @@ +/** + * @dev This is a developer note. + */ +uint constant x = 8; +// ---- diff --git a/test/libsolidity/syntaxTests/natspec/file_level_explicit_notice_error.sol b/test/libsolidity/syntaxTests/natspec/file_level_explicit_notice_error.sol new file mode 100644 index 000000000000..51d62d63197f --- /dev/null +++ b/test/libsolidity/syntaxTests/natspec/file_level_explicit_notice_error.sol @@ -0,0 +1,6 @@ +/** + * @notice This should error. + */ +uint constant x = 8; +// ---- +// DocstringParsingError 6546: (0-37): Documentation tag @notice not valid for file-level variables. diff --git a/test/libsolidity/syntaxTests/natspec/file_level_no_error_untagged_doc.sol b/test/libsolidity/syntaxTests/natspec/file_level_no_error_untagged_doc.sol new file mode 100644 index 000000000000..019da839a229 --- /dev/null +++ b/test/libsolidity/syntaxTests/natspec/file_level_no_error_untagged_doc.sol @@ -0,0 +1,5 @@ +/** + * whatever... + */ +uint constant x = 8; +// ---- diff --git a/test/libsolidity/syntaxTests/natspec/file_level_untagged_then_dev.sol b/test/libsolidity/syntaxTests/natspec/file_level_untagged_then_dev.sol new file mode 100644 index 000000000000..b419a4545c05 --- /dev/null +++ b/test/libsolidity/syntaxTests/natspec/file_level_untagged_then_dev.sol @@ -0,0 +1,6 @@ +/** + * Whatever untagged text. + * @dev This should still be parsed. + */ +uint constant x = 8; +// ----