aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/analysis/DocStringAnalyser.cpp33
-rw-r--r--libsolidity/analysis/DocStringAnalyser.h9
-rw-r--r--libsolidity/ast/AST.cpp7
-rw-r--r--libsolidity/ast/AST.h53
-rw-r--r--libsolidity/ast/ASTAnnotations.h8
-rw-r--r--libsolidity/parsing/Parser.cpp68
-rw-r--r--libsolidity/parsing/Parser.h12
7 files changed, 126 insertions, 64 deletions
diff --git a/libsolidity/analysis/DocStringAnalyser.cpp b/libsolidity/analysis/DocStringAnalyser.cpp
index 41bff87e..4f75f03d 100644
--- a/libsolidity/analysis/DocStringAnalyser.cpp
+++ b/libsolidity/analysis/DocStringAnalyser.cpp
@@ -39,12 +39,8 @@ bool DocStringAnalyser::analyseDocStrings(SourceUnit const& _sourceUnit)
bool DocStringAnalyser::visit(ContractDefinition const& _node)
{
- parseDocStrings(_node, _node.annotation());
-
- static const set<string> validTags = set<string>{"author", "title", "dev", "notice"};
- for (auto const& docTag: _node.annotation().docTags)
- if (!validTags.count(docTag.first))
- appendError("Doc tag @" + docTag.first + " not valid for contracts.");
+ static const set<string> validTags = set<string>{"author", "title", "dev", "notice", "why3"};
+ parseDocStrings(_node, _node.annotation(), validTags, "contracts");
return true;
}
@@ -69,17 +65,24 @@ bool DocStringAnalyser::visit(EventDefinition const& _node)
return true;
}
+bool DocStringAnalyser::visitNode(ASTNode const& _node)
+{
+ if (auto node = dynamic_cast<Statement const*>(&_node))
+ {
+ static const set<string> validTags = {"why3"};
+ parseDocStrings(*node, node->annotation(), validTags, "statements");
+ }
+ return true;
+}
+
void DocStringAnalyser::handleCallable(
CallableDeclaration const& _callable,
Documented const& _node,
DocumentedAnnotation& _annotation
)
{
- parseDocStrings(_node, _annotation);
static const set<string> validTags = set<string>{"author", "dev", "notice", "return", "param", "why3"};
- for (auto const& docTag: _annotation.docTags)
- if (!validTags.count(docTag.first))
- appendError("Doc tag @" + docTag.first + " not valid for functions.");
+ parseDocStrings(_node, _annotation, validTags, "functions");
set<string> validParams;
for (auto const& p: _callable.parameters())
@@ -97,7 +100,12 @@ void DocStringAnalyser::handleCallable(
);
}
-void DocStringAnalyser::parseDocStrings(Documented const& _node, DocumentedAnnotation& _annotation)
+void DocStringAnalyser::parseDocStrings(
+ Documented const& _node,
+ DocumentedAnnotation& _annotation,
+ set<string> const& _validTags,
+ string const& _nodeName
+)
{
DocStringParser parser;
if (_node.documentation() && !_node.documentation()->empty())
@@ -106,6 +114,9 @@ void DocStringAnalyser::parseDocStrings(Documented const& _node, DocumentedAnnot
m_errorOccured = true;
_annotation.docTags = parser.tags();
}
+ for (auto const& docTag: _annotation.docTags)
+ if (!_validTags.count(docTag.first))
+ appendError("Doc tag @" + docTag.first + " not valid for " + _nodeName + ".");
}
void DocStringAnalyser::appendError(string const& _description)
diff --git a/libsolidity/analysis/DocStringAnalyser.h b/libsolidity/analysis/DocStringAnalyser.h
index 06384c8d..cdf297e3 100644
--- a/libsolidity/analysis/DocStringAnalyser.h
+++ b/libsolidity/analysis/DocStringAnalyser.h
@@ -46,13 +46,20 @@ private:
virtual bool visit(ModifierDefinition const& _modifier) override;
virtual bool visit(EventDefinition const& _event) override;
+ virtual bool visitNode(ASTNode const&) override;
+
void handleCallable(
CallableDeclaration const& _callable,
Documented const& _node,
DocumentedAnnotation& _annotation
);
- void parseDocStrings(Documented const& _node, DocumentedAnnotation& _annotation);
+ void parseDocStrings(
+ Documented const& _node,
+ DocumentedAnnotation& _annotation,
+ std::set<std::string> const& _validTags,
+ std::string const& _nodeName
+ );
void appendError(std::string const& _description);
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 9d1fb811..41a4d182 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -336,6 +336,13 @@ VariableDeclarationAnnotation& VariableDeclaration::annotation() const
return static_cast<VariableDeclarationAnnotation&>(*m_annotation);
}
+StatementAnnotation& Statement::annotation() const
+{
+ if (!m_annotation)
+ m_annotation = new StatementAnnotation();
+ return static_cast<StatementAnnotation&>(*m_annotation);
+}
+
ReturnAnnotation& Return::annotation() const
{
if (!m_annotation)
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 6a593d3e..1a204dca 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -792,10 +792,15 @@ private:
/**
* Abstract base class for statements.
*/
-class Statement: public ASTNode
+class Statement: public ASTNode, public Documented
{
public:
- explicit Statement(SourceLocation const& _location): ASTNode(_location) {}
+ explicit Statement(
+ SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString
+ ): ASTNode(_location), Documented(_docString) {}
+
+ virtual StatementAnnotation& annotation() const override;
};
/**
@@ -806,9 +811,10 @@ class Block: public Statement
public:
Block(
SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
std::vector<ASTPointer<Statement>> const& _statements
):
- Statement(_location), m_statements(_statements) {}
+ Statement(_location, _docString), m_statements(_statements) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -823,7 +829,10 @@ private:
class PlaceholderStatement: public Statement
{
public:
- explicit PlaceholderStatement(SourceLocation const& _location): Statement(_location) {}
+ explicit PlaceholderStatement(
+ SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString
+ ): Statement(_location, _docString) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -838,11 +847,12 @@ class IfStatement: public Statement
public:
IfStatement(
SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _condition,
ASTPointer<Statement> const& _trueBody,
ASTPointer<Statement> const& _falseBody
):
- Statement(_location),
+ Statement(_location, _docString),
m_condition(_condition),
m_trueBody(_trueBody),
m_falseBody(_falseBody)
@@ -867,7 +877,10 @@ private:
class BreakableStatement: public Statement
{
public:
- explicit BreakableStatement(SourceLocation const& _location): Statement(_location) {}
+ explicit BreakableStatement(
+ SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString
+ ): Statement(_location, _docString) {}
};
class WhileStatement: public BreakableStatement
@@ -875,10 +888,11 @@ class WhileStatement: public BreakableStatement
public:
WhileStatement(
SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _condition,
ASTPointer<Statement> const& _body
):
- BreakableStatement(_location), m_condition(_condition), m_body(_body) {}
+ BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -898,12 +912,13 @@ class ForStatement: public BreakableStatement
public:
ForStatement(
SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
ASTPointer<Statement> const& _initExpression,
ASTPointer<Expression> const& _conditionExpression,
ASTPointer<ExpressionStatement> const& _loopExpression,
ASTPointer<Statement> const& _body
):
- BreakableStatement(_location),
+ BreakableStatement(_location, _docString),
m_initExpression(_initExpression),
m_condExpression(_conditionExpression),
m_loopExpression(_loopExpression),
@@ -931,7 +946,8 @@ private:
class Continue: public Statement
{
public:
- explicit Continue(SourceLocation const& _location): Statement(_location) {}
+ explicit Continue(SourceLocation const& _location, ASTPointer<ASTString> const& _docString):
+ Statement(_location, _docString) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
};
@@ -939,7 +955,8 @@ public:
class Break: public Statement
{
public:
- explicit Break(SourceLocation const& _location): Statement(_location) {}
+ explicit Break(SourceLocation const& _location, ASTPointer<ASTString> const& _docString):
+ Statement(_location, _docString) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
};
@@ -947,8 +964,11 @@ public:
class Return: public Statement
{
public:
- Return(SourceLocation const& _location, ASTPointer<Expression> _expression):
- Statement(_location), m_expression(_expression) {}
+ Return(
+ SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
+ ASTPointer<Expression> _expression
+ ): Statement(_location, _docString), m_expression(_expression) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -966,7 +986,8 @@ private:
class Throw: public Statement
{
public:
- explicit Throw(SourceLocation const& _location): Statement(_location) {}
+ explicit Throw(SourceLocation const& _location, ASTPointer<ASTString> const& _docString):
+ Statement(_location, _docString) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
};
@@ -985,10 +1006,11 @@ class VariableDeclarationStatement: public Statement
public:
VariableDeclarationStatement(
SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
std::vector<ASTPointer<VariableDeclaration>> const& _variables,
ASTPointer<Expression> const& _initialValue
):
- Statement(_location), m_variables(_variables), m_initialValue(_initialValue) {}
+ Statement(_location, _docString), m_variables(_variables), m_initialValue(_initialValue) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
@@ -1012,9 +1034,10 @@ class ExpressionStatement: public Statement
public:
ExpressionStatement(
SourceLocation const& _location,
+ ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> _expression
):
- Statement(_location), m_expression(_expression) {}
+ Statement(_location, _docString), m_expression(_expression) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h
index 094a178e..bb59ceae 100644
--- a/libsolidity/ast/ASTAnnotations.h
+++ b/libsolidity/ast/ASTAnnotations.h
@@ -90,7 +90,11 @@ struct VariableDeclarationAnnotation: ASTAnnotation
TypePointer type;
};
-struct ReturnAnnotation: ASTAnnotation
+struct StatementAnnotation: ASTAnnotation, DocumentedAnnotation
+{
+};
+
+struct ReturnAnnotation: StatementAnnotation
{
/// Reference to the return parameters of the function.
ParameterList const* functionReturnParameters = nullptr;
@@ -109,7 +113,7 @@ struct UserDefinedTypeNameAnnotation: TypeNameAnnotation
Declaration const* referencedDeclaration = nullptr;
};
-struct VariableDeclarationStatementAnnotation: ASTAnnotation
+struct VariableDeclarationStatementAnnotation: StatementAnnotation
{
/// Information about which component of the value is assigned to which variable.
/// The pointer can be null to signify that the component is discarded.
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index 35872f78..d89218bb 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -600,7 +600,7 @@ ASTPointer<ParameterList> Parser::parseParameterList(
return nodeFactory.createNode<ParameterList>(parameters);
}
-ASTPointer<Block> Parser::parseBlock()
+ASTPointer<Block> Parser::parseBlock(ASTPointer<ASTString> const& _docString)
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::LBrace);
@@ -609,29 +609,32 @@ ASTPointer<Block> Parser::parseBlock()
statements.push_back(parseStatement());
nodeFactory.markEndPosition();
expectToken(Token::RBrace);
- return nodeFactory.createNode<Block>(statements);
+ return nodeFactory.createNode<Block>(_docString, statements);
}
ASTPointer<Statement> Parser::parseStatement()
{
+ ASTPointer<ASTString> docString;
+ if (m_scanner->currentCommentLiteral() != "")
+ docString = make_shared<ASTString>(m_scanner->currentCommentLiteral());
ASTPointer<Statement> statement;
switch (m_scanner->currentToken())
{
case Token::If:
- return parseIfStatement();
+ return parseIfStatement(docString);
case Token::While:
- return parseWhileStatement();
+ return parseWhileStatement(docString);
case Token::For:
- return parseForStatement();
+ return parseForStatement(docString);
case Token::LBrace:
- return parseBlock();
+ return parseBlock(docString);
// starting from here, all statements must be terminated by a semicolon
case Token::Continue:
- statement = ASTNodeFactory(*this).createNode<Continue>();
+ statement = ASTNodeFactory(*this).createNode<Continue>(docString);
m_scanner->next();
break;
case Token::Break:
- statement = ASTNodeFactory(*this).createNode<Break>();
+ statement = ASTNodeFactory(*this).createNode<Break>(docString);
m_scanner->next();
break;
case Token::Return:
@@ -643,31 +646,31 @@ ASTPointer<Statement> Parser::parseStatement()
expression = parseExpression();
nodeFactory.setEndPositionFromNode(expression);
}
- statement = nodeFactory.createNode<Return>(expression);
+ statement = nodeFactory.createNode<Return>(docString, expression);
break;
}
case Token::Throw:
{
- statement = ASTNodeFactory(*this).createNode<Throw>();
+ statement = ASTNodeFactory(*this).createNode<Throw>(docString);
m_scanner->next();
break;
}
case Token::Identifier:
if (m_insideModifier && m_scanner->currentLiteral() == "_")
{
- statement = ASTNodeFactory(*this).createNode<PlaceholderStatement>();
+ statement = ASTNodeFactory(*this).createNode<PlaceholderStatement>(docString);
m_scanner->next();
return statement;
}
// fall-through
default:
- statement = parseSimpleStatement();
+ statement = parseSimpleStatement(docString);
}
expectToken(Token::Semicolon);
return statement;
}
-ASTPointer<IfStatement> Parser::parseIfStatement()
+ASTPointer<IfStatement> Parser::parseIfStatement(ASTPointer<ASTString> const& _docString)
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::If);
@@ -684,10 +687,10 @@ ASTPointer<IfStatement> Parser::parseIfStatement()
}
else
nodeFactory.setEndPositionFromNode(trueBody);
- return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody);
+ return nodeFactory.createNode<IfStatement>(_docString, condition, trueBody, falseBody);
}
-ASTPointer<WhileStatement> Parser::parseWhileStatement()
+ASTPointer<WhileStatement> Parser::parseWhileStatement(ASTPointer<ASTString> const& _docString)
{
ASTNodeFactory nodeFactory(*this);
expectToken(Token::While);
@@ -696,10 +699,10 @@ ASTPointer<WhileStatement> Parser::parseWhileStatement()
expectToken(Token::RParen);
ASTPointer<Statement> body = parseStatement();
nodeFactory.setEndPositionFromNode(body);
- return nodeFactory.createNode<WhileStatement>(condition, body);
+ return nodeFactory.createNode<WhileStatement>(_docString, condition, body);
}
-ASTPointer<ForStatement> Parser::parseForStatement()
+ASTPointer<ForStatement> Parser::parseForStatement(ASTPointer<ASTString> const& _docString)
{
ASTNodeFactory nodeFactory(*this);
ASTPointer<Statement> initExpression;
@@ -710,7 +713,7 @@ ASTPointer<ForStatement> Parser::parseForStatement()
// LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RParen?
if (m_scanner->currentToken() != Token::Semicolon)
- initExpression = parseSimpleStatement();
+ initExpression = parseSimpleStatement(ASTPointer<ASTString>());
expectToken(Token::Semicolon);
if (m_scanner->currentToken() != Token::Semicolon)
@@ -718,18 +721,21 @@ ASTPointer<ForStatement> Parser::parseForStatement()
expectToken(Token::Semicolon);
if (m_scanner->currentToken() != Token::RParen)
- loopExpression = parseExpressionStatement();
+ loopExpression = parseExpressionStatement(ASTPointer<ASTString>());
expectToken(Token::RParen);
ASTPointer<Statement> body = parseStatement();
nodeFactory.setEndPositionFromNode(body);
- return nodeFactory.createNode<ForStatement>(initExpression,
- conditionExpression,
- loopExpression,
- body);
+ return nodeFactory.createNode<ForStatement>(
+ _docString,
+ initExpression,
+ conditionExpression,
+ loopExpression,
+ body
+ );
}
-ASTPointer<Statement> Parser::parseSimpleStatement()
+ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)
{
// These two cases are very hard to distinguish:
// x[7 * 20 + 3] a; - x[7 * 20 + 3] = 9;
@@ -740,9 +746,9 @@ ASTPointer<Statement> Parser::parseSimpleStatement()
switch (peekStatementType())
{
case LookAheadInfo::VariableDeclarationStatement:
- return parseVariableDeclarationStatement();
+ return parseVariableDeclarationStatement(_docString);
case LookAheadInfo::ExpressionStatement:
- return parseExpressionStatement();
+ return parseExpressionStatement(_docString);
default:
break;
}
@@ -781,12 +787,13 @@ ASTPointer<Statement> Parser::parseSimpleStatement()
}
if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken()))
- return parseVariableDeclarationStatement(typeNameIndexAccessStructure(path, indices));
+ return parseVariableDeclarationStatement(_docString, typeNameIndexAccessStructure(path, indices));
else
- return parseExpressionStatement(expressionFromIndexAccessStructure(path, indices));
+ return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(path, indices));
}
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
+ ASTPointer<ASTString> const& _docString,
ASTPointer<TypeName> const& _lookAheadArrayType
)
{
@@ -845,15 +852,16 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme
value = parseExpression();
nodeFactory.setEndPositionFromNode(value);
}
- return nodeFactory.createNode<VariableDeclarationStatement>(variables, value);
+ return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);
}
ASTPointer<ExpressionStatement> Parser::parseExpressionStatement(
+ ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _lookAheadIndexAccessStructure
)
{
ASTPointer<Expression> expression = parseExpression(_lookAheadIndexAccessStructure);
- return ASTNodeFactory(*this, expression).createNode<ExpressionStatement>(expression);
+ return ASTNodeFactory(*this, expression).createNode<ExpressionStatement>(_docString, expression);
}
ASTPointer<Expression> Parser::parseExpression(
diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h
index 5e226ba5..663c0f92 100644
--- a/libsolidity/parsing/Parser.h
+++ b/libsolidity/parsing/Parser.h
@@ -82,17 +82,19 @@ private:
VarDeclParserOptions const& _options,
bool _allowEmpty = true
);
- ASTPointer<Block> parseBlock();
+ ASTPointer<Block> parseBlock(ASTPointer<ASTString> const& _docString = {});
ASTPointer<Statement> parseStatement();
- ASTPointer<IfStatement> parseIfStatement();
- ASTPointer<WhileStatement> parseWhileStatement();
- ASTPointer<ForStatement> parseForStatement();
+ ASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);
+ ASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);
+ ASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);
/// A "simple statement" can be a variable declaration statement or an expression statement.
- ASTPointer<Statement> parseSimpleStatement();
+ ASTPointer<Statement> parseSimpleStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<VariableDeclarationStatement> parseVariableDeclarationStatement(
+ ASTPointer<ASTString> const& _docString,
ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
);
ASTPointer<ExpressionStatement> parseExpressionStatement(
+ ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>()
);
ASTPointer<Expression> parseExpression(