diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 33a475214..8fe2c4c1b 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -171,6 +171,7 @@ def print_ids_per_file(ids, id_to_file_names, top_dir): def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): test_sub_dirs = [ + path.join("test", "libsolidity", "natspecJSON"), path.join("test", "libsolidity", "smtCheckerTests"), path.join("test", "libsolidity", "syntaxTests"), path.join("test", "libyul", "yulSyntaxTests") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 119104aca..f8242db7a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -84,6 +84,8 @@ set(libsolidity_sources libsolidity/Metadata.cpp libsolidity/MemoryGuardTest.cpp libsolidity/MemoryGuardTest.h + libsolidity/NatspecJSONTest.cpp + libsolidity/NatspecJSONTest.h libsolidity/SemanticTest.cpp libsolidity/SemanticTest.h libsolidity/SemVerMatcher.cpp @@ -95,7 +97,6 @@ set(libsolidity_sources libsolidity/SolidityExecutionFramework.h libsolidity/SolidityExpressionCompiler.cpp libsolidity/SolidityNameAndTypeResolution.cpp - libsolidity/SolidityNatspecJSON.cpp libsolidity/SolidityOptimizer.cpp libsolidity/SolidityParser.cpp libsolidity/SolidityTypes.cpp diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index 01e47afe0..5021d801b 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ Testsuite const g_interactiveTestsuites[] = { {"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create}, {"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create}, {"JSON ABI", "libsolidity", "ABIJson", false, false, &ABIJsonTest::create}, + {"JSON Natspec", "libsolidity", "natspecJSON", false, false, &NatspecJSONTest::create}, {"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SMTCheckerTest::create}, {"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create}, {"Memory Guard", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create}, diff --git a/test/libsolidity/NatspecJSONTest.cpp b/test/libsolidity/NatspecJSONTest.cpp new file mode 100644 index 000000000..434d5b392 --- /dev/null +++ b/test/libsolidity/NatspecJSONTest.cpp @@ -0,0 +1,210 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . + */ +/** + * Unit tests for the solidity compiler ABI JSON Interface output. + */ + +#include + +#include +#include + +#include + +#include + +#include + +using namespace std; +using namespace solidity::frontend::test; +using namespace solidity::util; + +ostream& solidity::frontend::test::operator<<(ostream& _output, NatspecJSONKind _kind) +{ + switch (_kind) { + case NatspecJSONKind::Devdoc: _output << "devdoc"; break; + case NatspecJSONKind::Userdoc: _output << "userdoc"; break; + } + return _output; +} + +unique_ptr NatspecJSONTest::create(Config const& _config) +{ + return make_unique(_config.filename, _config.evmVersion); +} + +void NatspecJSONTest::parseCustomExpectations(istream& _stream) +{ + soltestAssert(m_expectedNatspecJSON.empty()); + + // We expect a series of expectations in the following format: + // + // // + // // + + string line; + while (getline(_stream, line)) + { + string_view strippedLine = expectLinePrefix(line); + if (strippedLine.empty()) + continue; + + auto [contractName, kind] = parseExpectationHeader(strippedLine); + + string rawJSON = extractExpectationJSON(_stream); + string jsonErrors; + Json::Value parsedJSON; + bool jsonParsingSuccessful = jsonParseStrict(rawJSON, parsedJSON, &jsonErrors); + if (!jsonParsingSuccessful) + BOOST_THROW_EXCEPTION(runtime_error(fmt::format( + "Malformed JSON in {} expectation for contract {}.\n" + "Note that JSON expectations must be pretty-printed to be split correctly. " + "The object is assumed to and at the first unindented closing brace.\n" + "{}", + toString(kind), + contractName, + rawJSON + ))); + + m_expectedNatspecJSON[string(contractName)][kind] = parsedJSON; + } +} + +bool NatspecJSONTest::expectationsMatch() +{ + // NOTE: Comparing pretty printed Json::Values to avoid using its operator==, which fails to + // compare equal numbers as equal. For example, for 'version' field the value is sometimes int, + // sometimes uint and they compare as different even when both are 1. + return + SyntaxTest::expectationsMatch() && + prettyPrinted(obtainedNatspec()) == prettyPrinted(m_expectedNatspecJSON); +} + +void NatspecJSONTest::printExpectedResult(ostream& _stream, string const& _linePrefix, bool _formatted) const +{ + SyntaxTest::printExpectedResult(_stream, _linePrefix, _formatted); + if (!m_expectedNatspecJSON.empty()) + { + _stream << _linePrefix << "----" << endl; + printIndented(_stream, formatNatspecExpectations(m_expectedNatspecJSON), _linePrefix); + } +} + +void NatspecJSONTest::printObtainedResult(ostream& _stream, string const& _linePrefix, bool _formatted) const +{ + SyntaxTest::printObtainedResult(_stream, _linePrefix, _formatted); + + NatspecMap natspecJSON = obtainedNatspec(); + if (!natspecJSON.empty()) + { + _stream << _linePrefix << "----" << endl; + // TODO: Diff both versions and highlight differences. + // We should have a helper for doing that in newly defined test cases without much effort. + printIndented(_stream, formatNatspecExpectations(natspecJSON), _linePrefix); + } +} + +tuple NatspecJSONTest::parseExpectationHeader(string_view _line) +{ + for (NatspecJSONKind kind: {NatspecJSONKind::Devdoc, NatspecJSONKind::Userdoc}) + { + string kindSuffix = " " + toString(kind); + if (boost::algorithm::ends_with(_line, kindSuffix)) + return {_line.substr(0, _line.size() - kindSuffix.size()), kind}; + } + + BOOST_THROW_EXCEPTION(runtime_error( + "Natspec kind (devdoc/userdoc) not present in the expectation: "s.append(_line) + )); +} + +string NatspecJSONTest::extractExpectationJSON(istream& _stream) +{ + string rawJSON; + string line; + while (getline(_stream, line)) + { + string_view strippedLine = expectLinePrefix(line); + rawJSON += strippedLine; + rawJSON += "\n"; + + if (boost::algorithm::starts_with(strippedLine, "}")) + break; + } + + return rawJSON; +} + +string_view NatspecJSONTest::expectLinePrefix(string_view _line) +{ + size_t startPosition = 0; + if (!boost::algorithm::starts_with(_line, "//")) + BOOST_THROW_EXCEPTION(runtime_error( + "Expectation line is not a comment: "s.append(_line) + )); + + startPosition += 2; + if (startPosition < _line.size() && _line[startPosition] == ' ') + ++startPosition; + + return _line.substr(startPosition, _line.size() - startPosition); +} + +string NatspecJSONTest::formatNatspecExpectations(NatspecMap const& _expectations) const +{ + string output; + bool first = true; + // NOTE: Not sorting explicitly because CompilerStack seems to put contracts roughly in the + // order in which they appear in the source, which is much better than alphabetical order. + for (auto const& [contractName, expectationsForAllKinds]: _expectations) + for (auto const& [jsonKind, natspecJSON]: expectationsForAllKinds) + { + if (!first) + output += "\n\n"; + first = false; + + output += contractName + " " + toString(jsonKind) + "\n"; + output += jsonPrint(natspecJSON, {JsonFormat::Pretty, 4}); + } + + return output; +} + +NatspecMap NatspecJSONTest::obtainedNatspec() const +{ + if (compiler().state() < CompilerStack::AnalysisSuccessful) + return {}; + + NatspecMap result; + for (string contractName: compiler().contractNames()) + { + result[contractName][NatspecJSONKind::Devdoc] = compiler().natspecDev(contractName); + result[contractName][NatspecJSONKind::Userdoc] = compiler().natspecUser(contractName); + } + + return result; +} + +SerializedNatspecMap NatspecJSONTest::prettyPrinted(NatspecMap const& _expectations) const +{ + SerializedNatspecMap result; + for (auto const& [contractName, expectationsForAllKinds]: _expectations) + for (auto const& [jsonKind, natspecJSON]: expectationsForAllKinds) + result[contractName][jsonKind] = jsonPrint(natspecJSON, {JsonFormat::Pretty, 4}); + + return result; +} diff --git a/test/libsolidity/NatspecJSONTest.h b/test/libsolidity/NatspecJSONTest.h new file mode 100644 index 000000000..762b88d10 --- /dev/null +++ b/test/libsolidity/NatspecJSONTest.h @@ -0,0 +1,82 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Unit tests for the Natspec userdoc and devdoc JSON output. + */ + +#pragma once + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace solidity::frontend::test +{ + +enum class NatspecJSONKind +{ + Devdoc, + Userdoc, +}; + +std::ostream& operator<<(std::ostream& _output, NatspecJSONKind _kind); + +using NatspecMap = std::map>; +using SerializedNatspecMap = std::map>; + +class NatspecJSONTest: public SyntaxTest +{ +public: + + static std::unique_ptr create(Config const& _config); + + NatspecJSONTest(std::string const& _filename, langutil::EVMVersion _evmVersion): + SyntaxTest( + _filename, + _evmVersion, + langutil::Error::Severity::Error // _minSeverity + ) + {} + +protected: + void parseCustomExpectations(std::istream& _stream) override; + bool expectationsMatch() override; + void printExpectedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const override; + void printObtainedResult(std::ostream& _stream, std::string const& _linePrefix, bool _formatted) const override; + + NatspecMap m_expectedNatspecJSON; + +private: + static std::tuple parseExpectationHeader(std::string_view _line); + static std::string extractExpectationJSON(std::istream& _stream); + static std::string_view expectLinePrefix(std::string_view _line); + + std::string formatNatspecExpectations(NatspecMap const& _expectations) const; + SerializedNatspecMap prettyPrinted(NatspecMap const& _expectations) const; + NatspecMap obtainedNatspec() const; +}; + +} diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp deleted file mode 100644 index 9ecd35aef..000000000 --- a/test/libsolidity/SolidityNatspecJSON.cpp +++ /dev/null @@ -1,3391 +0,0 @@ -/* - This file is part of solidity. - - solidity is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - solidity is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with solidity. If not, see . - */ -/** - * @author Lefteris Karapetsas - * @date 2014 - * Unit tests for the solidity compiler JSON Interface output. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace solidity::langutil; - -namespace solidity::frontend::test -{ - -class DocumentationChecker -{ -public: - void checkNatspec( - std::string const& _code, - std::string const& _contractName, - std::string const& _expectedDocumentationString, - bool _userDocumentation - ) - { - m_compilerStack.reset(); - m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}}); - m_compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); - BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed"); - - Json::Value generatedDocumentation; - if (_userDocumentation) - generatedDocumentation = m_compilerStack.natspecUser(_contractName); - else - generatedDocumentation = m_compilerStack.natspecDev(_contractName); - Json::Value expectedDocumentation; - std::string parseError; - BOOST_REQUIRE_MESSAGE(util::jsonParseStrict(_expectedDocumentationString, expectedDocumentation, &parseError), parseError); - - expectedDocumentation["version"] = Json::Value(Natspec::c_natspecVersion); - expectedDocumentation["kind"] = Json::Value(_userDocumentation ? "user" : "dev"); - - BOOST_CHECK_MESSAGE( - expectedDocumentation == generatedDocumentation, - "Expected:\n" << util::jsonPrettyPrint(expectedDocumentation) << - "\n but got:\n" << util::jsonPrettyPrint(generatedDocumentation) - ); - } - - void expectNatspecError(std::string const& _code) - { - m_compilerStack.reset(); - m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}}); - m_compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); - BOOST_CHECK(!m_compilerStack.parseAndAnalyze()); - BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError)); - } - -protected: - CompilerStack m_compilerStack; -}; - -BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker) - -BOOST_AUTO_TEST_CASE(user_empty_natspec_test) -{ - char const* sourceCode = R"( - contract test { - /// - /// - function f() public { - } - } - )"; - - char const* natspec = R"( - { - "methods": {} - } - )"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(user_newline_break) -{ - char const* sourceCode = R"( - contract test { - /// - /// @notice hello - - /// @notice world - function f() public { - } - } - )"; - - char const* natspec = R"ABCDEF( - { - "methods": - { - "f()": - { - "notice": "world" - } - } - } - )ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(user_multiline_empty_lines) -{ - char const* sourceCode = R"( - contract test { - /** - * - * - * @notice hello world - */ - function f() public { - } - } - )"; - - char const* natspec = R"ABCDEF( - { - "methods": - { - "f()": - { - "notice": "hello world" - } - } - } - )ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - - -BOOST_AUTO_TEST_CASE(user_basic_test) -{ - char const* sourceCode = R"( - contract test { - /// @notice Multiplies `a` by 7 - function mul(uint a) public returns(uint d) { return a * 7; } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256)\":{ \"notice\": \"Multiplies `a` by 7\"}" - "}}"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_and_user_basic_test) -{ - char const* sourceCode = R"( - contract test { - /// @notice Multiplies `a` by 7 - /// @dev Multiplies a number by 7 - function mul(uint a) public returns (uint d) { return a * 7; } - } - )"; - - char const* devNatspec = R"R( - { - "methods": - { - "mul(uint256)": - { - "details": "Multiplies a number by 7" - } - } - })R"; - - char const* userNatspec = R"R( - { - "methods": - { - "mul(uint256)": - { - "notice": "Multiplies `a` by 7" - } - } - })R"; - - checkNatspec(sourceCode, "test", devNatspec, false); - checkNatspec(sourceCode, "test", userNatspec, true); -} - -BOOST_AUTO_TEST_CASE(user_multiline_comment) -{ - char const* sourceCode = R"( - contract test { - /// @notice Multiplies `a` by 7 - /// and then adds `b` - function mul_and_add(uint a, uint256 b) public returns (uint256 d) { - return (a * 7) + b; - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul_and_add(uint256,uint256)\":{ \"notice\": \"Multiplies `a` by 7 and then adds `b`\"}" - "}}"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(user_multiple_functions) -{ - char const* sourceCode = R"( - contract test { - /// @notice Multiplies `a` by 7 and then adds `b` - function mul_and_add(uint a, uint256 b) public returns (uint256 d) { - return (a * 7) + b; - } - - /// @notice Divides `input` by `div` - function divide(uint input, uint div) public returns (uint d) { - return input / div; - } - - /// @notice Subtracts 3 from `input` - function sub(int input) public returns (int d) { - return input - 3; - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul_and_add(uint256,uint256)\":{ \"notice\": \"Multiplies `a` by 7 and then adds `b`\"}," - " \"divide(uint256,uint256)\":{ \"notice\": \"Divides `input` by `div`\"}," - " \"sub(int256)\":{ \"notice\": \"Subtracts 3 from `input`\"}" - "}}"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(user_empty_contract) -{ - char const* sourceCode = R"( - contract test { } - )"; - - char const* natspec = "{\"methods\":{} }"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_and_user_no_doc) -{ - char const* sourceCode = R"( - contract test { - function mul(uint a) public returns (uint d) { - return a * 7; - } - function sub(int input) public returns (int d) { - return input - 3; - } - } - )"; - - char const* devNatspec = "{\"methods\":{}}"; - char const* userNatspec = "{\"methods\":{}}"; - - checkNatspec(sourceCode, "test", devNatspec, false); - checkNatspec(sourceCode, "test", userNatspec, true); -} - -BOOST_AUTO_TEST_CASE(public_state_variable) -{ - char const* sourceCode = R"( - contract test { - /// @notice example of notice - /// @dev example of dev - /// @return returns state - uint public state; - } - )"; - - char const* devDoc = R"R( - { - "methods": {}, - "stateVariables": - { - "state": - { - "details": "example of dev", - "return": "returns state", - "returns": - { - "_0": "returns state" - } - } - } - } - )R"; - checkNatspec(sourceCode, "test", devDoc, false); - - char const* userDoc = R"R( - { - "methods": - { - "state()": - { - "notice": "example of notice" - } - } - } - )R"; - checkNatspec(sourceCode, "test", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(public_state_variable_struct) -{ - char const* sourceCode = R"( - contract Bank { - struct Coin { - string observeGraphicURL; - string reverseGraphicURL; - } - - /// @notice Get the n-th coin I own - /// @return observeGraphicURL Front pic - /// @return reverseGraphicURL Back pic - Coin[] public coinStack; - } - )"; - - char const* devDoc = R"R( - { - "methods": {}, - "stateVariables": - { - "coinStack": - { - "returns": - { - "observeGraphicURL": "Front pic", - "reverseGraphicURL": "Back pic" - } - } - } - } - )R"; - checkNatspec(sourceCode, "Bank", devDoc, false); - - char const* userDoc = R"R( - { - "methods": - { - "coinStack(uint256)": - { - "notice": "Get the n-th coin I own" - } - } - } - )R"; - checkNatspec(sourceCode, "Bank", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(public_state_variable_struct_repeated) -{ - char const* sourceCode = R"( - contract Bank { - struct Coin { - string obverseGraphicURL; - string reverseGraphicURL; - } - - /// @notice Get the n-th coin I own - /// @return obverseGraphicURL Front pic - /// @return obverseGraphicURL Front pic - Coin[] public coinStack; - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(private_state_variable) -{ - char const* sourceCode = R"( - contract test { - /// @dev example of dev - uint private state; - } - )"; - - char const* devDoc = R"( - { - "methods": {}, - "stateVariables": - { - "state": - { - "details": "example of dev" - } - } - } - )"; - checkNatspec(sourceCode, "test", devDoc, false); - - char const* userDoc = R"( - { - "methods":{} - } - )"; - checkNatspec(sourceCode, "test", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(event) -{ - char const* sourceCode = R"( - contract ERC20 { - /// @notice This event is emitted when a transfer occurs. - /// @param from The source account. - /// @param to The destination account. - /// @param amount The amount. - /// @dev A test case! - event Transfer(address indexed from, address indexed to, uint amount); - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "Transfer(address,address,uint256)": - { - "details": "A test case!", - "params": - { - "amount": "The amount.", "from": "The source account.", "to": "The destination account." - } - } - }, - "methods": {} - } - )ABCDEF"; - checkNatspec(sourceCode, "ERC20", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "Transfer(address,address,uint256)": - { - "notice": "This event is emitted when a transfer occurs." - } - }, - "methods": {} - } - )ABCDEF"; - checkNatspec(sourceCode, "ERC20", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_event_from_foreign_contract) -{ - char const* sourceCode = R"( - contract X { - /// @notice Userdoc for event E. - /// @dev Devdoc for event E. - event E(); - } - - contract C { - function g() public { - emit X.E(); - } - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "E()": - { - "details": "Devdoc for event E." - } - }, - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "E()": - { - "notice": "Userdoc for event E." - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_event_from_foreign_contract_with_same_signature) -{ - char const* sourceCode = R"( - contract C { - /// @notice C.E event - /// @dev C.E event - event E(uint256 value); - } - - contract D { - /// @notice D.E event - /// @dev D.E event - event E(uint256 value); - - function test() public { - emit C.E(1); - emit E(2); - } - } - )"; - - char const* devDocC = R"ABCDEF( - { - "events": - { - "E(uint256)": - { - "details": "C.E event" - } - }, - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", devDocC, false); - - char const* devDocD = R"ABCDEF( - { - "events": - { - "E(uint256)": - { - "details": "D.E event" - } - }, - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "D", devDocD, false); - - char const* userDocC = R"ABCDEF( - { - "events": - { - "E(uint256)": - { - "notice": "C.E event" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", userDocC, true); - - char const* userDocD = R"ABCDEF( - { - "events": - { - "E(uint256)": - { - "notice": "D.E event" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "D", userDocD, true); -} - -// Tests that emitting an event from contract C in contract D does not inherit natspec from C.E -BOOST_AUTO_TEST_CASE(emit_event_from_foreign_contract_no_inheritance) -{ - char const* sourceCode = R"( - contract C { - /// @notice C.E event - /// @dev C.E event - event E(); - } - - contract D { - event E(); - - function test() public { - emit C.E(); - } - } - )"; - - char const* devDoc = R"ABCDEF( - { - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "D", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "D", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_same_signature_event_library_contract) -{ - char const* sourceCode = R"( - library L { - /// @notice This event is defined in Library L - /// @dev This should not appear in Contract C dev doc - event SameSignatureEvent(uint16); - /// @notice This event is defined in Library L - /// @dev This should appear in Contract C dev doc - event LibraryEvent(uint32); - } - contract C { - /// @notice This event is defined in Contract C - /// @dev This should appear in Contract C dev doc - event SameSignatureEvent(uint16); - /// @notice This event is defined in Contract C - /// @dev This should appear in contract C dev doc - event ContractEvent(uint32); - function f() public { - emit L.SameSignatureEvent(0); - emit SameSignatureEvent(1); - emit L.LibraryEvent(2); - emit ContractEvent(3); - } - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "ContractEvent(uint32)": - { - "details": "This should appear in contract C dev doc" - }, - "LibraryEvent(uint32)": - { - "details": "This should appear in Contract C dev doc" - }, - "SameSignatureEvent(uint16)": - { - "details": "This should appear in Contract C dev doc" - } - }, - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "ContractEvent(uint32)": - { - "notice": "This event is defined in Contract C" - }, - "LibraryEvent(uint32)": - { - "notice": "This event is defined in Library L" - }, - "SameSignatureEvent(uint16)": - { - "notice": "This event is defined in Contract C" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_same_signature_event_different_libraries) -{ - char const* sourceCode = R"( - library L1 { - /// @notice This event is defined in Library L1 - /// @dev This should not appear in Contract C dev doc - event SameSignatureEvent(uint16); - } - library L2 { - /// @notice This event is defined in Library L2 - /// @dev This should not appear in Contract C dev doc - event SameSignatureEvent(uint16); - } - library L3 { - /// @notice This event is defined in Library L3 - /// @dev This should not appear in Contract C dev doc - event SameSignatureEvent(uint16); - } - contract C { - function f() public { - emit L1.SameSignatureEvent(0); - emit L2.SameSignatureEvent(1); - emit L3.SameSignatureEvent(2); - } - } - )"; - - 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); - - char const* libraryDevDoc = R"ABCDEF( - { - "events": - { - "SameSignatureEvent(uint16)": - { - "details": "This should not appear in Contract C dev doc" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "L1", libraryDevDoc, false); - - char const* libraryUserDoc = R"ABCDEF( - { - "events": - { - "SameSignatureEvent(uint16)": - { - "notice": "This event is defined in Library L1" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "L1", libraryUserDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_same_signature_event_library_inherited) -{ - char const* sourceCode = R"( - contract D { - /// @notice This event is defined in contract D - /// @dev This should appear in Contract C dev doc - event SameSignatureEvent(uint16); - } - library L { - /// @notice This event is defined in Library L - /// @dev This should not appear in Contract C - event SameSignatureEvent(uint16); - } - contract C is D { - function f() public { - emit L.SameSignatureEvent(0); - emit D.SameSignatureEvent(1); - } - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "SameSignatureEvent(uint16)": - { - "details": "This should appear in Contract C dev doc" - } - }, - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "SameSignatureEvent(uint16)": - { - "notice": "This event is defined in contract D" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_same_signature_event_library_contract_missing_natspec) -{ - char const* sourceCode = R"( - library L { - /// @notice This event is defined in library L - /// @dev This should not appear in contract C devdoc - event SameSignatureEvent(uint16); - /// @notice This event is defined in library L - /// @dev This should appear in contract C devdoc - event LibraryEvent(uint32); - } - contract C { - event SameSignatureEvent(uint16); - /// @notice This event is defined in contract C - event ContractEvent(uint32); - function f() public { - emit L.SameSignatureEvent(0); - emit SameSignatureEvent(1); - emit L.LibraryEvent(2); - emit ContractEvent(3); - } - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "LibraryEvent(uint32)": - { - "details": "This should appear in contract C devdoc" - } - }, - "kind": "dev", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "ContractEvent(uint32)": - { - "notice": "This event is defined in contract C" - }, - "LibraryEvent(uint32)": - { - "notice": "This event is defined in library L" - } - }, - "kind": "user", - "methods": {}, - "version": 1 - } - )ABCDEF"; - checkNatspec(sourceCode, "C", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(emit_same_signature_event_different_libraries_missing_natspec) -{ - char const* sourceCode = R"( - library L1 { - event SameSignatureEvent(uint16); - } - library L2 { - /// @notice This event is defined in library L2 - /// @dev This should not appear in Contract C devdoc - event SameSignatureEvent(uint16); - } - library L3 { - event SameSignatureEvent(uint16); - } - contract C { - function f() public { - emit L1.SameSignatureEvent(0); - emit L2.SameSignatureEvent(1); - emit L3.SameSignatureEvent(2); - } - } - )"; - - 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(emit_same_signature_event_library_inherited_missing_natspec) -{ - char const* sourceCode = R"( - contract D { - event SameSignatureEvent(uint16); - } - library L { - /// @notice This event is defined in library L - /// @dev This should not appear in contract C devdoc - event SameSignatureEvent(uint16); - } - contract C is D { - function f() public { - emit L.SameSignatureEvent(0); - emit D.SameSignatureEvent(1); - } - } - )"; - - 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(event_inheritance_interface) -{ - char const* sourceCode = R"( - interface ERC20 { - /// @notice This event is emitted when a transfer occurs. - /// @param from The source account. - /// @param to The destination account. - /// @param amount The amount. - /// @dev A test case! - event Transfer(address indexed from, address indexed to, uint amount); - } - contract A is ERC20 { - } - contract B is A { - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "Transfer(address,address,uint256)": - { - "details": "A test case!", - "params": - { - "amount": "The amount.", - "from": "The source account.", - "to": "The destination account." - } - } - }, - "methods": {} - } - )ABCDEF"; - checkNatspec(sourceCode, "ERC20", devDoc, false); - checkNatspec(sourceCode, "A", devDoc, false); - checkNatspec(sourceCode, "B", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "Transfer(address,address,uint256)": - { - "notice": "This event is emitted when a transfer occurs." - } - }, - "methods": {} - } - )ABCDEF"; - checkNatspec(sourceCode, "ERC20", userDoc, true); - checkNatspec(sourceCode, "A", userDoc, true); - checkNatspec(sourceCode, "B", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(event_inheritance) -{ - char const* sourceCode = R"( - contract ERC20 { - /// @notice This event is emitted when a transfer occurs. - /// @param from The source account. - /// @param to The destination account. - /// @param amount The amount. - /// @dev A test case! - event Transfer(address indexed from, address indexed to, uint amount); - } - contract A is ERC20 { - } - contract B is A { - } - )"; - - char const* devDoc = R"ABCDEF( - { - "events": - { - "Transfer(address,address,uint256)": - { - "details": "A test case!", - "params": - { - "amount": "The amount.", - "from": "The source account.", - "to": "The destination account." - } - } - }, - "methods": {} - } - )ABCDEF"; - checkNatspec(sourceCode, "ERC20", devDoc, false); - checkNatspec(sourceCode, "A", devDoc, false); - checkNatspec(sourceCode, "B", devDoc, false); - - char const* userDoc = R"ABCDEF( - { - "events": - { - "Transfer(address,address,uint256)": - { - "notice": "This event is emitted when a transfer occurs." - } - }, - "methods": {} - } - )ABCDEF"; - checkNatspec(sourceCode, "ERC20", userDoc, true); - checkNatspec(sourceCode, "A", userDoc, true); - checkNatspec(sourceCode, "B", userDoc, true); -} - -BOOST_AUTO_TEST_CASE(dev_desc_after_nl) -{ - char const* sourceCode = R"( - contract test { - /// @dev - /// Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param second Documentation for the second parameter - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_multiple_params) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param second Documentation for the second parameter - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_multiple_params_mixed_whitespace) -{ - char const* sourceCode = "contract test {\n" - " /// @dev Multiplies a number by 7 and adds second parameter\n" - " /// @param a Documentation for the first parameter\n" - " /// @param second Documentation for the second parameter\n" - " function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; }\n" - "}\n"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_mutiline_param_description) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_multiple_functions) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param second Documentation for the second parameter - function mul(uint a, uint second) public returns (uint d) { - return a * 7 + second; - } - /// @dev Divides 2 numbers - /// @param input Documentation for the input parameter - /// @param div Documentation for the div parameter - function divide(uint input, uint div) public returns (uint d) { - return input / div; - } - /// @dev Subtracts 3 from `input` - /// @param input Documentation for the input parameter - function sub(int input) public returns (int d) { - return input - 3; - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " }\n" - " },\n" - " \"divide(uint256,uint256)\":{ \n" - " \"details\": \"Divides 2 numbers\",\n" - " \"params\": {\n" - " \"input\": \"Documentation for the input parameter\",\n" - " \"div\": \"Documentation for the div parameter\"\n" - " }\n" - " },\n" - " \"sub(int256)\":{ \n" - " \"details\": \"Subtracts 3 from `input`\",\n" - " \"params\": {\n" - " \"input\": \"Documentation for the input parameter\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_no_params) -{ - char const* sourceCode = R"( - contract test { - /// @return d The result of the multiplication - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = R"ABCDEF( - { - "methods": - { - "mul(uint256,uint256)": - { - "returns": { "d": "The result of the multiplication" } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return d The result of the multiplication - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " },\n" - " \"returns\": {\n" - " \"d\": \"The result of the multiplication\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return - /// d The result of the multiplication - function mul(uint a, uint second) public returns (uint d) { - return a * 7 + second; - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " },\n" - " \"returns\": {\n" - " \"d\": \"The result of the multiplication\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_desc_multiple_unamed_mixed) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return The result of the multiplication - /// @return _cookies And cookies with nutella - function mul(uint a, uint second) public returns (uint, uint _cookies) { - uint mul = a * 7; - return (mul, second); - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " },\n" - " \"returns\": {\n" - " \"_0\": \"The result of the multiplication\",\n" - " \"_cookies\": \"And cookies with nutella\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_desc_multiple_unamed_mixed_2) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return _cookies And cookies with nutella - /// @return The result of the multiplication - /// @return _milk And milk with nutella - function mul(uint a, uint second) public returns (uint _cookies, uint, uint _milk) { - uint mul = a * 7; - uint milk = 4; - return (mul, second, milk); - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " },\n" - " \"returns\": {\n" - " \"_cookies\": \"And cookies with nutella\",\n" - " \"_1\": \"The result of the multiplication\",\n" - " \"_milk\": \"And milk with nutella\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_desc_multiple_unamed) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return The result of the multiplication - /// @return And cookies with nutella - function mul(uint a, uint second) public returns (uint, uint) { - uint mul = a * 7; - return (mul, second); - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " },\n" - " \"returns\": {\n" - " \"_0\": \"The result of the multiplication\",\n" - " \"_1\": \"And cookies with nutella\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_desc_multiple) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return d The result of the multiplication - /// @return f And cookies with nutella - function mul(uint a, uint second) public returns (uint d, uint f) { - uint mul = a * 7; - return (mul, second); - } - } - )"; - - char const* natspec = "{" - "\"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" - " \"params\": {\n" - " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" - " \"second\": \"Documentation for the second parameter\"\n" - " },\n" - " \"returns\": {\n" - " \"d\": \"The result of the multiplication\",\n" - " \"f\": \"And cookies with nutella\"\n" - " }\n" - " }\n" - "}}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_multiline_return) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return d The result of the multiplication - /// and cookies with nutella - function mul(uint a, uint second) public returns (uint d) { - return a * 7 + second; - } - } - )"; - - char const* natspec = R"R({ - "methods": - { - "mul(uint256,uint256)": - { - "details": "Multiplies a number by 7 and adds second parameter", - "params": - { - "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", - "second": "Documentation for the second parameter" - }, - "returns": - { - "d": "The result of the multiplication and cookies with nutella" - } - } - } - })R"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_multiline_comment) -{ - char const* sourceCode = R"( - contract test { - /** - * @dev Multiplies a number by 7 and adds second parameter - * @param a Documentation for the first parameter starts here. - * Since it's a really complicated parameter we need 2 lines - * @param second Documentation for the second parameter - * @return d The result of the multiplication - * and cookies with nutella - */ - function mul(uint a, uint second) public returns (uint d) { - return a * 7 + second; - } - } - )"; - - char const* natspec = R"R( - { - "methods": - { - "mul(uint256,uint256)": - { - "details": "Multiplies a number by 7 and adds second parameter", - "params": - { - "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", - "second": "Documentation for the second parameter" - }, - "returns": - { - "d": "The result of the multiplication and cookies with nutella" - } - } - } - })R"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_documenting_no_return_paramname) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param second Documentation for the second parameter - /// @return - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(dev_contract_no_doc) -{ - char const* sourceCode = R"( - contract test { - /// @dev Mul function - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = "{" - " \"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Mul function\"\n" - " }\n" - " }\n" - "}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_contract_doc) -{ - char const* sourceCode = R"( - /// @author Lefteris - /// @title Just a test contract - contract test { - /// @dev Mul function - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = "{" - " \"author\": \"Lefteris\"," - " \"title\": \"Just a test contract\"," - " \"methods\":{" - " \"mul(uint256,uint256)\":{ \n" - " \"details\": \"Mul function\"\n" - " }\n" - " }\n" - "}"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_author_at_function) -{ - char const* sourceCode = R"( - /// @author Lefteris - /// @title Just a test contract - contract test { - /// @dev Mul function - /// @author John Doe - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(struct_no_docs) -{ - char const* sourceCode = R"( - contract C { - /// @title example of title - /// @author example of author - /// @notice example of notice - /// @dev example of dev - struct Example { - string text; - bool valid; - uint256 value; - } - } - )"; - - 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(enum_no_docs) -{ - char const* sourceCode = R"( - contract C { - /// @title example of title - /// @author example of author - /// @notice example of notice - /// @dev example of dev - enum Color { - Red, - Green - } - } - )"; - - 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(natspec_notice_without_tag) -{ - char const* sourceCode = R"( - contract test { - /// I do something awesome - function mul(uint a) public returns (uint d) { return a * 7; } - } - )"; - - - char const* natspec = R"ABCDEF( - { - "methods": - { - "mul(uint256)": - { - "notice": "I do something awesome" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(natspec_multiline_notice_without_tag) -{ - char const* sourceCode = R"( - contract test { - /// I do something awesome - /// which requires two lines to explain - function mul(uint a) public returns (uint d) { return a * 7; } - } - )"; - - char const* natspec = R"ABCDEF( - { - "methods": - { - "mul(uint256)": - { - "notice": "I do something awesome which requires two lines to explain" - } - } - } - )ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(empty_comment) -{ - char const* sourceCode = R"( - // - contract test - {} - )"; - char const* natspec = R"ABCDEF( - { - "methods": {} - } - )ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_title_at_function_error) -{ - char const* sourceCode = R"( - /// @author Lefteris - /// @title Just a test contract - contract test { - /// @dev Mul function - /// @title I really should not be here - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(dev_documenting_nonexistent_param) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param not_existing Documentation for the second parameter - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(dev_documenting_no_paramname) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(dev_documenting_no_paramname_end) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param se - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(dev_documenting_no_param_description) -{ - char const* sourceCode = R"( - contract test { - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter - /// @param second - function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(user_constructor) -{ - char const* sourceCode = R"( - contract test { - /// @notice this is a really nice constructor - constructor(uint a, uint second) { } - } - )"; - - char const* natspec = R"ABCDEF({ - "methods": - { - "constructor": - { - "notice": "this is a really nice constructor" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(user_constructor_and_function) -{ - char const* sourceCode = R"( - contract test { - /// @notice this is a really nice constructor - constructor(uint a, uint second) { } - /// another multiplier - function mul(uint a, uint second) public returns(uint d) { return a * 7 + second; } - } - )"; - - char const* natspec = R"ABCDEF({ - "methods": - { - "mul(uint256,uint256)": - { - "notice": "another multiplier" - }, - "constructor": - { - "notice": "this is a really nice constructor" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_constructor) -{ - char const *sourceCode = R"( - contract test { - /// @param a the parameter a is really nice and very useful - /// @param second the second parameter is not very useful, it just provides additional confusion - constructor(uint a, uint second) { } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "constructor": - { - "params": - { - "a": "the parameter a is really nice and very useful", - "second": "the second parameter is not very useful, it just provides additional confusion" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(dev_constructor_return) -{ - char const* sourceCode = R"( - contract test { - /// @param a the parameter a is really nice and very useful - /// @param second the second parameter is not very useful, it just provides additional confusion - /// @return return should not work within constructors - constructor(uint a, uint second) { } - } - )"; - - expectNatspecError(sourceCode); -} - -BOOST_AUTO_TEST_CASE(dev_constructor_and_function) -{ - char const *sourceCode = R"( - contract test { - /// @param a the parameter a is really nice and very useful - /// @param second the second parameter is not very useful, it just provides additional confusion - constructor(uint a, uint second) { } - /// @dev Multiplies a number by 7 and adds second parameter - /// @param a Documentation for the first parameter starts here. - /// Since it's a really complicated parameter we need 2 lines - /// @param second Documentation for the second parameter - /// @return d The result of the multiplication - /// and cookies with nutella - function mul(uint a, uint second) public returns(uint d) { - return a * 7 + second; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "mul(uint256,uint256)": - { - "details": "Multiplies a number by 7 and adds second parameter", - "params": - { - "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", - "second": "Documentation for the second parameter" - }, - "returns": - { - "d": "The result of the multiplication and cookies with nutella" - } - }, - "constructor": - { - "params": - { - "a": "the parameter a is really nice and very useful", - "second": "the second parameter is not very useful, it just provides additional confusion" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, false); -} - -BOOST_AUTO_TEST_CASE(slash4) -{ - char const* sourceCode = R"( - contract test { - //// @notice lorem ipsum - function f() public { } - } - )"; - - char const* natspec = R"( { "methods": {} } )"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(star3) -{ - char const* sourceCode = R"( - contract test { - /*** - * @notice lorem ipsum - */ - function f() public { } - } - )"; - - char const* natspec = R"( { "methods": {} } )"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(slash3_slash3) -{ - char const* sourceCode = R"( - contract test { - /// @notice lorem - /// ipsum - function f() public { } - } - )"; - - char const* natspec = R"ABCDEF({ - "methods": - { - "f()": { "notice": "lorem ipsum" } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(slash3_slash4) -{ - char const* sourceCode = R"( - contract test { - /// @notice lorem - //// ipsum - function f() public { } - } - )"; - - char const* natspec = R"ABCDEF({ - "methods": - { - "f()": { "notice": "lorem" } - } - })ABCDEF"; - - checkNatspec(sourceCode, "test", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_default_inherit_variable) -{ - char const *sourceCode = R"( - contract C { - /// @notice Hello world - /// @dev test - function x() virtual external returns (uint) { - return 1; - } - } - - contract D is C { - uint public override x; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": { "x()": { "details": "test" } } - })ABCDEF"; - - char const *natspec1 = R"ABCDEF({ - "methods": {}, - "stateVariables": - { - "x": - { - "details": "test" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "C", natspec, false); - checkNatspec(sourceCode, "D", natspec1, false); -} - -BOOST_AUTO_TEST_CASE(user_default_inherit_variable) -{ - char const *sourceCode = R"( - contract C { - /// @notice Hello world - /// @dev test - function x() virtual external returns (uint) { - return 1; - } - } - - contract D is C { - uint public override x; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": { "x()": { "notice": "Hello world" } } - })ABCDEF"; - - checkNatspec(sourceCode, "C", natspec, true); - checkNatspec(sourceCode, "D", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_explicit_inherit_variable) -{ - char const *sourceCode = R"( - contract B { - function x() virtual external returns (uint) { - return 1; - } - } - - contract C { - /// @notice Hello world - /// @dev test - function x() virtual external returns (uint) { - return 1; - } - } - - contract D is C, B { - /// @inheritdoc C - uint public override(C, B) x; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": { "x()": { "details": "test" } } - })ABCDEF"; - - char const *natspec1 = R"ABCDEF({ - "methods": {}, - "stateVariables": - { - "x": - { - "details": "test" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "C", natspec, false); - checkNatspec(sourceCode, "D", natspec1, false); -} - -BOOST_AUTO_TEST_CASE(user_explicit_inherit_variable) -{ - char const *sourceCode = R"( - contract B { - function x() virtual external returns (uint) { - return 1; - } - } - - contract C { - /// @notice Hello world - /// @dev test - function x() virtual external returns (uint) { - return 1; - } - } - - contract D is C, B { - /// @inheritdoc C - uint public override(C, B) x; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": { "x()": { "notice": "Hello world" } } - })ABCDEF"; - - checkNatspec(sourceCode, "C", natspec, true); - checkNatspec(sourceCode, "D", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_default_inherit) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// Second line. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract Middle is ERC20 { - function transfer(address to, uint amount) virtual override external returns (bool) - { - return false; - } - } - - contract Token is Middle { - function transfer(address to, uint amount) override external returns (bool) - { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, false); - checkNatspec(sourceCode, "Middle", natspec, false); - checkNatspec(sourceCode, "Token", natspec, false); -} - -BOOST_AUTO_TEST_CASE(user_default_inherit) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// Second line. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract Middle is ERC20 { - function transfer(address to, uint amount) virtual override external returns (bool) - { - return false; - } - } - - contract Token is Middle { - function transfer(address to, uint amount) override external returns (bool) - { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, true); - checkNatspec(sourceCode, "Middle", natspec, true); - checkNatspec(sourceCode, "Token", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_explicit_inherit) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 { - function transfer(address to, uint amount) virtual external returns (bool) { - return false; - } - } - - contract Token is ERC21, ERC20 { - /// @inheritdoc ERC20 - function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, false); - checkNatspec(sourceCode, "Token", natspec, false); -} - -BOOST_AUTO_TEST_CASE(user_explicit_inherit) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 { - function transfer(address to, uint amount) virtual external returns (bool) { - return false; - } - } - - contract Token is ERC21, ERC20 { - /// @inheritdoc ERC20 - function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, true); - checkNatspec(sourceCode, "Token", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_explicit_inherit2) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 is ERC20 { - function transfer(address to, uint amount) virtual override external returns (bool) { - return false; - } - } - - contract Token is ERC20 { - /// @inheritdoc ERC20 - function transfer(address to, uint amount) override external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, false); - checkNatspec(sourceCode, "ERC21", natspec, false); - checkNatspec(sourceCode, "Token", natspec, false); -} - -BOOST_AUTO_TEST_CASE(user_explicit_inherit2) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 is ERC20 { - function transfer(address to, uint amount) virtual override external returns (bool) { - return false; - } - } - - contract Token is ERC20 { - /// @inheritdoc ERC20 - function transfer(address to, uint amount) override external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, true); - checkNatspec(sourceCode, "ERC21", natspec, true); - checkNatspec(sourceCode, "Token", natspec, true); -} - -BOOST_AUTO_TEST_CASE(dev_explicit_inherit_partial2) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 is ERC20 { - /// @inheritdoc ERC20 - /// @dev override dev comment - /// @notice override notice - function transfer(address to, uint amount) virtual override external returns (bool) { - return false; - } - } - - contract Token is ERC21 { - function transfer(address to, uint amount) override external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "override dev comment", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, false); - checkNatspec(sourceCode, "Token", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(user_explicit_inherit_partial2) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 is ERC20 { - /// @inheritdoc ERC20 - /// @dev override dev comment - /// @notice override notice - function transfer(address to, uint amount) virtual override external returns (bool) { - return false; - } - } - - contract Token is ERC21 { - function transfer(address to, uint amount) override external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "override notice" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, true); - checkNatspec(sourceCode, "Token", natspec2, true); -} - -BOOST_AUTO_TEST_CASE(dev_explicit_inherit_partial) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 { - function transfer(address to, uint amount) virtual external returns (bool) { - return false; - } - } - - contract Token is ERC21, ERC20 { - /// @inheritdoc ERC20 - /// @dev override dev comment - /// @notice override notice - function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "override dev comment", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, false); - checkNatspec(sourceCode, "Token", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(user_explicit_inherit_partial) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract ERC21 { - function transfer(address to, uint amount) virtual external returns (bool) { - return false; - } - } - - contract Token is ERC21, ERC20 { - /// @inheritdoc ERC20 - /// @dev override dev comment - /// @notice override notice - function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "override notice" - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, true); - checkNatspec(sourceCode, "Token", natspec2, true); -} - -BOOST_AUTO_TEST_CASE(dev_inherit_parameter_mismatch) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract Middle is ERC20 { - function transfer(address to, uint amount) override virtual external returns (bool) { - return false; - } - } - - contract Token is Middle { - function transfer(address too, uint amount) override external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": { } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, false); - checkNatspec(sourceCode, "Middle", natspec, false); - checkNatspec(sourceCode, "Token", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(user_inherit_parameter_mismatch) -{ - char const *sourceCode = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - contract Middle is ERC20 { - function transfer(address to, uint amount) override virtual external returns (bool) { - return false; - } - } - - contract Token is Middle { - function transfer(address too, uint amount) override external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": { } - })ABCDEF"; - - checkNatspec(sourceCode, "ERC20", natspec, true); - checkNatspec(sourceCode, "Middle", natspec, true); - checkNatspec(sourceCode, "Token", natspec2, true); -} - -BOOST_AUTO_TEST_CASE(dev_explicit_inehrit_complex) -{ - char const *sourceCode1 = R"( - interface ERC20 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - - interface ERC21 { - /// Transfer ``amount`` from ``msg.sender`` to ``to``. - /// @dev test2 - /// @param to address to transfer to - /// @param amount amount to transfer - function transfer(address to, uint amount) external returns (bool); - } - )"; - - char const *sourceCode2 = R"( - import "Interfaces.sol" as myInterfaces; - - contract Token is myInterfaces.ERC20, myInterfaces.ERC21 { - /// @inheritdoc myInterfaces.ERC20 - function transfer(address too, uint amount) - override(myInterfaces.ERC20, myInterfaces.ERC21) external returns (bool) { - return false; - } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "transfer(address,uint256)": - { - "details": "test", - "params": - { - "amount": "amount to transfer", - "to": "address to transfer to" - } - } - } - })ABCDEF"; - - m_compilerStack.reset(); - m_compilerStack.setSources({ - {"Interfaces.sol", "pragma solidity >=0.0;\n" + std::string(sourceCode1)}, - {"Testfile.sol", "pragma solidity >=0.0;\n" + std::string(sourceCode2)} - }); - - m_compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion()); - - BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed"); - - Json::Value generatedDocumentation = m_compilerStack.natspecDev("Token"); - Json::Value expectedDocumentation; - util::jsonParseStrict(natspec, expectedDocumentation); - - expectedDocumentation["version"] = Json::Value(Natspec::c_natspecVersion); - expectedDocumentation["kind"] = Json::Value("dev"); - - BOOST_CHECK_MESSAGE( - expectedDocumentation == generatedDocumentation, - "Expected:\n" << util::jsonPrettyPrint(expectedDocumentation) << - "\n but got:\n" << util::jsonPrettyPrint(generatedDocumentation) - ); -} - -BOOST_AUTO_TEST_CASE(dev_different_return_name) -{ - char const *sourceCode = R"( - contract A { - /// @return y value - function g(int x) public pure virtual returns (int y) { return x; } - } - - contract B is A { - function g(int x) public pure override returns (int z) { return x; } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "y": "value" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "z": "value" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspec, false); - checkNatspec(sourceCode, "B", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(dev_different_return_name_multiple) -{ - char const *sourceCode = R"( - contract A { - /// @return a value A - /// @return b value B - function g(int x) public pure virtual returns (int a, int b) { return (1, 2); } - } - - contract B is A { - function g(int x) public pure override returns (int z, int y) { return (1, 2); } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "a": "value A", - "b": "value B" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "z": "value A", - "y": "value B" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspec, false); - checkNatspec(sourceCode, "B", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(dev_different_return_name_multiple_partly_unnamed) -{ - char const *sourceCode = R"( - contract A { - /// @return value A - /// @return b value B - function g(int x) public pure virtual returns (int, int b) { return (1, 2); } - } - - contract B is A { - function g(int x) public pure override returns (int z, int) { return (1, 2); } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "_0": "value A", - "b": "value B" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "z": "value A", - "_1": "value B" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspec, false); - checkNatspec(sourceCode, "B", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(dev_different_return_name_multiple_unnamed) -{ - char const *sourceCode = R"( - contract A { - /// @return value A - /// @return value B - function g(int x) public pure virtual returns (int, int) { return (1, 2); } - } - - contract B is A { - function g(int x) public pure override returns (int z, int y) { return (1, 2); } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "_0": "value A", - "_1": "value B" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "z": "value A", - "y": "value B" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspec, false); - checkNatspec(sourceCode, "B", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(dev_return_name_no_description) -{ - char const *sourceCode = R"( - contract A { - /// @return a - function g(int x) public pure virtual returns (int a) { return 2; } - } - - contract B is A { - function g(int x) public pure override returns (int b) { return 2; } - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "a": "a" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": - { - "g(int256)": - { - "returns": - { - "b": "a" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspec, false); - checkNatspec(sourceCode, "B", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(error) -{ - char const* sourceCode = R"( - contract test { - /// Something failed. - /// @dev an error. - /// @param a first parameter - /// @param b second parameter - error E(uint a, uint b); - } - )"; - - char const* devdoc = R"X({ - "errors":{ - "E(uint256,uint256)": [{ - "details": "an error.", - "params": - { - "a": "first parameter", - "b": "second parameter" - } - }] - }, - "methods": {} - })X"; - - checkNatspec(sourceCode, "test", devdoc, false); - - char const* userdoc = R"X({ - "errors":{ - "E(uint256,uint256)": [{ - "notice": "Something failed." - }] - }, - "methods": {} - })X"; - checkNatspec(sourceCode, "test", userdoc, true); -} - -BOOST_AUTO_TEST_CASE(error_multiple) -{ - char const* sourceCode = R"( - contract A { - /// Something failed. - /// @dev an error. - /// @param x first parameter - /// @param y second parameter - error E(uint x, uint y); - } - contract test { - /// X Something failed. - /// @dev X an error. - /// @param a X first parameter - /// @param b X second parameter - error E(uint a, uint b); - function f(bool a) public pure { - if (a) - revert E(1, 2); - else - revert A.E(5, 6); - } - } - )"; - - char const* devdoc = R"X({ - "methods": {}, - "errors": - { - "E(uint256,uint256)": [ - { - "details": "an error.", - "params": - { - "x": "first parameter", - "y": "second parameter" - } - }, - { - "details": "X an error.", - "params": - { - "a": "X first parameter", - "b": "X second parameter" - } - } - ] - } - })X"; - - checkNatspec(sourceCode, "test", devdoc, false); - - char const* userdoc = R"X({ - "errors":{ - "E(uint256,uint256)": [ - { "notice": "Something failed." }, - { "notice": "X Something failed." } - ] - }, - "methods": {} - })X"; - checkNatspec(sourceCode, "test", userdoc, true); -} - -BOOST_AUTO_TEST_CASE(custom) -{ - char const* sourceCode = R"( - /// @custom:x one two three - /// @custom:y line - /// break - /// @custom:t one - /// @custom:t two - contract A { - /// @custom:note statevar - uint x; - /// @custom:since 2014 - function g(int x) public pure virtual returns (int, int) { return (1, 2); } - } - )"; - - char const* natspec = R"ABCDEF({ - "custom:t": "onetwo", - "custom:x": "one two three", - "custom:y": "line break", - "methods": - { - "g(int256)": - { - "custom:since": "2014" - } - }, - "stateVariables": { "x": { "custom:note": "statevar" } } - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspec, false); -} - -BOOST_AUTO_TEST_CASE(custom_inheritance) -{ - char const *sourceCode = R"( - contract A { - /// @custom:since 2014 - function g(uint x) public pure virtual {} - } - contract B is A { - function g(uint x) public pure override {} - } - )"; - - char const* natspecA = R"ABCDEF( - { - "methods": - { - "g(uint256)": - { - "custom:since": "2014" - } - } - })ABCDEF"; - char const* natspecB = R"ABCDEF( - { - "methods": {} - })ABCDEF"; - - checkNatspec(sourceCode, "A", natspecA, false); - checkNatspec(sourceCode, "B", natspecB, false); -} - -BOOST_AUTO_TEST_CASE(dev_struct_getter_override) -{ - char const *sourceCode = R"( - interface IThing { - /// @return x a number - /// @return y another number - function value() external view returns (uint128 x, uint128 y); - } - - contract Thing is IThing { - struct Value { - uint128 x; - uint128 y; - } - - Value public override value; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "value()": - { - "returns": - { - "x": "a number", - "y": "another number" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": {}, - "stateVariables": - { - "value": - { - "returns": - { - "x": "a number", - "y": "another number" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "IThing", natspec, false); - checkNatspec(sourceCode, "Thing", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(dev_struct_getter_override_no_return_name) -{ - char const *sourceCode = R"( - interface IThing { - ///@return - function value(uint) external returns (uint128,uint128); - } - - contract Thing is IThing { - struct Value { - uint128 x; - uint128 A; - } - mapping(uint=>Value) public override value; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "value(uint256)": - { - "returns": - { - "_0": "" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": {}, - "stateVariables": - { - "value": - { - "return": "x ", - "returns": - { - "x": "" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "IThing", natspec, false); - checkNatspec(sourceCode, "Thing", natspec2, false); -} - -BOOST_AUTO_TEST_CASE(dev_struct_getter_override_different_return_parameter_names) -{ - char const *sourceCode = R"( - interface IThing { - /// @return x a number - /// @return y another number - function value() external view returns (uint128 x, uint128 y); - } - - contract Thing is IThing { - struct Value { - uint128 a; - uint128 b; - } - - Value public override value; - } - )"; - - char const *natspec = R"ABCDEF({ - "methods": - { - "value()": - { - "returns": - { - "x": "a number", - "y": "another number" - } - } - } - })ABCDEF"; - - char const *natspec2 = R"ABCDEF({ - "methods": {}, - "stateVariables": - { - "value": - { - "returns": - { - "a": "a number", - "b": "another number" - } - } - } - })ABCDEF"; - - checkNatspec(sourceCode, "IThing", natspec, false); - checkNatspec(sourceCode, "Thing", natspec2, false); -} - -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/natspecJSON/custom.sol b/test/libsolidity/natspecJSON/custom.sol new file mode 100644 index 000000000..28073c0bf --- /dev/null +++ b/test/libsolidity/natspecJSON/custom.sol @@ -0,0 +1,43 @@ +/// @custom:x one two three +/// @custom:y line +/// break +/// @custom:t one +/// @custom:t two +contract A { + /// @custom:note statevar + uint x; + /// @custom:since 2014 + function g(int x) public pure virtual returns (int, int) { return (1, 2); } +} + +// ---- +// ---- +// :A devdoc +// { +// "custom:t": "onetwo", +// "custom:x": "one two three", +// "custom:y": "line break", +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "custom:since": "2014" +// } +// }, +// "stateVariables": +// { +// "x": +// { +// "custom:note": "statevar" +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/custom_inheritance.sol b/test/libsolidity/natspecJSON/custom_inheritance.sol new file mode 100644 index 000000000..c4a1360fb --- /dev/null +++ b/test/libsolidity/natspecJSON/custom_inheritance.sol @@ -0,0 +1,43 @@ +contract A { + /// @custom:since 2014 + function g(uint x) public pure virtual {} +} +contract B is A { + function g(uint x) public pure override {} +} + +// ---- +// ---- +// :A devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(uint256)": +// { +// "custom:since": "2014" +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_and_user_basic_test.sol b/test/libsolidity/natspecJSON/dev_and_user_basic_test.sol new file mode 100644 index 000000000..422522354 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_and_user_basic_test.sol @@ -0,0 +1,33 @@ +contract test { + /// @notice Multiplies `a` by 7 + /// @dev Multiplies a number by 7 + function mul(uint a) public returns (uint d) { return a * 7; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256)": +// { +// "details": "Multiplies a number by 7" +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "mul(uint256)": +// { +// "notice": "Multiplies `a` by 7" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_and_user_no_doc.sol b/test/libsolidity/natspecJSON/dev_and_user_no_doc.sol new file mode 100644 index 000000000..db7447914 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_and_user_no_doc.sol @@ -0,0 +1,24 @@ +contract test { + function mul(uint a) public returns (uint d) { + return a * 7; + } + function sub(int input) public returns (int d) { + return input - 3; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_author_at_function.sol b/test/libsolidity/natspecJSON/dev_author_at_function.sol new file mode 100644 index 000000000..10a21f753 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_author_at_function.sol @@ -0,0 +1,10 @@ +/// @author Lefteris +/// @title Just a test contract +contract test { + /// @dev Mul function + /// @author John Doe + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 6546: (73-119): Documentation tag @author not valid for functions. diff --git a/test/libsolidity/natspecJSON/dev_constructor.sol b/test/libsolidity/natspecJSON/dev_constructor.sol new file mode 100644 index 000000000..9cb1e05af --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_constructor.sol @@ -0,0 +1,31 @@ +contract test { + /// @param a the parameter a is really nice and very useful + /// @param second the second parameter is not very useful, it just provides additional confusion + constructor(uint a, uint second) { } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "constructor": +// { +// "params": +// { +// "a": "the parameter a is really nice and very useful", +// "second": "the second parameter is not very useful, it just provides additional confusion" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_constructor_and_function.sol b/test/libsolidity/natspecJSON/dev_constructor_and_function.sol new file mode 100644 index 000000000..0954009f9 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_constructor_and_function.sol @@ -0,0 +1,53 @@ +contract test { + /// @param a the parameter a is really nice and very useful + /// @param second the second parameter is not very useful, it just provides additional confusion + constructor(uint a, uint second) { } + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return d The result of the multiplication + /// and cookies with nutella + function mul(uint a, uint second) public returns(uint d) { + return a * 7 + second; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "constructor": +// { +// "params": +// { +// "a": "the parameter a is really nice and very useful", +// "second": "the second parameter is not very useful, it just provides additional confusion" +// } +// }, +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "d": "The result of the multiplication and cookies with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_constructor_return.sol b/test/libsolidity/natspecJSON/dev_constructor_return.sol new file mode 100644 index 000000000..4695806d2 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_constructor_return.sol @@ -0,0 +1,10 @@ +contract test { + /// @param a the parameter a is really nice and very useful + /// @param second the second parameter is not very useful, it just provides additional confusion + /// @return return should not work within constructors + constructor(uint a, uint second) { } +} + +// ---- +// DocstringParsingError 6546: (20-239): Documentation tag @return not valid for constructor. +// DocstringParsingError 2604: (20-239): Documentation tag "@return return should not work within constructors" exceeds the number of return parameters. diff --git a/test/libsolidity/natspecJSON/dev_contract_doc.sol b/test/libsolidity/natspecJSON/dev_contract_doc.sol new file mode 100644 index 000000000..3958a01ed --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_contract_doc.sol @@ -0,0 +1,30 @@ +/// @author Lefteris +/// @title Just a test contract +contract test { + /// @dev Mul function + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "author": "Lefteris", +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Mul function" +// } +// }, +// "title": "Just a test contract", +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_contract_no_doc.sol b/test/libsolidity/natspecJSON/dev_contract_no_doc.sol new file mode 100644 index 000000000..a60847d7e --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_contract_no_doc.sol @@ -0,0 +1,26 @@ +contract test { + /// @dev Mul function + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Mul function" +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_default_inherit.sol b/test/libsolidity/natspecJSON/dev_default_inherit.sol new file mode 100644 index 000000000..dd65ddfbe --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_default_inherit.sol @@ -0,0 +1,117 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// Second line. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract Middle is ERC20 { + function transfer(address to, uint amount) virtual override external returns (bool) + { + return false; + } +} + +contract Token is Middle { + function transfer(address to, uint amount) override external returns (bool) + { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." +// } +// }, +// "version": 1 +// } +// +// :Middle devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Middle userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_default_inherit_variable.sol b/test/libsolidity/natspecJSON/dev_default_inherit_variable.sol new file mode 100644 index 000000000..89d57d011 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_default_inherit_variable.sol @@ -0,0 +1,66 @@ +contract C { + /// @notice Hello world + /// @dev test + function x() virtual external returns (uint) { + return 1; + } +} + +contract D is C { + uint public override x; +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": +// { +// "x()": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } +// +// :D devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "x": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :D userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_desc_after_nl.sol b/test/libsolidity/natspecJSON/dev_desc_after_nl.sol new file mode 100644 index 000000000..fd83ff1b9 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_desc_after_nl.sol @@ -0,0 +1,34 @@ +contract test { + /// @dev + /// Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter", +// "second": "Documentation for the second parameter" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_different_return_name.sol b/test/libsolidity/natspecJSON/dev_different_return_name.sol new file mode 100644 index 000000000..7d74cc294 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_different_return_name.sol @@ -0,0 +1,56 @@ +contract A { + /// @return y value + function g(int x) public pure virtual returns (int y) { return x; } +} + +contract B is A { + function g(int x) public pure override returns (int z) { return x; } +} + +// ---- +// ---- +// :A devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "y": "value" +// } +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "z": "value" +// } +// } +// }, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_different_return_name_multiple.sol b/test/libsolidity/natspecJSON/dev_different_return_name_multiple.sol new file mode 100644 index 000000000..2a8ba399f --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_different_return_name_multiple.sol @@ -0,0 +1,59 @@ +contract A { + /// @return a value A + /// @return b value B + function g(int x) public pure virtual returns (int a, int b) { return (1, 2); } +} + +contract B is A { + function g(int x) public pure override returns (int z, int y) { return (1, 2); } +} + +// ---- +// ---- +// :A devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "a": "value A", +// "b": "value B" +// } +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "y": "value B", +// "z": "value A" +// } +// } +// }, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_different_return_name_multiple_partly_unnamed.sol b/test/libsolidity/natspecJSON/dev_different_return_name_multiple_partly_unnamed.sol new file mode 100644 index 000000000..c41336d8f --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_different_return_name_multiple_partly_unnamed.sol @@ -0,0 +1,59 @@ +contract A { + /// @return value A + /// @return b value B + function g(int x) public pure virtual returns (int, int b) { return (1, 2); } +} + +contract B is A { + function g(int x) public pure override returns (int z, int) { return (1, 2); } +} + +// ---- +// ---- +// :A devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "_0": "value A", +// "b": "value B" +// } +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "_1": "value B", +// "z": "value A" +// } +// } +// }, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_different_return_name_multiple_unnamed.sol b/test/libsolidity/natspecJSON/dev_different_return_name_multiple_unnamed.sol new file mode 100644 index 000000000..3bf40011f --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_different_return_name_multiple_unnamed.sol @@ -0,0 +1,59 @@ +contract A { + /// @return value A + /// @return value B + function g(int x) public pure virtual returns (int, int) { return (1, 2); } +} + +contract B is A { + function g(int x) public pure override returns (int z, int y) { return (1, 2); } +} + +// ---- +// ---- +// :A devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "_0": "value A", +// "_1": "value B" +// } +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "y": "value B", +// "z": "value A" +// } +// } +// }, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_documenting_no_param_description.sol b/test/libsolidity/natspecJSON/dev_documenting_no_param_description.sol new file mode 100644 index 000000000..e02437ace --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_documenting_no_param_description.sol @@ -0,0 +1,9 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 9942: (20-156): No description given for param second diff --git a/test/libsolidity/natspecJSON/dev_documenting_no_param_name.sol b/test/libsolidity/natspecJSON/dev_documenting_no_param_name.sol new file mode 100644 index 000000000..c8da55d75 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_documenting_no_param_name.sol @@ -0,0 +1,9 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 3335: (20-149): No param name given diff --git a/test/libsolidity/natspecJSON/dev_documenting_no_param_name_end.sol b/test/libsolidity/natspecJSON/dev_documenting_no_param_name_end.sol new file mode 100644 index 000000000..500092e1d --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_documenting_no_param_name_end.sol @@ -0,0 +1,9 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param se + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 9942: (20-152): No description given for param se diff --git a/test/libsolidity/natspecJSON/dev_documenting_no_return_param_name.sol b/test/libsolidity/natspecJSON/dev_documenting_no_return_param_name.sol new file mode 100644 index 000000000..2a99c78a8 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_documenting_no_return_param_name.sol @@ -0,0 +1,10 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + /// @return + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 5856: (20-211): Documentation tag "@return " does not contain the name of its return parameter. diff --git a/test/libsolidity/natspecJSON/dev_documenting_nonexistent_param.sol b/test/libsolidity/natspecJSON/dev_documenting_nonexistent_param.sol new file mode 100644 index 000000000..a2ebc2652 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_documenting_nonexistent_param.sol @@ -0,0 +1,9 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param not_existing Documentation for the second parameter + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 3881: (20-201): Documented parameter "not_existing" not found in the parameter list of the function. diff --git a/test/libsolidity/natspecJSON/dev_explicit_inherit.sol b/test/libsolidity/natspecJSON/dev_explicit_inherit.sol new file mode 100644 index 000000000..a8ddb3133 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_explicit_inherit.sol @@ -0,0 +1,98 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 { + function transfer(address to, uint amount) virtual external returns (bool) { + return false; + } +} + +contract Token is ERC21, ERC20 { + /// @inheritdoc ERC20 + function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_explicit_inherit2.sol b/test/libsolidity/natspecJSON/dev_explicit_inherit2.sol new file mode 100644 index 000000000..4c726f552 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_explicit_inherit2.sol @@ -0,0 +1,115 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 is ERC20 { + function transfer(address to, uint amount) virtual override external returns (bool) { + return false; + } +} + +contract Token is ERC20 { + /// @inheritdoc ERC20 + function transfer(address to, uint amount) override external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_explicit_inherit_complex.sol b/test/libsolidity/natspecJSON/dev_explicit_inherit_complex.sol new file mode 100644 index 000000000..38726c778 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_explicit_inherit_complex.sol @@ -0,0 +1,122 @@ +==== Source: Interfaces.sol ==== +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +interface ERC21 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test2 + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +==== Source: Testfile.sol ==== +import "Interfaces.sol" as myInterfaces; + +contract Token is myInterfaces.ERC20, myInterfaces.ERC21 { + /// @inheritdoc myInterfaces.ERC20 + function transfer(address too, uint amount) + override(myInterfaces.ERC20, myInterfaces.ERC21) external returns (bool) { + return false; + } +} + +// ---- +// ---- +// Interfaces.sol:ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// Interfaces.sol:ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// Interfaces.sol:ERC21 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test2", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// Interfaces.sol:ERC21 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// Testfile.sol:Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// Testfile.sol:Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_explicit_inherit_partial.sol b/test/libsolidity/natspecJSON/dev_explicit_inherit_partial.sol new file mode 100644 index 000000000..c69bd4121 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_explicit_inherit_partial.sol @@ -0,0 +1,100 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 { + function transfer(address to, uint amount) virtual external returns (bool) { + return false; + } +} + +contract Token is ERC21, ERC20 { + /// @inheritdoc ERC20 + /// @dev override dev comment + /// @notice override notice + function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "override dev comment", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "override notice" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_explicit_inherit_partial2.sol b/test/libsolidity/natspecJSON/dev_explicit_inherit_partial2.sol new file mode 100644 index 000000000..6bb49e887 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_explicit_inherit_partial2.sol @@ -0,0 +1,117 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 is ERC20 { + /// @inheritdoc ERC20 + /// @dev override dev comment + /// @notice override notice + function transfer(address to, uint amount) virtual override external returns (bool) { + return false; + } +} + +contract Token is ERC21 { + function transfer(address to, uint amount) override external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "override dev comment", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "override notice" +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "override dev comment", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "override notice" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_explicit_inherit_variable.sol b/test/libsolidity/natspecJSON/dev_explicit_inherit_variable.sol new file mode 100644 index 000000000..b35a92873 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_explicit_inherit_variable.sol @@ -0,0 +1,87 @@ +contract B { + function x() virtual external returns (uint) { + return 1; + } +} + +contract C { + /// @notice Hello world + /// @dev test + function x() virtual external returns (uint) { + return 1; + } +} + +contract D is C, B { + /// @inheritdoc C + uint public override(C, B) x; +} + +// ---- +// ---- +// :B devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :C devdoc +// { +// "kind": "dev", +// "methods": +// { +// "x()": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } +// +// :D devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "x": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :D userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_inherit_parameter_mismatch.sol b/test/libsolidity/natspecJSON/dev_inherit_parameter_mismatch.sol new file mode 100644 index 000000000..a8ab60bd1 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_inherit_parameter_mismatch.sol @@ -0,0 +1,97 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract Middle is ERC20 { + function transfer(address to, uint amount) override virtual external returns (bool) { + return false; + } +} + +contract Token is Middle { + function transfer(address too, uint amount) override external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :Middle devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Middle userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_multiline_comment.sol b/test/libsolidity/natspecJSON/dev_multiline_comment.sol new file mode 100644 index 000000000..b86bcff92 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_multiline_comment.sol @@ -0,0 +1,44 @@ +contract test { + /** + * @dev Multiplies a number by 7 and adds second parameter + * @param a Documentation for the first parameter starts here. + * Since it's a really complicated parameter we need 2 lines + * @param second Documentation for the second parameter + * @return d The result of the multiplication + * and cookies with nutella + */ + function mul(uint a, uint second) public returns (uint d) { + return a * 7 + second; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "d": "The result of the multiplication and cookies with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_multiline_return.sol b/test/libsolidity/natspecJSON/dev_multiline_return.sol new file mode 100644 index 000000000..cd3c1df98 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_multiline_return.sol @@ -0,0 +1,42 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return d The result of the multiplication + /// and cookies with nutella + function mul(uint a, uint second) public returns (uint d) { + return a * 7 + second; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "d": "The result of the multiplication and cookies with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_multiple_functions.sol b/test/libsolidity/natspecJSON/dev_multiple_functions.sol new file mode 100644 index 000000000..899fb5e26 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_multiple_functions.sol @@ -0,0 +1,63 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) public returns (uint d) { + return a * 7 + second; + } + /// @dev Divides 2 numbers + /// @param input Documentation for the input parameter + /// @param div Documentation for the div parameter + function divide(uint input, uint div) public returns (uint d) { + return input / div; + } + /// @dev Subtracts 3 from `input` + /// @param input Documentation for the input parameter + function sub(int input) public returns (int d) { + return input - 3; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "divide(uint256,uint256)": +// { +// "details": "Divides 2 numbers", +// "params": +// { +// "div": "Documentation for the div parameter", +// "input": "Documentation for the input parameter" +// } +// }, +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter", +// "second": "Documentation for the second parameter" +// } +// }, +// "sub(int256)": +// { +// "details": "Subtracts 3 from `input`", +// "params": +// { +// "input": "Documentation for the input parameter" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_multiple_params.sol b/test/libsolidity/natspecJSON/dev_multiple_params.sol new file mode 100644 index 000000000..424f368d1 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_multiple_params.sol @@ -0,0 +1,33 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter", +// "second": "Documentation for the second parameter" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol b/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol new file mode 100644 index 000000000..61f45aa62 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_multiple_params_mixed_whitespace.sol @@ -0,0 +1,33 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter + /// @param second Documentation for the second parameter + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter", +// "second": "Documentation for the second parameter" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_mutiline_param_description.sol b/test/libsolidity/natspecJSON/dev_mutiline_param_description.sol new file mode 100644 index 000000000..9bdfd0504 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_mutiline_param_description.sol @@ -0,0 +1,34 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return.sol b/test/libsolidity/natspecJSON/dev_return.sol new file mode 100644 index 000000000..c97897047 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return.sol @@ -0,0 +1,39 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return d The result of the multiplication + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "d": "The result of the multiplication" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_desc_after_nl.sol b/test/libsolidity/natspecJSON/dev_return_desc_after_nl.sol new file mode 100644 index 000000000..b6ae9f2f6 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_desc_after_nl.sol @@ -0,0 +1,42 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return + /// d The result of the multiplication + function mul(uint a, uint second) public returns (uint d) { + return a * 7 + second; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "d": "The result of the multiplication" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple.sol new file mode 100644 index 000000000..0c93dfdd9 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_desc_multiple.sol @@ -0,0 +1,44 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return d The result of the multiplication + /// @return f And cookies with nutella + function mul(uint a, uint second) public returns (uint d, uint f) { + uint mul = a * 7; + return (mul, second); + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "d": "The result of the multiplication", +// "f": "And cookies with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed.sol new file mode 100644 index 000000000..1d93b4aba --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed.sol @@ -0,0 +1,44 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return The result of the multiplication + /// @return And cookies with nutella + function mul(uint a, uint second) public returns (uint, uint) { + uint mul = a * 7; + return (mul, second); + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "_0": "The result of the multiplication", +// "_1": "And cookies with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed.sol new file mode 100644 index 000000000..6147aace7 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed.sol @@ -0,0 +1,44 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return The result of the multiplication + /// @return _cookies And cookies with nutella + function mul(uint a, uint second) public returns (uint, uint _cookies) { + uint mul = a * 7; + return (mul, second); + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "_0": "The result of the multiplication", +// "_cookies": "And cookies with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed_2.sol b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed_2.sol new file mode 100644 index 000000000..824671ee4 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_desc_multiple_unamed_mixed_2.sol @@ -0,0 +1,47 @@ +contract test { + /// @dev Multiplies a number by 7 and adds second parameter + /// @param a Documentation for the first parameter starts here. + /// Since it's a really complicated parameter we need 2 lines + /// @param second Documentation for the second parameter + /// @return _cookies And cookies with nutella + /// @return The result of the multiplication + /// @return _milk And milk with nutella + function mul(uint a, uint second) public returns (uint _cookies, uint, uint _milk) { + uint mul = a * 7; + uint milk = 4; + return (mul, second, milk); + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "details": "Multiplies a number by 7 and adds second parameter", +// "params": +// { +// "a": "Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines", +// "second": "Documentation for the second parameter" +// }, +// "returns": +// { +// "_1": "The result of the multiplication", +// "_cookies": "And cookies with nutella", +// "_milk": "And milk with nutella" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_name_no_description.sol b/test/libsolidity/natspecJSON/dev_return_name_no_description.sol new file mode 100644 index 000000000..1e65a235a --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_name_no_description.sol @@ -0,0 +1,56 @@ +contract A { + /// @return a + function g(int x) public pure virtual returns (int a) { return 2; } +} + +contract B is A { + function g(int x) public pure override returns (int b) { return 2; } +} + +// ---- +// ---- +// :A devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "a": "a" +// } +// } +// }, +// "version": 1 +// } +// +// :A userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "kind": "dev", +// "methods": +// { +// "g(int256)": +// { +// "returns": +// { +// "b": "a" +// } +// } +// }, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_return_no_params.sol b/test/libsolidity/natspecJSON/dev_return_no_params.sol new file mode 100644 index 000000000..37442f10a --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_return_no_params.sol @@ -0,0 +1,29 @@ +contract test { + /// @return d The result of the multiplication + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": +// { +// "mul(uint256,uint256)": +// { +// "returns": +// { +// "d": "The result of the multiplication" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_struct_getter_override.sol b/test/libsolidity/natspecJSON/dev_struct_getter_override.sol new file mode 100644 index 000000000..019e1a335 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_struct_getter_override.sol @@ -0,0 +1,65 @@ +interface IThing { + /// @return x a number + /// @return y another number + function value() external view returns (uint128 x, uint128 y); +} + +contract Thing is IThing { + struct Value { + uint128 x; + uint128 y; + } + + Value public override value; +} + +// ---- +// ---- +// :IThing devdoc +// { +// "kind": "dev", +// "methods": +// { +// "value()": +// { +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :IThing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Thing devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "value": +// { +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :Thing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_struct_getter_override_different_return_parameter_names.sol b/test/libsolidity/natspecJSON/dev_struct_getter_override_different_return_parameter_names.sol new file mode 100644 index 000000000..0acfa70fc --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_struct_getter_override_different_return_parameter_names.sol @@ -0,0 +1,65 @@ +interface IThing { + /// @return x a number + /// @return y another number + function value() external view returns (uint128 x, uint128 y); +} + +contract Thing is IThing { + struct Value { + uint128 a; + uint128 b; + } + + Value public override value; +} + +// ---- +// ---- +// :IThing devdoc +// { +// "kind": "dev", +// "methods": +// { +// "value()": +// { +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :IThing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Thing devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "value": +// { +// "returns": +// { +// "a": "a number", +// "b": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :Thing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_struct_getter_override_no_return_name.sol b/test/libsolidity/natspecJSON/dev_struct_getter_override_no_return_name.sol new file mode 100644 index 000000000..06810957a --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_struct_getter_override_no_return_name.sol @@ -0,0 +1,62 @@ +interface IThing { + ///@return + function value(uint) external returns (uint128,uint128); +} + +contract Thing is IThing { + struct Value { + uint128 x; + uint128 A; + } + mapping(uint=>Value) public override value; +} + +// ---- +// ---- +// :IThing devdoc +// { +// "kind": "dev", +// "methods": +// { +// "value(uint256)": +// { +// "returns": +// { +// "_0": "" +// } +// } +// }, +// "version": 1 +// } +// +// :IThing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Thing devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "value": +// { +// "return": "x ", +// "returns": +// { +// "x": "" +// } +// } +// }, +// "version": 1 +// } +// +// :Thing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/dev_title_at_function_error.sol b/test/libsolidity/natspecJSON/dev_title_at_function_error.sol new file mode 100644 index 000000000..2b18e8076 --- /dev/null +++ b/test/libsolidity/natspecJSON/dev_title_at_function_error.sol @@ -0,0 +1,10 @@ +/// @author Lefteris +/// @title Just a test contract +contract test { + /// @dev Mul function + /// @title I really should not be here + function mul(uint a, uint second) public returns (uint d) { return a * 7 + second; } +} + +// ---- +// DocstringParsingError 6546: (73-137): Documentation tag @title not valid for functions. diff --git a/test/libsolidity/natspecJSON/docstring_double_empty.sol b/test/libsolidity/natspecJSON/docstring_double_empty.sol new file mode 100644 index 000000000..16222d0ac --- /dev/null +++ b/test/libsolidity/natspecJSON/docstring_double_empty.sol @@ -0,0 +1,21 @@ +contract C { + /// + /// + function vote(uint id) public { + } +} +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/natspec/docstring_enum.sol b/test/libsolidity/natspecJSON/docstring_enum.sol similarity index 51% rename from test/libsolidity/syntaxTests/natspec/docstring_enum.sol rename to test/libsolidity/natspecJSON/docstring_enum.sol index d80484446..d5ace6b14 100644 --- a/test/libsolidity/syntaxTests/natspec/docstring_enum.sol +++ b/test/libsolidity/natspecJSON/docstring_enum.sol @@ -9,3 +9,17 @@ contract C { } } // ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/docstring_named_return_parameter.sol b/test/libsolidity/natspecJSON/docstring_named_return_parameter.sol new file mode 100644 index 000000000..01e0368d4 --- /dev/null +++ b/test/libsolidity/natspecJSON/docstring_named_return_parameter.sol @@ -0,0 +1,28 @@ +abstract contract C { + /// @return value The value returned by this function. + function vote() public virtual returns (uint value); +} +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": +// { +// "vote()": +// { +// "returns": +// { +// "value": "The value returned by this function." +// } +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/natspec/docstring_parameter.sol b/test/libsolidity/natspecJSON/docstring_parameter.sol similarity index 61% rename from test/libsolidity/syntaxTests/natspec/docstring_parameter.sol rename to test/libsolidity/natspecJSON/docstring_parameter.sol index 84a2c2ae0..deacbbcaa 100644 --- a/test/libsolidity/syntaxTests/natspec/docstring_parameter.sol +++ b/test/libsolidity/natspecJSON/docstring_parameter.sol @@ -10,3 +10,17 @@ contract C { } } // ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/docstring_private_state_variable.sol b/test/libsolidity/natspecJSON/docstring_private_state_variable.sol new file mode 100644 index 000000000..2ea1747e0 --- /dev/null +++ b/test/libsolidity/natspecJSON/docstring_private_state_variable.sol @@ -0,0 +1,27 @@ +contract C { + /// @notice example of notice + /// @dev example of dev + uint private state; +} +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "state": +// { +// "details": "example of dev" +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/docstring_state_variable.sol b/test/libsolidity/natspecJSON/docstring_state_variable.sol new file mode 100644 index 000000000..5627c2060 --- /dev/null +++ b/test/libsolidity/natspecJSON/docstring_state_variable.sol @@ -0,0 +1,33 @@ +contract C { + /// @notice example of notice + /// @dev example of dev + uint public state; +} +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "state": +// { +// "details": "example of dev" +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": +// { +// "state()": +// { +// "notice": "example of notice" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/natspec/docstring_struct.sol b/test/libsolidity/natspecJSON/docstring_struct.sol similarity index 56% rename from test/libsolidity/syntaxTests/natspec/docstring_struct.sol rename to test/libsolidity/natspecJSON/docstring_struct.sol index 621a88a53..91e5802dd 100644 --- a/test/libsolidity/syntaxTests/natspec/docstring_struct.sol +++ b/test/libsolidity/natspecJSON/docstring_struct.sol @@ -10,3 +10,17 @@ contract C { } } // ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/natspec/docstring_variable.sol b/test/libsolidity/natspecJSON/docstring_variable.sol similarity index 64% rename from test/libsolidity/syntaxTests/natspec/docstring_variable.sol rename to test/libsolidity/natspecJSON/docstring_variable.sol index ccbd4c8a5..66a143ff8 100644 --- a/test/libsolidity/syntaxTests/natspec/docstring_variable.sol +++ b/test/libsolidity/natspecJSON/docstring_variable.sol @@ -11,3 +11,17 @@ contract C { } } // ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_event_from_foreign_contract.sol b/test/libsolidity/natspecJSON/emit_event_from_foreign_contract.sol new file mode 100644 index 000000000..669775131 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_event_from_foreign_contract.sol @@ -0,0 +1,69 @@ +contract X { + /// @notice Userdoc for event E. + /// @dev Devdoc for event E. + event E(); +} + +contract C { + function g() public { + emit X.E(); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "events": +// { +// "E()": +// { +// "details": "Devdoc for event E." +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "events": +// { +// "E()": +// { +// "notice": "Userdoc for event E." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :X devdoc +// { +// "events": +// { +// "E()": +// { +// "details": "Devdoc for event E." +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :X userdoc +// { +// "events": +// { +// "E()": +// { +// "notice": "Userdoc for event E." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_event_from_foreign_contract_no_inheritance.sol b/test/libsolidity/natspecJSON/emit_event_from_foreign_contract_no_inheritance.sol new file mode 100644 index 000000000..c89091391 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_event_from_foreign_contract_no_inheritance.sol @@ -0,0 +1,59 @@ +// Tests that emitting an event from contract C in contract D does not inherit natspec from C.E + +contract C { + /// @notice C.E event + /// @dev C.E event + event E(); +} + +contract D { + event E(); + + function test() public { + emit C.E(); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "events": +// { +// "E()": +// { +// "details": "C.E event" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "events": +// { +// "E()": +// { +// "notice": "C.E event" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :D devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :D userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_event_from_foreign_contract_with_same_signature.sol b/test/libsolidity/natspecJSON/emit_event_from_foreign_contract_with_same_signature.sol new file mode 100644 index 000000000..6030c27d9 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_event_from_foreign_contract_with_same_signature.sol @@ -0,0 +1,74 @@ +contract C { + /// @notice C.E event + /// @dev C.E event + event E(uint256 value); +} + +contract D { + /// @notice D.E event + /// @dev D.E event + event E(uint256 value); + + function test() public { + emit C.E(1); + emit E(2); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "events": +// { +// "E(uint256)": +// { +// "details": "C.E event" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "events": +// { +// "E(uint256)": +// { +// "notice": "C.E event" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :D devdoc +// { +// "events": +// { +// "E(uint256)": +// { +// "details": "D.E event" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :D userdoc +// { +// "events": +// { +// "E(uint256)": +// { +// "notice": "D.E event" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries.sol b/test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries.sol new file mode 100644 index 000000000..46c8cadf5 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries.sol @@ -0,0 +1,122 @@ +library L1 { + /// @notice This event is defined in Library L1 + /// @dev This should not appear in Contract C dev doc + event SameSignatureEvent(uint16); +} +library L2 { + /// @notice This event is defined in Library L2 + /// @dev This should not appear in Contract C dev doc + event SameSignatureEvent(uint16); +} +library L3 { + /// @notice This event is defined in Library L3 + /// @dev This should not appear in Contract C dev doc + event SameSignatureEvent(uint16); +} +contract C { + function f() public { + emit L1.SameSignatureEvent(0); + emit L2.SameSignatureEvent(1); + emit L3.SameSignatureEvent(2); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L1 devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L1 userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in Library L1" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L2 devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L2 userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in Library L2" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L3 devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L3 userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in Library L3" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries_missing_natspec.sol b/test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries_missing_natspec.sol new file mode 100644 index 000000000..ba51b10c6 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_same_signature_event_different_libraries_missing_natspec.sol @@ -0,0 +1,90 @@ +library L1 { + event SameSignatureEvent(uint16); +} +library L2 { + /// @notice This event is defined in library L2 + /// @dev This should not appear in Contract C devdoc + event SameSignatureEvent(uint16); +} +library L3 { + event SameSignatureEvent(uint16); +} +contract C { + function f() public { + emit L1.SameSignatureEvent(0); + emit L2.SameSignatureEvent(1); + emit L3.SameSignatureEvent(2); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L1 devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L1 userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L2 devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in Contract C devdoc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L2 userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in library L2" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L3 devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L3 userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_same_signature_event_library_contract.sol b/test/libsolidity/natspecJSON/emit_same_signature_event_library_contract.sol new file mode 100644 index 000000000..9b198afde --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_same_signature_event_library_contract.sol @@ -0,0 +1,104 @@ +library L { + /// @notice This event is defined in Library L + /// @dev This should not appear in Contract C dev doc + event SameSignatureEvent(uint16); + /// @notice This event is defined in Library L + /// @dev This should appear in Contract C dev doc + event LibraryEvent(uint32); +} +contract C { + /// @notice This event is defined in Contract C + /// @dev This should appear in Contract C dev doc + event SameSignatureEvent(uint16); + /// @notice This event is defined in Contract C + /// @dev This should appear in contract C dev doc + event ContractEvent(uint32); + function f() public { + emit L.SameSignatureEvent(0); + emit SameSignatureEvent(1); + emit L.LibraryEvent(2); + emit ContractEvent(3); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "events": +// { +// "ContractEvent(uint32)": +// { +// "details": "This should appear in contract C dev doc" +// }, +// "LibraryEvent(uint32)": +// { +// "details": "This should appear in Contract C dev doc" +// }, +// "SameSignatureEvent(uint16)": +// { +// "details": "This should appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "events": +// { +// "ContractEvent(uint32)": +// { +// "notice": "This event is defined in Contract C" +// }, +// "LibraryEvent(uint32)": +// { +// "notice": "This event is defined in Library L" +// }, +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in Contract C" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L devdoc +// { +// "events": +// { +// "LibraryEvent(uint32)": +// { +// "details": "This should appear in Contract C dev doc" +// }, +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L userdoc +// { +// "events": +// { +// "LibraryEvent(uint32)": +// { +// "notice": "This event is defined in Library L" +// }, +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in Library L" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_same_signature_event_library_contract_missing_natspec.sol b/test/libsolidity/natspecJSON/emit_same_signature_event_library_contract_missing_natspec.sol new file mode 100644 index 000000000..9bc2f57f3 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_same_signature_event_library_contract_missing_natspec.sol @@ -0,0 +1,89 @@ +library L { + /// @notice This event is defined in library L + /// @dev This should not appear in contract C devdoc + event SameSignatureEvent(uint16); + /// @notice This event is defined in library L + /// @dev This should appear in contract C devdoc + event LibraryEvent(uint32); +} +contract C { + event SameSignatureEvent(uint16); + /// @notice This event is defined in contract C + event ContractEvent(uint32); + function f() public { + emit L.SameSignatureEvent(0); + emit SameSignatureEvent(1); + emit L.LibraryEvent(2); + emit ContractEvent(3); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "events": +// { +// "LibraryEvent(uint32)": +// { +// "details": "This should appear in contract C devdoc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "events": +// { +// "ContractEvent(uint32)": +// { +// "notice": "This event is defined in contract C" +// }, +// "LibraryEvent(uint32)": +// { +// "notice": "This event is defined in library L" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L devdoc +// { +// "events": +// { +// "LibraryEvent(uint32)": +// { +// "details": "This should appear in contract C devdoc" +// }, +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in contract C devdoc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L userdoc +// { +// "events": +// { +// "LibraryEvent(uint32)": +// { +// "notice": "This event is defined in library L" +// }, +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in library L" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited.sol b/test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited.sol new file mode 100644 index 000000000..ecc7ee627 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited.sol @@ -0,0 +1,102 @@ +contract D { + /// @notice This event is defined in contract D + /// @dev This should appear in Contract C dev doc + event SameSignatureEvent(uint16); +} +library L { + /// @notice This event is defined in Library L + /// @dev This should not appear in Contract C + event SameSignatureEvent(uint16); +} +contract C is D { + function f() public { + emit L.SameSignatureEvent(0); + emit D.SameSignatureEvent(1); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in contract D" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :D devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should appear in Contract C dev doc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :D userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in contract D" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in Contract C" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in Library L" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited_missing_natspec.sol b/test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited_missing_natspec.sol new file mode 100644 index 000000000..a3a6286c5 --- /dev/null +++ b/test/libsolidity/natspecJSON/emit_same_signature_event_library_inherited_missing_natspec.sol @@ -0,0 +1,72 @@ +contract D { + event SameSignatureEvent(uint16); +} +library L { + /// @notice This event is defined in library L + /// @dev This should not appear in contract C devdoc + event SameSignatureEvent(uint16); +} +contract C is D { + function f() public { + emit L.SameSignatureEvent(0); + emit D.SameSignatureEvent(1); + } +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :D devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :D userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :L devdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "details": "This should not appear in contract C devdoc" +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :L userdoc +// { +// "events": +// { +// "SameSignatureEvent(uint16)": +// { +// "notice": "This event is defined in library L" +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/empty_comment.sol b/test/libsolidity/natspecJSON/empty_comment.sol new file mode 100644 index 000000000..4310c26d2 --- /dev/null +++ b/test/libsolidity/natspecJSON/empty_comment.sol @@ -0,0 +1,19 @@ +// +contract test +{} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/enum_no_docs.sol b/test/libsolidity/natspecJSON/enum_no_docs.sol new file mode 100644 index 000000000..021f7c6b2 --- /dev/null +++ b/test/libsolidity/natspecJSON/enum_no_docs.sol @@ -0,0 +1,26 @@ +contract C { + /// @title example of title + /// @author example of author + /// @notice example of notice + /// @dev example of dev + enum Color { + Red, + Green + } +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/error.sol b/test/libsolidity/natspecJSON/error.sol new file mode 100644 index 000000000..c82412fec --- /dev/null +++ b/test/libsolidity/natspecJSON/error.sol @@ -0,0 +1,46 @@ +contract test { + /// Something failed. + /// @dev an error. + /// @param a first parameter + /// @param b second parameter + error E(uint a, uint b); +} + +// ---- +// ---- +// :test devdoc +// { +// "errors": +// { +// "E(uint256,uint256)": +// [ +// { +// "details": "an error.", +// "params": +// { +// "a": "first parameter", +// "b": "second parameter" +// } +// } +// ] +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "errors": +// { +// "E(uint256,uint256)": +// [ +// { +// "notice": "Something failed." +// } +// ] +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/error_multiple.sol b/test/libsolidity/natspecJSON/error_multiple.sol new file mode 100644 index 000000000..205e79a99 --- /dev/null +++ b/test/libsolidity/natspecJSON/error_multiple.sol @@ -0,0 +1,107 @@ +contract A { + /// Something failed. + /// @dev an error. + /// @param x first parameter + /// @param y second parameter + error E(uint x, uint y); +} +contract test { + /// X Something failed. + /// @dev X an error. + /// @param a X first parameter + /// @param b X second parameter + error E(uint a, uint b); + function f(bool a) public pure { + if (a) + revert E(1, 2); + else + revert A.E(5, 6); + } +} + +// ---- +// ---- +// :A devdoc +// { +// "errors": +// { +// "E(uint256,uint256)": +// [ +// { +// "details": "an error.", +// "params": +// { +// "x": "first parameter", +// "y": "second parameter" +// } +// } +// ] +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :A userdoc +// { +// "errors": +// { +// "E(uint256,uint256)": +// [ +// { +// "notice": "Something failed." +// } +// ] +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :test devdoc +// { +// "errors": +// { +// "E(uint256,uint256)": +// [ +// { +// "details": "an error.", +// "params": +// { +// "x": "first parameter", +// "y": "second parameter" +// } +// }, +// { +// "details": "X an error.", +// "params": +// { +// "a": "X first parameter", +// "b": "X second parameter" +// } +// } +// ] +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "errors": +// { +// "E(uint256,uint256)": +// [ +// { +// "notice": "Something failed." +// }, +// { +// "notice": "X Something failed." +// } +// ] +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/event.sol b/test/libsolidity/natspecJSON/event.sol new file mode 100644 index 000000000..9887b021d --- /dev/null +++ b/test/libsolidity/natspecJSON/event.sol @@ -0,0 +1,44 @@ +contract ERC20 { + /// @notice This event is emitted when a transfer occurs. + /// @param from The source account. + /// @param to The destination account. + /// @param amount The amount. + /// @dev A test case! + event Transfer(address indexed from, address indexed to, uint amount); +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/event_inheritance.sol b/test/libsolidity/natspecJSON/event_inheritance.sol new file mode 100644 index 000000000..7912bd1b5 --- /dev/null +++ b/test/libsolidity/natspecJSON/event_inheritance.sol @@ -0,0 +1,116 @@ +contract ERC20 { + /// @notice This event is emitted when a transfer occurs. + /// @param from The source account. + /// @param to The destination account. + /// @param amount The amount. + /// @dev A test case! + event Transfer(address indexed from, address indexed to, uint amount); +} +contract A is ERC20 { +} +contract B is A { +} + +// ---- +// ---- +// :A devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :A userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :B userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :ERC20 devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/event_inheritance_interface.sol b/test/libsolidity/natspecJSON/event_inheritance_interface.sol new file mode 100644 index 000000000..8b4137fcc --- /dev/null +++ b/test/libsolidity/natspecJSON/event_inheritance_interface.sol @@ -0,0 +1,116 @@ +interface ERC20 { + /// @notice This event is emitted when a transfer occurs. + /// @param from The source account. + /// @param to The destination account. + /// @param amount The amount. + /// @dev A test case! + event Transfer(address indexed from, address indexed to, uint amount); +} +contract A is ERC20 { +} +contract B is A { +} + +// ---- +// ---- +// :A devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :A userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :B devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :B userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :ERC20 devdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "details": "A test case!", +// "params": +// { +// "amount": "The amount.", +// "from": "The source account.", +// "to": "The destination account." +// } +// } +// }, +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "events": +// { +// "Transfer(address,address,uint256)": +// { +// "notice": "This event is emitted when a transfer occurs." +// } +// }, +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_author_function.sol b/test/libsolidity/natspecJSON/invalid/docstring_author_function.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_author_function.sol rename to test/libsolidity/natspecJSON/invalid/docstring_author_function.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_author_title_state_variable.sol b/test/libsolidity/natspecJSON/invalid/docstring_author_title_state_variable.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_author_title_state_variable.sol rename to test/libsolidity/natspecJSON/invalid/docstring_author_title_state_variable.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_empty_description.sol b/test/libsolidity/natspecJSON/invalid/docstring_empty_description.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_empty_description.sol rename to test/libsolidity/natspecJSON/invalid/docstring_empty_description.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_empty_tag.sol b/test/libsolidity/natspecJSON/invalid/docstring_empty_tag.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_empty_tag.sol rename to test/libsolidity/natspecJSON/invalid/docstring_empty_tag.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inherit_modifier_no_return.sol b/test/libsolidity/natspecJSON/invalid/docstring_inherit_modifier_no_return.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inherit_modifier_no_return.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inherit_modifier_no_return.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inherit_modifier_no_return2.sol b/test/libsolidity/natspecJSON/invalid/docstring_inherit_modifier_no_return2.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inherit_modifier_no_return2.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inherit_modifier_no_return2.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc.sol b/test/libsolidity/natspecJSON/invalid/docstring_inheritdoc.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inheritdoc.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc2.sol b/test/libsolidity/natspecJSON/invalid/docstring_inheritdoc2.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc2.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inheritdoc2.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc3.sol b/test/libsolidity/natspecJSON/invalid/docstring_inheritdoc3.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc3.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inheritdoc3.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc_emptys.sol b/test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_emptys.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc_emptys.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_emptys.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc_twice.sol b/test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_twice.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc_twice.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_twice.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc_wrong_type.sol b/test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_wrong_type.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_inheritdoc_wrong_type.sol rename to test/libsolidity/natspecJSON/invalid/docstring_inheritdoc_wrong_type.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_named_return_param_mismatch.sol b/test/libsolidity/natspecJSON/invalid/docstring_named_return_param_mismatch.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_named_return_param_mismatch.sol rename to test/libsolidity/natspecJSON/invalid/docstring_named_return_param_mismatch.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_non_public_state_variable_with_return.sol b/test/libsolidity/natspecJSON/invalid/docstring_non_public_state_variable_with_return.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_non_public_state_variable_with_return.sol rename to test/libsolidity/natspecJSON/invalid/docstring_non_public_state_variable_with_return.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_parameter.sol b/test/libsolidity/natspecJSON/invalid/docstring_parameter.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_parameter.sol rename to test/libsolidity/natspecJSON/invalid/docstring_parameter.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_return_size_mismatch.sol b/test/libsolidity/natspecJSON/invalid/docstring_return_size_mismatch.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_return_size_mismatch.sol rename to test/libsolidity/natspecJSON/invalid/docstring_return_size_mismatch.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_state_variable_too_many_return_tags.sol b/test/libsolidity/natspecJSON/invalid/docstring_state_variable_too_many_return_tags.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_state_variable_too_many_return_tags.sol rename to test/libsolidity/natspecJSON/invalid/docstring_state_variable_too_many_return_tags.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/docstring_too_many_return_tags.sol b/test/libsolidity/natspecJSON/invalid/docstring_too_many_return_tags.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/docstring_too_many_return_tags.sol rename to test/libsolidity/natspecJSON/invalid/docstring_too_many_return_tags.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/inherit_doc_events.sol b/test/libsolidity/natspecJSON/invalid/inherit_doc_events.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/inherit_doc_events.sol rename to test/libsolidity/natspecJSON/invalid/inherit_doc_events.sol diff --git a/test/libsolidity/syntaxTests/natspec/invalid/invalid_tag.sol b/test/libsolidity/natspecJSON/invalid/invalid_tag.sol similarity index 100% rename from test/libsolidity/syntaxTests/natspec/invalid/invalid_tag.sol rename to test/libsolidity/natspecJSON/invalid/invalid_tag.sol diff --git a/test/libsolidity/natspecJSON/multiline_notice_without_tag.sol b/test/libsolidity/natspecJSON/multiline_notice_without_tag.sol new file mode 100644 index 000000000..4f055b2f0 --- /dev/null +++ b/test/libsolidity/natspecJSON/multiline_notice_without_tag.sol @@ -0,0 +1,27 @@ +contract test { + /// I do something awesome + /// which requires two lines to explain + function mul(uint a) public returns (uint d) { return a * 7; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "mul(uint256)": +// { +// "notice": "I do something awesome which requires two lines to explain" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/notice_without_tag.sol b/test/libsolidity/natspecJSON/notice_without_tag.sol new file mode 100644 index 000000000..d56299339 --- /dev/null +++ b/test/libsolidity/natspecJSON/notice_without_tag.sol @@ -0,0 +1,26 @@ +contract test { + /// I do something awesome + function mul(uint a) public returns (uint d) { return a * 7; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "mul(uint256)": +// { +// "notice": "I do something awesome" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/private_state_variable.sol b/test/libsolidity/natspecJSON/private_state_variable.sol new file mode 100644 index 000000000..7d7707a8d --- /dev/null +++ b/test/libsolidity/natspecJSON/private_state_variable.sol @@ -0,0 +1,27 @@ +contract test { + /// @dev example of dev + uint private state; +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "state": +// { +// "details": "example of dev" +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/public_state_variable.sol b/test/libsolidity/natspecJSON/public_state_variable.sol new file mode 100644 index 000000000..5fda30cec --- /dev/null +++ b/test/libsolidity/natspecJSON/public_state_variable.sol @@ -0,0 +1,40 @@ +contract test { + /// @notice example of notice + /// @dev example of dev + /// @return returns state + uint public state; +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "state": +// { +// "details": "example of dev", +// "return": "returns state", +// "returns": +// { +// "_0": "returns state" +// } +// } +// }, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "state()": +// { +// "notice": "example of notice" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/public_state_variable_struct.sol b/test/libsolidity/natspecJSON/public_state_variable_struct.sol new file mode 100644 index 000000000..438247243 --- /dev/null +++ b/test/libsolidity/natspecJSON/public_state_variable_struct.sol @@ -0,0 +1,44 @@ +contract Bank { + struct Coin { + string observeGraphicURL; + string reverseGraphicURL; + } + + /// @notice Get the n-th coin I own + /// @return observeGraphicURL Front pic + /// @return reverseGraphicURL Back pic + Coin[] public coinStack; +} + +// ---- +// ---- +// :Bank devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "coinStack": +// { +// "returns": +// { +// "observeGraphicURL": "Front pic", +// "reverseGraphicURL": "Back pic" +// } +// } +// }, +// "version": 1 +// } +// +// :Bank userdoc +// { +// "kind": "user", +// "methods": +// { +// "coinStack(uint256)": +// { +// "notice": "Get the n-th coin I own" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/public_state_variable_struct_repeated.sol b/test/libsolidity/natspecJSON/public_state_variable_struct_repeated.sol new file mode 100644 index 000000000..78a6f9eed --- /dev/null +++ b/test/libsolidity/natspecJSON/public_state_variable_struct_repeated.sol @@ -0,0 +1,14 @@ +contract Bank { + struct Coin { + string obverseGraphicURL; + string reverseGraphicURL; + } + + /// @notice Get the n-th coin I own + /// @return obverseGraphicURL Front pic + /// @return obverseGraphicURL Front pic + Coin[] public coinStack; +} + +// ---- +// DocstringParsingError 5856: (113-236): Documentation tag "@return obverseGraphicURL Front pic" does not contain the name of its return parameter. diff --git a/test/libsolidity/natspecJSON/return_param_amount_differs.sol b/test/libsolidity/natspecJSON/return_param_amount_differs.sol new file mode 100644 index 000000000..2d18ce8a1 --- /dev/null +++ b/test/libsolidity/natspecJSON/return_param_amount_differs.sol @@ -0,0 +1,64 @@ +interface IThing { + /// @return x a number + /// @return y another number + function value() external view returns (uint128 x, uint128 y); +} + +contract Thing is IThing { + struct Value { + uint128 x; + uint128 y; + } + + Value public override value; +} +// ---- +// ---- +// :IThing devdoc +// { +// "kind": "dev", +// "methods": +// { +// "value()": +// { +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :IThing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Thing devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "value": +// { +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :Thing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/return_param_amount_differs2.sol b/test/libsolidity/natspecJSON/return_param_amount_differs2.sol new file mode 100644 index 000000000..e10802c10 --- /dev/null +++ b/test/libsolidity/natspecJSON/return_param_amount_differs2.sol @@ -0,0 +1,73 @@ +interface IThing { + /// @param v value to search for + /// @return x a number + /// @return y another number + function value(uint256 v) external view returns (uint128 x, uint128 y); +} + +contract Thing is IThing { + struct Value { + uint128 x; + uint128 y; + } + + mapping(uint256=>Value) public override value; +} +// ---- +// ---- +// :IThing devdoc +// { +// "kind": "dev", +// "methods": +// { +// "value(uint256)": +// { +// "params": +// { +// "v": "value to search for" +// }, +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :IThing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Thing devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "value": +// { +// "params": +// { +// "v": "value to search for" +// }, +// "returns": +// { +// "x": "a number", +// "y": "another number" +// } +// } +// }, +// "version": 1 +// } +// +// :Thing userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/slash3_slash3.sol b/test/libsolidity/natspecJSON/slash3_slash3.sol new file mode 100644 index 000000000..fc8e47f96 --- /dev/null +++ b/test/libsolidity/natspecJSON/slash3_slash3.sol @@ -0,0 +1,27 @@ +contract test { + /// @notice lorem + /// ipsum + function f() public { } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "f()": +// { +// "notice": "lorem ipsum" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/slash3_slash4.sol b/test/libsolidity/natspecJSON/slash3_slash4.sol new file mode 100644 index 000000000..c428f5e19 --- /dev/null +++ b/test/libsolidity/natspecJSON/slash3_slash4.sol @@ -0,0 +1,27 @@ +contract test { + /// @notice lorem + //// ipsum + function f() public { } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "f()": +// { +// "notice": "lorem" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/slash4.sol b/test/libsolidity/natspecJSON/slash4.sol new file mode 100644 index 000000000..74997524e --- /dev/null +++ b/test/libsolidity/natspecJSON/slash4.sol @@ -0,0 +1,20 @@ +contract test { + //// @notice lorem ipsum + function f() public { } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/star3.sol b/test/libsolidity/natspecJSON/star3.sol new file mode 100644 index 000000000..24e742f8a --- /dev/null +++ b/test/libsolidity/natspecJSON/star3.sol @@ -0,0 +1,22 @@ +contract test { + /*** + * @notice lorem ipsum + */ + function f() public { } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/struct_no_docs.sol b/test/libsolidity/natspecJSON/struct_no_docs.sol new file mode 100644 index 000000000..e29a4b8e9 --- /dev/null +++ b/test/libsolidity/natspecJSON/struct_no_docs.sol @@ -0,0 +1,27 @@ +contract C { + /// @title example of title + /// @author example of author + /// @notice example of notice + /// @dev example of dev + struct Example { + string text; + bool valid; + uint256 value; + } +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_basic_test.sol b/test/libsolidity/natspecJSON/user_basic_test.sol new file mode 100644 index 000000000..0ec21750d --- /dev/null +++ b/test/libsolidity/natspecJSON/user_basic_test.sol @@ -0,0 +1,26 @@ +contract test { + /// @notice Multiplies `a` by 7 + function mul(uint a) public returns(uint d) { return a * 7; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "mul(uint256)": +// { +// "notice": "Multiplies `a` by 7" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_constructor.sol b/test/libsolidity/natspecJSON/user_constructor.sol new file mode 100644 index 000000000..0dedd30a6 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_constructor.sol @@ -0,0 +1,26 @@ +contract test { + /// @notice this is a really nice constructor + constructor(uint a, uint second) { } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "constructor": +// { +// "notice": "this is a really nice constructor" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_constructor_and_function.sol b/test/libsolidity/natspecJSON/user_constructor_and_function.sol new file mode 100644 index 000000000..5e8cfd04a --- /dev/null +++ b/test/libsolidity/natspecJSON/user_constructor_and_function.sol @@ -0,0 +1,32 @@ +contract test { + /// @notice this is a really nice constructor + constructor(uint a, uint second) { } + /// another multiplier + function mul(uint a, uint second) public returns(uint d) { return a * 7 + second; } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "constructor": +// { +// "notice": "this is a really nice constructor" +// }, +// "mul(uint256,uint256)": +// { +// "notice": "another multiplier" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_default_inherit.sol b/test/libsolidity/natspecJSON/user_default_inherit.sol new file mode 100644 index 000000000..b4f97cfa3 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_default_inherit.sol @@ -0,0 +1,117 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// Second line. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract Middle is ERC20 { + function transfer(address to, uint amount) virtual override external returns (bool) + { + return false; + } +} + +contract Token is Middle { + function transfer(address to, uint amount) override external returns (bool) + { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." +// } +// }, +// "version": 1 +// } +// +// :Middle devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Middle userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``. Second line." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_default_inherit_variable.sol b/test/libsolidity/natspecJSON/user_default_inherit_variable.sol new file mode 100644 index 000000000..89d57d011 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_default_inherit_variable.sol @@ -0,0 +1,66 @@ +contract C { + /// @notice Hello world + /// @dev test + function x() virtual external returns (uint) { + return 1; + } +} + +contract D is C { + uint public override x; +} + +// ---- +// ---- +// :C devdoc +// { +// "kind": "dev", +// "methods": +// { +// "x()": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } +// +// :D devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "x": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :D userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_empty_contract.sol b/test/libsolidity/natspecJSON/user_empty_contract.sol new file mode 100644 index 000000000..09f178606 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_empty_contract.sol @@ -0,0 +1,17 @@ +contract test { } + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_empty_natspec_test.sol b/test/libsolidity/natspecJSON/user_empty_natspec_test.sol new file mode 100644 index 000000000..aa19fac3a --- /dev/null +++ b/test/libsolidity/natspecJSON/user_empty_natspec_test.sol @@ -0,0 +1,22 @@ +contract test { + /// + /// + function f() public { + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_explicit_inherit.sol b/test/libsolidity/natspecJSON/user_explicit_inherit.sol new file mode 100644 index 000000000..a8ddb3133 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_explicit_inherit.sol @@ -0,0 +1,98 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 { + function transfer(address to, uint amount) virtual external returns (bool) { + return false; + } +} + +contract Token is ERC21, ERC20 { + /// @inheritdoc ERC20 + function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_explicit_inherit2.sol b/test/libsolidity/natspecJSON/user_explicit_inherit2.sol new file mode 100644 index 000000000..4c726f552 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_explicit_inherit2.sol @@ -0,0 +1,115 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 is ERC20 { + function transfer(address to, uint amount) virtual override external returns (bool) { + return false; + } +} + +contract Token is ERC20 { + /// @inheritdoc ERC20 + function transfer(address to, uint amount) override external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_explicit_inherit_partial.sol b/test/libsolidity/natspecJSON/user_explicit_inherit_partial.sol new file mode 100644 index 000000000..c69bd4121 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_explicit_inherit_partial.sol @@ -0,0 +1,100 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 { + function transfer(address to, uint amount) virtual external returns (bool) { + return false; + } +} + +contract Token is ERC21, ERC20 { + /// @inheritdoc ERC20 + /// @dev override dev comment + /// @notice override notice + function transfer(address to, uint amount) override(ERC21, ERC20) external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "override dev comment", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "override notice" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_explicit_inherit_partial2.sol b/test/libsolidity/natspecJSON/user_explicit_inherit_partial2.sol new file mode 100644 index 000000000..6bb49e887 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_explicit_inherit_partial2.sol @@ -0,0 +1,117 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract ERC21 is ERC20 { + /// @inheritdoc ERC20 + /// @dev override dev comment + /// @notice override notice + function transfer(address to, uint amount) virtual override external returns (bool) { + return false; + } +} + +contract Token is ERC21 { + function transfer(address to, uint amount) override external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :ERC21 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "override dev comment", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC21 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "override notice" +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "override dev comment", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "override notice" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_explicit_inherit_variable.sol b/test/libsolidity/natspecJSON/user_explicit_inherit_variable.sol new file mode 100644 index 000000000..b35a92873 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_explicit_inherit_variable.sol @@ -0,0 +1,87 @@ +contract B { + function x() virtual external returns (uint) { + return 1; + } +} + +contract C { + /// @notice Hello world + /// @dev test + function x() virtual external returns (uint) { + return 1; + } +} + +contract D is C, B { + /// @inheritdoc C + uint public override(C, B) x; +} + +// ---- +// ---- +// :B devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :B userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } +// +// :C devdoc +// { +// "kind": "dev", +// "methods": +// { +// "x()": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :C userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } +// +// :D devdoc +// { +// "kind": "dev", +// "methods": {}, +// "stateVariables": +// { +// "x": +// { +// "details": "test" +// } +// }, +// "version": 1 +// } +// +// :D userdoc +// { +// "kind": "user", +// "methods": +// { +// "x()": +// { +// "notice": "Hello world" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_inherit_parameter_mismatch.sol b/test/libsolidity/natspecJSON/user_inherit_parameter_mismatch.sol new file mode 100644 index 000000000..a8ab60bd1 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_inherit_parameter_mismatch.sol @@ -0,0 +1,97 @@ +interface ERC20 { + /// Transfer ``amount`` from ``msg.sender`` to ``to``. + /// @dev test + /// @param to address to transfer to + /// @param amount amount to transfer + function transfer(address to, uint amount) external returns (bool); +} + +contract Middle is ERC20 { + function transfer(address to, uint amount) override virtual external returns (bool) { + return false; + } +} + +contract Token is Middle { + function transfer(address too, uint amount) override external returns (bool) { + return false; + } +} + +// ---- +// ---- +// :ERC20 devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :ERC20 userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :Middle devdoc +// { +// "kind": "dev", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "details": "test", +// "params": +// { +// "amount": "amount to transfer", +// "to": "address to transfer to" +// } +// } +// }, +// "version": 1 +// } +// +// :Middle userdoc +// { +// "kind": "user", +// "methods": +// { +// "transfer(address,uint256)": +// { +// "notice": "Transfer ``amount`` from ``msg.sender`` to ``to``." +// } +// }, +// "version": 1 +// } +// +// :Token devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :Token userdoc +// { +// "kind": "user", +// "methods": {}, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_multiline_comment.sol b/test/libsolidity/natspecJSON/user_multiline_comment.sol new file mode 100644 index 000000000..5407c7fe8 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_multiline_comment.sol @@ -0,0 +1,29 @@ +contract test { + /// @notice Multiplies `a` by 7 + /// and then adds `b` + function mul_and_add(uint a, uint256 b) public returns (uint256 d) { + return (a * 7) + b; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "mul_and_add(uint256,uint256)": +// { +// "notice": "Multiplies `a` by 7 and then adds `b`" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_multiline_empty_lines.sol b/test/libsolidity/natspecJSON/user_multiline_empty_lines.sol new file mode 100644 index 000000000..12bc050e7 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_multiline_empty_lines.sol @@ -0,0 +1,31 @@ +contract test { + /** + * + * + * @notice hello world + */ + function f() public { + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "f()": +// { +// "notice": "hello world" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_multiple_functions.sol b/test/libsolidity/natspecJSON/user_multiple_functions.sol new file mode 100644 index 000000000..3c6759bd2 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_multiple_functions.sol @@ -0,0 +1,46 @@ +contract test { + /// @notice Multiplies `a` by 7 and then adds `b` + function mul_and_add(uint a, uint256 b) public returns (uint256 d) { + return (a * 7) + b; + } + + /// @notice Divides `input` by `div` + function divide(uint input, uint div) public returns (uint d) { + return input / div; + } + + /// @notice Subtracts 3 from `input` + function sub(int input) public returns (int d) { + return input - 3; + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "divide(uint256,uint256)": +// { +// "notice": "Divides `input` by `div`" +// }, +// "mul_and_add(uint256,uint256)": +// { +// "notice": "Multiplies `a` by 7 and then adds `b`" +// }, +// "sub(int256)": +// { +// "notice": "Subtracts 3 from `input`" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/natspecJSON/user_newline_break.sol b/test/libsolidity/natspecJSON/user_newline_break.sol new file mode 100644 index 000000000..7284c8808 --- /dev/null +++ b/test/libsolidity/natspecJSON/user_newline_break.sol @@ -0,0 +1,30 @@ +contract test { + /// + /// @notice hello + + /// @notice world + function f() public { + } +} + +// ---- +// ---- +// :test devdoc +// { +// "kind": "dev", +// "methods": {}, +// "version": 1 +// } +// +// :test userdoc +// { +// "kind": "user", +// "methods": +// { +// "f()": +// { +// "notice": "world" +// } +// }, +// "version": 1 +// } diff --git a/test/libsolidity/syntaxTests/natspec/docstring_double_empty.sol b/test/libsolidity/syntaxTests/natspec/docstring_double_empty.sol deleted file mode 100644 index a84d5d928..000000000 --- a/test/libsolidity/syntaxTests/natspec/docstring_double_empty.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - /// - /// - function vote(uint id) public { - } -} -// ---- diff --git a/test/libsolidity/syntaxTests/natspec/docstring_named_return_parameter.sol b/test/libsolidity/syntaxTests/natspec/docstring_named_return_parameter.sol deleted file mode 100644 index b7cbad677..000000000 --- a/test/libsolidity/syntaxTests/natspec/docstring_named_return_parameter.sol +++ /dev/null @@ -1,5 +0,0 @@ -abstract contract C { - /// @return value The value returned by this function. - function vote() public virtual returns (uint value); -} -// ---- diff --git a/test/libsolidity/syntaxTests/natspec/docstring_private_state_variable.sol b/test/libsolidity/syntaxTests/natspec/docstring_private_state_variable.sol deleted file mode 100644 index 5b6cfcce4..000000000 --- a/test/libsolidity/syntaxTests/natspec/docstring_private_state_variable.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract C { - /// @notice example of notice - /// @dev example of dev - uint private state; -} -// ---- diff --git a/test/libsolidity/syntaxTests/natspec/docstring_state_variable.sol b/test/libsolidity/syntaxTests/natspec/docstring_state_variable.sol deleted file mode 100644 index deb7bf22c..000000000 --- a/test/libsolidity/syntaxTests/natspec/docstring_state_variable.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract C { - /// @notice example of notice - /// @dev example of dev - uint public state; -} -// ---- diff --git a/test/libsolidity/syntaxTests/natspec/invalid/return_param_amount_differs.sol b/test/libsolidity/syntaxTests/natspec/invalid/return_param_amount_differs.sol deleted file mode 100644 index 7e40b10b9..000000000 --- a/test/libsolidity/syntaxTests/natspec/invalid/return_param_amount_differs.sol +++ /dev/null @@ -1,14 +0,0 @@ -interface IThing { - /// @return x a number - /// @return y another number - function value() external view returns (uint128 x, uint128 y); -} - -contract Thing is IThing { - struct Value { - uint128 x; - uint128 y; - } - - Value public override value; -} diff --git a/test/libsolidity/syntaxTests/natspec/invalid/return_param_amount_differs2.sol b/test/libsolidity/syntaxTests/natspec/invalid/return_param_amount_differs2.sol deleted file mode 100644 index cffe2b390..000000000 --- a/test/libsolidity/syntaxTests/natspec/invalid/return_param_amount_differs2.sol +++ /dev/null @@ -1,16 +0,0 @@ -interface IThing { - /// @param v value to search for - /// @return x a number - /// @return y another number - function value(uint256 v) external view returns (uint128 x, uint128 y); -} - -contract Thing is IThing { - struct Value { - uint128 x; - uint128 y; - } - - mapping(uint256=>Value) public override value; -} -// ---- diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 2e57718bd..a86e6382d 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -25,6 +25,7 @@ add_executable(isoltest ../libsolidity/util/TestFunctionCall.cpp ../libsolidity/GasTest.cpp ../libsolidity/MemoryGuardTest.cpp + ../libsolidity/NatspecJSONTest.cpp ../libsolidity/SyntaxTest.cpp ../libsolidity/SemanticTest.cpp ../libsolidity/AnalysisFramework.cpp