diff --git a/Changelog.md b/Changelog.md index 2ddf6647e..030a0c6f8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Compiler Features: * Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. * Commandline Interface: Respect ``--optimize-yul`` and ``--no-optimize-yul`` in compiler mode and accept them in assembler mode as well. ``--optimize --no-optimize-yul`` combination now allows enabling EVM assembly optimizer without enabling Yul optimizer. * EWasm: Remove EWasm backend. + * NatSpec: Add support for NatSpec documentation in UDVT definitions. * Parser: Introduce ``pragma experimental solidity``, which will enable an experimental language mode that in particular has no stability guarantees between non-breaking releases and is not suited for production use. * SMTChecker: Add ``--model-checker-print-query`` CLI option and ``settings.modelChecker.printQuery`` JSON option to output the SMTChecker queries in the SMTLIB2 format. This requires using `smtlib2` solver only. * Standard JSON Interface: Add ``ast`` file-level output for Yul input. @@ -16,6 +17,7 @@ Compiler Features: * Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation. + Bugfixes: * Commandline Interface: Fix internal error when using ``--stop-after parsing`` and requesting some of the outputs that require full analysis or compilation. * Commandline Interface: It is no longer possible to specify both ``--optimize-yul`` and ``--no-optimize-yul`` at the same time. diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 9d754202d..edd473d00 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -803,7 +803,7 @@ public: * User defined value types, i.e., custom types, for example, `type MyInt is int`. Allows creating a * zero cost abstraction over value type with stricter type requirements. */ -class UserDefinedValueTypeDefinition: public Declaration +class UserDefinedValueTypeDefinition: public Declaration, public StructurallyDocumented { public: UserDefinedValueTypeDefinition( @@ -811,9 +811,11 @@ public: SourceLocation const& _location, ASTPointer _name, SourceLocation _nameLocation, - ASTPointer _underlyingType + ASTPointer _underlyingType, + ASTPointer _documentation ): Declaration(_id, _location, _name, std::move(_nameLocation), Visibility::Default), + StructurallyDocumented(std::move(_documentation)), m_underlyingType(std::move(_underlyingType)) { } diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index da7f76936..f2a6367bb 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -424,7 +424,8 @@ bool ASTJsonExporter::visit(UserDefinedValueTypeDefinition const& _node) std::vector> attributes = { make_pair("name", _node.name()), make_pair("nameLocation", sourceLocationToString(_node.nameLocation())), - make_pair("underlyingType", toJson(*_node.underlyingType())) + make_pair("underlyingType", toJson(*_node.underlyingType())), + make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue) }; addIfSet(attributes, "canonicalName", _node.annotation().canonicalName); diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index dd7098aab..d03e54314 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -486,7 +486,8 @@ ASTPointer ASTJsonImporter::createUserDefinedVal _node, memberAsASTString(_node, "name"), createNameSourceLocation(_node), - convertJsonToASTNode(member(_node, "underlyingType")) + convertJsonToASTNode(member(_node, "underlyingType")), + _node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")) ); } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index efbe85448..c3ca20050 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1101,6 +1101,7 @@ ASTPointer Parser::parseUserDefinedTypeName() ASTPointer Parser::parseUserDefinedValueTypeDefinition() { ASTNodeFactory nodeFactory(*this); + ASTPointer documentation = parseStructuredDocumentation(); expectToken(Token::Type); auto&& [name, nameLocation] = expectIdentifierWithLocation(); expectToken(Token::Is); @@ -1110,7 +1111,8 @@ ASTPointer Parser::parseUserDefinedValueTypeDefi return nodeFactory.createNode( name, std::move(nameLocation), - typeName + typeName, + std::move(documentation) ); } diff --git a/test/libsolidity/ASTJSON/udvt_definition_natspec.json b/test/libsolidity/ASTJSON/udvt_definition_natspec.json new file mode 100644 index 000000000..d3d67bcc3 --- /dev/null +++ b/test/libsolidity/ASTJSON/udvt_definition_natspec.json @@ -0,0 +1,43 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "Price": + [ + 3 + ] + }, + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "Price", + "documentation": + { + "id": 1, + "nodeType": "StructuredDocumentation", + "src": "0:112:1", + "text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev" + }, + "id": 3, + "name": "Price", + "nameLocation": "117:5:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "112:22:1", + "underlyingType": + { + "id": 2, + "name": "uint128", + "nodeType": "ElementaryTypeName", + "src": "126:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint128", + "typeString": "uint128" + } + } + } + ], + "src": "112:23:1" +} diff --git a/test/libsolidity/ASTJSON/udvt_definition_natspec.sol b/test/libsolidity/ASTJSON/udvt_definition_natspec.sol new file mode 100644 index 000000000..2710f12f8 --- /dev/null +++ b/test/libsolidity/ASTJSON/udvt_definition_natspec.sol @@ -0,0 +1,7 @@ +/// @title example of title +/// @author example of author +/// @notice example of notice +/// @dev example of dev +type Price is uint128; + +// ---- diff --git a/test/libsolidity/ASTJSON/udvt_definition_natspec_parseOnly.json b/test/libsolidity/ASTJSON/udvt_definition_natspec_parseOnly.json new file mode 100644 index 000000000..eba4b3758 --- /dev/null +++ b/test/libsolidity/ASTJSON/udvt_definition_natspec_parseOnly.json @@ -0,0 +1,31 @@ +{ + "absolutePath": "a", + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "documentation": + { + "id": 1, + "nodeType": "StructuredDocumentation", + "src": "0:112:1", + "text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev" + }, + "id": 3, + "name": "Price", + "nameLocation": "117:5:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "112:22:1", + "underlyingType": + { + "id": 2, + "name": "uint128", + "nodeType": "ElementaryTypeName", + "src": "126:7:1", + "typeDescriptions": {} + } + } + ], + "src": "112:23:1" +} diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp index a54460eb6..d6876fa0e 100644 --- a/test/libsolidity/SolidityNatspecJSON.cpp +++ b/test/libsolidity/SolidityNatspecJSON.cpp @@ -1479,6 +1479,37 @@ BOOST_AUTO_TEST_CASE(dev_author_at_function) expectNatspecError(sourceCode); } +BOOST_AUTO_TEST_CASE(udvt_definition_no_docs) +{ + char const* sourceCode = R"( + contract C { + /// @title example of title + /// @author example of author + /// @notice example of notice + /// @dev example of dev + type Price is uint128; + } + )"; + + char const* devDoc = R"ABCDEF( + { + "kind": "dev", + "methods": {}, + "version": 1 + })ABCDEF"; + + checkNatspec(sourceCode, "C", devDoc, false); + + char const* userDoc = R"ABCDEF( + { + "kind": "user", + "methods": {}, + "version": 1 + })ABCDEF"; + + checkNatspec(sourceCode, "C", userDoc, true); +} + BOOST_AUTO_TEST_CASE(struct_no_docs) { char const* sourceCode = R"( diff --git a/test/libsolidity/syntaxTests/natspec/docstring_udvt_definition.sol b/test/libsolidity/syntaxTests/natspec/docstring_udvt_definition.sol new file mode 100644 index 000000000..9499101dd --- /dev/null +++ b/test/libsolidity/syntaxTests/natspec/docstring_udvt_definition.sol @@ -0,0 +1,8 @@ +contract C { + /// @title example of title + /// @author example of author + /// @notice example of notice + /// @dev example of dev + type Price is uint128; +} +// ----