Browse Source

Coding style and cleanup

cl-refactor
Christian 10 years ago
parent
commit
116070f304
  1. 29
      libsolidity/AST.cpp
  2. 138
      libsolidity/AST.h
  3. 4
      libsolidity/ASTPrinter.cpp
  4. 2
      libsolidity/ASTPrinter.h
  5. 4
      libsolidity/BaseTypes.h
  6. 6
      libsolidity/Exceptions.h
  7. 8
      libsolidity/NameAndTypeResolver.cpp
  8. 9
      libsolidity/NameAndTypeResolver.h
  9. 98
      libsolidity/Parser.cpp
  10. 74
      libsolidity/Scanner.cpp
  11. 113
      libsolidity/Scanner.h
  12. 1
      libsolidity/Scope.cpp
  13. 2
      libsolidity/Scope.h
  14. 26
      libsolidity/Types.h

29
libsolidity/AST.cpp

@ -45,18 +45,14 @@ void ContractDefinition::accept(ASTVisitor& _visitor)
void StructDefinition::accept(ASTVisitor& _visitor) void StructDefinition::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
listAccept(m_members, _visitor); listAccept(m_members, _visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
void ParameterList::accept(ASTVisitor& _visitor) void ParameterList::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
listAccept(m_parameters, _visitor); listAccept(m_parameters, _visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
@ -75,10 +71,8 @@ void FunctionDefinition::accept(ASTVisitor& _visitor)
void VariableDeclaration::accept(ASTVisitor& _visitor) void VariableDeclaration::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
if (m_typeName) if (m_typeName)
m_typeName->accept(_visitor); m_typeName->accept(_visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
@ -119,9 +113,7 @@ void Statement::accept(ASTVisitor& _visitor)
void Block::accept(ASTVisitor& _visitor) void Block::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
listAccept(m_statements, _visitor); listAccept(m_statements, _visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
@ -168,10 +160,8 @@ void Break::accept(ASTVisitor& _visitor)
void Return::accept(ASTVisitor& _visitor) void Return::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
if (m_expression) if (m_expression)
m_expression->accept(_visitor); m_expression->accept(_visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
@ -199,9 +189,7 @@ void Assignment::accept(ASTVisitor& _visitor)
void UnaryOperation::accept(ASTVisitor& _visitor) void UnaryOperation::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
m_subExpression->accept(_visitor); m_subExpression->accept(_visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
@ -228,9 +216,7 @@ void FunctionCall::accept(ASTVisitor& _visitor)
void MemberAccess::accept(ASTVisitor& _visitor) void MemberAccess::accept(ASTVisitor& _visitor)
{ {
if (_visitor.visit(*this)) if (_visitor.visit(*this))
{
m_expression->accept(_visitor); m_expression->accept(_visitor);
}
_visitor.endVisit(*this); _visitor.endVisit(*this);
} }
@ -272,7 +258,7 @@ void Statement::expectType(Expression& _expression, const Type& _expectedType)
ptr<Type> Block::checkTypeRequirements() ptr<Type> Block::checkTypeRequirements()
{ {
for (ptr<Statement> const & statement : m_statements) for (ptr<Statement> const& statement: m_statements)
statement->checkTypeRequirements(); statement->checkTypeRequirements();
return ptr<Type>(); return ptr<Type>();
} }
@ -281,7 +267,8 @@ ptr<Type> IfStatement::checkTypeRequirements()
{ {
expectType(*m_condition, BoolType()); expectType(*m_condition, BoolType());
m_trueBody->checkTypeRequirements(); m_trueBody->checkTypeRequirements();
if (m_falseBody) m_falseBody->checkTypeRequirements(); if (m_falseBody)
m_falseBody->checkTypeRequirements();
return ptr<Type>(); return ptr<Type>();
} }
@ -324,14 +311,10 @@ ptr<Type> VariableDefinition::checkTypeRequirements()
if (m_value) if (m_value)
{ {
if (m_variable->getType()) if (m_variable->getType())
{
expectType(*m_value, *m_variable->getType()); expectType(*m_value, *m_variable->getType());
}
else else
{
// no type declared and no previous assignment, infer the type // no type declared and no previous assignment, infer the type
m_variable->setType(m_value->checkTypeRequirements()); m_variable->setType(m_value->checkTypeRequirements());
}
} }
return ptr<Type>(); return ptr<Type>();
} }
@ -371,9 +354,7 @@ ptr<Type> BinaryOperation::checkTypeRequirements()
else else
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("No common type found in binary operation.")); BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("No common type found in binary operation."));
if (Token::isCompareOp(m_operator)) if (Token::isCompareOp(m_operator))
{
m_type = std::make_shared<BoolType>(); m_type = std::make_shared<BoolType>();
}
else else
{ {
BOOST_ASSERT(Token::isBinaryOp(m_operator)); BOOST_ASSERT(Token::isBinaryOp(m_operator));
@ -387,7 +368,7 @@ ptr<Type> BinaryOperation::checkTypeRequirements()
ptr<Type> FunctionCall::checkTypeRequirements() ptr<Type> FunctionCall::checkTypeRequirements()
{ {
m_expression->checkTypeRequirements(); m_expression->checkTypeRequirements();
for (ptr<Expression> const & argument : m_arguments) for (ptr<Expression> const& argument: m_arguments)
argument->checkTypeRequirements(); argument->checkTypeRequirements();
ptr<Type> expressionType = m_expression->getType(); ptr<Type> expressionType = m_expression->getType();
Type::Category const category = expressionType->getCategory(); Type::Category const category = expressionType->getCategory();
@ -418,11 +399,9 @@ ptr<Type> FunctionCall::checkTypeRequirements()
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for " BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for "
"function call.")); "function call."));
for (size_t i = 0; i < m_arguments.size(); ++i) for (size_t i = 0; i < m_arguments.size(); ++i)
{
if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameters[i]->getType())) if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameters[i]->getType()))
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Invalid type for argument in " BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Invalid type for argument in "
"function call.")); "function call."));
}
// @todo actually the return type should be an anonymous struct, // @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 // but we change it to the type of the first return value until we have structs
if (fun.getReturnParameterList()->getParameters().empty()) if (fun.getReturnParameterList()->getParameters().empty())

