-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Natspec: Implement inheritance and @inheritdoc #9218
Conversation
a96752e
to
0039eb1
Compare
685f833
to
5450612
Compare
We are missing an entry in the documentation for |
Does this both implement the explicit inheritance via |
@chriseth this implements both |
796e12b
to
e314541
Compare
There is a minor issue. According to documentation, This could be an issue with the documentation, because when running tests, I was able to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly constness suggestions and one boost algorithm proposal.
a955f59
to
07e4ccf
Compare
@hrkrshnn according to the code |
Ah well.. no.
|
@@ -52,6 +52,17 @@ void copyMissingTags(StructurallyDocumentedAnnotation& _target, set<CallableDecl | |||
_target.docTags.emplace(tag, content); | |||
} | |||
|
|||
CallableDeclaration const* findBaseCallable(std::set<CallableDeclaration const*>& _baseFunctions, int64_t _contractId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CallableDeclaration const* findBaseCallable(std::set<CallableDeclaration const*>& _baseFunctions, int64_t _contractId) | |
CallableDeclaration const* findBaseCallable(set<CallableDeclaration const*> const& _baseFunctions, int64_t _contractId) |
_node.documentation()->location(), | ||
"Documentation tag @inheritdoc references contract \"" + | ||
_annotation.inheritdocReference->name() + | ||
"\", but the contract does not override this function." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't it be
"...contract does not contain a function that is overridden by this function"?
{ | ||
|
||
/** | ||
* Parses the doc tags and does basic vadility checks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Parses the doc tags and does basic vadility checks. | |
* Parses the doc tags and does basic validity checks. |
5142_error, | ||
_documentation.location(), | ||
"Documentation tag @inheritdoc can only be given once." | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
case 1: | ||
{ | ||
string const& name = _annotation.docTags.find("inheritdoc")->second.content; | ||
vector<Declaration const*> results = m_resolver.nameFromCurrentScope(name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use pathFromCurrentScope
to allow more complex use-cases.
Good apart from the comments! |
Changelog.md
Outdated
@@ -26,6 +26,7 @@ Language Features: | |||
Compiler Features: | |||
* NatSpec: Add fields ``kind`` and ``version`` to the JSON output. | |||
* NatSpec: Inherit tags from unique base functions if derived function does not provide any. | |||
* NatSpec: Implement tag ``@inheritdoc`` to copy documentation from a specific contract. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not yet fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only rebased, fixes are about to come
string const& name = _annotation.docTags.find("inheritdoc")->second.content; | ||
vector<string> path; | ||
boost::split(path, name, boost::is_any_of(".")); | ||
Declaration const* result = m_resolver.pathFromCurrentScope(path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a test case for that? You will need to use a multi-file test that uses import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test does a resolving of a path: https:/ethereum/solidity/pull/9218/files#diff-5dcd49ff3e08e5ff224ee08fbb7ac514
It's not a contract and thus fails later but it does successfully resolve the path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please still add a multi-file test?
6dfa28e
to
636d259
Compare
@@ -52,6 +52,17 @@ void copyMissingTags(StructurallyDocumentedAnnotation& _target, set<CallableDecl | |||
_target.docTags.emplace(tag, content); | |||
} | |||
|
|||
CallableDeclaration const* findBaseCallable(set<CallableDeclaration const*> const& _baseFunctions, int64_t _contractId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why int
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because that's the type that ContractDefinition->id()
returns
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. Now I'm confused why id
is int
} | ||
|
||
void DocStringAnalyser::parseDocStrings( | ||
CallableDeclaration const* DocStringAnalyser::resolveInheritDoc( | ||
std::set<CallableDeclaration const*>& _baseFuncs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::set<CallableDeclaration const*>& _baseFuncs, | |
std::set<CallableDeclaration const*> const& _baseFuncs, |
?
m_errorReporter.docstringParsingError( | ||
9397_error, | ||
_documentation.location(), | ||
"Documentation tag @inheritdoc references unexisting contract \"" + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Documentation tag @inheritdoc references unexisting contract \"" + | |
"Documentation tag @inheritdoc references inexistent contract \"" + |
checkNatspec(sourceCode, "D", natspec, true); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(dev_explicit_inherit_variable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did these tests have to be added via cpp tests? Couldn't they have been added as command line tests? (or something that is not cpp tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose anything could be a cmdline test, but this file is specifically for natspecs so it does seem to be the right place..
Whether we want/should turn the whole thing into not-cpp tests is a different question (of which I'd be in favour)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I just wondered if some similar tests had already been "converted" into cmd line tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure cmd line tests should be the favored target, maybe a more specific extension in (i)soltest would be better.
Json::Value user; | ||
// since @notice is the only user tag if missing function should not appear | ||
user["notice"] = Json::Value(value); | ||
methods[it.second->externalSignature()] = user; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happened to these 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I simplified the code a bit, they just moved to line 74/75
); | ||
} | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation looks off
"Documentation tag @" + docTag.first + " not valid for " + _nodeName + "." | ||
); | ||
else | ||
if (docTag.first == "return") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (docTag.first == "return") | |
else if (docTag.first == "return") |
if (docTag.first == "return") | ||
{ | ||
returnTagsVisited++; | ||
if (auto* varDecl = dynamic_cast<VariableDeclaration const*>(&_node)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (auto* varDecl = dynamic_cast<VariableDeclaration const*>(&_node)) | |
if (auto const* varDecl = dynamic_cast<VariableDeclaration const*>(&_node)) |
"Documentation tag \"@" + docTag.first + "\" is only allowed once on state-variables." | ||
); | ||
} | ||
else if (auto* function = dynamic_cast<FunctionDefinition const*>(&_node)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else if (auto* function = dynamic_cast<FunctionDefinition const*>(&_node)) | |
else if (auto const* function = dynamic_cast<FunctionDefinition const*>(&_node)) |
fixes #8911