Merge pull request #14506 from ethereum/extracted-natspec-json-tests

Replace Boost-based Natspec test case with one derived from `SyntaxTest`
This commit is contained in:
Kamil Śliwak 2023-09-11 19:28:31 +02:00 committed by GitHub
commit 64a0f62700
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
134 changed files with 5543 additions and 3446 deletions

View File

@ -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): def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
test_sub_dirs = [ test_sub_dirs = [
path.join("test", "libsolidity", "natspecJSON"),
path.join("test", "libsolidity", "smtCheckerTests"), path.join("test", "libsolidity", "smtCheckerTests"),
path.join("test", "libsolidity", "syntaxTests"), path.join("test", "libsolidity", "syntaxTests"),
path.join("test", "libyul", "yulSyntaxTests") path.join("test", "libyul", "yulSyntaxTests")

View File

@ -84,6 +84,8 @@ set(libsolidity_sources
libsolidity/Metadata.cpp libsolidity/Metadata.cpp
libsolidity/MemoryGuardTest.cpp libsolidity/MemoryGuardTest.cpp
libsolidity/MemoryGuardTest.h libsolidity/MemoryGuardTest.h
libsolidity/NatspecJSONTest.cpp
libsolidity/NatspecJSONTest.h
libsolidity/SemanticTest.cpp libsolidity/SemanticTest.cpp
libsolidity/SemanticTest.h libsolidity/SemanticTest.h
libsolidity/SemVerMatcher.cpp libsolidity/SemVerMatcher.cpp
@ -95,7 +97,6 @@ set(libsolidity_sources
libsolidity/SolidityExecutionFramework.h libsolidity/SolidityExecutionFramework.h
libsolidity/SolidityExpressionCompiler.cpp libsolidity/SolidityExpressionCompiler.cpp
libsolidity/SolidityNameAndTypeResolution.cpp libsolidity/SolidityNameAndTypeResolution.cpp
libsolidity/SolidityNatspecJSON.cpp
libsolidity/SolidityOptimizer.cpp libsolidity/SolidityOptimizer.cpp
libsolidity/SolidityParser.cpp libsolidity/SolidityParser.cpp
libsolidity/SolidityTypes.cpp libsolidity/SolidityTypes.cpp

View File

@ -24,6 +24,7 @@
#include <test/libsolidity/ASTPropertyTest.h> #include <test/libsolidity/ASTPropertyTest.h>
#include <test/libsolidity/GasTest.h> #include <test/libsolidity/GasTest.h>
#include <test/libsolidity/MemoryGuardTest.h> #include <test/libsolidity/MemoryGuardTest.h>
#include <test/libsolidity/NatspecJSONTest.h>
#include <test/libsolidity/SyntaxTest.h> #include <test/libsolidity/SyntaxTest.h>
#include <test/libsolidity/SemanticTest.h> #include <test/libsolidity/SemanticTest.h>
#include <test/libsolidity/SMTCheckerTest.h> #include <test/libsolidity/SMTCheckerTest.h>
@ -74,6 +75,7 @@ Testsuite const g_interactiveTestsuites[] = {
{"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create}, {"Semantic", "libsolidity", "semanticTests", false, true, &SemanticTest::create},
{"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create}, {"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create},
{"JSON ABI", "libsolidity", "ABIJson", false, false, &ABIJsonTest::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}, {"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SMTCheckerTest::create},
{"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create}, {"Gas Estimates", "libsolidity", "gasTests", false, false, &GasTest::create},
{"Memory Guard", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create}, {"Memory Guard", "libsolidity", "memoryGuardTests", false, false, &MemoryGuardTest::create},

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* Unit tests for the solidity compiler ABI JSON Interface output.
*/
#include <test/libsolidity/NatspecJSONTest.h>
#include <libsolutil/CommonIO.h>
#include <libsolutil/StringUtils.h>
#include <boost/algorithm/string/predicate.hpp>
#include <fmt/format.h>
#include <vector>
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<TestCase> NatspecJSONTest::create(Config const& _config)
{
return make_unique<NatspecJSONTest>(_config.filename, _config.evmVersion);
}
void NatspecJSONTest::parseCustomExpectations(istream& _stream)
{
soltestAssert(m_expectedNatspecJSON.empty());
// We expect a series of expectations in the following format:
//
// // <qualified contract name> <devdoc|userdoc>
// // <json>
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<string_view, NatspecJSONKind> 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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
/**
* Unit tests for the Natspec userdoc and devdoc JSON output.
*/
#pragma once
#include <test/libsolidity/SyntaxTest.h>
#include <libsolutil/JSON.h>
#include <istream>
#include <map>
#include <memory>
#include <ostream>
#include <string>
#include <string_view>
#include <tuple>
namespace solidity::frontend::test
{
enum class NatspecJSONKind
{
Devdoc,
Userdoc,
};
std::ostream& operator<<(std::ostream& _output, NatspecJSONKind _kind);
using NatspecMap = std::map<std::string, std::map<NatspecJSONKind, Json::Value>>;
using SerializedNatspecMap = std::map<std::string, std::map<NatspecJSONKind, std::string>>;
class NatspecJSONTest: public SyntaxTest
{
public:
static std::unique_ptr<TestCase> 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<std::string_view, NatspecJSONKind> 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;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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.

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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.

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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.

View File

@ -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
// }

View File

@ -9,3 +9,17 @@ contract C {
} }
} }
// ---- // ----
// ----
// :C devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }

View File

@ -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
// }

View File

@ -10,3 +10,17 @@ contract C {
} }
} }
// ---- // ----
// ----
// :C devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -10,3 +10,17 @@ contract C {
} }
} }
// ---- // ----
// ----
// :C devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }

View File

@ -11,3 +11,17 @@ contract C {
} }
} }
// ---- // ----
// ----
// :C devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -0,0 +1,19 @@
//
contract test
{}
// ----
// ----
// :test devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :test userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

View File

@ -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
// }

Some files were not shown because too many files have changed in this diff Show More