138
libsolidity/AST.h

@ -40,7 +40,7 @@ namespace solidity
class ASTVisitor; class ASTVisitor;
class ASTNode : private boost::noncopyable class ASTNode: private boost::noncopyable
{ {
public: public:
explicit ASTNode(Location const& _location) explicit ASTNode(Location const& _location)
@ -53,7 +53,7 @@ public:
template <class T> template <class T>
static void listAccept(vecptr<T>& _list, ASTVisitor& _visitor) static void listAccept(vecptr<T>& _list, ASTVisitor& _visitor)
{ {
for (ptr<T>& element : _list) for (ptr<T>& element: _list)
element->accept(_visitor); element->accept(_visitor);
} }
@ -62,7 +62,7 @@ private:
Location m_location; Location m_location;
}; };
class Declaration : public ASTNode class Declaration: public ASTNode
{ {
public: public:
Declaration(Location const& _location, ptr<ASTString> const& _name) Declaration(Location const& _location, ptr<ASTString> const& _name)
@ -73,7 +73,7 @@ private:
ptr<ASTString> m_name; ptr<ASTString> m_name;
}; };
class ContractDefinition : public Declaration class ContractDefinition: public Declaration
{ {
public: public:
ContractDefinition(Location const& _location, ContractDefinition(Location const& _location,
@ -98,14 +98,13 @@ private:
vecptr<FunctionDefinition> m_definedFunctions; vecptr<FunctionDefinition> m_definedFunctions;
}; };
class StructDefinition : public Declaration class StructDefinition: public Declaration
{ {
public: public:
StructDefinition(Location const& _location, StructDefinition(Location const& _location,
ptr<ASTString> const& _name, ptr<ASTString> const& _name,
vecptr<VariableDeclaration> const& _members) vecptr<VariableDeclaration> const& _members)
: Declaration(_location, _name), m_members(_members) : Declaration(_location, _name), m_members(_members) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
private: private:
@ -115,12 +114,11 @@ private:
/// Used as function parameter list and return list /// Used as function parameter list and return list
/// None of the parameters is allowed to contain mappings (not even recursively /// None of the parameters is allowed to contain mappings (not even recursively
/// inside structs) /// inside structs)
class ParameterList : public ASTNode class ParameterList: public ASTNode
{ {
public: public:
ParameterList(Location const& _location, vecptr<VariableDeclaration> const& _parameters) ParameterList(Location const& _location, vecptr<VariableDeclaration> const& _parameters)
: ASTNode(_location), m_parameters(_parameters) : ASTNode(_location), m_parameters(_parameters) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
vecptr<VariableDeclaration> const& getParameters() { return m_parameters; } vecptr<VariableDeclaration> const& getParameters() { return m_parameters; }
@ -128,7 +126,7 @@ private:
vecptr<VariableDeclaration> m_parameters; vecptr<VariableDeclaration> m_parameters;
}; };
class FunctionDefinition : public Declaration class FunctionDefinition: public Declaration
{ {
public: public:
FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic, FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic,
@ -138,8 +136,7 @@ public:
ptr<Block> const& _body) ptr<Block> const& _body)
: Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters), : Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters),
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters), m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
m_body(_body) m_body(_body) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
bool isPublic() const { return m_isPublic; } bool isPublic() const { return m_isPublic; }
@ -156,14 +153,12 @@ private:
ptr<Block> m_body; ptr<Block> m_body;
}; };
class VariableDeclaration : public Declaration class VariableDeclaration: public Declaration
{ {
public: public:
VariableDeclaration(Location const& _location, VariableDeclaration(Location const& _location, ptr<TypeName> const& _type,
ptr<TypeName> const& _type,
ptr<ASTString> const& _name) ptr<ASTString> const& _name)
: Declaration(_location, _name), m_typeName(_type) : Declaration(_location, _name), m_typeName(_type) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
bool isTypeGivenExplicitly() const { return m_typeName.get() != nullptr; } bool isTypeGivenExplicitly() const { return m_typeName.get() != nullptr; }
@ -182,22 +177,21 @@ private:
/// types /// types
/// @{ /// @{
class TypeName : public ASTNode class TypeName: public ASTNode
{ {
public: public:
explicit TypeName(Location const& _location) : ASTNode(_location) {} explicit TypeName(Location const& _location): ASTNode(_location) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> toType() = 0; virtual ptr<Type> toType() = 0;
}; };
/// any pre-defined type that is not a mapping /// any pre-defined type that is not a mapping
class ElementaryTypeName : public TypeName class ElementaryTypeName: public TypeName
{ {
public: public:
explicit ElementaryTypeName(Location const& _location, Token::Value _type) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); } virtual ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); }
@ -206,12 +200,11 @@ private:
Token::Value m_type; Token::Value m_type;
}; };
class UserDefinedTypeName : public TypeName class UserDefinedTypeName: public TypeName
{ {
public: public:
UserDefinedTypeName(Location const& _location, ptr<ASTString> const& _name) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); } virtual ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); }
@ -224,13 +217,12 @@ private:
StructDefinition* m_referencedStruct; StructDefinition* m_referencedStruct;
}; };
class Mapping : public TypeName class Mapping: public TypeName
{ {
public: public:
Mapping(Location const& _location, ptr<ElementaryTypeName> const& _keyType, Mapping(Location const& _location, ptr<ElementaryTypeName> const& _keyType,
ptr<TypeName> const& _valueType) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> toType() override { return Type::fromMapping(*this); } virtual ptr<Type> toType() override { return Type::fromMapping(*this); }
private: private:
@ -243,10 +235,10 @@ private:
/// Statements /// Statements
/// @{ /// @{
class Statement : public ASTNode class Statement: public ASTNode
{ {
public: public:
explicit Statement(Location const& _location) : ASTNode(_location) {} explicit Statement(Location const& _location): ASTNode(_location) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
//! Check all type requirements, throws exception if some requirement is not met. //! Check all type requirements, throws exception if some requirement is not met.
@ -259,12 +251,11 @@ protected:
void expectType(Expression& _expression, Type const& _expectedType); void expectType(Expression& _expression, Type const& _expectedType);
}; };
class Block : public Statement class Block: public Statement
{ {
public: public:
Block(Location const& _location, vecptr<Statement> const& _statements) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -272,14 +263,13 @@ private:
vecptr<Statement> m_statements; vecptr<Statement> m_statements;
}; };
class IfStatement : public Statement class IfStatement: public Statement
{ {
public: public:
IfStatement(Location const& _location, ptr<Expression> const& _condition, IfStatement(Location const& _location, ptr<Expression> const& _condition,
ptr<Statement> const& _trueBody, ptr<Statement> const& _falseBody) ptr<Statement> const& _trueBody, ptr<Statement> const& _falseBody)
: Statement(_location), m_condition(_condition), : Statement(_location), m_condition(_condition),
m_trueBody(_trueBody), m_falseBody(_falseBody) m_trueBody(_trueBody), m_falseBody(_falseBody) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
private: private:
@ -288,20 +278,19 @@ private:
ptr<Statement> m_falseBody; //< "else" part, optional ptr<Statement> m_falseBody; //< "else" part, optional
}; };
class BreakableStatement : public Statement class BreakableStatement: public Statement
{ {
public: public:
BreakableStatement(Location const& _location) : Statement(_location) {} BreakableStatement(Location const& _location): Statement(_location) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
}; };
class WhileStatement : public BreakableStatement class WhileStatement: public BreakableStatement
{ {
public: public:
WhileStatement(Location const& _location, ptr<Expression> const& _condition, WhileStatement(Location const& _location, ptr<Expression> const& _condition,
ptr<Statement> const& _body) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
private: private:
@ -309,28 +298,27 @@ private:
ptr<Statement> m_body; ptr<Statement> m_body;
}; };
class Continue : public Statement class Continue: public Statement
{ {
public: public:
Continue(Location const& _location) : Statement(_location) {} Continue(Location const& _location): Statement(_location) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
}; };
class Break : public Statement class Break: public Statement
{ {
public: public:
Break(Location const& _location) : Statement(_location) {} Break(Location const& _location): Statement(_location) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
}; };
class Return : public Statement class Return: public Statement
{ {
public: public:
Return(Location const& _location, ptr<Expression> _expression) Return(Location const& _location, ptr<Expression> _expression)
: Statement(_location), m_expression(_expression) : Statement(_location), m_expression(_expression) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -341,13 +329,12 @@ private:
ParameterList* m_returnParameters; //< extracted from the function declaration ParameterList* m_returnParameters; //< extracted from the function declaration
}; };
class VariableDefinition : public Statement class VariableDefinition: public Statement
{ {
public: public:
VariableDefinition(Location const& _location, ptr<VariableDeclaration> _variable, VariableDefinition(Location const& _location, ptr<VariableDeclaration> _variable,
ptr<Expression> _value) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -356,10 +343,10 @@ private:
ptr<Expression> m_value; ///< can be missing ptr<Expression> m_value; ///< can be missing
}; };
class Expression : public Statement class Expression: public Statement
{ {
public: public:
Expression(Location const& _location) : Statement(_location) {} Expression(Location const& _location): Statement(_location) {}
ptr<Type> const& getType() { return m_type; } ptr<Type> const& getType() { return m_type; }
protected: protected:
ptr<Type> m_type; ptr<Type> m_type;
@ -370,14 +357,13 @@ protected:
/// Expressions /// Expressions
/// @{ /// @{
class Assignment : public Expression class Assignment: public Expression
{ {
public: public:
Assignment(Location const& _location, ptr<Expression> const& _leftHandSide, Assignment(Location const& _location, ptr<Expression> const& _leftHandSide,
Token::Value _assignmentOperator, ptr<Expression> const& _rightHandSide) Token::Value _assignmentOperator, ptr<Expression> const& _rightHandSide)
: Expression(_location), m_leftHandSide(_leftHandSide), : Expression(_location), m_leftHandSide(_leftHandSide),
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -388,14 +374,13 @@ private:
ptr<Expression> m_rightHandSide; ptr<Expression> m_rightHandSide;
}; };
class UnaryOperation : public Expression class UnaryOperation: public Expression
{ {
public: public:
UnaryOperation(Location const& _location, Token::Value _operator, UnaryOperation(Location const& _location, Token::Value _operator,
ptr<Expression> const& _subExpression, bool _isPrefix) ptr<Expression> const& _subExpression, bool _isPrefix)
: Expression(_location), m_operator(_operator), : Expression(_location), m_operator(_operator),
m_subExpression(_subExpression), m_isPrefix(_isPrefix) m_subExpression(_subExpression), m_isPrefix(_isPrefix) {}
{}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -407,13 +392,12 @@ private:
bool m_isPrefix; bool m_isPrefix;
}; };
class BinaryOperation : public Expression class BinaryOperation: public Expression
{ {
public: public:
BinaryOperation(Location const& _location, ptr<Expression> const& _left, BinaryOperation(Location const& _location, ptr<Expression> const& _left,
Token::Value _operator, ptr<Expression> const& _right) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -427,13 +411,12 @@ private:
}; };
/// Can be ordinary function call, type cast or struct construction. /// Can be ordinary function call, type cast or struct construction.
class FunctionCall : public Expression class FunctionCall: public Expression
{ {
public: public:
FunctionCall(Location const& _location, ptr<Expression> const& _expression, FunctionCall(Location const& _location, ptr<Expression> const& _expression,
vecptr<Expression> const& _arguments) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
private: private:
@ -441,13 +424,12 @@ private:
vecptr<Expression> m_arguments; vecptr<Expression> m_arguments;
}; };
class MemberAccess : public Expression class MemberAccess: public Expression
{ {
public: public:
MemberAccess(Location const& _location, ptr<Expression> _expression, MemberAccess(Location const& _location, ptr<Expression> _expression,
ptr<ASTString> const& _memberName) 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; virtual void accept(ASTVisitor& _visitor) override;
const ASTString& getMemberName() const { return *m_memberName; } const ASTString& getMemberName() const { return *m_memberName; }
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
@ -456,13 +438,12 @@ private:
ptr<ASTString> m_memberName; ptr<ASTString> m_memberName;
}; };
class IndexAccess : public Expression class IndexAccess: public Expression
{ {
public: public:
IndexAccess(Location const& _location, ptr<Expression> const& _base, IndexAccess(Location const& _location, ptr<Expression> const& _base,
ptr<Expression> const& _index) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;
private: private:
@ -470,13 +451,13 @@ private:
ptr<Expression> m_index; ptr<Expression> m_index;
}; };
class PrimaryExpression : public Expression class PrimaryExpression: public Expression
{ {
public: public:
PrimaryExpression(Location const& _location) : Expression(_location) {} PrimaryExpression(Location const& _location): Expression(_location) {}
}; };
class Identifier : public PrimaryExpression class Identifier: public PrimaryExpression
{ {
public: public:
Identifier(Location const& _location, ptr<ASTString> const& _name) Identifier(Location const& _location, ptr<ASTString> const& _name)
@ -494,7 +475,7 @@ private:
Declaration* m_referencedDeclaration; Declaration* m_referencedDeclaration;
}; };
class ElementaryTypeNameExpression : public PrimaryExpression class ElementaryTypeNameExpression: public PrimaryExpression
{ {
public: public:
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken) ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken)
@ -507,12 +488,11 @@ private:
Token::Value m_typeToken; Token::Value m_typeToken;
}; };
class Literal : public PrimaryExpression class Literal: public PrimaryExpression
{ {
public: public:
Literal(Location const& _location, Token::Value _token, ptr<ASTString> const& _value) 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 void accept(ASTVisitor& _visitor) override;
virtual ptr<Type> checkTypeRequirements() override; virtual ptr<Type> checkTypeRequirements() override;

4
libsolidity/ASTPrinter.cpp

@ -244,7 +244,7 @@ bool ASTPrinter::visit(Literal& _node)
{ {
const char* tokenString = Token::toString(_node.getToken()); const char* tokenString = Token::toString(_node.getToken());
if (tokenString == nullptr) if (tokenString == nullptr)
tokenString = "----"; tokenString = "[no token]";
writeLine(std::string("Literal, token: ") + tokenString + " value: " + _node.getValue()); writeLine(std::string("Literal, token: ") + tokenString + " value: " + _node.getValue());
printSourcePart(_node); printSourcePart(_node);
return goDeeper(); return goDeeper();
@ -255,8 +255,6 @@ void ASTPrinter::endVisit(ASTNode&)
m_indentation--; m_indentation--;
} }
// @todo instead of this, we could make the default implementation of endVisit call the
// superclass' endVisit
void ASTPrinter::endVisit(ContractDefinition&) void ASTPrinter::endVisit(ContractDefinition&)
{ {
m_indentation--; m_indentation--;

2
libsolidity/ASTPrinter.h

@ -30,7 +30,7 @@ namespace dev
namespace solidity namespace solidity
{ {
class ASTPrinter : public ASTVisitor class ASTPrinter: public ASTVisitor
{ {
public: public:
/// Create a printer for the given abstract syntax tree. If the source is specified, /// Create a printer for the given abstract syntax tree. If the source is specified,

4
libsolidity/BaseTypes.h

@ -32,8 +32,8 @@ namespace solidity
/// The interval includes start and excludes end. /// The interval includes start and excludes end.
struct Location struct Location
{ {
Location(int _start, int _end) : start(_start), end(_end) { } Location(int _start, int _end): start(_start), end(_end) { }
Location() : start(-1), end(-1) { } Location(): start(-1), end(-1) { }
bool IsValid() const { return start >= 0 && end >= start; } bool IsValid() const { return start >= 0 && end >= start; }

6
libsolidity/Exceptions.h

@ -29,9 +29,9 @@ namespace dev
namespace solidity namespace solidity
{ {
struct ParserError : virtual Exception {}; struct ParserError: virtual Exception {};
struct TypeError : virtual Exception {}; struct TypeError: virtual Exception {};
struct DeclarationError : virtual Exception {}; struct DeclarationError: virtual Exception {};
} }
} }

8
libsolidity/NameAndTypeResolver.cpp

@ -42,18 +42,18 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
DeclarationRegistrationHelper registrar(m_scopes, _contract); DeclarationRegistrationHelper registrar(m_scopes, _contract);
m_currentScope = &m_scopes[&_contract]; m_currentScope = &m_scopes[&_contract];
//@todo structs //@todo structs
for (ptr<VariableDeclaration> const & variable : _contract.getStateVariables()) for (ptr<VariableDeclaration> const& variable: _contract.getStateVariables())
ReferencesResolver resolver(*variable, *this, nullptr); 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()]; m_currentScope = &m_scopes[function.get()];
ReferencesResolver referencesResolver(*function, *this, ReferencesResolver referencesResolver(*function, *this,
function->getReturnParameterList().get()); 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 // the types, since it is possible to call functions that are only defined later
// in the source. // in the source.
for (ptr<FunctionDefinition> const & function : _contract.getDefinedFunctions()) for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions())
{ {
m_currentScope = &m_scopes[function.get()]; m_currentScope = &m_scopes[function.get()];
function->getBody().checkTypeRequirements(); function->getBody().checkTypeRequirements();

9
libsolidity/NameAndTypeResolver.h

@ -34,8 +34,9 @@ namespace dev
namespace solidity namespace solidity
{ {
//! Resolves name references, resolves all types and checks that all operations are valid for the
class NameAndTypeResolver : private boost::noncopyable //! inferred types. An exception is throw on the first error.
class NameAndTypeResolver: private boost::noncopyable
{ {
public: public:
NameAndTypeResolver(); NameAndTypeResolver();
@ -54,7 +55,7 @@ private:
//! Traverses the given AST upon construction and fills _scopes with all declarations inside the //! Traverses the given AST upon construction and fills _scopes with all declarations inside the
//! AST. //! AST.
class DeclarationRegistrationHelper : private ASTVisitor class DeclarationRegistrationHelper: private ASTVisitor
{ {
public: public:
DeclarationRegistrationHelper(std::map<ASTNode*, Scope>& _scopes, ASTNode& _astRoot); 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 //! Resolves references to declarations (of variables and types) and also establishes the link
//! between a return statement and the return parameter list. //! between a return statement and the return parameter list.
class ReferencesResolver : private ASTVisitor class ReferencesResolver: private ASTVisitor
{ {
public: public:
ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver, ParameterList* _returnParameters); ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver, ParameterList* _returnParameters);

98
libsolidity/Parser.cpp

@ -43,27 +43,13 @@ ptr<ContractDefinition> Parser::parse(std::shared_ptr<Scanner> const& _scanner)
class Parser::ASTNodeFactory class Parser::ASTNodeFactory
{ {
public: public:
ASTNodeFactory(const Parser& _parser) ASTNodeFactory(const Parser& _parser) : m_parser(_parser), m_location(_parser.getPosition(), -1) {}
: m_parser(_parser), m_location(_parser.getPosition(), -1)
{}
void markEndPosition()
{
m_location.end = m_parser.getEndPosition();
}
void setLocationEmpty()
{
m_location.end = m_location.start;
}
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. /// Set the end position to the one of the given node.
void setEndPositionFromNode(const ptr<ASTNode>& _node) void setEndPositionFromNode(const ptr<ASTNode>& _node) { m_location.end = _node->getLocation().end; }
{
m_location.end = _node->getLocation().end;
}
/// @todo: check that this actually uses perfect forwarding
template <class NodeType, typename... Args> template <class NodeType, typename... Args>
ptr<NodeType> createNode(Args&& ... _args) ptr<NodeType> createNode(Args&& ... _args)
{ {
@ -102,9 +88,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
{ {
Token::Value currentToken = m_scanner->getCurrentToken(); Token::Value currentToken = m_scanner->getCurrentToken();
if (currentToken == Token::RBRACE) if (currentToken == Token::RBRACE)
{
break; break;
}
else if (currentToken == Token::PUBLIC || currentToken == Token::PRIVATE) else if (currentToken == Token::PUBLIC || currentToken == Token::PRIVATE)
{ {
visibilityIsPublic = (m_scanner->getCurrentToken() == Token::PUBLIC); visibilityIsPublic = (m_scanner->getCurrentToken() == Token::PUBLIC);
@ -112,13 +96,9 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
expectToken(Token::COLON); expectToken(Token::COLON);
} }
else if (currentToken == Token::FUNCTION) else if (currentToken == Token::FUNCTION)
{
functions.push_back(parseFunctionDefinition(visibilityIsPublic)); functions.push_back(parseFunctionDefinition(visibilityIsPublic));
}
else if (currentToken == Token::STRUCT) else if (currentToken == Token::STRUCT)
{
structs.push_back(parseStructDefinition()); structs.push_back(parseStructDefinition());
}
else if (currentToken == Token::IDENTIFIER || currentToken == Token::MAPPING || else if (currentToken == Token::IDENTIFIER || currentToken == Token::MAPPING ||
Token::isElementaryTypeName(currentToken)) Token::isElementaryTypeName(currentToken))
{ {
@ -127,9 +107,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
expectToken(Token::SEMICOLON); expectToken(Token::SEMICOLON);
} }
else else
{
throwExpectationError("Function, variable or struct declaration expected."); throwExpectationError("Function, variable or struct declaration expected.");
}
} }
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expectToken(Token::RBRACE); expectToken(Token::RBRACE);
@ -221,9 +199,7 @@ ptr<TypeName> Parser::parseTypeName(bool _allowVar)
type = nodeFactory.createNode<UserDefinedTypeName>(expectIdentifierToken()); type = nodeFactory.createNode<UserDefinedTypeName>(expectIdentifierToken());
} }
else else
{
throwExpectationError("Expected type name"); throwExpectationError("Expected type name");
}
return type; return type;
} }
@ -271,9 +247,7 @@ ptr<Block> Parser::parseBlock()
expectToken(Token::LBRACE); expectToken(Token::LBRACE);
vecptr<Statement> statements; vecptr<Statement> statements;
while (m_scanner->getCurrentToken() != Token::RBRACE) while (m_scanner->getCurrentToken() != Token::RBRACE)
{
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>(statements);
@ -318,15 +292,10 @@ ptr<Statement> Parser::parseStatement()
m_scanner->getCurrentToken() == Token::VAR || m_scanner->getCurrentToken() == Token::VAR ||
Token::isElementaryTypeName(m_scanner->getCurrentToken()) || Token::isElementaryTypeName(m_scanner->getCurrentToken()) ||
(m_scanner->getCurrentToken() == Token::IDENTIFIER && (m_scanner->getCurrentToken() == Token::IDENTIFIER &&
m_scanner->peek() == Token::IDENTIFIER)) m_scanner->peekNextToken() == Token::IDENTIFIER))
{
statement = parseVariableDefinition(); statement = parseVariableDefinition();
} else // "ordinary" expression
else
{
// "ordinary" expression
statement = parseExpression(); statement = parseExpression();
}
} }
expectToken(Token::SEMICOLON); expectToken(Token::SEMICOLON);
return statement; return statement;
@ -348,9 +317,7 @@ ptr<IfStatement> Parser::parseIfStatement()
nodeFactory.setEndPositionFromNode(falseBody); nodeFactory.setEndPositionFromNode(falseBody);
} }
else else
{
nodeFactory.setEndPositionFromNode(trueBody); nodeFactory.setEndPositionFromNode(trueBody);
}
return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody); return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody);
} }
@ -379,9 +346,7 @@ ptr<VariableDefinition> Parser::parseVariableDefinition()
nodeFactory.setEndPositionFromNode(value); nodeFactory.setEndPositionFromNode(value);
} }
else else
{
nodeFactory.setEndPositionFromNode(variable); nodeFactory.setEndPositionFromNode(variable);
}
return nodeFactory.createNode<VariableDefinition>(variable, value); return nodeFactory.createNode<VariableDefinition>(variable, value);
} }
@ -450,29 +415,29 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
switch (m_scanner->getCurrentToken()) switch (m_scanner->getCurrentToken())
{ {
case Token::LBRACK: case Token::LBRACK:
{ {
m_scanner->next(); m_scanner->next();
ptr<Expression> index = parseExpression(); ptr<Expression> index = parseExpression();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expectToken(Token::RBRACK); expectToken(Token::RBRACK);
expression = nodeFactory.createNode<IndexAccess>(expression, index); expression = nodeFactory.createNode<IndexAccess>(expression, index);
} }
break; break;
case Token::PERIOD: case Token::PERIOD:
{ {
m_scanner->next(); m_scanner->next();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken()); expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
} }
break; break;
case Token::LPAREN: case Token::LPAREN:
{ {
m_scanner->next(); m_scanner->next();
vecptr<Expression> arguments = parseFunctionCallArguments(); vecptr<Expression> arguments = parseFunctionCallArguments();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expectToken(Token::RPAREN); expectToken(Token::RPAREN);
expression = nodeFactory.createNode<FunctionCall>(expression, arguments); expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
} }
break; break;
default: default:
return expression; return expression;
@ -502,12 +467,12 @@ ptr<Expression> Parser::parsePrimaryExpression()
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance()); expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
break; break;
case Token::LPAREN: case Token::LPAREN:
{ {
m_scanner->next(); m_scanner->next();
ptr<Expression> expression = parseExpression(); ptr<Expression> expression = parseExpression();
expectToken(Token::RPAREN); expectToken(Token::RPAREN);
return expression; return expression;
} }
default: default:
if (Token::isElementaryTypeName(token)) if (Token::isElementaryTypeName(token))
{ {
@ -520,6 +485,7 @@ ptr<Expression> Parser::parsePrimaryExpression()
throwExpectationError("Expected primary expression."); throwExpectationError("Expected primary expression.");
return ptr<Expression>(); // this is not reached return ptr<Expression>(); // this is not reached
} }
break;
} }
return expression; return expression;
} }

74
libsolidity/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; char x = 0;
for (int i = 0; i < expected_length; i++) for (int i = 0; i < _expectedLength; i++)
{ {
int d = HexValue(m_char); int d = HexValue(m_char);
if (d < 0) if (d < 0)
@ -118,7 +118,7 @@ bool Scanner::scanHexNumber(char& scanned_number, int expected_length)
x = x * 16 + d; x = x * 16 + d;
advance(); advance();
} }
scanned_number = x; o_scannedNumber = x;
return true; return true;
} }
@ -129,24 +129,25 @@ BOOST_STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
Token::Value Scanner::next() Token::Value Scanner::next()
{ {
m_current_token = m_next_token; m_current_token = m_next_token;
m_hasLineTerminatorBeforeNext = false;
m_hasMultilineCommentBeforeNext = false;
scanToken(); scanToken();
return m_current_token.token; 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() bool Scanner::skipWhitespace()
{ {
const int start_position = getSourcePos(); const int start_position = getSourcePos();
while (true) while (IsWhiteSpace(m_char))
{
if (IsLineTerminator(m_char))
m_hasLineTerminatorBeforeNext = true;
else if (!IsWhiteSpace(m_char))
break;
advance(); advance();
}
// Return whether or not we skipped any characters. // Return whether or not we skipped any characters.
return getSourcePos() != start_position; return getSourcePos() != start_position;
} }
@ -170,12 +171,7 @@ Token::Value Scanner::skipMultiLineComment()
{ {
char ch = m_char; char ch = m_char;
advance(); 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 // If we have reached the end of the multi-line comment, we
// consume the '/' and insert a whitespace. This way all // consume the '/' and insert a whitespace. This way all
// multi-line comments are treated as whitespace. // multi-line comments are treated as whitespace.
@ -199,8 +195,7 @@ void Scanner::scanToken()
m_next_token.location.start = getSourcePos(); m_next_token.location.start = getSourcePos();
switch (m_char) switch (m_char)
{ {
case '\n': case '\n': // fall-through
m_hasLineTerminatorBeforeNext = true; // fall-through
case ' ': case ' ':
case '\t': case '\t':
token = selectToken(Token::WHITESPACE); token = selectToken(Token::WHITESPACE);
@ -395,37 +390,35 @@ bool Scanner::scanEscape()
switch (c) switch (c)
{ {
case '\'': // fall through case '\'': // fall through
case '"' : // fall through case '"': // fall through
case '\\': case '\\':
break; break;
case 'b' : case 'b':
c = '\b'; c = '\b';
break; break;
case 'f' : case 'f':
c = '\f'; c = '\f';
break; break;
case 'n' : case 'n':
c = '\n'; c = '\n';
break; break;
case 'r' : case 'r':
c = '\r'; c = '\r';
break; break;
case 't' : case 't':
c = '\t'; c = '\t';
break; break;
case 'u' : case 'u':
if (!scanHexNumber(c, 4)) return false; if (!scanHexNumber(c, 4)) return false;
break; break;
case 'v' : case 'v':
c = '\v'; c = '\v';
break; break;
case 'x' : case 'x':
if (!scanHexNumber(c, 2)) return false; if (!scanHexNumber(c, 2)) return false;
break; 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); addLiteralChar(c);
return true; return true;
} }
@ -653,6 +646,21 @@ Token::Value Scanner::scanIdentifierOrKeyword()
return KeywordOrIdentifierToken(m_next_token.literal); 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 std::string CharStream::getLineAtPosition(int _position) const
{ {
// if _position points to \n, it returns the line before the \n // if _position points to \n, it returns the line before the \n

113
libsolidity/Scanner.h

@ -63,27 +63,13 @@ class ParserRecorder;
class CharStream class CharStream
{ {
public: public:
CharStream() CharStream() : m_pos(0) {}
: m_pos(0) explicit CharStream(const std::string& _source): m_source(_source), m_pos(0) {}
{}
explicit CharStream(const std::string& _source) : m_source(_source), m_pos(0) {}
int getPos() const { return m_pos; } int getPos() const { return m_pos; }
bool isPastEndOfInput() const { return m_pos >= m_source.size(); } bool isPastEndOfInput() const { return m_pos >= m_source.size(); }
char get() const { return m_source[m_pos]; } char get() const { return m_source[m_pos]; }
char advanceAndGet() char advanceAndGet();
{ char rollback(size_t _amount);
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();
}
/// Functions that help pretty-printing parse errors /// Functions that help pretty-printing parse errors
/// Do only use in error cases, they are quite expensive. /// Do only use in error cases, they are quite expensive.
@ -96,8 +82,6 @@ private:
size_t m_pos; size_t m_pos;
}; };
// ----------------------------------------------------------------------------
// JavaScript Scanner.
class Scanner class Scanner
{ {
@ -107,7 +91,7 @@ public:
class LiteralScope class LiteralScope
{ {
public: 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(); } ~LiteralScope() { if (!complete_) scanner_->dropLiteral(); }
void Complete() { complete_ = true; } void Complete() { complete_ = true; }
@ -118,47 +102,36 @@ public:
explicit Scanner(const CharStream& _source); 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); void reset(const CharStream& _source);
// Returns the next token and advances input. /// Returns the next token and advances input.
Token::Value next(); 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; } 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; } Location getCurrentLocation() const { return m_current_token.location; }
const std::string& getCurrentLiteral() const { return m_current_token.literal; } const std::string& getCurrentLiteral() const { return m_current_token.literal; }
/// @}
// Similar functions for the upcoming token. /// Information about the next token
/// @{
// One token look-ahead (past the token returned by Next()). /// Returns the next token without advancing input.
Token::Value peek() const { return m_next_token.token; } Token::Value peekNextToken() const { return m_next_token.token; }
Location peekLocation() const { return m_next_token.location; } Location peekLocation() const { return m_next_token.location; }
const std::string& peekLiteral() const { return m_next_token.literal; } const std::string& peekLiteral() const { return m_next_token.literal; }
/// @}
/// Functions that help pretty-printing parse errors. /// Functions that help pretty-printing parse errors.
/// Do only use in error cases, they are quite expensive. /// Do only use in error cases, they are quite expensive.
/// @{ /// @{
std::string getLineAtPosition(int _position) const std::string getLineAtPosition(int _position) const { return m_source.getLineAtPosition(_position); }
{ std::tuple<int, int> translatePositionToLineColumn(int _position) const { return m_source.translatePositionToLineColumn(_position); }
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: private:
// Used for the current and look-ahead token. // Used for the current and look-ahead token.
struct TokenDesc struct TokenDesc
@ -168,34 +141,22 @@ private:
std::string literal; std::string literal;
}; };
// Literal buffer support /// Literal buffer support
/// @{
inline void startNewLiteral() { m_next_token.literal.clear(); } inline void startNewLiteral() { m_next_token.literal.clear(); }
inline void addLiteralChar(char c) { m_next_token.literal.push_back(c); } inline void addLiteralChar(char c) { m_next_token.literal.push_back(c); }
inline void dropLiteral() { m_next_token.literal.clear(); } inline void dropLiteral() { m_next_token.literal.clear(); }
inline void addLiteralCharAndAdvance() { addLiteralChar(m_char); advance(); } inline void addLiteralCharAndAdvance() { addLiteralChar(m_char); advance(); }
/// @}
// Low-level scanning support.
bool advance() { m_char = m_source.advanceAndGet(); return !m_source.isPastEndOfInput(); } 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_) bool scanHexNumber(char& o_scannedNumber, int _expectedLength);
{
advance();
if (m_char == next)
{
advance();
return then;
}
else
return else_;
}
bool scanHexNumber(char& scanned_number, int expected_length);
// Scans a single JavaScript token. // Scans a single JavaScript token.
void scanToken(); void scanToken();
@ -210,12 +171,12 @@ private:
Token::Value scanString(); Token::Value scanString();
// Scans an escape-sequence which is part of a string and adds the /// Scans an escape-sequence which is part of a string and adds the
// decoded character to the current literal. Returns true if a pattern /// decoded character to the current literal. Returns true if a pattern
// is scanned. /// is scanned.
bool scanEscape(); bool scanEscape();
// Return the current source position. /// Return the current source position.
int getSourcePos() { return m_source.getPos(); } int getSourcePos() { return m_source.getPos(); }
bool isSourcePastEndOfInput() { return m_source.isPastEndOfInput(); } bool isSourcePastEndOfInput() { return m_source.isPastEndOfInput(); }
@ -224,16 +185,8 @@ private:
CharStream m_source; 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; 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;
}; };
} }

1
libsolidity/Scope.cpp

@ -28,7 +28,6 @@ namespace dev
namespace solidity namespace solidity
{ {
bool Scope::registerDeclaration(Declaration& _declaration) bool Scope::registerDeclaration(Declaration& _declaration)
{ {
if (m_declarations.find(_declaration.getName()) != m_declarations.end()) if (m_declarations.find(_declaration.getName()) != m_declarations.end())

2
libsolidity/Scope.h

@ -36,7 +36,7 @@ namespace solidity
class Scope class Scope
{ {
public: 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 /// Registers the declaration in the scope unless its name is already declared. Returns true iff
/// it was not yet declared. /// it was not yet declared.
bool registerDeclaration(Declaration& _declaration); bool registerDeclaration(Declaration& _declaration);

26
libsolidity/Types.h

@ -48,7 +48,7 @@ using ptr = std::shared_ptr<T>;
// @todo realMxN, string<N>, mapping // @todo realMxN, string<N>, mapping
class Type : private boost::noncopyable class Type: private boost::noncopyable
{ {
public: public:
enum class Category enum class Category
@ -73,7 +73,7 @@ public:
virtual bool acceptsUnaryOperator(Token::Value) const { return false; } virtual bool acceptsUnaryOperator(Token::Value) const { return false; }
}; };
class IntegerType : public Type class IntegerType: public Type
{ {
public: public:
enum class Modifier enum class Modifier
@ -100,7 +100,7 @@ private:
Modifier m_modifier; Modifier m_modifier;
}; };
class BoolType : public Type class BoolType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::BOOL; } virtual Category getCategory() const { return Category::BOOL; }
@ -119,21 +119,21 @@ public:
} }
}; };
class ContractType : public Type class ContractType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::CONTRACT; } 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; virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const;
private: private:
ContractDefinition const& m_contract; ContractDefinition const& m_contract;
}; };
class StructType : public Type class StructType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::STRUCT; } 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 isImplicitlyConvertibleTo(Type const& _convertTo) const;
virtual bool acceptsUnaryOperator(Token::Value _operator) const override virtual bool acceptsUnaryOperator(Token::Value _operator) const override
{ {
@ -143,18 +143,18 @@ private:
StructDefinition const& m_struct; StructDefinition const& m_struct;
}; };
class FunctionType : public Type class FunctionType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::FUNCTION; } 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; } FunctionDefinition const& getFunction() const { return m_function; }
private: private:
FunctionDefinition const& m_function; FunctionDefinition const& m_function;
}; };
class MappingType : public Type class MappingType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::MAPPING; } virtual Category getCategory() const { return Category::MAPPING; }
@ -164,18 +164,18 @@ private:
}; };
//@todo should be changed into "empty anonymous struct" //@todo should be changed into "empty anonymous struct"
class VoidType : public Type class VoidType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::VOID; } virtual Category getCategory() const { return Category::VOID; }
VoidType() {} VoidType() {}
}; };
class TypeType : public Type class TypeType: public Type
{ {
public: public:
virtual Category getCategory() const { return Category::TYPE; } 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; } ptr<Type> const& getActualType() { return m_actualType; }
private: private:

Loading…
Cancel
Save