mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Adds NatSpec to AST for struct definitions.
This commit is contained in:
parent
f0c0df2d8c
commit
07def48f45
@ -7,6 +7,7 @@ Compiler Features:
|
|||||||
* Assembler: Use ``push0`` for placing ``0`` in the stack for EVM versions starting from "Shanghai". This decreases the deployment costs.
|
* Assembler: Use ``push0`` for placing ``0`` in the stack for EVM versions starting from "Shanghai". This decreases the deployment costs.
|
||||||
* EVM: Support for the EVM Version "Shanghai".
|
* EVM: Support for the EVM Version "Shanghai".
|
||||||
* NatSpec: Add support for NatSpec documentation in ``enum`` definitions.
|
* NatSpec: Add support for NatSpec documentation in ``enum`` definitions.
|
||||||
|
* NatSpec: Add support for NatSpec documentation in ``struct`` definitions.
|
||||||
* Optimizer: Re-implement simplified version of UnusedAssignEliminator and UnusedStoreEliminator. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version.
|
* Optimizer: Re-implement simplified version of UnusedAssignEliminator and UnusedStoreEliminator. It can correctly remove some unused assignments in deeply nested loops that were ignored by the old version.
|
||||||
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
||||||
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
|
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
|
||||||
|
@ -709,7 +709,7 @@ private:
|
|||||||
bool m_global = false;
|
bool m_global = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StructDefinition: public Declaration, public ScopeOpener
|
class StructDefinition: public Declaration, public StructurallyDocumented, public ScopeOpener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StructDefinition(
|
StructDefinition(
|
||||||
@ -717,9 +717,13 @@ public:
|
|||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
ASTPointer<ASTString> const& _name,
|
ASTPointer<ASTString> const& _name,
|
||||||
SourceLocation _nameLocation,
|
SourceLocation _nameLocation,
|
||||||
std::vector<ASTPointer<VariableDeclaration>> _members
|
std::vector<ASTPointer<VariableDeclaration>> _members,
|
||||||
|
ASTPointer<StructuredDocumentation> _documentation
|
||||||
):
|
):
|
||||||
Declaration(_id, _location, _name, std::move(_nameLocation)), m_members(std::move(_members)) {}
|
Declaration(_id, _location, _name, std::move(_nameLocation)),
|
||||||
|
StructurallyDocumented(std::move(_documentation)),
|
||||||
|
m_members(std::move(_members))
|
||||||
|
{}
|
||||||
|
|
||||||
void accept(ASTVisitor& _visitor) override;
|
void accept(ASTVisitor& _visitor) override;
|
||||||
void accept(ASTConstVisitor& _visitor) const override;
|
void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
@ -367,6 +367,7 @@ bool ASTJsonExporter::visit(StructDefinition const& _node)
|
|||||||
std::vector<pair<string, Json::Value>> attributes = {
|
std::vector<pair<string, Json::Value>> attributes = {
|
||||||
make_pair("name", _node.name()),
|
make_pair("name", _node.name()),
|
||||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||||
|
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
|
||||||
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||||
make_pair("members", toJson(_node.members())),
|
make_pair("members", toJson(_node.members())),
|
||||||
make_pair("scope", idOrNull(_node.scope()))
|
make_pair("scope", idOrNull(_node.scope()))
|
||||||
|
@ -449,7 +449,8 @@ ASTPointer<ASTNode> ASTJsonImporter::createStructDefinition(Json::Value const& _
|
|||||||
_node,
|
_node,
|
||||||
memberAsASTString(_node, "name"),
|
memberAsASTString(_node, "name"),
|
||||||
createNameSourceLocation(_node),
|
createNameSourceLocation(_node),
|
||||||
members
|
members,
|
||||||
|
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,6 +682,7 @@ ASTPointer<StructDefinition> Parser::parseStructDefinition()
|
|||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
ASTPointer<StructuredDocumentation> documentation = parseStructuredDocumentation();
|
||||||
expectToken(Token::Struct);
|
expectToken(Token::Struct);
|
||||||
auto [name, nameLocation] = expectIdentifierWithLocation();
|
auto [name, nameLocation] = expectIdentifierWithLocation();
|
||||||
vector<ASTPointer<VariableDeclaration>> members;
|
vector<ASTPointer<VariableDeclaration>> members;
|
||||||
@ -693,7 +694,7 @@ ASTPointer<StructDefinition> Parser::parseStructDefinition()
|
|||||||
}
|
}
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RBrace);
|
expectToken(Token::RBrace);
|
||||||
return nodeFactory.createNode<StructDefinition>(std::move(name), std::move(nameLocation), std::move(members));
|
return nodeFactory.createNode<StructDefinition>(std::move(name), std::move(nameLocation), std::move(members), std::move(documentation));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<EnumValue> Parser::parseEnumValue()
|
ASTPointer<EnumValue> Parser::parseEnumValue()
|
||||||
|
126
test/libsolidity/ASTJSON/struct_natspec.json
Normal file
126
test/libsolidity/ASTJSON/struct_natspec.json
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
{
|
||||||
|
"absolutePath": "a",
|
||||||
|
"exportedSymbols":
|
||||||
|
{
|
||||||
|
"Example":
|
||||||
|
[
|
||||||
|
8
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": 9,
|
||||||
|
"nodeType": "SourceUnit",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"canonicalName": "Example",
|
||||||
|
"documentation":
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"nodeType": "StructuredDocumentation",
|
||||||
|
"src": "0:112:1",
|
||||||
|
"text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev"
|
||||||
|
},
|
||||||
|
"id": 8,
|
||||||
|
"members":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 3,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "text",
|
||||||
|
"nameLocation": "140:4:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"scope": 8,
|
||||||
|
"src": "133:11:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_string_storage_ptr",
|
||||||
|
"typeString": "string"
|
||||||
|
},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "string",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "133:6:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_string_storage_ptr",
|
||||||
|
"typeString": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 5,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "valid",
|
||||||
|
"nameLocation": "155:5:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"scope": 8,
|
||||||
|
"src": "150:10:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_bool",
|
||||||
|
"typeString": "bool"
|
||||||
|
},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "bool",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "150:4:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_bool",
|
||||||
|
"typeString": "bool"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 7,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "value",
|
||||||
|
"nameLocation": "174:5:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"scope": 8,
|
||||||
|
"src": "166:13:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_uint256",
|
||||||
|
"typeString": "uint256"
|
||||||
|
},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "uint256",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "166:7:1",
|
||||||
|
"typeDescriptions":
|
||||||
|
{
|
||||||
|
"typeIdentifier": "t_uint256",
|
||||||
|
"typeString": "uint256"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Example",
|
||||||
|
"nameLocation": "119:7:1",
|
||||||
|
"nodeType": "StructDefinition",
|
||||||
|
"scope": 9,
|
||||||
|
"src": "112:70:1",
|
||||||
|
"visibility": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "112:71:1"
|
||||||
|
}
|
11
test/libsolidity/ASTJSON/struct_natspec.sol
Normal file
11
test/libsolidity/ASTJSON/struct_natspec.sol
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/// @title example of title
|
||||||
|
/// @author example of author
|
||||||
|
/// @notice example of notice
|
||||||
|
/// @dev example of dev
|
||||||
|
struct Example {
|
||||||
|
string text;
|
||||||
|
bool valid;
|
||||||
|
uint256 value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
90
test/libsolidity/ASTJSON/struct_natspec_parseOnly.json
Normal file
90
test/libsolidity/ASTJSON/struct_natspec_parseOnly.json
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"absolutePath": "a",
|
||||||
|
"id": 9,
|
||||||
|
"nodeType": "SourceUnit",
|
||||||
|
"nodes":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"documentation":
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"nodeType": "StructuredDocumentation",
|
||||||
|
"src": "0:112:1",
|
||||||
|
"text": "@title example of title\n @author example of author\n @notice example of notice\n @dev example of dev"
|
||||||
|
},
|
||||||
|
"id": 8,
|
||||||
|
"members":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 3,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "text",
|
||||||
|
"nameLocation": "140:4:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"src": "133:11:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions": {},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "string",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "133:6:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 5,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "valid",
|
||||||
|
"nameLocation": "155:5:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"src": "150:10:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions": {},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "bool",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "150:4:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"id": 7,
|
||||||
|
"mutability": "mutable",
|
||||||
|
"name": "value",
|
||||||
|
"nameLocation": "174:5:1",
|
||||||
|
"nodeType": "VariableDeclaration",
|
||||||
|
"src": "166:13:1",
|
||||||
|
"stateVariable": false,
|
||||||
|
"storageLocation": "default",
|
||||||
|
"typeDescriptions": {},
|
||||||
|
"typeName":
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "uint256",
|
||||||
|
"nodeType": "ElementaryTypeName",
|
||||||
|
"src": "166:7:1",
|
||||||
|
"typeDescriptions": {}
|
||||||
|
},
|
||||||
|
"visibility": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Example",
|
||||||
|
"nameLocation": "119:7:1",
|
||||||
|
"nodeType": "StructDefinition",
|
||||||
|
"src": "112:70:1",
|
||||||
|
"visibility": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"src": "112:71:1"
|
||||||
|
}
|
@ -1076,6 +1076,41 @@ BOOST_AUTO_TEST_CASE(dev_author_at_function)
|
|||||||
expectNatspecError(sourceCode);
|
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)
|
BOOST_AUTO_TEST_CASE(enum_no_docs)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
|
@ -187,7 +187,7 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
|
|||||||
BOOST_CHECK_EQUAL(c.type()->identifier(), "t_type$_t_contract$_MyContract$$$_$2_$");
|
BOOST_CHECK_EQUAL(c.type()->identifier(), "t_type$_t_contract$_MyContract$$$_$2_$");
|
||||||
BOOST_CHECK_EQUAL(ContractType(c, true).identifier(), "t_super$_MyContract$$$_$2");
|
BOOST_CHECK_EQUAL(ContractType(c, true).identifier(), "t_super$_MyContract$$$_$2");
|
||||||
|
|
||||||
StructDefinition s(++id, {}, make_shared<string>("Struct"), {}, {});
|
StructDefinition s(++id, {}, make_shared<string>("Struct"), {}, {}, {});
|
||||||
s.annotation().recursive = false;
|
s.annotation().recursive = false;
|
||||||
BOOST_CHECK_EQUAL(s.type()->identifier(), "t_type$_t_struct$_Struct_$3_storage_ptr_$");
|
BOOST_CHECK_EQUAL(s.type()->identifier(), "t_type$_t_struct$_Struct_$3_storage_ptr_$");
|
||||||
|
|
||||||
|
12
test/libsolidity/syntaxTests/natspec/docstring_struct.sol
Normal file
12
test/libsolidity/syntaxTests/natspec/docstring_struct.sol
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
Loading…
Reference in New Issue
Block a user