mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Allow docstrings for statements.
This commit is contained in:
parent
e77deccfb3
commit
8fb49d85f9
@ -39,12 +39,8 @@ bool DocStringAnalyser::analyseDocStrings(SourceUnit const& _sourceUnit)
|
|||||||
|
|
||||||
bool DocStringAnalyser::visit(ContractDefinition const& _node)
|
bool DocStringAnalyser::visit(ContractDefinition const& _node)
|
||||||
{
|
{
|
||||||
parseDocStrings(_node, _node.annotation());
|
static const set<string> validTags = set<string>{"author", "title", "dev", "notice", "why3"};
|
||||||
|
parseDocStrings(_node, _node.annotation(), validTags, "contracts");
|
||||||
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.");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -69,17 +65,24 @@ bool DocStringAnalyser::visit(EventDefinition const& _node)
|
|||||||
return true;
|
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(
|
void DocStringAnalyser::handleCallable(
|
||||||
CallableDeclaration const& _callable,
|
CallableDeclaration const& _callable,
|
||||||
Documented const& _node,
|
Documented const& _node,
|
||||||
DocumentedAnnotation& _annotation
|
DocumentedAnnotation& _annotation
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
parseDocStrings(_node, _annotation);
|
|
||||||
static const set<string> validTags = set<string>{"author", "dev", "notice", "return", "param", "why3"};
|
static const set<string> validTags = set<string>{"author", "dev", "notice", "return", "param", "why3"};
|
||||||
for (auto const& docTag: _annotation.docTags)
|
parseDocStrings(_node, _annotation, validTags, "functions");
|
||||||
if (!validTags.count(docTag.first))
|
|
||||||
appendError("Doc tag @" + docTag.first + " not valid for functions.");
|
|
||||||
|
|
||||||
set<string> validParams;
|
set<string> validParams;
|
||||||
for (auto const& p: _callable.parameters())
|
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;
|
DocStringParser parser;
|
||||||
if (_node.documentation() && !_node.documentation()->empty())
|
if (_node.documentation() && !_node.documentation()->empty())
|
||||||
@ -106,6 +114,9 @@ void DocStringAnalyser::parseDocStrings(Documented const& _node, DocumentedAnnot
|
|||||||
m_errorOccured = true;
|
m_errorOccured = true;
|
||||||
_annotation.docTags = parser.tags();
|
_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)
|
void DocStringAnalyser::appendError(string const& _description)
|
||||||
|
@ -46,13 +46,20 @@ private:
|
|||||||
virtual bool visit(ModifierDefinition const& _modifier) override;
|
virtual bool visit(ModifierDefinition const& _modifier) override;
|
||||||
virtual bool visit(EventDefinition const& _event) override;
|
virtual bool visit(EventDefinition const& _event) override;
|
||||||
|
|
||||||
|
virtual bool visitNode(ASTNode const&) override;
|
||||||
|
|
||||||
void handleCallable(
|
void handleCallable(
|
||||||
CallableDeclaration const& _callable,
|
CallableDeclaration const& _callable,
|
||||||
Documented const& _node,
|
Documented const& _node,
|
||||||
DocumentedAnnotation& _annotation
|
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);
|
void appendError(std::string const& _description);
|
||||||
|
|
||||||
|
@ -336,6 +336,13 @@ VariableDeclarationAnnotation& VariableDeclaration::annotation() const
|
|||||||
return static_cast<VariableDeclarationAnnotation&>(*m_annotation);
|
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
|
ReturnAnnotation& Return::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
|
@ -792,10 +792,15 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Abstract base class for statements.
|
* Abstract base class for statements.
|
||||||
*/
|
*/
|
||||||
class Statement: public ASTNode
|
class Statement: public ASTNode, public Documented
|
||||||
{
|
{
|
||||||
public:
|
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:
|
public:
|
||||||
Block(
|
Block(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
std::vector<ASTPointer<Statement>> const& _statements
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
|
||||||
@ -823,7 +829,10 @@ private:
|
|||||||
class PlaceholderStatement: public Statement
|
class PlaceholderStatement: public Statement
|
||||||
{
|
{
|
||||||
public:
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
@ -838,11 +847,12 @@ class IfStatement: public Statement
|
|||||||
public:
|
public:
|
||||||
IfStatement(
|
IfStatement(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<Expression> const& _condition,
|
ASTPointer<Expression> const& _condition,
|
||||||
ASTPointer<Statement> const& _trueBody,
|
ASTPointer<Statement> const& _trueBody,
|
||||||
ASTPointer<Statement> const& _falseBody
|
ASTPointer<Statement> const& _falseBody
|
||||||
):
|
):
|
||||||
Statement(_location),
|
Statement(_location, _docString),
|
||||||
m_condition(_condition),
|
m_condition(_condition),
|
||||||
m_trueBody(_trueBody),
|
m_trueBody(_trueBody),
|
||||||
m_falseBody(_falseBody)
|
m_falseBody(_falseBody)
|
||||||
@ -867,7 +877,10 @@ private:
|
|||||||
class BreakableStatement: public Statement
|
class BreakableStatement: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit BreakableStatement(SourceLocation const& _location): Statement(_location) {}
|
explicit BreakableStatement(
|
||||||
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString
|
||||||
|
): Statement(_location, _docString) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WhileStatement: public BreakableStatement
|
class WhileStatement: public BreakableStatement
|
||||||
@ -875,10 +888,11 @@ class WhileStatement: public BreakableStatement
|
|||||||
public:
|
public:
|
||||||
WhileStatement(
|
WhileStatement(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<Expression> const& _condition,
|
ASTPointer<Expression> const& _condition,
|
||||||
ASTPointer<Statement> const& _body
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
|
||||||
@ -898,12 +912,13 @@ class ForStatement: public BreakableStatement
|
|||||||
public:
|
public:
|
||||||
ForStatement(
|
ForStatement(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<Statement> const& _initExpression,
|
ASTPointer<Statement> const& _initExpression,
|
||||||
ASTPointer<Expression> const& _conditionExpression,
|
ASTPointer<Expression> const& _conditionExpression,
|
||||||
ASTPointer<ExpressionStatement> const& _loopExpression,
|
ASTPointer<ExpressionStatement> const& _loopExpression,
|
||||||
ASTPointer<Statement> const& _body
|
ASTPointer<Statement> const& _body
|
||||||
):
|
):
|
||||||
BreakableStatement(_location),
|
BreakableStatement(_location, _docString),
|
||||||
m_initExpression(_initExpression),
|
m_initExpression(_initExpression),
|
||||||
m_condExpression(_conditionExpression),
|
m_condExpression(_conditionExpression),
|
||||||
m_loopExpression(_loopExpression),
|
m_loopExpression(_loopExpression),
|
||||||
@ -931,7 +946,8 @@ private:
|
|||||||
class Continue: public Statement
|
class Continue: public Statement
|
||||||
{
|
{
|
||||||
public:
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
};
|
};
|
||||||
@ -939,7 +955,8 @@ public:
|
|||||||
class Break: public Statement
|
class Break: public Statement
|
||||||
{
|
{
|
||||||
public:
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
};
|
};
|
||||||
@ -947,8 +964,11 @@ public:
|
|||||||
class Return: public Statement
|
class Return: public Statement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Return(SourceLocation const& _location, ASTPointer<Expression> _expression):
|
Return(
|
||||||
Statement(_location), m_expression(_expression) {}
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
|
||||||
@ -966,7 +986,8 @@ private:
|
|||||||
class Throw: public Statement
|
class Throw: public Statement
|
||||||
{
|
{
|
||||||
public:
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
};
|
};
|
||||||
@ -985,10 +1006,11 @@ class VariableDeclarationStatement: public Statement
|
|||||||
public:
|
public:
|
||||||
VariableDeclarationStatement(
|
VariableDeclarationStatement(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
std::vector<ASTPointer<VariableDeclaration>> const& _variables,
|
std::vector<ASTPointer<VariableDeclaration>> const& _variables,
|
||||||
ASTPointer<Expression> const& _initialValue
|
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(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
|
||||||
@ -1012,9 +1034,10 @@ class ExpressionStatement: public Statement
|
|||||||
public:
|
public:
|
||||||
ExpressionStatement(
|
ExpressionStatement(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<Expression> _expression
|
ASTPointer<Expression> _expression
|
||||||
):
|
):
|
||||||
Statement(_location), m_expression(_expression) {}
|
Statement(_location, _docString), m_expression(_expression) {}
|
||||||
virtual void accept(ASTVisitor& _visitor) override;
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||||
|
|
||||||
|
@ -90,7 +90,11 @@ struct VariableDeclarationAnnotation: ASTAnnotation
|
|||||||
TypePointer type;
|
TypePointer type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReturnAnnotation: ASTAnnotation
|
struct StatementAnnotation: ASTAnnotation, DocumentedAnnotation
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ReturnAnnotation: StatementAnnotation
|
||||||
{
|
{
|
||||||
/// Reference to the return parameters of the function.
|
/// Reference to the return parameters of the function.
|
||||||
ParameterList const* functionReturnParameters = nullptr;
|
ParameterList const* functionReturnParameters = nullptr;
|
||||||
@ -109,7 +113,7 @@ struct UserDefinedTypeNameAnnotation: TypeNameAnnotation
|
|||||||
Declaration const* referencedDeclaration = nullptr;
|
Declaration const* referencedDeclaration = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariableDeclarationStatementAnnotation: ASTAnnotation
|
struct VariableDeclarationStatementAnnotation: StatementAnnotation
|
||||||
{
|
{
|
||||||
/// Information about which component of the value is assigned to which variable.
|
/// Information about which component of the value is assigned to which variable.
|
||||||
/// The pointer can be null to signify that the component is discarded.
|
/// The pointer can be null to signify that the component is discarded.
|
||||||
|
@ -600,7 +600,7 @@ ASTPointer<ParameterList> Parser::parseParameterList(
|
|||||||
return nodeFactory.createNode<ParameterList>(parameters);
|
return nodeFactory.createNode<ParameterList>(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<Block> Parser::parseBlock()
|
ASTPointer<Block> Parser::parseBlock(ASTPointer<ASTString> const& _docString)
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::LBrace);
|
expectToken(Token::LBrace);
|
||||||
@ -609,29 +609,32 @@ ASTPointer<Block> Parser::parseBlock()
|
|||||||
statements.push_back(parseStatement());
|
statements.push_back(parseStatement());
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RBrace);
|
expectToken(Token::RBrace);
|
||||||
return nodeFactory.createNode<Block>(statements);
|
return nodeFactory.createNode<Block>(_docString, statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<Statement> Parser::parseStatement()
|
ASTPointer<Statement> Parser::parseStatement()
|
||||||
{
|
{
|
||||||
|
ASTPointer<ASTString> docString;
|
||||||
|
if (m_scanner->currentCommentLiteral() != "")
|
||||||
|
docString = make_shared<ASTString>(m_scanner->currentCommentLiteral());
|
||||||
ASTPointer<Statement> statement;
|
ASTPointer<Statement> statement;
|
||||||
switch (m_scanner->currentToken())
|
switch (m_scanner->currentToken())
|
||||||
{
|
{
|
||||||
case Token::If:
|
case Token::If:
|
||||||
return parseIfStatement();
|
return parseIfStatement(docString);
|
||||||
case Token::While:
|
case Token::While:
|
||||||
return parseWhileStatement();
|
return parseWhileStatement(docString);
|
||||||
case Token::For:
|
case Token::For:
|
||||||
return parseForStatement();
|
return parseForStatement(docString);
|
||||||
case Token::LBrace:
|
case Token::LBrace:
|
||||||
return parseBlock();
|
return parseBlock(docString);
|
||||||
// starting from here, all statements must be terminated by a semicolon
|
// starting from here, all statements must be terminated by a semicolon
|
||||||
case Token::Continue:
|
case Token::Continue:
|
||||||
statement = ASTNodeFactory(*this).createNode<Continue>();
|
statement = ASTNodeFactory(*this).createNode<Continue>(docString);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
break;
|
break;
|
||||||
case Token::Break:
|
case Token::Break:
|
||||||
statement = ASTNodeFactory(*this).createNode<Break>();
|
statement = ASTNodeFactory(*this).createNode<Break>(docString);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
break;
|
break;
|
||||||
case Token::Return:
|
case Token::Return:
|
||||||
@ -643,31 +646,31 @@ ASTPointer<Statement> Parser::parseStatement()
|
|||||||
expression = parseExpression();
|
expression = parseExpression();
|
||||||
nodeFactory.setEndPositionFromNode(expression);
|
nodeFactory.setEndPositionFromNode(expression);
|
||||||
}
|
}
|
||||||
statement = nodeFactory.createNode<Return>(expression);
|
statement = nodeFactory.createNode<Return>(docString, expression);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Token::Throw:
|
case Token::Throw:
|
||||||
{
|
{
|
||||||
statement = ASTNodeFactory(*this).createNode<Throw>();
|
statement = ASTNodeFactory(*this).createNode<Throw>(docString);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Token::Identifier:
|
case Token::Identifier:
|
||||||
if (m_insideModifier && m_scanner->currentLiteral() == "_")
|
if (m_insideModifier && m_scanner->currentLiteral() == "_")
|
||||||
{
|
{
|
||||||
statement = ASTNodeFactory(*this).createNode<PlaceholderStatement>();
|
statement = ASTNodeFactory(*this).createNode<PlaceholderStatement>(docString);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
// fall-through
|
// fall-through
|
||||||
default:
|
default:
|
||||||
statement = parseSimpleStatement();
|
statement = parseSimpleStatement(docString);
|
||||||
}
|
}
|
||||||
expectToken(Token::Semicolon);
|
expectToken(Token::Semicolon);
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<IfStatement> Parser::parseIfStatement()
|
ASTPointer<IfStatement> Parser::parseIfStatement(ASTPointer<ASTString> const& _docString)
|
||||||
{
|
{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::If);
|
expectToken(Token::If);
|
||||||
@ -684,10 +687,10 @@ ASTPointer<IfStatement> Parser::parseIfStatement()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
nodeFactory.setEndPositionFromNode(trueBody);
|
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);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::While);
|
expectToken(Token::While);
|
||||||
@ -696,10 +699,10 @@ ASTPointer<WhileStatement> Parser::parseWhileStatement()
|
|||||||
expectToken(Token::RParen);
|
expectToken(Token::RParen);
|
||||||
ASTPointer<Statement> body = parseStatement();
|
ASTPointer<Statement> body = parseStatement();
|
||||||
nodeFactory.setEndPositionFromNode(body);
|
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);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
ASTPointer<Statement> initExpression;
|
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?
|
// LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RParen?
|
||||||
if (m_scanner->currentToken() != Token::Semicolon)
|
if (m_scanner->currentToken() != Token::Semicolon)
|
||||||
initExpression = parseSimpleStatement();
|
initExpression = parseSimpleStatement(ASTPointer<ASTString>());
|
||||||
expectToken(Token::Semicolon);
|
expectToken(Token::Semicolon);
|
||||||
|
|
||||||
if (m_scanner->currentToken() != Token::Semicolon)
|
if (m_scanner->currentToken() != Token::Semicolon)
|
||||||
@ -718,18 +721,21 @@ ASTPointer<ForStatement> Parser::parseForStatement()
|
|||||||
expectToken(Token::Semicolon);
|
expectToken(Token::Semicolon);
|
||||||
|
|
||||||
if (m_scanner->currentToken() != Token::RParen)
|
if (m_scanner->currentToken() != Token::RParen)
|
||||||
loopExpression = parseExpressionStatement();
|
loopExpression = parseExpressionStatement(ASTPointer<ASTString>());
|
||||||
expectToken(Token::RParen);
|
expectToken(Token::RParen);
|
||||||
|
|
||||||
ASTPointer<Statement> body = parseStatement();
|
ASTPointer<Statement> body = parseStatement();
|
||||||
nodeFactory.setEndPositionFromNode(body);
|
nodeFactory.setEndPositionFromNode(body);
|
||||||
return nodeFactory.createNode<ForStatement>(initExpression,
|
return nodeFactory.createNode<ForStatement>(
|
||||||
conditionExpression,
|
_docString,
|
||||||
loopExpression,
|
initExpression,
|
||||||
body);
|
conditionExpression,
|
||||||
|
loopExpression,
|
||||||
|
body
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<Statement> Parser::parseSimpleStatement()
|
ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString)
|
||||||
{
|
{
|
||||||
// These two cases are very hard to distinguish:
|
// These two cases are very hard to distinguish:
|
||||||
// x[7 * 20 + 3] a; - x[7 * 20 + 3] = 9;
|
// x[7 * 20 + 3] a; - x[7 * 20 + 3] = 9;
|
||||||
@ -740,9 +746,9 @@ ASTPointer<Statement> Parser::parseSimpleStatement()
|
|||||||
switch (peekStatementType())
|
switch (peekStatementType())
|
||||||
{
|
{
|
||||||
case LookAheadInfo::VariableDeclarationStatement:
|
case LookAheadInfo::VariableDeclarationStatement:
|
||||||
return parseVariableDeclarationStatement();
|
return parseVariableDeclarationStatement(_docString);
|
||||||
case LookAheadInfo::ExpressionStatement:
|
case LookAheadInfo::ExpressionStatement:
|
||||||
return parseExpressionStatement();
|
return parseExpressionStatement(_docString);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -781,12 +787,13 @@ ASTPointer<Statement> Parser::parseSimpleStatement()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken()))
|
if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken()))
|
||||||
return parseVariableDeclarationStatement(typeNameIndexAccessStructure(path, indices));
|
return parseVariableDeclarationStatement(_docString, typeNameIndexAccessStructure(path, indices));
|
||||||
else
|
else
|
||||||
return parseExpressionStatement(expressionFromIndexAccessStructure(path, indices));
|
return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(path, indices));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
|
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement(
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<TypeName> const& _lookAheadArrayType
|
ASTPointer<TypeName> const& _lookAheadArrayType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -845,15 +852,16 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme
|
|||||||
value = parseExpression();
|
value = parseExpression();
|
||||||
nodeFactory.setEndPositionFromNode(value);
|
nodeFactory.setEndPositionFromNode(value);
|
||||||
}
|
}
|
||||||
return nodeFactory.createNode<VariableDeclarationStatement>(variables, value);
|
return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<ExpressionStatement> Parser::parseExpressionStatement(
|
ASTPointer<ExpressionStatement> Parser::parseExpressionStatement(
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<Expression> const& _lookAheadIndexAccessStructure
|
ASTPointer<Expression> const& _lookAheadIndexAccessStructure
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ASTPointer<Expression> expression = parseExpression(_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(
|
ASTPointer<Expression> Parser::parseExpression(
|
||||||
|
@ -82,17 +82,19 @@ private:
|
|||||||
VarDeclParserOptions const& _options,
|
VarDeclParserOptions const& _options,
|
||||||
bool _allowEmpty = true
|
bool _allowEmpty = true
|
||||||
);
|
);
|
||||||
ASTPointer<Block> parseBlock();
|
ASTPointer<Block> parseBlock(ASTPointer<ASTString> const& _docString = {});
|
||||||
ASTPointer<Statement> parseStatement();
|
ASTPointer<Statement> parseStatement();
|
||||||
ASTPointer<IfStatement> parseIfStatement();
|
ASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);
|
||||||
ASTPointer<WhileStatement> parseWhileStatement();
|
ASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);
|
||||||
ASTPointer<ForStatement> parseForStatement();
|
ASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);
|
||||||
/// A "simple statement" can be a variable declaration statement or an expression statement.
|
/// 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<VariableDeclarationStatement> parseVariableDeclarationStatement(
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
|
ASTPointer<TypeName> const& _lookAheadArrayType = ASTPointer<TypeName>()
|
||||||
);
|
);
|
||||||
ASTPointer<ExpressionStatement> parseExpressionStatement(
|
ASTPointer<ExpressionStatement> parseExpressionStatement(
|
||||||
|
ASTPointer<ASTString> const& _docString,
|
||||||
ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>()
|
ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>()
|
||||||
);
|
);
|
||||||
ASTPointer<Expression> parseExpression(
|
ASTPointer<Expression> parseExpression(
|
||||||
|
Loading…
Reference in New Issue
Block a user