mark an identifier as callable if its next token is '('

This commit is contained in:
Lu Guanqun 2015-02-28 16:11:59 +08:00
parent 67ffc3db71
commit 1efef53cb3
2 changed files with 11 additions and 3 deletions

7
AST.h
View File

@ -1134,8 +1134,8 @@ public:
class Identifier: public PrimaryExpression class Identifier: public PrimaryExpression
{ {
public: public:
Identifier(SourceLocation const& _location, ASTPointer<ASTString> const& _name): Identifier(SourceLocation const& _location, ASTPointer<ASTString> const& _name, bool _isCallable):
PrimaryExpression(_location), m_name(_name) {} PrimaryExpression(_location), m_name(_name), m_isCallable(_isCallable) {}
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;
virtual void checkTypeRequirements() override; virtual void checkTypeRequirements() override;
@ -1151,6 +1151,8 @@ public:
Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; } Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; }
ContractDefinition const* getCurrentContract() const { return m_currentContract; } ContractDefinition const* getCurrentContract() const { return m_currentContract; }
bool isCallable() const { return m_isCallable; }
private: private:
ASTPointer<ASTString> m_name; ASTPointer<ASTString> m_name;
@ -1159,6 +1161,7 @@ private:
/// Stores a reference to the current contract. This is needed because types of base contracts /// Stores a reference to the current contract. This is needed because types of base contracts
/// change depending on the context. /// change depending on the context.
ContractDefinition const* m_currentContract = nullptr; ContractDefinition const* m_currentContract = nullptr;
bool m_isCallable = false;
}; };
/** /**

View File

@ -837,9 +837,14 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance()); expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
break; break;
case Token::Identifier: case Token::Identifier:
{
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance()); // if the next token is '(', this identifier looks like function call,
// it could be a contract, event etc.
bool isCallable = m_scanner->peekNextToken() == Token::LParen;
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance(), isCallable);
break; break;
}
case Token::LParen: case Token::LParen:
{ {
m_scanner->next(); m_scanner->next();