diff options
author | Christian <c@ethdev.com> | 2014-10-17 05:49:45 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-10-17 18:37:51 +0800 |
commit | a7f9815c0f68a7cb9571193ded851fbedb418422 (patch) | |
tree | 09adba8ef0aa273f5a84251ed53662b7d7fe3972 | |
parent | 8a506b505f4725e8a76bbad8399562099e4510c3 (diff) | |
download | dexon-solidity-a7f9815c0f68a7cb9571193ded851fbedb418422.tar.gz dexon-solidity-a7f9815c0f68a7cb9571193ded851fbedb418422.tar.zst dexon-solidity-a7f9815c0f68a7cb9571193ded851fbedb418422.zip |
Coding style and cleanup
-rw-r--r-- | AST.cpp | 29 | ||||
-rw-r--r-- | AST.h | 138 | ||||
-rw-r--r-- | ASTPrinter.cpp | 4 | ||||
-rw-r--r-- | ASTPrinter.h | 2 | ||||
-rw-r--r-- | BaseTypes.h | 4 | ||||
-rw-r--r-- | Exceptions.h | 6 | ||||
-rw-r--r-- | NameAndTypeResolver.cpp | 8 | ||||
-rw-r--r-- | NameAndTypeResolver.h | 9 | ||||
-rw-r--r-- | Parser.cpp | 98 | ||||
-rw-r--r-- | Scanner.cpp | 74 | ||||
-rw-r--r-- | Scanner.h | 113 | ||||
-rw-r--r-- | Scope.cpp | 1 | ||||
-rw-r--r-- | Scope.h | 2 | ||||
-rw-r--r-- | Types.h | 26 |
14 files changed, 199 insertions, 315 deletions
@@ -45,18 +45,14 @@ void ContractDefinition::accept(ASTVisitor& _visitor) void StructDefinition::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { listAccept(m_members, _visitor); - } _visitor.endVisit(*this); } void ParameterList::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { listAccept(m_parameters, _visitor); - } _visitor.endVisit(*this); } @@ -75,10 +71,8 @@ void FunctionDefinition::accept(ASTVisitor& _visitor) void VariableDeclaration::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { if (m_typeName) m_typeName->accept(_visitor); - } _visitor.endVisit(*this); } @@ -119,9 +113,7 @@ void Statement::accept(ASTVisitor& _visitor) void Block::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { listAccept(m_statements, _visitor); - } _visitor.endVisit(*this); } @@ -168,10 +160,8 @@ void Break::accept(ASTVisitor& _visitor) void Return::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { if (m_expression) m_expression->accept(_visitor); - } _visitor.endVisit(*this); } @@ -199,9 +189,7 @@ void Assignment::accept(ASTVisitor& _visitor) void UnaryOperation::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { m_subExpression->accept(_visitor); - } _visitor.endVisit(*this); } @@ -228,9 +216,7 @@ void FunctionCall::accept(ASTVisitor& _visitor) void MemberAccess::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) - { m_expression->accept(_visitor); - } _visitor.endVisit(*this); } @@ -272,7 +258,7 @@ void Statement::expectType(Expression& _expression, const Type& _expectedType) ptr<Type> Block::checkTypeRequirements() { - for (ptr<Statement> const & statement : m_statements) + for (ptr<Statement> const& statement: m_statements) statement->checkTypeRequirements(); return ptr<Type>(); } @@ -281,7 +267,8 @@ ptr<Type> IfStatement::checkTypeRequirements() { expectType(*m_condition, BoolType()); m_trueBody->checkTypeRequirements(); - if (m_falseBody) m_falseBody->checkTypeRequirements(); + if (m_falseBody) + m_falseBody->checkTypeRequirements(); return ptr<Type>(); } @@ -324,14 +311,10 @@ ptr<Type> VariableDefinition::checkTypeRequirements() if (m_value) { if (m_variable->getType()) - { expectType(*m_value, *m_variable->getType()); - } else - { // no type declared and no previous assignment, infer the type m_variable->setType(m_value->checkTypeRequirements()); - } } return ptr<Type>(); } @@ -371,9 +354,7 @@ ptr<Type> BinaryOperation::checkTypeRequirements() else BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("No common type found in binary operation.")); if (Token::isCompareOp(m_operator)) - { m_type = std::make_shared<BoolType>(); - } else { BOOST_ASSERT(Token::isBinaryOp(m_operator)); @@ -387,7 +368,7 @@ ptr<Type> BinaryOperation::checkTypeRequirements() ptr<Type> FunctionCall::checkTypeRequirements() { m_expression->checkTypeRequirements(); - for (ptr<Expression> const & argument : m_arguments) + for (ptr<Expression> const& argument: m_arguments) argument->checkTypeRequirements(); ptr<Type> expressionType = m_expression->getType(); Type::Category const category = expressionType->getCategory(); @@ -418,11 +399,9 @@ ptr<Type> FunctionCall::checkTypeRequirements() BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for " "function call.")); for (size_t i = 0; i < m_arguments.size(); ++i) - { if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameters[i]->getType())) BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Invalid type for argument in " "function call.")); - } // @todo actually the return type should be an anonymous struct, // but we change it to the type of the first return value until we have structs if (fun.getReturnParameterList()->getParameters().empty()) @@ -40,7 +40,7 @@ namespace solidity class ASTVisitor; -class ASTNode : private boost::noncopyable +class ASTNode: private boost::noncopyable { public: explicit ASTNode(Location const& _location) @@ -53,7 +53,7 @@ public: template <class T> static void listAccept(vecptr<T>& _list, ASTVisitor& _visitor) { - for (ptr<T>& element : _list) + for (ptr<T>& element: _list) element->accept(_visitor); } @@ -62,7 +62,7 @@ private: Location m_location; }; -class Declaration : public ASTNode +class Declaration: public ASTNode { public: Declaration(Location const& _location, ptr<ASTString> const& _name) @@ -73,7 +73,7 @@ private: ptr<ASTString> m_name; }; -class ContractDefinition : public Declaration +class ContractDefinition: public Declaration { public: ContractDefinition(Location const& _location, @@ -98,14 +98,13 @@ private: vecptr<FunctionDefinition> m_definedFunctions; }; -class StructDefinition : public Declaration +class StructDefinition: public Declaration { public: StructDefinition(Location const& _location, ptr<ASTString> const& _name, vecptr<VariableDeclaration> const& _members) - : Declaration(_location, _name), m_members(_members) - {} + : Declaration(_location, _name), m_members(_members) {} virtual void accept(ASTVisitor& _visitor) override; private: @@ -115,12 +114,11 @@ private: /// Used as function parameter list and return list /// None of the parameters is allowed to contain mappings (not even recursively /// inside structs) -class ParameterList : public ASTNode +class ParameterList: public ASTNode { public: ParameterList(Location const& _location, vecptr<VariableDeclaration> const& _parameters) - : ASTNode(_location), m_parameters(_parameters) - {} + : ASTNode(_location), m_parameters(_parameters) {} virtual void accept(ASTVisitor& _visitor) override; vecptr<VariableDeclaration> const& getParameters() { return m_parameters; } @@ -128,7 +126,7 @@ private: vecptr<VariableDeclaration> m_parameters; }; -class FunctionDefinition : public Declaration +class FunctionDefinition: public Declaration { public: FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic, @@ -138,8 +136,7 @@ public: ptr<Block> const& _body) : Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters), m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters), - m_body(_body) - {} + m_body(_body) {} virtual void accept(ASTVisitor& _visitor) override; bool isPublic() const { return m_isPublic; } @@ -156,14 +153,12 @@ private: ptr<Block> m_body; }; -class VariableDeclaration : public Declaration +class VariableDeclaration: public Declaration { public: - VariableDeclaration(Location const& _location, - ptr<TypeName> const& _type, + VariableDeclaration(Location const& _location, ptr<TypeName> const& _type, ptr<ASTString> const& _name) - : Declaration(_location, _name), m_typeName(_type) - {} + : Declaration(_location, _name), m_typeName(_type) {} virtual void accept(ASTVisitor& _visitor) override; bool isTypeGivenExplicitly() const { return m_typeName.get() != nullptr; } @@ -182,22 +177,21 @@ private: /// types /// @{ -class TypeName : public ASTNode +class TypeName: public ASTNode { public: - explicit TypeName(Location const& _location) : ASTNode(_location) {} + explicit TypeName(Location const& _location): ASTNode(_location) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> toType() = 0; }; /// any pre-defined type that is not a mapping -class ElementaryTypeName : public TypeName +class ElementaryTypeName: public TypeName { public: explicit ElementaryTypeName(Location const& _location, Token::Value _type) - : TypeName(_location), m_type(_type) - {} + : TypeName(_location), m_type(_type) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); } @@ -206,12 +200,11 @@ private: Token::Value m_type; }; -class UserDefinedTypeName : public TypeName +class UserDefinedTypeName: public TypeName { public: UserDefinedTypeName(Location const& _location, ptr<ASTString> const& _name) - : TypeName(_location), m_name(_name) - {} + : TypeName(_location), m_name(_name) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); } @@ -224,13 +217,12 @@ private: StructDefinition* m_referencedStruct; }; -class Mapping : public TypeName +class Mapping: public TypeName { public: Mapping(Location const& _location, ptr<ElementaryTypeName> const& _keyType, ptr<TypeName> const& _valueType) - : TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) - {} + : TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> toType() override { return Type::fromMapping(*this); } private: @@ -243,10 +235,10 @@ private: /// Statements /// @{ -class Statement : public ASTNode +class Statement: public ASTNode { public: - explicit Statement(Location const& _location) : ASTNode(_location) {} + explicit Statement(Location const& _location): ASTNode(_location) {} virtual void accept(ASTVisitor& _visitor) override; //! Check all type requirements, throws exception if some requirement is not met. @@ -259,12 +251,11 @@ protected: void expectType(Expression& _expression, Type const& _expectedType); }; -class Block : public Statement +class Block: public Statement { public: Block(Location const& _location, vecptr<Statement> const& _statements) - : Statement(_location), m_statements(_statements) - {} + : Statement(_location), m_statements(_statements) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; @@ -272,14 +263,13 @@ private: vecptr<Statement> m_statements; }; -class IfStatement : public Statement +class IfStatement: public Statement { public: IfStatement(Location const& _location, ptr<Expression> const& _condition, ptr<Statement> const& _trueBody, ptr<Statement> const& _falseBody) : Statement(_location), m_condition(_condition), - m_trueBody(_trueBody), m_falseBody(_falseBody) - {} + m_trueBody(_trueBody), m_falseBody(_falseBody) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; private: @@ -288,20 +278,19 @@ private: ptr<Statement> m_falseBody; //< "else" part, optional }; -class BreakableStatement : public Statement +class BreakableStatement: public Statement { public: - BreakableStatement(Location const& _location) : Statement(_location) {} + BreakableStatement(Location const& _location): Statement(_location) {} virtual void accept(ASTVisitor& _visitor) override; }; -class WhileStatement : public BreakableStatement +class WhileStatement: public BreakableStatement { public: WhileStatement(Location const& _location, ptr<Expression> const& _condition, ptr<Statement> const& _body) - : BreakableStatement(_location), m_condition(_condition), m_body(_body) - {} + : BreakableStatement(_location), m_condition(_condition), m_body(_body) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; private: @@ -309,28 +298,27 @@ private: ptr<Statement> m_body; }; -class Continue : public Statement +class Continue: public Statement { public: - Continue(Location const& _location) : Statement(_location) {} + Continue(Location const& _location): Statement(_location) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; }; -class Break : public Statement +class Break: public Statement { public: - Break(Location const& _location) : Statement(_location) {} + Break(Location const& _location): Statement(_location) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; }; -class Return : public Statement +class Return: public Statement { public: Return(Location const& _location, ptr<Expression> _expression) - : Statement(_location), m_expression(_expression) - {} + : Statement(_location), m_expression(_expression) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; @@ -341,13 +329,12 @@ private: ParameterList* m_returnParameters; //< extracted from the function declaration }; -class VariableDefinition : public Statement +class VariableDefinition: public Statement { public: VariableDefinition(Location const& _location, ptr<VariableDeclaration> _variable, ptr<Expression> _value) - : Statement(_location), m_variable(_variable), m_value(_value) - {} + : Statement(_location), m_variable(_variable), m_value(_value) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; @@ -356,10 +343,10 @@ private: ptr<Expression> m_value; ///< can be missing }; -class Expression : public Statement +class Expression: public Statement { public: - Expression(Location const& _location) : Statement(_location) {} + Expression(Location const& _location): Statement(_location) {} ptr<Type> const& getType() { return m_type; } protected: ptr<Type> m_type; @@ -370,14 +357,13 @@ protected: /// Expressions /// @{ -class Assignment : public Expression +class Assignment: public Expression { public: Assignment(Location const& _location, ptr<Expression> const& _leftHandSide, Token::Value _assignmentOperator, ptr<Expression> const& _rightHandSide) : Expression(_location), m_leftHandSide(_leftHandSide), - m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) - {} + m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; @@ -388,14 +374,13 @@ private: ptr<Expression> m_rightHandSide; }; -class UnaryOperation : public Expression +class UnaryOperation: public Expression { public: UnaryOperation(Location const& _location, Token::Value _operator, ptr<Expression> const& _subExpression, bool _isPrefix) : Expression(_location), m_operator(_operator), - m_subExpression(_subExpression), m_isPrefix(_isPrefix) - {} + m_subExpression(_subExpression), m_isPrefix(_isPrefix) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; @@ -407,13 +392,12 @@ private: bool m_isPrefix; }; -class BinaryOperation : public Expression +class BinaryOperation: public Expression { public: BinaryOperation(Location const& _location, ptr<Expression> const& _left, Token::Value _operator, ptr<Expression> const& _right) - : Expression(_location), m_left(_left), m_operator(_operator), m_right(_right) - {} + : Expression(_location), m_left(_left), m_operator(_operator), m_right(_right) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; @@ -427,13 +411,12 @@ private: }; /// Can be ordinary function call, type cast or struct construction. -class FunctionCall : public Expression +class FunctionCall: public Expression { public: FunctionCall(Location const& _location, ptr<Expression> const& _expression, vecptr<Expression> const& _arguments) - : Expression(_location), m_expression(_expression), m_arguments(_arguments) - {} + : Expression(_location), m_expression(_expression), m_arguments(_arguments) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; private: @@ -441,13 +424,12 @@ private: vecptr<Expression> m_arguments; }; -class MemberAccess : public Expression +class MemberAccess: public Expression { public: MemberAccess(Location const& _location, ptr<Expression> _expression, ptr<ASTString> const& _memberName) - : Expression(_location), m_expression(_expression), m_memberName(_memberName) - {} + : Expression(_location), m_expression(_expression), m_memberName(_memberName) {} virtual void accept(ASTVisitor& _visitor) override; const ASTString& getMemberName() const { return *m_memberName; } virtual ptr<Type> checkTypeRequirements() override; @@ -456,13 +438,12 @@ private: ptr<ASTString> m_memberName; }; -class IndexAccess : public Expression +class IndexAccess: public Expression { public: IndexAccess(Location const& _location, ptr<Expression> const& _base, ptr<Expression> const& _index) - : Expression(_location), m_base(_base), m_index(_index) - {} + : Expression(_location), m_base(_base), m_index(_index) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; private: @@ -470,13 +451,13 @@ private: ptr<Expression> m_index; }; -class PrimaryExpression : public Expression +class PrimaryExpression: public Expression { public: - PrimaryExpression(Location const& _location) : Expression(_location) {} + PrimaryExpression(Location const& _location): Expression(_location) {} }; -class Identifier : public PrimaryExpression +class Identifier: public PrimaryExpression { public: Identifier(Location const& _location, ptr<ASTString> const& _name) @@ -494,7 +475,7 @@ private: Declaration* m_referencedDeclaration; }; -class ElementaryTypeNameExpression : public PrimaryExpression +class ElementaryTypeNameExpression: public PrimaryExpression { public: ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken) @@ -507,12 +488,11 @@ private: Token::Value m_typeToken; }; -class Literal : public PrimaryExpression +class Literal: public PrimaryExpression { public: Literal(Location const& _location, Token::Value _token, ptr<ASTString> const& _value) - : PrimaryExpression(_location), m_token(_token), m_value(_value) - {} + : PrimaryExpression(_location), m_token(_token), m_value(_value) {} virtual void accept(ASTVisitor& _visitor) override; virtual ptr<Type> checkTypeRequirements() override; diff --git a/ASTPrinter.cpp b/ASTPrinter.cpp index 7c48dacb..cd8263f2 100644 --- a/ASTPrinter.cpp +++ b/ASTPrinter.cpp @@ -244,7 +244,7 @@ bool ASTPrinter::visit(Literal& _node) { const char* tokenString = Token::toString(_node.getToken()); if (tokenString == nullptr) - tokenString = "----"; + tokenString = "[no token]"; writeLine(std::string("Literal, token: ") + tokenString + " value: " + _node.getValue()); printSourcePart(_node); return goDeeper(); @@ -255,8 +255,6 @@ void ASTPrinter::endVisit(ASTNode&) m_indentation--; } -// @todo instead of this, we could make the default implementation of endVisit call the -// superclass' endVisit void ASTPrinter::endVisit(ContractDefinition&) { m_indentation--; diff --git a/ASTPrinter.h b/ASTPrinter.h index 52f34991..00c681f3 100644 --- a/ASTPrinter.h +++ b/ASTPrinter.h @@ -30,7 +30,7 @@ namespace dev namespace solidity { -class ASTPrinter : public ASTVisitor +class ASTPrinter: public ASTVisitor { public: /// Create a printer for the given abstract syntax tree. If the source is specified, diff --git a/BaseTypes.h b/BaseTypes.h index c8926b6a..fdf3f7b5 100644 --- a/BaseTypes.h +++ b/BaseTypes.h @@ -32,8 +32,8 @@ namespace solidity /// The interval includes start and excludes end. struct Location { - Location(int _start, int _end) : start(_start), end(_end) { } - Location() : start(-1), end(-1) { } + Location(int _start, int _end): start(_start), end(_end) { } + Location(): start(-1), end(-1) { } bool IsValid() const { return start >= 0 && end >= start; } diff --git a/Exceptions.h b/Exceptions.h index c14e0d79..c600ebf1 100644 --- a/Exceptions.h +++ b/Exceptions.h @@ -29,9 +29,9 @@ namespace dev namespace solidity { -struct ParserError : virtual Exception {}; -struct TypeError : virtual Exception {}; -struct DeclarationError : virtual Exception {}; +struct ParserError: virtual Exception {}; +struct TypeError: virtual Exception {}; +struct DeclarationError: virtual Exception {}; } } diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp index ada987b0..628d9476 100644 --- a/NameAndTypeResolver.cpp +++ b/NameAndTypeResolver.cpp @@ -42,18 +42,18 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) DeclarationRegistrationHelper registrar(m_scopes, _contract); m_currentScope = &m_scopes[&_contract]; //@todo structs - for (ptr<VariableDeclaration> const & variable : _contract.getStateVariables()) + for (ptr<VariableDeclaration> const& variable: _contract.getStateVariables()) ReferencesResolver resolver(*variable, *this, nullptr); - for (ptr<FunctionDefinition> const & function : _contract.getDefinedFunctions()) + for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions()) { m_currentScope = &m_scopes[function.get()]; ReferencesResolver referencesResolver(*function, *this, function->getReturnParameterList().get()); } - // First, all function parameter types need to be resolved before we can check + // First, the parameter types of all functions need to be resolved before we can check // the types, since it is possible to call functions that are only defined later // in the source. - for (ptr<FunctionDefinition> const & function : _contract.getDefinedFunctions()) + for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions()) { m_currentScope = &m_scopes[function.get()]; function->getBody().checkTypeRequirements(); diff --git a/NameAndTypeResolver.h b/NameAndTypeResolver.h index 346c9e64..076b1389 100644 --- a/NameAndTypeResolver.h +++ b/NameAndTypeResolver.h @@ -34,8 +34,9 @@ namespace dev namespace solidity { - -class NameAndTypeResolver : private boost::noncopyable +//! Resolves name references, resolves all types and checks that all operations are valid for the +//! inferred types. An exception is throw on the first error. +class NameAndTypeResolver: private boost::noncopyable { public: NameAndTypeResolver(); @@ -54,7 +55,7 @@ private: //! Traverses the given AST upon construction and fills _scopes with all declarations inside the //! AST. -class DeclarationRegistrationHelper : private ASTVisitor +class DeclarationRegistrationHelper: private ASTVisitor { public: DeclarationRegistrationHelper(std::map<ASTNode*, Scope>& _scopes, ASTNode& _astRoot); @@ -79,7 +80,7 @@ private: //! Resolves references to declarations (of variables and types) and also establishes the link //! between a return statement and the return parameter list. -class ReferencesResolver : private ASTVisitor +class ReferencesResolver: private ASTVisitor { public: ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver, ParameterList* _returnParameters); @@ -43,27 +43,13 @@ ptr<ContractDefinition> Parser::parse(std::shared_ptr<Scanner> const& _scanner) class Parser::ASTNodeFactory { public: - ASTNodeFactory(const Parser& _parser) - : m_parser(_parser), m_location(_parser.getPosition(), -1) - {} - - void markEndPosition() - { - m_location.end = m_parser.getEndPosition(); - } - - void setLocationEmpty() - { - m_location.end = m_location.start; - } + ASTNodeFactory(const Parser& _parser) : m_parser(_parser), m_location(_parser.getPosition(), -1) {} + void markEndPosition() { m_location.end = m_parser.getEndPosition(); } + void setLocationEmpty() { m_location.end = m_location.start; } /// Set the end position to the one of the given node. - void setEndPositionFromNode(const ptr<ASTNode>& _node) - { - m_location.end = _node->getLocation().end; - } + void setEndPositionFromNode(const ptr<ASTNode>& _node) { m_location.end = _node->getLocation().end; } - /// @todo: check that this actually uses perfect forwarding template <class NodeType, typename... Args> ptr<NodeType> createNode(Args&& ... _args) { @@ -102,9 +88,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition() { Token::Value currentToken = m_scanner->getCurrentToken(); if (currentToken == Token::RBRACE) - { break; - } else if (currentToken == Token::PUBLIC || currentToken == Token::PRIVATE) { visibilityIsPublic = (m_scanner->getCurrentToken() == Token::PUBLIC); @@ -112,13 +96,9 @@ ptr<ContractDefinition> Parser::parseContractDefinition() expectToken(Token::COLON); } else if (currentToken == Token::FUNCTION) - { functions.push_back(parseFunctionDefinition(visibilityIsPublic)); - } else if (currentToken == Token::STRUCT) - { structs.push_back(parseStructDefinition()); - } else if (currentToken == Token::IDENTIFIER || currentToken == Token::MAPPING || Token::isElementaryTypeName(currentToken)) { @@ -127,9 +107,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition() expectToken(Token::SEMICOLON); } else - { throwExpectationError("Function, variable or struct declaration expected."); - } } nodeFactory.markEndPosition(); expectToken(Token::RBRACE); @@ -221,9 +199,7 @@ ptr<TypeName> Parser::parseTypeName(bool _allowVar) type = nodeFactory.createNode<UserDefinedTypeName>(expectIdentifierToken()); } else - { throwExpectationError("Expected type name"); - } return type; } @@ -271,9 +247,7 @@ ptr<Block> Parser::parseBlock() expectToken(Token::LBRACE); vecptr<Statement> statements; while (m_scanner->getCurrentToken() != Token::RBRACE) - { statements.push_back(parseStatement()); - } nodeFactory.markEndPosition(); expectToken(Token::RBRACE); return nodeFactory.createNode<Block>(statements); @@ -318,15 +292,10 @@ ptr<Statement> Parser::parseStatement() m_scanner->getCurrentToken() == Token::VAR || Token::isElementaryTypeName(m_scanner->getCurrentToken()) || (m_scanner->getCurrentToken() == Token::IDENTIFIER && - m_scanner->peek() == Token::IDENTIFIER)) - { + m_scanner->peekNextToken() == Token::IDENTIFIER)) statement = parseVariableDefinition(); - } - else - { - // "ordinary" expression + else // "ordinary" expression statement = parseExpression(); - } } expectToken(Token::SEMICOLON); return statement; @@ -348,9 +317,7 @@ ptr<IfStatement> Parser::parseIfStatement() nodeFactory.setEndPositionFromNode(falseBody); } else - { nodeFactory.setEndPositionFromNode(trueBody); - } return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody); } @@ -379,9 +346,7 @@ ptr<VariableDefinition> Parser::parseVariableDefinition() nodeFactory.setEndPositionFromNode(value); } else - { nodeFactory.setEndPositionFromNode(variable); - } return nodeFactory.createNode<VariableDefinition>(variable, value); } @@ -450,29 +415,29 @@ ptr<Expression> Parser::parseLeftHandSideExpression() switch (m_scanner->getCurrentToken()) { case Token::LBRACK: - { - m_scanner->next(); - ptr<Expression> index = parseExpression(); - nodeFactory.markEndPosition(); - expectToken(Token::RBRACK); - expression = nodeFactory.createNode<IndexAccess>(expression, index); - } + { + m_scanner->next(); + ptr<Expression> index = parseExpression(); + nodeFactory.markEndPosition(); + expectToken(Token::RBRACK); + expression = nodeFactory.createNode<IndexAccess>(expression, index); + } break; case Token::PERIOD: - { - m_scanner->next(); - nodeFactory.markEndPosition(); - expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken()); - } + { + m_scanner->next(); + nodeFactory.markEndPosition(); + expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken()); + } break; case Token::LPAREN: - { - m_scanner->next(); - vecptr<Expression> arguments = parseFunctionCallArguments(); - nodeFactory.markEndPosition(); - expectToken(Token::RPAREN); - expression = nodeFactory.createNode<FunctionCall>(expression, arguments); - } + { + m_scanner->next(); + vecptr<Expression> arguments = parseFunctionCallArguments(); + nodeFactory.markEndPosition(); + expectToken(Token::RPAREN); + expression = nodeFactory.createNode<FunctionCall>(expression, arguments); + } break; default: return expression; @@ -502,12 +467,12 @@ ptr<Expression> Parser::parsePrimaryExpression() expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance()); break; case Token::LPAREN: - { - m_scanner->next(); - ptr<Expression> expression = parseExpression(); - expectToken(Token::RPAREN); - return expression; - } + { + m_scanner->next(); + ptr<Expression> expression = parseExpression(); + expectToken(Token::RPAREN); + return expression; + } default: if (Token::isElementaryTypeName(token)) { @@ -520,6 +485,7 @@ ptr<Expression> Parser::parsePrimaryExpression() throwExpectationError("Expected primary expression."); return ptr<Expression>(); // this is not reached } + break; } return expression; } diff --git a/Scanner.cpp b/Scanner.cpp index c2875c9c..61f56f29 100644 --- a/Scanner.cpp +++ b/Scanner.cpp @@ -103,11 +103,11 @@ void Scanner::reset(const CharStream& _source) } -bool Scanner::scanHexNumber(char& scanned_number, int expected_length) +bool Scanner::scanHexNumber(char& o_scannedNumber, int _expectedLength) { - BOOST_ASSERT(expected_length <= 4); // prevent overflow + BOOST_ASSERT(_expectedLength <= 4); // prevent overflow char x = 0; - for (int i = 0; i < expected_length; i++) + for (int i = 0; i < _expectedLength; i++) { int d = HexValue(m_char); if (d < 0) @@ -118,7 +118,7 @@ bool Scanner::scanHexNumber(char& scanned_number, int expected_length) x = x * 16 + d; advance(); } - scanned_number = x; + o_scannedNumber = x; return true; } @@ -129,24 +129,25 @@ BOOST_STATIC_ASSERT(Token::NUM_TOKENS <= 0x100); Token::Value Scanner::next() { m_current_token = m_next_token; - m_hasLineTerminatorBeforeNext = false; - m_hasMultilineCommentBeforeNext = false; scanToken(); return m_current_token.token; } +Token::Value Scanner::selectToken(char _next, Token::Value _then, Token::Value _else) +{ + advance(); + if (m_char == _next) + selectToken(_then); + else + return _else; +} + bool Scanner::skipWhitespace() { const int start_position = getSourcePos(); - while (true) - { - if (IsLineTerminator(m_char)) - m_hasLineTerminatorBeforeNext = true; - else if (!IsWhiteSpace(m_char)) - break; + while (IsWhiteSpace(m_char)) advance(); - } // Return whether or not we skipped any characters. return getSourcePos() != start_position; } @@ -170,12 +171,7 @@ Token::Value Scanner::skipMultiLineComment() { char ch = m_char; advance(); - if (IsLineTerminator(ch)) - { - // Following ECMA-262, section 7.4, a comment containing - // a newline will make the comment count as a line-terminator. - m_hasMultilineCommentBeforeNext = true; - } + // If we have reached the end of the multi-line comment, we // consume the '/' and insert a whitespace. This way all // multi-line comments are treated as whitespace. @@ -199,8 +195,7 @@ void Scanner::scanToken() m_next_token.location.start = getSourcePos(); switch (m_char) { - case '\n': - m_hasLineTerminatorBeforeNext = true; // fall-through + case '\n': // fall-through case ' ': case '\t': token = selectToken(Token::WHITESPACE); @@ -395,37 +390,35 @@ bool Scanner::scanEscape() switch (c) { case '\'': // fall through - case '"' : // fall through + case '"': // fall through case '\\': break; - case 'b' : + case 'b': c = '\b'; break; - case 'f' : + case 'f': c = '\f'; break; - case 'n' : + case 'n': c = '\n'; break; - case 'r' : + case 'r': c = '\r'; break; - case 't' : + case 't': c = '\t'; break; - case 'u' : + case 'u': if (!scanHexNumber(c, 4)) return false; break; - case 'v' : + case 'v': c = '\v'; break; - case 'x' : + case 'x': if (!scanHexNumber(c, 2)) return false; break; } - // According to ECMA-262, section 7.8.4, characters not covered by the - // above cases should be illegal, but they are commonly handled as - // non-escaped characters by JS VMs. + addLiteralChar(c); return true; } @@ -653,6 +646,21 @@ Token::Value Scanner::scanIdentifierOrKeyword() return KeywordOrIdentifierToken(m_next_token.literal); } +char CharStream::advanceAndGet() +{ + if (isPastEndOfInput()) return 0; + ++m_pos; + if (isPastEndOfInput()) return 0; + return get(); +} + +char CharStream::rollback(size_t _amount) +{ + BOOST_ASSERT(m_pos >= _amount); + m_pos -= _amount; + return get(); +} + std::string CharStream::getLineAtPosition(int _position) const { // if _position points to \n, it returns the line before the \n @@ -63,27 +63,13 @@ class ParserRecorder; class CharStream { public: - CharStream() - : m_pos(0) - {} - - explicit CharStream(const std::string& _source) : m_source(_source), m_pos(0) {} + CharStream() : m_pos(0) {} + explicit CharStream(const std::string& _source): m_source(_source), m_pos(0) {} int getPos() const { return m_pos; } bool isPastEndOfInput() const { return m_pos >= m_source.size(); } char get() const { return m_source[m_pos]; } - char advanceAndGet() - { - if (isPastEndOfInput()) return 0; - ++m_pos; - if (isPastEndOfInput()) return 0; - return get(); - } - char rollback(size_t _amount) - { - BOOST_ASSERT(m_pos >= _amount); - m_pos -= _amount; - return get(); - } + char advanceAndGet(); + char rollback(size_t _amount); /// Functions that help pretty-printing parse errors /// Do only use in error cases, they are quite expensive. @@ -96,8 +82,6 @@ private: size_t m_pos; }; -// ---------------------------------------------------------------------------- -// JavaScript Scanner. class Scanner { @@ -107,7 +91,7 @@ public: class LiteralScope { public: - explicit LiteralScope(Scanner* self) : scanner_(self), complete_(false) { scanner_->startNewLiteral(); } + explicit LiteralScope(Scanner* self): scanner_(self), complete_(false) { scanner_->startNewLiteral(); } ~LiteralScope() { if (!complete_) scanner_->dropLiteral(); } void Complete() { complete_ = true; } @@ -118,47 +102,36 @@ public: explicit Scanner(const CharStream& _source); - // Resets the scanner as if newly constructed with _input as input. + /// Resets the scanner as if newly constructed with _input as input. void reset(const CharStream& _source); - // Returns the next token and advances input. + /// Returns the next token and advances input. Token::Value next(); - // Returns the current token again. + + /// Information about the current token + /// @{ + + /// Returns the current token Token::Value getCurrentToken() { return m_current_token.token; } - // Returns the location information for the current token - // (the token last returned by Next()). Location getCurrentLocation() const { return m_current_token.location; } const std::string& getCurrentLiteral() const { return m_current_token.literal; } + /// @} - // Similar functions for the upcoming token. - - // One token look-ahead (past the token returned by Next()). - Token::Value peek() const { return m_next_token.token; } - + /// Information about the next token + /// @{ + /// Returns the next token without advancing input. + Token::Value peekNextToken() const { return m_next_token.token; } Location peekLocation() const { return m_next_token.location; } const std::string& peekLiteral() const { return m_next_token.literal; } + /// @} /// Functions that help pretty-printing parse errors. /// Do only use in error cases, they are quite expensive. /// @{ - std::string getLineAtPosition(int _position) const - { - return m_source.getLineAtPosition(_position); - } - std::tuple<int, int> translatePositionToLineColumn(int _position) const - { - return m_source.translatePositionToLineColumn(_position); - } + std::string getLineAtPosition(int _position) const { return m_source.getLineAtPosition(_position); } + std::tuple<int, int> translatePositionToLineColumn(int _position) const { return m_source.translatePositionToLineColumn(_position); } /// @} - // Returns true if there was a line terminator before the peek'ed token, - // possibly inside a multi-line comment. - bool hasAnyLineTerminatorBeforeNext() const - { - return m_hasLineTerminatorBeforeNext || - m_hasMultilineCommentBeforeNext; - } - private: // Used for the current and look-ahead token. struct TokenDesc @@ -168,34 +141,22 @@ private: std::string literal; }; - // Literal buffer support + /// Literal buffer support + /// @{ inline void startNewLiteral() { m_next_token.literal.clear(); } - inline void addLiteralChar(char c) { m_next_token.literal.push_back(c); } - inline void dropLiteral() { m_next_token.literal.clear(); } - inline void addLiteralCharAndAdvance() { addLiteralChar(m_char); advance(); } + /// @} - // Low-level scanning support. bool advance() { m_char = m_source.advanceAndGet(); return !m_source.isPastEndOfInput(); } - void rollback(int amount) { m_char = m_source.rollback(amount); } + void rollback(int _amount) { m_char = m_source.rollback(_amount); } - inline Token::Value selectToken(Token::Value tok) { advance(); return tok; } + inline Token::Value selectToken(Token::Value _tok) { advance(); return _tok; } + /// If the next character is _next, advance and return _then, otherwise return _else. + inline Token::Value selectToken(char _next, Token::Value _then, Token::Value _else); - inline Token::Value selectToken(char next, Token::Value then, Token::Value else_) - { - advance(); - if (m_char == next) - { - advance(); - return then; - } - else - return else_; - } - - bool scanHexNumber(char& scanned_number, int expected_length); + bool scanHexNumber(char& o_scannedNumber, int _expectedLength); // Scans a single JavaScript token. void scanToken(); @@ -210,12 +171,12 @@ private: Token::Value scanString(); - // Scans an escape-sequence which is part of a string and adds the - // decoded character to the current literal. Returns true if a pattern - // is scanned. + /// Scans an escape-sequence which is part of a string and adds the + /// decoded character to the current literal. Returns true if a pattern + /// is scanned. bool scanEscape(); - // Return the current source position. + /// Return the current source position. int getSourcePos() { return m_source.getPos(); } bool isSourcePastEndOfInput() { return m_source.isPastEndOfInput(); } @@ -224,16 +185,8 @@ private: CharStream m_source; - // one character look-ahead, equals 0 at end of input + /// one character look-ahead, equals 0 at end of input char m_char; - - // Whether there is a line terminator whitespace character after - // the current token, and before the next. Does not count newlines - // inside multiline comments. - bool m_hasLineTerminatorBeforeNext; - // Whether there is a multi-line comment that contains a - // line-terminator after the current token, and before the next. - bool m_hasMultilineCommentBeforeNext; }; } @@ -28,7 +28,6 @@ namespace dev namespace solidity { - bool Scope::registerDeclaration(Declaration& _declaration) { if (m_declarations.find(_declaration.getName()) != m_declarations.end()) @@ -36,7 +36,7 @@ namespace solidity class Scope { public: - explicit Scope(Scope* _outerScope = nullptr) : m_outerScope(_outerScope) {} + explicit Scope(Scope* _outerScope = nullptr): m_outerScope(_outerScope) {} /// Registers the declaration in the scope unless its name is already declared. Returns true iff /// it was not yet declared. bool registerDeclaration(Declaration& _declaration); @@ -48,7 +48,7 @@ using ptr = std::shared_ptr<T>; // @todo realMxN, string<N>, mapping -class Type : private boost::noncopyable +class Type: private boost::noncopyable { public: enum class Category @@ -73,7 +73,7 @@ public: virtual bool acceptsUnaryOperator(Token::Value) const { return false; } }; -class IntegerType : public Type +class IntegerType: public Type { public: enum class Modifier @@ -100,7 +100,7 @@ private: Modifier m_modifier; }; -class BoolType : public Type +class BoolType: public Type { public: virtual Category getCategory() const { return Category::BOOL; } @@ -119,21 +119,21 @@ public: } }; -class ContractType : public Type +class ContractType: public Type { public: virtual Category getCategory() const { return Category::CONTRACT; } - ContractType(ContractDefinition const& _contract) : m_contract(_contract) {} + ContractType(ContractDefinition const& _contract): m_contract(_contract) {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const; private: ContractDefinition const& m_contract; }; -class StructType : public Type +class StructType: public Type { public: virtual Category getCategory() const { return Category::STRUCT; } - StructType(StructDefinition const& _struct) : m_struct(_struct) {} + StructType(StructDefinition const& _struct): m_struct(_struct) {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const; virtual bool acceptsUnaryOperator(Token::Value _operator) const override { @@ -143,18 +143,18 @@ private: StructDefinition const& m_struct; }; -class FunctionType : public Type +class FunctionType: public Type { public: virtual Category getCategory() const { return Category::FUNCTION; } - FunctionType(FunctionDefinition const& _function) : m_function(_function) {} + FunctionType(FunctionDefinition const& _function): m_function(_function) {} FunctionDefinition const& getFunction() const { return m_function; } private: FunctionDefinition const& m_function; }; -class MappingType : public Type +class MappingType: public Type { public: virtual Category getCategory() const { return Category::MAPPING; } @@ -164,18 +164,18 @@ private: }; //@todo should be changed into "empty anonymous struct" -class VoidType : public Type +class VoidType: public Type { public: virtual Category getCategory() const { return Category::VOID; } VoidType() {} }; -class TypeType : public Type +class TypeType: public Type { public: virtual Category getCategory() const { return Category::TYPE; } - TypeType(ptr<Type> const& _actualType) : m_actualType(_actualType) {} + TypeType(ptr<Type> const& _actualType): m_actualType(_actualType) {} ptr<Type> const& getActualType() { return m_actualType; } private: |