diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/DocStringAnalyser.cpp | 33 | ||||
-rw-r--r-- | libsolidity/analysis/DocStringAnalyser.h | 9 | ||||
-rw-r--r-- | libsolidity/ast/AST.cpp | 7 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 53 | ||||
-rw-r--r-- | libsolidity/ast/ASTAnnotations.h | 8 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 68 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.h | 12 |
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( |