mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
AST printer and command line tool, some fixes.
This commit is contained in:
parent
924f7c62bd
commit
98bdd74299
232
AST.cpp
232
AST.cpp
@ -21,3 +21,235 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libsolidity/AST.h>
|
#include <libsolidity/AST.h>
|
||||||
|
#include <libsolidity/ASTVisitor.h>
|
||||||
|
|
||||||
|
namespace dev {
|
||||||
|
namespace solidity {
|
||||||
|
|
||||||
|
void ContractDefinition::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
listAccept(m_definedStructs, _visitor);
|
||||||
|
listAccept(m_stateVariables, _visitor);
|
||||||
|
listAccept(m_definedFunctions, _visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionDefinition::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_parameters->accept(_visitor);
|
||||||
|
if (m_returnParameters)
|
||||||
|
m_returnParameters->accept(_visitor);
|
||||||
|
m_body->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VariableDeclaration::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
if (m_type)
|
||||||
|
m_type->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeName::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementaryTypeName::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapping::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_keyType->accept(_visitor);
|
||||||
|
m_valueType->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
listAccept(m_statements, _visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfStatement::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_condition->accept(_visitor);
|
||||||
|
m_trueBody->accept(_visitor);
|
||||||
|
if (m_falseBody)
|
||||||
|
m_falseBody->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BreakableStatement::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WhileStatement::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_condition->accept(_visitor);
|
||||||
|
m_body->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Continue::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Break::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Return::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
if (m_expression)
|
||||||
|
m_expression->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VariableDefinition::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_variable->accept(_visitor);
|
||||||
|
if (m_value)
|
||||||
|
m_value->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Expression::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Assignment::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_leftHandSide->accept(_visitor);
|
||||||
|
m_rightHandSide->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnaryOperation::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_subExpression->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryOperation::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_left->accept(_visitor);
|
||||||
|
m_right->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionCall::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_expression->accept(_visitor);
|
||||||
|
listAccept(m_arguments, _visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemberAccess::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_expression->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndexAccess::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
if (_visitor.visit(*this)) {
|
||||||
|
m_base->accept(_visitor);
|
||||||
|
m_index->accept(_visitor);
|
||||||
|
}
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimaryExpression::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Identifier::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementaryTypeNameExpression::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Literal::accept(ASTVisitor& _visitor)
|
||||||
|
{
|
||||||
|
_visitor.visit(*this);
|
||||||
|
_visitor.endVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
||||||
|
118
AST.h
118
AST.h
@ -26,26 +26,14 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include <libsolidity/ASTForward.h>
|
||||||
#include <libsolidity/BaseTypes.h>
|
#include <libsolidity/BaseTypes.h>
|
||||||
#include <libsolidity/Token.h>
|
#include <libsolidity/Token.h>
|
||||||
|
|
||||||
namespace dev {
|
namespace dev {
|
||||||
namespace solidity {
|
namespace solidity {
|
||||||
|
|
||||||
// Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do
|
class ASTVisitor;
|
||||||
// not do reference counting but point to a special memory area that is completely released
|
|
||||||
// explicitly.
|
|
||||||
template <class T>
|
|
||||||
using ptr = std::shared_ptr<T>;
|
|
||||||
template <class T>
|
|
||||||
using vecptr = std::vector<ptr<T>>;
|
|
||||||
|
|
||||||
class VariableDeclaration;
|
|
||||||
class StructDefinition;
|
|
||||||
class FunctionDefinition;
|
|
||||||
class TypeName;
|
|
||||||
class Block;
|
|
||||||
class Expression;
|
|
||||||
|
|
||||||
class ASTNode
|
class ASTNode
|
||||||
{
|
{
|
||||||
@ -56,7 +44,13 @@ public:
|
|||||||
|
|
||||||
virtual ~ASTNode() {}
|
virtual ~ASTNode() {}
|
||||||
|
|
||||||
Location getLocation() const { return m_location; }
|
virtual void accept(ASTVisitor& _visitor) = 0;
|
||||||
|
template <class T>
|
||||||
|
static void listAccept(vecptr<T>& _list, ASTVisitor& _visitor) {
|
||||||
|
for (ptr<T>& element : _list) element->accept(_visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
Location const& getLocation() const { return m_location; }
|
||||||
private:
|
private:
|
||||||
Location m_location;
|
Location m_location;
|
||||||
};
|
};
|
||||||
@ -65,7 +59,7 @@ class ContractDefinition : public ASTNode
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContractDefinition(Location const& _location,
|
ContractDefinition(Location const& _location,
|
||||||
std::string const& _name,
|
ptr<ASTString> const& _name,
|
||||||
vecptr<StructDefinition> const& _definedStructs,
|
vecptr<StructDefinition> const& _definedStructs,
|
||||||
vecptr<VariableDeclaration> const& _stateVariables,
|
vecptr<VariableDeclaration> const& _stateVariables,
|
||||||
vecptr<FunctionDefinition> const& _definedFunctions)
|
vecptr<FunctionDefinition> const& _definedFunctions)
|
||||||
@ -75,8 +69,11 @@ public:
|
|||||||
m_definedFunctions(_definedFunctions)
|
m_definedFunctions(_definedFunctions)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
|
const ASTString& getName() const { return *m_name; }
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
ptr<ASTString> m_name;
|
||||||
vecptr<StructDefinition> m_definedStructs;
|
vecptr<StructDefinition> m_definedStructs;
|
||||||
vecptr<VariableDeclaration> m_stateVariables;
|
vecptr<VariableDeclaration> m_stateVariables;
|
||||||
vecptr<FunctionDefinition> m_definedFunctions;
|
vecptr<FunctionDefinition> m_definedFunctions;
|
||||||
@ -86,12 +83,15 @@ class StructDefinition : public ASTNode
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StructDefinition(Location const& _location,
|
StructDefinition(Location const& _location,
|
||||||
std::string const& _name,
|
ptr<ASTString> const& _name,
|
||||||
vecptr<VariableDeclaration> const& _members)
|
vecptr<VariableDeclaration> const& _members)
|
||||||
: ASTNode(_location), m_name(_name), m_members(_members)
|
: ASTNode(_location), m_name(_name), m_members(_members)
|
||||||
{}
|
{}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
|
const ASTString& getName() const { return *m_name; }
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
ptr<ASTString> m_name;
|
||||||
vecptr<VariableDeclaration> m_members;
|
vecptr<VariableDeclaration> m_members;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,6 +104,7 @@ 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;
|
||||||
private:
|
private:
|
||||||
vecptr<VariableDeclaration> m_parameters;
|
vecptr<VariableDeclaration> m_parameters;
|
||||||
};
|
};
|
||||||
@ -111,7 +112,7 @@ private:
|
|||||||
class FunctionDefinition : public ASTNode
|
class FunctionDefinition : public ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FunctionDefinition(Location const& _location, std::string const& _name, bool _isPublic,
|
FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic,
|
||||||
ptr<ParameterList> const& _parameters,
|
ptr<ParameterList> const& _parameters,
|
||||||
bool _isDeclaredConst,
|
bool _isDeclaredConst,
|
||||||
ptr<ParameterList> const& _returnParameters,
|
ptr<ParameterList> const& _returnParameters,
|
||||||
@ -120,8 +121,13 @@ public:
|
|||||||
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
|
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
|
||||||
m_body(_body)
|
m_body(_body)
|
||||||
{}
|
{}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
|
const ASTString& getName() const { return *m_name; }
|
||||||
|
bool isPublic() const { return m_isPublic; }
|
||||||
|
bool isDeclaredConst() const { return m_isDeclaredConst; }
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
ptr<ASTString> m_name;
|
||||||
bool m_isPublic;
|
bool m_isPublic;
|
||||||
ptr<ParameterList> m_parameters;
|
ptr<ParameterList> m_parameters;
|
||||||
bool m_isDeclaredConst;
|
bool m_isDeclaredConst;
|
||||||
@ -134,12 +140,15 @@ class VariableDeclaration : public ASTNode
|
|||||||
public:
|
public:
|
||||||
VariableDeclaration(Location const& _location,
|
VariableDeclaration(Location const& _location,
|
||||||
ptr<TypeName> const& _type,
|
ptr<TypeName> const& _type,
|
||||||
std::string const& _name)
|
ptr<ASTString> const& _name)
|
||||||
: ASTNode(_location), m_type(_type), m_name(_name)
|
: ASTNode(_location), m_type(_type), m_name(_name)
|
||||||
{}
|
{}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
|
const ASTString& getName() const { return *m_name; }
|
||||||
private:
|
private:
|
||||||
ptr<TypeName> m_type; ///< can be empty ("var")
|
ptr<TypeName> m_type; ///< can be empty ("var")
|
||||||
std::string m_name;
|
ptr<ASTString> m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// types
|
/// types
|
||||||
@ -149,6 +158,7 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// any pre-defined type that is not a mapping
|
/// any pre-defined type that is not a mapping
|
||||||
@ -158,6 +168,9 @@ 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;
|
||||||
|
|
||||||
|
Token::Value getType() const { return m_type; }
|
||||||
private:
|
private:
|
||||||
Token::Value m_type;
|
Token::Value m_type;
|
||||||
};
|
};
|
||||||
@ -165,11 +178,14 @@ private:
|
|||||||
class UserDefinedTypeName : public TypeName
|
class UserDefinedTypeName : public TypeName
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UserDefinedTypeName(Location const& _location, std::string 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;
|
||||||
|
|
||||||
|
const ASTString& getName() const { return *m_name; }
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
ptr<ASTString> m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mapping : public TypeName
|
class Mapping : public TypeName
|
||||||
@ -179,6 +195,7 @@ public:
|
|||||||
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;
|
||||||
private:
|
private:
|
||||||
ptr<ElementaryTypeName> m_keyType;
|
ptr<ElementaryTypeName> m_keyType;
|
||||||
ptr<TypeName> m_valueType;
|
ptr<TypeName> m_valueType;
|
||||||
@ -193,6 +210,7 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Block : public Statement
|
class Block : public Statement
|
||||||
@ -201,6 +219,7 @@ 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;
|
||||||
private:
|
private:
|
||||||
vecptr<Statement> m_statements;
|
vecptr<Statement> m_statements;
|
||||||
};
|
};
|
||||||
@ -213,16 +232,18 @@ public:
|
|||||||
: 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;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_condition;
|
ptr<Expression> m_condition;
|
||||||
ptr<Statement> m_trueBody;
|
ptr<Statement> m_trueBody;
|
||||||
ptr<Statement> m_falseBody;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WhileStatement : public BreakableStatement
|
class WhileStatement : public BreakableStatement
|
||||||
@ -232,6 +253,7 @@ public:
|
|||||||
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;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_condition;
|
ptr<Expression> m_condition;
|
||||||
ptr<Statement> m_body;
|
ptr<Statement> m_body;
|
||||||
@ -241,12 +263,14 @@ class Continue : public Statement
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Continue(Location const& _location) : Statement(_location) {}
|
Continue(Location const& _location) : Statement(_location) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Return : public Statement
|
class Return : public Statement
|
||||||
@ -255,8 +279,9 @@ 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;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_expression;
|
ptr<Expression> m_expression; //< value to return, optional
|
||||||
};
|
};
|
||||||
|
|
||||||
class VariableDefinition : public Statement
|
class VariableDefinition : public Statement
|
||||||
@ -266,6 +291,7 @@ public:
|
|||||||
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;
|
||||||
private:
|
private:
|
||||||
ptr<VariableDeclaration> m_variable;
|
ptr<VariableDeclaration> m_variable;
|
||||||
ptr<Expression> m_value; ///< can be missing
|
ptr<Expression> m_value; ///< can be missing
|
||||||
@ -275,6 +301,7 @@ class Expression : public Statement
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Expression(Location const& _location) : Statement(_location) {}
|
Expression(Location const& _location) : Statement(_location) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
@ -290,6 +317,9 @@ public:
|
|||||||
: 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;
|
||||||
|
|
||||||
|
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_leftHandSide;
|
ptr<Expression> m_leftHandSide;
|
||||||
Token::Value m_assigmentOperator;
|
Token::Value m_assigmentOperator;
|
||||||
@ -304,7 +334,10 @@ public:
|
|||||||
: 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;
|
||||||
|
|
||||||
|
Token::Value getOperator() const { return m_operator; }
|
||||||
|
bool isPrefixOperation() const { return m_isPrefix; }
|
||||||
private:
|
private:
|
||||||
Token::Value m_operator;
|
Token::Value m_operator;
|
||||||
ptr<Expression> m_subExpression;
|
ptr<Expression> m_subExpression;
|
||||||
@ -318,6 +351,9 @@ public:
|
|||||||
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;
|
||||||
|
|
||||||
|
Token::Value getOperator() const { return m_operator; }
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_left;
|
ptr<Expression> m_left;
|
||||||
Token::Value m_operator;
|
Token::Value m_operator;
|
||||||
@ -332,6 +368,7 @@ public:
|
|||||||
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;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_expression;
|
ptr<Expression> m_expression;
|
||||||
vecptr<Expression> m_arguments;
|
vecptr<Expression> m_arguments;
|
||||||
@ -341,12 +378,14 @@ class MemberAccess : public Expression
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemberAccess(Location const& _location, ptr<Expression> _expression,
|
MemberAccess(Location const& _location, ptr<Expression> _expression,
|
||||||
std::string 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;
|
||||||
|
const ASTString& getMemberName() const { return *m_memberName; }
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_expression;
|
ptr<Expression> m_expression;
|
||||||
std::string m_memberName;
|
ptr<ASTString> m_memberName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IndexAccess : public Expression
|
class IndexAccess : public Expression
|
||||||
@ -356,6 +395,7 @@ public:
|
|||||||
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;
|
||||||
private:
|
private:
|
||||||
ptr<Expression> m_base;
|
ptr<Expression> m_base;
|
||||||
ptr<Expression> m_index;
|
ptr<Expression> m_index;
|
||||||
@ -365,15 +405,19 @@ class PrimaryExpression : public Expression
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrimaryExpression(Location const& _location) : Expression(_location) {}
|
PrimaryExpression(Location const& _location) : Expression(_location) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Identifier : public PrimaryExpression
|
class Identifier : public PrimaryExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Identifier(Location const& _location, std::string const& _name)
|
Identifier(Location const& _location, ptr<ASTString> const& _name)
|
||||||
: PrimaryExpression(_location), m_name(_name) {}
|
: PrimaryExpression(_location), m_name(_name) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
|
ASTString const& getName() const { return *m_name; }
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
ptr<ASTString> m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ElementaryTypeNameExpression : public PrimaryExpression
|
class ElementaryTypeNameExpression : public PrimaryExpression
|
||||||
@ -381,6 +425,9 @@ class ElementaryTypeNameExpression : public PrimaryExpression
|
|||||||
public:
|
public:
|
||||||
ElementaryTypeNameExpression(Location const& _location, Token::Value _type)
|
ElementaryTypeNameExpression(Location const& _location, Token::Value _type)
|
||||||
: PrimaryExpression(_location), m_type(_type) {}
|
: PrimaryExpression(_location), m_type(_type) {}
|
||||||
|
virtual void accept(ASTVisitor& _visitor) override;
|
||||||
|
|
||||||
|
Token::Value getType() const { return m_type; }
|
||||||
private:
|
private:
|
||||||
Token::Value m_type;
|
Token::Value m_type;
|
||||||
};
|
};
|
||||||
@ -388,15 +435,18 @@ private:
|
|||||||
class Literal : public PrimaryExpression
|
class Literal : public PrimaryExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Literal(Location const& _location, Token::Value _token, std::string 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;
|
||||||
|
|
||||||
|
Token::Value getToken() const { return m_token; }
|
||||||
|
ASTString const& getValue() const { return *m_value; }
|
||||||
private:
|
private:
|
||||||
Token::Value m_token;
|
Token::Value m_token;
|
||||||
std::string m_value;
|
ptr<ASTString> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
53
ASTForward.h
Normal file
53
ASTForward.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Forward-declare all AST node types
|
||||||
|
|
||||||
|
namespace dev {
|
||||||
|
namespace solidity {
|
||||||
|
|
||||||
|
class ASTNode;
|
||||||
|
class ContractDefinition;
|
||||||
|
class StructDefinition;
|
||||||
|
class ParameterList;
|
||||||
|
class FunctionDefinition;
|
||||||
|
class VariableDeclaration;
|
||||||
|
class TypeName;
|
||||||
|
class ElementaryTypeName;
|
||||||
|
class UserDefinedTypeName;
|
||||||
|
class Mapping;
|
||||||
|
class Statement;
|
||||||
|
class Block;
|
||||||
|
class IfStatement;
|
||||||
|
class BreakableStatement;
|
||||||
|
class WhileStatement;
|
||||||
|
class Continue;
|
||||||
|
class Break;
|
||||||
|
class Return;
|
||||||
|
class VariableDefinition;
|
||||||
|
class Expression;
|
||||||
|
class Assignment;
|
||||||
|
class UnaryOperation;
|
||||||
|
class BinaryOperation;
|
||||||
|
class FunctionCall;
|
||||||
|
class MemberAccess;
|
||||||
|
class IndexAccess;
|
||||||
|
class PrimaryExpression;
|
||||||
|
class ElementaryTypeNameExpression;
|
||||||
|
class Literal;
|
||||||
|
|
||||||
|
// Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do
|
||||||
|
// not do reference counting but point to a special memory area that is completely released
|
||||||
|
// explicitly.
|
||||||
|
template <class T>
|
||||||
|
using ptr = std::shared_ptr<T>;
|
||||||
|
template <class T>
|
||||||
|
using vecptr = std::vector<ptr<T>>;
|
||||||
|
|
||||||
|
using ASTString = std::string;
|
||||||
|
|
||||||
|
|
||||||
|
} }
|
388
ASTPrinter.cpp
Normal file
388
ASTPrinter.cpp
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
#include <libsolidity/ASTPrinter.h>
|
||||||
|
#include <libsolidity/AST.h>
|
||||||
|
|
||||||
|
namespace dev {
|
||||||
|
namespace solidity {
|
||||||
|
|
||||||
|
ASTPrinter::ASTPrinter(ptr<ASTNode> _ast, const std::string& _source)
|
||||||
|
: m_indentation(0), m_source(_source), m_ast(_ast)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::print(std::ostream& _stream)
|
||||||
|
{
|
||||||
|
m_ostream = &_stream;
|
||||||
|
m_ast->accept(*this);
|
||||||
|
m_ostream = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(ContractDefinition& _node)
|
||||||
|
{
|
||||||
|
writeLine("ContractDefinition \"" + _node.getName() + "\"");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(StructDefinition& _node)
|
||||||
|
{
|
||||||
|
writeLine("StructDefinition \"" + _node.getName() + "\"");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(ParameterList& _node)
|
||||||
|
{
|
||||||
|
writeLine("ParameterList");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(FunctionDefinition& _node)
|
||||||
|
{
|
||||||
|
writeLine("FunctionDefinition \"" + _node.getName() + "\"" +
|
||||||
|
(_node.isPublic() ? " - public" : "") +
|
||||||
|
(_node.isDeclaredConst() ? " - const" : ""));
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(VariableDeclaration& _node)
|
||||||
|
{
|
||||||
|
writeLine("VariableDeclaration \"" + _node.getName() + "\"");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(TypeName& _node)
|
||||||
|
{
|
||||||
|
writeLine("TypeName");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(ElementaryTypeName& _node)
|
||||||
|
{
|
||||||
|
writeLine(std::string("ElementaryTypeName ") + Token::String(_node.getType()));
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(UserDefinedTypeName& _node)
|
||||||
|
{
|
||||||
|
writeLine("UserDefinedTypeName \"" + _node.getName() + "\"");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Mapping& _node)
|
||||||
|
{
|
||||||
|
writeLine("Mapping");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Statement& _node)
|
||||||
|
{
|
||||||
|
writeLine("Statement");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Block& _node)
|
||||||
|
{
|
||||||
|
writeLine("Block");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(IfStatement& _node)
|
||||||
|
{
|
||||||
|
writeLine("IfStatement");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(BreakableStatement& _node)
|
||||||
|
{
|
||||||
|
writeLine("BreakableStatement");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(WhileStatement& _node)
|
||||||
|
{
|
||||||
|
writeLine("WhileStatement");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Continue& _node)
|
||||||
|
{
|
||||||
|
writeLine("Continue");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Break& _node)
|
||||||
|
{
|
||||||
|
writeLine("Break");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Return& _node)
|
||||||
|
{
|
||||||
|
writeLine("Return");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(VariableDefinition& _node)
|
||||||
|
{
|
||||||
|
writeLine("VariableDefinition");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Expression& _node)
|
||||||
|
{
|
||||||
|
writeLine("Expression");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Assignment& _node)
|
||||||
|
{
|
||||||
|
writeLine(std::string("Assignment using operator ") + Token::String(_node.getAssignmentOperator()));
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(UnaryOperation& _node)
|
||||||
|
{
|
||||||
|
writeLine(std::string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") +
|
||||||
|
") " + Token::String(_node.getOperator()));
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(BinaryOperation& _node)
|
||||||
|
{
|
||||||
|
writeLine(std::string("BinaryOperation using operator ") + Token::String(_node.getOperator()));
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(FunctionCall& _node)
|
||||||
|
{
|
||||||
|
writeLine("FunctionCall");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(MemberAccess& _node)
|
||||||
|
{
|
||||||
|
writeLine("MemberAccess to member " + _node.getMemberName());
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(IndexAccess& _node)
|
||||||
|
{
|
||||||
|
writeLine("IndexAccess");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(PrimaryExpression& _node)
|
||||||
|
{
|
||||||
|
writeLine("PrimaryExpression");
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(ElementaryTypeNameExpression& _node)
|
||||||
|
{
|
||||||
|
writeLine(std::string("ElementaryTypeNameExpression ") + Token::String(_node.getType()));
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASTPrinter::visit(Literal& _node)
|
||||||
|
{
|
||||||
|
const char* tokenString = Token::String(_node.getToken());
|
||||||
|
if (tokenString == nullptr)
|
||||||
|
tokenString = "----";
|
||||||
|
writeLine(std::string("Literal, token: ") + tokenString + " value: " + _node.getValue());
|
||||||
|
printSourcePart(_node);
|
||||||
|
return goDeeper();
|
||||||
|
}
|
||||||
|
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(StructDefinition&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(ParameterList&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(FunctionDefinition&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(VariableDeclaration&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(TypeName&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(ElementaryTypeName&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(UserDefinedTypeName&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Mapping&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Statement&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Block&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(IfStatement&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(BreakableStatement&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(WhileStatement&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Continue&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Break&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Return&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(VariableDefinition&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Expression&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Assignment&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(UnaryOperation&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(BinaryOperation&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(FunctionCall&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(MemberAccess&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(IndexAccess&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(PrimaryExpression&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(ElementaryTypeNameExpression&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::endVisit(Literal&)
|
||||||
|
{
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::printSourcePart(ASTNode const& _node)
|
||||||
|
{
|
||||||
|
if (!m_source.empty()) {
|
||||||
|
Location const& location(_node.getLocation());
|
||||||
|
*m_ostream << getIndentation() << " Source: |"
|
||||||
|
<< m_source.substr(location.start, location.end - location.start) << "|\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ASTPrinter::getIndentation() const
|
||||||
|
{
|
||||||
|
return std::string(m_indentation * 2, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTPrinter::writeLine(const std::string& _line)
|
||||||
|
{
|
||||||
|
*m_ostream << getIndentation() << _line << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
88
ASTPrinter.h
Normal file
88
ASTPrinter.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <libsolidity/ASTVisitor.h>
|
||||||
|
|
||||||
|
namespace dev {
|
||||||
|
namespace solidity {
|
||||||
|
|
||||||
|
class ASTPrinter : public ASTVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Create a printer for the given abstract syntax tree. If the source is specified,
|
||||||
|
/// the corresponding parts of the source are printed with each node.
|
||||||
|
ASTPrinter(ptr<ASTNode> _ast, const std::string& _source = std::string());
|
||||||
|
/// Output the string representation of the AST to _stream.
|
||||||
|
void print(std::ostream& _stream);
|
||||||
|
|
||||||
|
bool visit(ContractDefinition& _node);
|
||||||
|
bool visit(StructDefinition& _node);
|
||||||
|
bool visit(ParameterList& _node);
|
||||||
|
bool visit(FunctionDefinition& _node);
|
||||||
|
bool visit(VariableDeclaration& _node);
|
||||||
|
bool visit(TypeName& _node);
|
||||||
|
bool visit(ElementaryTypeName& _node);
|
||||||
|
bool visit(UserDefinedTypeName& _node);
|
||||||
|
bool visit(Mapping& _node);
|
||||||
|
bool visit(Statement& _node);
|
||||||
|
bool visit(Block& _node);
|
||||||
|
bool visit(IfStatement& _node);
|
||||||
|
bool visit(BreakableStatement& _node);
|
||||||
|
bool visit(WhileStatement& _node);
|
||||||
|
bool visit(Continue& _node);
|
||||||
|
bool visit(Break& _node);
|
||||||
|
bool visit(Return& _node);
|
||||||
|
bool visit(VariableDefinition& _node);
|
||||||
|
bool visit(Expression& _node);
|
||||||
|
bool visit(Assignment& _node);
|
||||||
|
bool visit(UnaryOperation& _node);
|
||||||
|
bool visit(BinaryOperation& _node);
|
||||||
|
bool visit(FunctionCall& _node);
|
||||||
|
bool visit(MemberAccess& _node);
|
||||||
|
bool visit(IndexAccess& _node);
|
||||||
|
bool visit(PrimaryExpression& _node);
|
||||||
|
bool visit(ElementaryTypeNameExpression& _node);
|
||||||
|
bool visit(Literal& _node);
|
||||||
|
|
||||||
|
void endVisit(ASTNode & _node);
|
||||||
|
void endVisit(ContractDefinition&);
|
||||||
|
void endVisit(StructDefinition&);
|
||||||
|
void endVisit(ParameterList&);
|
||||||
|
void endVisit(FunctionDefinition&);
|
||||||
|
void endVisit(VariableDeclaration&);
|
||||||
|
void endVisit(TypeName&);
|
||||||
|
void endVisit(ElementaryTypeName&);
|
||||||
|
void endVisit(UserDefinedTypeName&);
|
||||||
|
void endVisit(Mapping&);
|
||||||
|
void endVisit(Statement&);
|
||||||
|
void endVisit(Block&);
|
||||||
|
void endVisit(IfStatement&);
|
||||||
|
void endVisit(BreakableStatement&);
|
||||||
|
void endVisit(WhileStatement&);
|
||||||
|
void endVisit(Continue&);
|
||||||
|
void endVisit(Break&);
|
||||||
|
void endVisit(Return&);
|
||||||
|
void endVisit(VariableDefinition&);
|
||||||
|
void endVisit(Expression&);
|
||||||
|
void endVisit(Assignment&);
|
||||||
|
void endVisit(UnaryOperation&);
|
||||||
|
void endVisit(BinaryOperation&);
|
||||||
|
void endVisit(FunctionCall&);
|
||||||
|
void endVisit(MemberAccess&);
|
||||||
|
void endVisit(IndexAccess&);
|
||||||
|
void endVisit(PrimaryExpression&);
|
||||||
|
void endVisit(ElementaryTypeNameExpression&);
|
||||||
|
void endVisit(Literal&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void printSourcePart(ASTNode const& _node);
|
||||||
|
std::string getIndentation() const;
|
||||||
|
void writeLine(std::string const& _line);
|
||||||
|
bool goDeeper() { m_indentation++; return true; }
|
||||||
|
int m_indentation;
|
||||||
|
std::string m_source;
|
||||||
|
ptr<ASTNode> m_ast;
|
||||||
|
std::ostream* m_ostream;
|
||||||
|
};
|
||||||
|
|
||||||
|
} }
|
76
ASTVisitor.h
Normal file
76
ASTVisitor.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libsolidity/ASTForward.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace dev {
|
||||||
|
namespace solidity {
|
||||||
|
|
||||||
|
class ASTVisitor {
|
||||||
|
public:
|
||||||
|
/// These functions are called after a call to ASTNode::accept,
|
||||||
|
/// first visit, then (if visit returns true) recursively for all
|
||||||
|
/// child nodes in document order (exception for contracts) and then
|
||||||
|
/// endVisit.
|
||||||
|
virtual bool visit(ASTNode&) { return true; }
|
||||||
|
virtual bool visit(ContractDefinition&) { return true; }
|
||||||
|
virtual bool visit(StructDefinition&) { return true; }
|
||||||
|
virtual bool visit(ParameterList&) { return true; }
|
||||||
|
virtual bool visit(FunctionDefinition&) { return true; }
|
||||||
|
virtual bool visit(VariableDeclaration&) { return true; }
|
||||||
|
virtual bool visit(TypeName&) { return true; }
|
||||||
|
virtual bool visit(ElementaryTypeName&) { return true; }
|
||||||
|
virtual bool visit(UserDefinedTypeName&) { return true; }
|
||||||
|
virtual bool visit(Mapping&) { return true; }
|
||||||
|
virtual bool visit(Statement&) { return true; }
|
||||||
|
virtual bool visit(Block&) { return true; }
|
||||||
|
virtual bool visit(IfStatement&) { return true; }
|
||||||
|
virtual bool visit(BreakableStatement&) { return true; }
|
||||||
|
virtual bool visit(WhileStatement&) { return true; }
|
||||||
|
virtual bool visit(Continue&) { return true; }
|
||||||
|
virtual bool visit(Break&) { return true; }
|
||||||
|
virtual bool visit(Return&) { return true; }
|
||||||
|
virtual bool visit(VariableDefinition&) { return true; }
|
||||||
|
virtual bool visit(Expression&) { return true; }
|
||||||
|
virtual bool visit(Assignment&) { return true; }
|
||||||
|
virtual bool visit(UnaryOperation&) { return true; }
|
||||||
|
virtual bool visit(BinaryOperation&) { return true; }
|
||||||
|
virtual bool visit(FunctionCall&) { return true; }
|
||||||
|
virtual bool visit(MemberAccess&) { return true; }
|
||||||
|
virtual bool visit(IndexAccess&) { return true; }
|
||||||
|
virtual bool visit(PrimaryExpression&) { return true; }
|
||||||
|
virtual bool visit(ElementaryTypeNameExpression&) { return true; }
|
||||||
|
virtual bool visit(Literal&) { return true; }
|
||||||
|
|
||||||
|
virtual void endVisit(ASTNode&) { }
|
||||||
|
virtual void endVisit(ContractDefinition&) { }
|
||||||
|
virtual void endVisit(StructDefinition&) { }
|
||||||
|
virtual void endVisit(ParameterList&) { }
|
||||||
|
virtual void endVisit(FunctionDefinition&) { }
|
||||||
|
virtual void endVisit(VariableDeclaration&) { }
|
||||||
|
virtual void endVisit(TypeName&) { }
|
||||||
|
virtual void endVisit(ElementaryTypeName&) { }
|
||||||
|
virtual void endVisit(UserDefinedTypeName&) { }
|
||||||
|
virtual void endVisit(Mapping&) { }
|
||||||
|
virtual void endVisit(Statement&) { }
|
||||||
|
virtual void endVisit(Block&) { }
|
||||||
|
virtual void endVisit(IfStatement&) { }
|
||||||
|
virtual void endVisit(BreakableStatement&) { }
|
||||||
|
virtual void endVisit(WhileStatement&) { }
|
||||||
|
virtual void endVisit(Continue&) { }
|
||||||
|
virtual void endVisit(Break&) { }
|
||||||
|
virtual void endVisit(Return&) { }
|
||||||
|
virtual void endVisit(VariableDefinition&) { }
|
||||||
|
virtual void endVisit(Expression&) { }
|
||||||
|
virtual void endVisit(Assignment&) { }
|
||||||
|
virtual void endVisit(UnaryOperation&) { }
|
||||||
|
virtual void endVisit(BinaryOperation&) { }
|
||||||
|
virtual void endVisit(FunctionCall&) { }
|
||||||
|
virtual void endVisit(MemberAccess&) { }
|
||||||
|
virtual void endVisit(IndexAccess&) { }
|
||||||
|
virtual void endVisit(PrimaryExpression&) { }
|
||||||
|
virtual void endVisit(ElementaryTypeNameExpression&) { }
|
||||||
|
virtual void endVisit(Literal&) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
} }
|
52
Parser.cpp
52
Parser.cpp
@ -57,7 +57,8 @@ public:
|
|||||||
template <class NodeType, typename... Args>
|
template <class NodeType, typename... Args>
|
||||||
ptr<NodeType> createNode(Args&&... _args)
|
ptr<NodeType> createNode(Args&&... _args)
|
||||||
{
|
{
|
||||||
if (m_location.end < 0) markEndPosition();
|
if (m_location.end < 0)
|
||||||
|
markEndPosition();
|
||||||
return std::make_shared<NodeType>(m_location, std::forward<Args>(_args)...);
|
return std::make_shared<NodeType>(m_location, std::forward<Args>(_args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
|
||||||
expectToken(Token::CONTRACT);
|
expectToken(Token::CONTRACT);
|
||||||
std::string name = expectIdentifier();
|
ptr<ASTString> name = expectIdentifierToken();
|
||||||
expectToken(Token::LBRACE);
|
expectToken(Token::LBRACE);
|
||||||
|
|
||||||
vecptr<StructDefinition> structs;
|
vecptr<StructDefinition> structs;
|
||||||
@ -111,7 +112,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
}
|
}
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
|
|
||||||
m_scanner->next();
|
expectToken(Token::RBRACE);
|
||||||
expectToken(Token::EOS);
|
expectToken(Token::EOS);
|
||||||
|
|
||||||
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
||||||
@ -122,7 +123,7 @@ ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
|
||||||
expectToken(Token::FUNCTION);
|
expectToken(Token::FUNCTION);
|
||||||
std::string name(expectIdentifier());
|
ptr<ASTString> name(expectIdentifierToken());
|
||||||
ptr<ParameterList> parameters(parseParameterList());
|
ptr<ParameterList> parameters(parseParameterList());
|
||||||
bool isDeclaredConst = false;
|
bool isDeclaredConst = false;
|
||||||
if (m_scanner->getCurrentToken() == Token::CONST) {
|
if (m_scanner->getCurrentToken() == Token::CONST) {
|
||||||
@ -145,7 +146,7 @@ ptr<StructDefinition> Parser::parseStructDefinition()
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
|
||||||
expectToken(Token::STRUCT);
|
expectToken(Token::STRUCT);
|
||||||
std::string name = expectIdentifier();
|
ptr<ASTString> name = expectIdentifierToken();
|
||||||
vecptr<VariableDeclaration> members;
|
vecptr<VariableDeclaration> members;
|
||||||
expectToken(Token::LBRACE);
|
expectToken(Token::LBRACE);
|
||||||
while (m_scanner->getCurrentToken() != Token::RBRACE) {
|
while (m_scanner->getCurrentToken() != Token::RBRACE) {
|
||||||
@ -164,8 +165,7 @@ ptr<VariableDeclaration> Parser::parseVariableDeclaration()
|
|||||||
|
|
||||||
ptr<TypeName> type = parseTypeName();
|
ptr<TypeName> type = parseTypeName();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
std::string name = expectIdentifier();
|
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken());
|
||||||
return nodeFactory.createNode<VariableDeclaration>(type, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr<TypeName> Parser::parseTypeName()
|
ptr<TypeName> Parser::parseTypeName()
|
||||||
@ -181,8 +181,9 @@ ptr<TypeName> Parser::parseTypeName()
|
|||||||
} else if (token == Token::MAPPING) {
|
} else if (token == Token::MAPPING) {
|
||||||
type = parseMapping();
|
type = parseMapping();
|
||||||
} else if (token == Token::IDENTIFIER) {
|
} else if (token == Token::IDENTIFIER) {
|
||||||
type = ASTNodeFactory(*this).createNode<UserDefinedTypeName>(m_scanner->getCurrentLiteral());
|
ASTNodeFactory nodeFactory(*this);
|
||||||
m_scanner->next();
|
nodeFactory.markEndPosition();
|
||||||
|
type = nodeFactory.createNode<UserDefinedTypeName>(expectIdentifierToken());
|
||||||
} else {
|
} else {
|
||||||
throwExpectationError("Expected type name");
|
throwExpectationError("Expected type name");
|
||||||
}
|
}
|
||||||
@ -410,8 +411,7 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
|||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
std::string memberName = expectIdentifier();
|
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
|
||||||
expression = nodeFactory.createNode<MemberAccess>(expression, memberName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Token::LPAREN:
|
case Token::LPAREN:
|
||||||
@ -431,19 +431,25 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
|||||||
|
|
||||||
ptr<Expression> Parser::parsePrimaryExpression()
|
ptr<Expression> Parser::parsePrimaryExpression()
|
||||||
{
|
{
|
||||||
|
ASTNodeFactory nodeFactory(*this);
|
||||||
Token::Value token = m_scanner->getCurrentToken();
|
Token::Value token = m_scanner->getCurrentToken();
|
||||||
|
ptr<Expression> expression;
|
||||||
|
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case Token::TRUE_LITERAL:
|
case Token::TRUE_LITERAL:
|
||||||
case Token::FALSE_LITERAL:
|
case Token::FALSE_LITERAL:
|
||||||
|
expression = nodeFactory.createNode<Literal>(token, ptr<ASTString>());
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
return ASTNodeFactory(*this).createNode<Literal>(token, std::string());
|
break;
|
||||||
case Token::NUMBER:
|
case Token::NUMBER:
|
||||||
case Token::STRING_LITERAL:
|
case Token::STRING_LITERAL:
|
||||||
m_scanner->next();
|
nodeFactory.markEndPosition();
|
||||||
return ASTNodeFactory(*this).createNode<Literal>(token, m_scanner->getCurrentLiteral());
|
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
||||||
|
break;
|
||||||
case Token::IDENTIFIER:
|
case Token::IDENTIFIER:
|
||||||
m_scanner->next();
|
nodeFactory.markEndPosition();
|
||||||
return ASTNodeFactory(*this).createNode<Identifier>(m_scanner->getCurrentLiteral());
|
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
|
||||||
|
break;
|
||||||
case Token::LPAREN:
|
case Token::LPAREN:
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -454,13 +460,14 @@ ptr<Expression> Parser::parsePrimaryExpression()
|
|||||||
default:
|
default:
|
||||||
if (Token::IsElementaryTypeName(token)) {
|
if (Token::IsElementaryTypeName(token)) {
|
||||||
// used for casts
|
// used for casts
|
||||||
|
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(token);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
return ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(token);
|
|
||||||
} else {
|
} else {
|
||||||
throwExpectationError("Expected primary expression.");
|
throwExpectationError("Expected primary expression.");
|
||||||
return ptr<Expression>(); // this is not reached
|
return ptr<Expression>(); // this is not reached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
vecptr<Expression> Parser::parseFunctionCallArguments()
|
vecptr<Expression> Parser::parseFunctionCallArguments()
|
||||||
@ -492,14 +499,19 @@ Token::Value Parser::expectAssignmentOperator()
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Parser::expectIdentifier()
|
ptr<ASTString> Parser::expectIdentifierToken()
|
||||||
{
|
{
|
||||||
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
||||||
throwExpectationError("Expected identifier");
|
throwExpectationError("Expected identifier");
|
||||||
|
|
||||||
std::string literal = m_scanner->getCurrentLiteral();
|
return getLiteralAndAdvance();
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr<ASTString> Parser::getLiteralAndAdvance()
|
||||||
|
{
|
||||||
|
ptr<ASTString> identifier = std::make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
return literal;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::throwExpectationError(const std::string& _description)
|
void Parser::throwExpectationError(const std::string& _description)
|
||||||
|
3
Parser.h
3
Parser.h
@ -69,7 +69,8 @@ private:
|
|||||||
/// If current token value is not _value, throw exception otherwise advance token.
|
/// If current token value is not _value, throw exception otherwise advance token.
|
||||||
void expectToken(Token::Value _value);
|
void expectToken(Token::Value _value);
|
||||||
Token::Value expectAssignmentOperator();
|
Token::Value expectAssignmentOperator();
|
||||||
std::string expectIdentifier();
|
ptr<ASTString> expectIdentifierToken();
|
||||||
|
ptr<ASTString> getLiteralAndAdvance();
|
||||||
void throwExpectationError(const std::string& _description);
|
void throwExpectationError(const std::string& _description);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user