From d5b1b4d624ce1ef1f2b7bdb02fd6221acc5762b9 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 5 Jan 2015 15:46:40 +0100 Subject: [PATCH 1/5] Preparing the ground for AST outputing to JSON --- ASTJsonConverter.cpp | 490 +++++++++++++++++++++++++++++++++++++++++++ ASTJsonConverter.h | 127 +++++++++++ 2 files changed, 617 insertions(+) create mode 100644 ASTJsonConverter.cpp create mode 100644 ASTJsonConverter.h diff --git a/ASTJsonConverter.cpp b/ASTJsonConverter.cpp new file mode 100644 index 000000000..82495dec0 --- /dev/null +++ b/ASTJsonConverter.cpp @@ -0,0 +1,490 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** + * @author Lefteris + * @date 2015 + * Converts the AST into json format + */ + +#include +#include + +using namespace std; + +namespace dev +{ +namespace solidity +{ + +void ASTJsonConverter::addJsonNode(string const& _typeName, + initializer_list> _list) +{ + Json::Value node; + Json::Value attrs; + + node["type"] = _typeName; + for (auto &e: _list) + attrs[e.first] = e.second; + node["attributes"] = attrs; + + m_childrenPtr->append(node); +} + +ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast) +{ + Json::Value attrs; + Json::Value children; + + m_astJson["type"] = "root"; + attrs["name"] = "nameoffile"; //TODO + m_astJson["attributes"] = attrs; + m_astJson["children"] = children; + m_childrenPtr = &m_astJson["children"]; +} + +void ASTJsonConverter::print(ostream& _stream) +{ + m_ast->accept(*this); + _stream << m_astJson; +} + + +bool ASTJsonConverter::visit(ImportDirective const& _node) +{ + addJsonNode("import", { make_pair("file", _node.getIdentifier())}); + return goDeeper(); +} + +bool ASTJsonConverter::visit(ContractDefinition const& _node) +{ + // writeLine("ContractDefinition \"" + _node.getName() + "\""); + // printSourcePart(_node); + addJsonNode("contract", { make_pair("name", _node.getName())}); + return goDeeper(); +} + +bool ASTJsonConverter::visit(StructDefinition const& _node) +{ + // writeLine("StructDefinition \"" + _node.getName() + "\""); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(ParameterList const& _node) +{ + // writeLine("ParameterList"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(FunctionDefinition const& _node) +{ + // writeLine("FunctionDefinition \"" + _node.getName() + "\"" + + // (_node.isPublic() ? " - public" : "") + + // (_node.isDeclaredConst() ? " - const" : "")); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(VariableDeclaration const& _node) +{ + // writeLine("VariableDeclaration \"" + _node.getName() + "\""); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(TypeName const& _node) +{ + // writeLine("TypeName"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(ElementaryTypeName const& _node) +{ + // writeLine(string("ElementaryTypeName ") + Token::toString(_node.getTypeName())); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(UserDefinedTypeName const& _node) +{ + // writeLine("UserDefinedTypeName \"" + _node.getName() + "\""); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Mapping const& _node) +{ + // writeLine("Mapping"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Statement const& _node) +{ + // writeLine("Statement"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Block const& _node) +{ + // writeLine("Block"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(IfStatement const& _node) +{ + // writeLine("IfStatement"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(BreakableStatement const& _node) +{ + // writeLine("BreakableStatement"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(WhileStatement const& _node) +{ + // writeLine("WhileStatement"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(ForStatement const& _node) +{ + // writeLine("ForStatement"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Continue const& _node) +{ + // writeLine("Continue"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Break const& _node) +{ + // writeLine("Break"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Return const& _node) +{ + // writeLine("Return"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(VariableDefinition const& _node) +{ + // writeLine("VariableDefinition"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(ExpressionStatement const& _node) +{ + // writeLine("ExpressionStatement"); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Expression const& _node) +{ + // writeLine("Expression"); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Assignment const& _node) +{ + // writeLine(string("Assignment using operator ") + Token::toString(_node.getAssignmentOperator())); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(UnaryOperation const& _node) +{ + // writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") + + // ") " + Token::toString(_node.getOperator())); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(BinaryOperation const& _node) +{ + // writeLine(string("BinaryOperation using operator ") + Token::toString(_node.getOperator())); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(FunctionCall const& _node) +{ + // writeLine("FunctionCall"); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(NewExpression const& _node) +{ + // writeLine("NewExpression"); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(MemberAccess const& _node) +{ + // writeLine("MemberAccess to member " + _node.getMemberName()); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(IndexAccess const& _node) +{ + // writeLine("IndexAccess"); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(PrimaryExpression const& _node) +{ + // writeLine("PrimaryExpression"); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Identifier const& _node) +{ + // writeLine(string("Identifier ") + _node.getName()); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) +{ + // writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.getTypeToken())); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +bool ASTJsonConverter::visit(Literal const& _node) +{ + // char const* tokenString = Token::toString(_node.getToken()); + // if (!tokenString) + // tokenString = "[no token]"; + // writeLine(string("Literal, token: ") + tokenString + " value: " + _node.getValue()); + // printType(_node); + // printSourcePart(_node); + return goDeeper(); +} + +void ASTJsonConverter::endVisit(ImportDirective const&) +{ + +} + +void ASTJsonConverter::endVisit(ContractDefinition const&) +{ + +} + +void ASTJsonConverter::endVisit(StructDefinition const&) +{ + +} + +void ASTJsonConverter::endVisit(ParameterList const&) +{ + +} + +void ASTJsonConverter::endVisit(FunctionDefinition const&) +{ + +} + +void ASTJsonConverter::endVisit(VariableDeclaration const&) +{ + +} + +void ASTJsonConverter::endVisit(TypeName const&) +{ + +} + +void ASTJsonConverter::endVisit(ElementaryTypeName const&) +{ + +} + +void ASTJsonConverter::endVisit(UserDefinedTypeName const&) +{ + +} + +void ASTJsonConverter::endVisit(Mapping const&) +{ + +} + +void ASTJsonConverter::endVisit(Statement const&) +{ + +} + +void ASTJsonConverter::endVisit(Block const&) +{ + +} + +void ASTJsonConverter::endVisit(IfStatement const&) +{ + +} + +void ASTJsonConverter::endVisit(BreakableStatement const&) +{ + +} + +void ASTJsonConverter::endVisit(WhileStatement const&) +{ + +} + +void ASTJsonConverter::endVisit(ForStatement const&) +{ + +} + +void ASTJsonConverter::endVisit(Continue const&) +{ + +} + +void ASTJsonConverter::endVisit(Break const&) +{ + +} + +void ASTJsonConverter::endVisit(Return const&) +{ + +} + +void ASTJsonConverter::endVisit(VariableDefinition const&) +{ + +} + +void ASTJsonConverter::endVisit(ExpressionStatement const&) +{ + +} + +void ASTJsonConverter::endVisit(Expression const&) +{ + +} + +void ASTJsonConverter::endVisit(Assignment const&) +{ + +} + +void ASTJsonConverter::endVisit(UnaryOperation const&) +{ + +} + +void ASTJsonConverter::endVisit(BinaryOperation const&) +{ + +} + +void ASTJsonConverter::endVisit(FunctionCall const&) +{ + +} + +void ASTJsonConverter::endVisit(NewExpression const&) +{ + +} + +void ASTJsonConverter::endVisit(MemberAccess const&) +{ + +} + +void ASTJsonConverter::endVisit(IndexAccess const&) +{ + +} + +void ASTJsonConverter::endVisit(PrimaryExpression const&) +{ + +} + +void ASTJsonConverter::endVisit(Identifier const&) +{ + +} + +void ASTJsonConverter::endVisit(ElementaryTypeNameExpression const&) +{ + +} + +void ASTJsonConverter::endVisit(Literal const&) +{ + +} + +void ASTJsonConverter::printType(Expression const& _expression) +{ + // if (_expression.getType()) + // *m_ostream << getIndentation() << " Type: " << _expression.getType()->toString() << "\n"; + // else + // *m_ostream << getIndentation() << " Type unknown.\n"; +} + + +} +} diff --git a/ASTJsonConverter.h b/ASTJsonConverter.h new file mode 100644 index 000000000..0c84ee9af --- /dev/null +++ b/ASTJsonConverter.h @@ -0,0 +1,127 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** + * @author Lefteris + * @date 2015 + * Converts the AST into json format + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace solidity +{ + +/** + * Converter of the AST into JSON format + */ +class ASTJsonConverter: public ASTConstVisitor +{ +public: + /// Create a converter for the given abstract syntax tree. If the source is specified, + /// the corresponding parts of the source are printed with each node. + ASTJsonConverter(ASTNode const& _ast); + /// Output the json representation of the AST to _stream. + void print(std::ostream& _stream); + + bool visit(ImportDirective const& _node) override; + bool visit(ContractDefinition const& _node) override; + bool visit(StructDefinition const& _node) override; + bool visit(ParameterList const& _node) override; + bool visit(FunctionDefinition const& _node) override; + bool visit(VariableDeclaration const& _node) override; + bool visit(TypeName const& _node) override; + bool visit(ElementaryTypeName const& _node) override; + bool visit(UserDefinedTypeName const& _node) override; + bool visit(Mapping const& _node) override; + bool visit(Statement const& _node) override; + bool visit(Block const& _node) override; + bool visit(IfStatement const& _node) override; + bool visit(BreakableStatement const& _node) override; + bool visit(WhileStatement const& _node) override; + bool visit(ForStatement const& _node) override; + bool visit(Continue const& _node) override; + bool visit(Break const& _node) override; + bool visit(Return const& _node) override; + bool visit(VariableDefinition const& _node) override; + bool visit(ExpressionStatement const& _node) override; + bool visit(Expression const& _node) override; + bool visit(Assignment const& _node) override; + bool visit(UnaryOperation const& _node) override; + bool visit(BinaryOperation const& _node) override; + bool visit(FunctionCall const& _node) override; + bool visit(NewExpression const& _node) override; + bool visit(MemberAccess const& _node) override; + bool visit(IndexAccess const& _node) override; + bool visit(PrimaryExpression const& _node) override; + bool visit(Identifier const& _node) override; + bool visit(ElementaryTypeNameExpression const& _node) override; + bool visit(Literal const& _node) override; + + void endVisit(ImportDirective const&) override; + void endVisit(ContractDefinition const&) override; + void endVisit(StructDefinition const&) override; + void endVisit(ParameterList const&) override; + void endVisit(FunctionDefinition const&) override; + void endVisit(VariableDeclaration const&) override; + void endVisit(TypeName const&) override; + void endVisit(ElementaryTypeName const&) override; + void endVisit(UserDefinedTypeName const&) override; + void endVisit(Mapping const&) override; + void endVisit(Statement const&) override; + void endVisit(Block const&) override; + void endVisit(IfStatement const&) override; + void endVisit(BreakableStatement const&) override; + void endVisit(WhileStatement const&) override; + void endVisit(ForStatement const&) override; + void endVisit(Continue const&) override; + void endVisit(Break const&) override; + void endVisit(Return const&) override; + void endVisit(VariableDefinition const&) override; + void endVisit(ExpressionStatement const&) override; + void endVisit(Expression const&) override; + void endVisit(Assignment const&) override; + void endVisit(UnaryOperation const&) override; + void endVisit(BinaryOperation const&) override; + void endVisit(FunctionCall const&) override; + void endVisit(NewExpression const&) override; + void endVisit(MemberAccess const&) override; + void endVisit(IndexAccess const&) override; + void endVisit(PrimaryExpression const&) override; + void endVisit(Identifier const&) override; + void endVisit(ElementaryTypeNameExpression const&) override; + void endVisit(Literal const&) override; + +private: + void addJsonNode(std::string const& _typeName, + std::initializer_list> _list); + void printType(Expression const& _expression); + bool goDeeper() { return true; } + + Json::Value m_astJson; + Json::Value *m_childrenPtr; + std::string m_source; + ASTNode const* m_ast; +}; + +} +} From bcf49095a2f66083f2a198be424daa98ac2e5b72 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 6 Jan 2015 16:50:04 +0100 Subject: [PATCH 2/5] More work on the AST export. Work in progress --- ASTJsonConverter.cpp | 215 ++++++++++++++++++++++++------------------- ASTJsonConverter.h | 17 +++- 2 files changed, 136 insertions(+), 96 deletions(-) diff --git a/ASTJsonConverter.cpp b/ASTJsonConverter.cpp index 82495dec0..3ef6728bb 100644 --- a/ASTJsonConverter.cpp +++ b/ASTJsonConverter.cpp @@ -31,7 +31,8 @@ namespace solidity { void ASTJsonConverter::addJsonNode(string const& _typeName, - initializer_list> _list) + initializer_list> _list, + bool _hasChildren = false) { Json::Value node; Json::Value attrs; @@ -41,19 +42,29 @@ void ASTJsonConverter::addJsonNode(string const& _typeName, attrs[e.first] = e.second; node["attributes"] = attrs; - m_childrenPtr->append(node); + m_jsonNodePtrs.top()->append(node); + + if (_hasChildren) { + Json::Value children(Json::arrayValue); + node["children"] = children; + m_jsonNodePtrs.push(&node["children"]); + m_depth ++; + cout << "goDown" << endl; + } } -ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast) +ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast), m_depth(0) { Json::Value attrs; - Json::Value children; + Json::Value children(Json::arrayValue); m_astJson["type"] = "root"; - attrs["name"] = "nameoffile"; //TODO m_astJson["attributes"] = attrs; + attrs["name"] = "nameoffile"; //TODO m_astJson["children"] = children; - m_childrenPtr = &m_astJson["children"]; + // m_jsonNodePtrs.push(&m_astJson["children"]); + m_jsonNodePtrs.push(&m_astJson["children"]); + // m_jsonNodePtrs.push(&children); } void ASTJsonConverter::print(ostream& _stream) @@ -66,215 +77,225 @@ void ASTJsonConverter::print(ostream& _stream) bool ASTJsonConverter::visit(ImportDirective const& _node) { addJsonNode("import", { make_pair("file", _node.getIdentifier())}); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(ContractDefinition const& _node) { - // writeLine("ContractDefinition \"" + _node.getName() + "\""); - // printSourcePart(_node); - addJsonNode("contract", { make_pair("name", _node.getName())}); - return goDeeper(); + addJsonNode("contract", { make_pair("name", _node.getName())}, true); + return true; } bool ASTJsonConverter::visit(StructDefinition const& _node) { - // writeLine("StructDefinition \"" + _node.getName() + "\""); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("struct", { make_pair("name", _node.getName())}, true); + return true; } bool ASTJsonConverter::visit(ParameterList const& _node) { - // writeLine("ParameterList"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("parameter_list", {}, true); + return true; } bool ASTJsonConverter::visit(FunctionDefinition const& _node) { - // writeLine("FunctionDefinition \"" + _node.getName() + "\"" + - // (_node.isPublic() ? " - public" : "") + - // (_node.isDeclaredConst() ? " - const" : "")); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("function", + { make_pair("name", _node.getName()), + make_pair("public", boost::lexical_cast(_node.isPublic())), + make_pair("const", boost::lexical_cast(_node.isDeclaredConst()))}, + true); + return true; } bool ASTJsonConverter::visit(VariableDeclaration const& _node) { - // writeLine("VariableDeclaration \"" + _node.getName() + "\""); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("variable_declaration", + { //make_pair("type", _node.getTypeName()->getName()), + make_pair("name", _node.getName()), + make_pair("local", boost::lexical_cast(_node.isLocalVariable()))}); + return true; } bool ASTJsonConverter::visit(TypeName const& _node) { // writeLine("TypeName"); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(ElementaryTypeName const& _node) { // writeLine(string("ElementaryTypeName ") + Token::toString(_node.getTypeName())); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(UserDefinedTypeName const& _node) { // writeLine("UserDefinedTypeName \"" + _node.getName() + "\""); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(Mapping const& _node) { // writeLine("Mapping"); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(Statement const& _node) { - // writeLine("Statement"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("statement", {}, true); + return true; } bool ASTJsonConverter::visit(Block const& _node) { - // writeLine("Block"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("block", {}, true); + return true; } bool ASTJsonConverter::visit(IfStatement const& _node) { - // writeLine("IfStatement"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("if_statement", {}, true); + return true; } bool ASTJsonConverter::visit(BreakableStatement const& _node) { // writeLine("BreakableStatement"); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(WhileStatement const& _node) { - // writeLine("WhileStatement"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("while_statement", {}, true); + return true; } bool ASTJsonConverter::visit(ForStatement const& _node) { - // writeLine("ForStatement"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("for_statement", {}, true); + return true; } bool ASTJsonConverter::visit(Continue const& _node) { - // writeLine("Continue"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("continue", {}); + return true; } bool ASTJsonConverter::visit(Break const& _node) { - // writeLine("Break"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("break", {}); + return true; } bool ASTJsonConverter::visit(Return const& _node) { - // writeLine("Return"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("return", {});; + return true; } bool ASTJsonConverter::visit(VariableDefinition const& _node) { - // writeLine("VariableDefinition"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("variable_definition", {}, true); + return true; } bool ASTJsonConverter::visit(ExpressionStatement const& _node) { - // writeLine("ExpressionStatement"); - // printSourcePart(_node); - return goDeeper(); + addJsonNode("expression_statement", {}, true); + return true; } bool ASTJsonConverter::visit(Expression const& _node) { + addJsonNode("expression", + { + make_pair("type", _node.getType()->toString()), + make_pair("lvalue", boost::lexical_cast(_node.isLValue())), + make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue())), + }, + true); // writeLine("Expression"); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(Assignment const& _node) { + addJsonNode("assignment", {make_pair("operator", Token::toString(_node.getAssignmentOperator()))}, true); // writeLine(string("Assignment using operator ") + Token::toString(_node.getAssignmentOperator())); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(UnaryOperation const& _node) { + addJsonNode("unary_op", + {make_pair("prefix", boost::lexical_cast(_node.isPrefixOperation())), + make_pair("operator", Token::toString(_node.getOperator()))}, + true); + // writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") + // ") " + Token::toString(_node.getOperator())); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(BinaryOperation const& _node) { + addJsonNode("binary_op", + {make_pair("operator", Token::toString(_node.getOperator()))}, + true); // writeLine(string("BinaryOperation using operator ") + Token::toString(_node.getOperator())); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(FunctionCall const& _node) { + addJsonNode("function_call", + {make_pair("type_conversion", boost::lexical_cast(_node.isTypeConversion()))}, + true); // writeLine("FunctionCall"); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(NewExpression const& _node) { + addJsonNode("new_expression", {}, true); // writeLine("NewExpression"); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(MemberAccess const& _node) { + addJsonNode("member_access", {make_pair("member_name", _node.getMemberName())}, true); // writeLine("MemberAccess to member " + _node.getMemberName()); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(IndexAccess const& _node) { - // writeLine("IndexAccess"); + addJsonNode("index_access", {}, true); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(PrimaryExpression const& _node) @@ -282,34 +303,43 @@ bool ASTJsonConverter::visit(PrimaryExpression const& _node) // writeLine("PrimaryExpression"); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(Identifier const& _node) { + addJsonNode("identifier", {make_pair("value", _node.getName())}); // writeLine(string("Identifier ") + _node.getName()); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) { + addJsonNode("elementary_typename_expression", + {make_pair("value", Token::toString(_node.getTypeToken()))}); // writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.getTypeToken())); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } bool ASTJsonConverter::visit(Literal const& _node) { + char const* tokenString = Token::toString(_node.getToken()); + addJsonNode("literal", + { + make_pair("string", (tokenString) ? tokenString : "null"), + make_pair("value", _node.getValue())}); + // char const* tokenString = Token::toString(_node.getToken()); // if (!tokenString) // tokenString = "[no token]"; // writeLine(string("Literal, token: ") + tokenString + " value: " + _node.getValue()); // printType(_node); // printSourcePart(_node); - return goDeeper(); + return true; } void ASTJsonConverter::endVisit(ImportDirective const&) @@ -319,27 +349,26 @@ void ASTJsonConverter::endVisit(ImportDirective const&) void ASTJsonConverter::endVisit(ContractDefinition const&) { - + goUp(); } void ASTJsonConverter::endVisit(StructDefinition const&) { - + goUp(); } void ASTJsonConverter::endVisit(ParameterList const&) { - + goUp(); } void ASTJsonConverter::endVisit(FunctionDefinition const&) { - + goUp(); } void ASTJsonConverter::endVisit(VariableDeclaration const&) { - } void ASTJsonConverter::endVisit(TypeName const&) @@ -364,17 +393,17 @@ void ASTJsonConverter::endVisit(Mapping const&) void ASTJsonConverter::endVisit(Statement const&) { - + goUp(); } void ASTJsonConverter::endVisit(Block const&) { - + goUp(); } void ASTJsonConverter::endVisit(IfStatement const&) { - + goUp(); } void ASTJsonConverter::endVisit(BreakableStatement const&) @@ -384,12 +413,12 @@ void ASTJsonConverter::endVisit(BreakableStatement const&) void ASTJsonConverter::endVisit(WhileStatement const&) { - + goUp(); } void ASTJsonConverter::endVisit(ForStatement const&) { - + goUp(); } void ASTJsonConverter::endVisit(Continue const&) @@ -409,52 +438,52 @@ void ASTJsonConverter::endVisit(Return const&) void ASTJsonConverter::endVisit(VariableDefinition const&) { - + goUp(); } void ASTJsonConverter::endVisit(ExpressionStatement const&) { - + goUp(); } void ASTJsonConverter::endVisit(Expression const&) { - + goUp(); } void ASTJsonConverter::endVisit(Assignment const&) { - + goUp(); } void ASTJsonConverter::endVisit(UnaryOperation const&) { - + goUp(); } void ASTJsonConverter::endVisit(BinaryOperation const&) { - + goUp(); } void ASTJsonConverter::endVisit(FunctionCall const&) { - + goUp(); } void ASTJsonConverter::endVisit(NewExpression const&) { - + goUp(); } void ASTJsonConverter::endVisit(MemberAccess const&) { - + goUp(); } void ASTJsonConverter::endVisit(IndexAccess const&) { - + goUp(); } void ASTJsonConverter::endVisit(PrimaryExpression const&) diff --git a/ASTJsonConverter.h b/ASTJsonConverter.h index 0c84ee9af..44bd34617 100644 --- a/ASTJsonConverter.h +++ b/ASTJsonConverter.h @@ -23,7 +23,9 @@ #pragma once #include +#include #include +#include #include namespace dev @@ -113,14 +115,23 @@ public: private: void addJsonNode(std::string const& _typeName, - std::initializer_list> _list); + std::initializer_list> _list, + bool _hasChildren); void printType(Expression const& _expression); - bool goDeeper() { return true; } + inline void goUp() + { + std::cout << "goUp" << std::endl; + m_jsonNodePtrs.pop(); + m_depth--; + if (m_depth < 0) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal error")); + }; Json::Value m_astJson; - Json::Value *m_childrenPtr; + std::stack m_jsonNodePtrs; std::string m_source; ASTNode const* m_ast; + int m_depth; }; } From 2eaf9ff865c029fb1a2aa3595a93275963ffe0cd Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 14 Jan 2015 15:27:31 +0100 Subject: [PATCH 3/5] ASTJSonconverter stack takes objects and not pointers --- ASTJsonConverter.cpp | 8 +++----- ASTJsonConverter.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ASTJsonConverter.cpp b/ASTJsonConverter.cpp index 3ef6728bb..0e40713ac 100644 --- a/ASTJsonConverter.cpp +++ b/ASTJsonConverter.cpp @@ -42,12 +42,12 @@ void ASTJsonConverter::addJsonNode(string const& _typeName, attrs[e.first] = e.second; node["attributes"] = attrs; - m_jsonNodePtrs.top()->append(node); + m_jsonNodePtrs.top().append(node); if (_hasChildren) { Json::Value children(Json::arrayValue); node["children"] = children; - m_jsonNodePtrs.push(&node["children"]); + m_jsonNodePtrs.push(node["children"]); m_depth ++; cout << "goDown" << endl; } @@ -62,9 +62,7 @@ ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast), m_depth(0 m_astJson["attributes"] = attrs; attrs["name"] = "nameoffile"; //TODO m_astJson["children"] = children; - // m_jsonNodePtrs.push(&m_astJson["children"]); - m_jsonNodePtrs.push(&m_astJson["children"]); - // m_jsonNodePtrs.push(&children); + m_jsonNodePtrs.push(m_astJson["children"]); } void ASTJsonConverter::print(ostream& _stream) diff --git a/ASTJsonConverter.h b/ASTJsonConverter.h index 44bd34617..6db625fed 100644 --- a/ASTJsonConverter.h +++ b/ASTJsonConverter.h @@ -128,7 +128,7 @@ private: }; Json::Value m_astJson; - std::stack m_jsonNodePtrs; + std::stack m_jsonNodePtrs; std::string m_source; ASTNode const* m_ast; int m_depth; From 9c8ce499693c13c32773ae65181573140ca1fc74 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 15 Jan 2015 16:54:59 +0100 Subject: [PATCH 4/5] Solidity AST Json Exporter - A first version of the exporter is ready with this commit - Further refinement will follow once it gets used --- ASTJsonConverter.cpp | 229 +++++++++++++++++++------------------------ ASTJsonConverter.h | 13 ++- 2 files changed, 105 insertions(+), 137 deletions(-) diff --git a/ASTJsonConverter.cpp b/ASTJsonConverter.cpp index 0e40713ac..70821a8f0 100644 --- a/ASTJsonConverter.cpp +++ b/ASTJsonConverter.cpp @@ -30,39 +30,50 @@ namespace dev namespace solidity { -void ASTJsonConverter::addJsonNode(string const& _typeName, +void ASTJsonConverter::addKeyValue(Json::Value& _obj, string const& _key, string const& _val) +{ + // special handling for booleans + if (_key == "const" || _key == "public" || _key == "local" || + _key == "lvalue" || _key == "local_lvalue" || _key == "prefix") + _obj[_key] = (_val == "1") ? true : false; + else + // else simply add it as a string + _obj[_key] = _val; +} + +void ASTJsonConverter::addJsonNode(string const& _nodeName, initializer_list> _list, bool _hasChildren = false) { Json::Value node; - Json::Value attrs; - node["type"] = _typeName; - for (auto &e: _list) - attrs[e.first] = e.second; - node["attributes"] = attrs; + node["name"] = _nodeName; + if (_list.size() !=0) + { + Json::Value attrs; + for (auto &e: _list) + addKeyValue(attrs, e.first, e.second); + node["attributes"] = attrs; + } - m_jsonNodePtrs.top().append(node); + (*m_jsonNodePtrs.top()).append(node); - if (_hasChildren) { + if (_hasChildren) + { + Json::Value& addedNode = (*m_jsonNodePtrs.top())[m_jsonNodePtrs.top()->size() - 1]; Json::Value children(Json::arrayValue); - node["children"] = children; - m_jsonNodePtrs.push(node["children"]); - m_depth ++; - cout << "goDown" << endl; + addedNode["children"] = children; + m_jsonNodePtrs.push(&addedNode["children"]); } } -ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast), m_depth(0) +ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast) { - Json::Value attrs; Json::Value children(Json::arrayValue); - m_astJson["type"] = "root"; - m_astJson["attributes"] = attrs; - attrs["name"] = "nameoffile"; //TODO + m_astJson["name"] = "root"; m_astJson["children"] = children; - m_jsonNodePtrs.push(m_astJson["children"]); + m_jsonNodePtrs.push(&m_astJson["children"]); } void ASTJsonConverter::print(ostream& _stream) @@ -74,31 +85,31 @@ void ASTJsonConverter::print(ostream& _stream) bool ASTJsonConverter::visit(ImportDirective const& _node) { - addJsonNode("import", { make_pair("file", _node.getIdentifier())}); + addJsonNode("Import", { make_pair("file", _node.getIdentifier())}); return true; } bool ASTJsonConverter::visit(ContractDefinition const& _node) { - addJsonNode("contract", { make_pair("name", _node.getName())}, true); + addJsonNode("Contract", { make_pair("name", _node.getName())}, true); return true; } bool ASTJsonConverter::visit(StructDefinition const& _node) { - addJsonNode("struct", { make_pair("name", _node.getName())}, true); + addJsonNode("Struct", { make_pair("name", _node.getName())}, true); return true; } -bool ASTJsonConverter::visit(ParameterList const& _node) +bool ASTJsonConverter::visit(ParameterList const&) { - addJsonNode("parameter_list", {}, true); + addJsonNode("ParameterList", {}, true); return true; } bool ASTJsonConverter::visit(FunctionDefinition const& _node) { - addJsonNode("function", + addJsonNode("Function", { make_pair("name", _node.getName()), make_pair("public", boost::lexical_cast(_node.isPublic())), make_pair("const", boost::lexical_cast(_node.isDeclaredConst()))}, @@ -108,235 +119,196 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) bool ASTJsonConverter::visit(VariableDeclaration const& _node) { - addJsonNode("variable_declaration", - { //make_pair("type", _node.getTypeName()->getName()), - make_pair("name", _node.getName()), - make_pair("local", boost::lexical_cast(_node.isLocalVariable()))}); + addJsonNode("VariableDeclaration", + { make_pair("name", _node.getName()), + make_pair("local", boost::lexical_cast(_node.isLocalVariable()))}, + true); return true; } -bool ASTJsonConverter::visit(TypeName const& _node) +bool ASTJsonConverter::visit(TypeName const&) { - // writeLine("TypeName"); - // printSourcePart(_node); return true; } bool ASTJsonConverter::visit(ElementaryTypeName const& _node) { - // writeLine(string("ElementaryTypeName ") + Token::toString(_node.getTypeName())); - // printSourcePart(_node); + addJsonNode("ElementaryTypeName", { make_pair("name", Token::toString(_node.getTypeName())) }); return true; } bool ASTJsonConverter::visit(UserDefinedTypeName const& _node) { - // writeLine("UserDefinedTypeName \"" + _node.getName() + "\""); - // printSourcePart(_node); + addJsonNode("UserDefinedTypeName", { make_pair("name", _node.getName()) }); return true; } -bool ASTJsonConverter::visit(Mapping const& _node) +bool ASTJsonConverter::visit(Mapping const&) { - // writeLine("Mapping"); - // printSourcePart(_node); + addJsonNode("Mapping", {}, true); return true; } -bool ASTJsonConverter::visit(Statement const& _node) +bool ASTJsonConverter::visit(Statement const&) { - addJsonNode("statement", {}, true); + addJsonNode("Statement", {}, true); return true; } -bool ASTJsonConverter::visit(Block const& _node) +bool ASTJsonConverter::visit(Block const&) { - addJsonNode("block", {}, true); + addJsonNode("Block", {}, true); return true; } -bool ASTJsonConverter::visit(IfStatement const& _node) +bool ASTJsonConverter::visit(IfStatement const&) { - addJsonNode("if_statement", {}, true); + addJsonNode("IfStatement", {}, true); return true; } -bool ASTJsonConverter::visit(BreakableStatement const& _node) +bool ASTJsonConverter::visit(BreakableStatement const&) { - // writeLine("BreakableStatement"); - // printSourcePart(_node); return true; } -bool ASTJsonConverter::visit(WhileStatement const& _node) +bool ASTJsonConverter::visit(WhileStatement const&) { - addJsonNode("while_statement", {}, true); + addJsonNode("WhileStatement", {}, true); return true; } -bool ASTJsonConverter::visit(ForStatement const& _node) +bool ASTJsonConverter::visit(ForStatement const&) { - addJsonNode("for_statement", {}, true); + addJsonNode("ForStatement", {}, true); return true; } -bool ASTJsonConverter::visit(Continue const& _node) +bool ASTJsonConverter::visit(Continue const&) { - addJsonNode("continue", {}); + addJsonNode("Continue", {}); return true; } -bool ASTJsonConverter::visit(Break const& _node) +bool ASTJsonConverter::visit(Break const&) { - addJsonNode("break", {}); + addJsonNode("Break", {}); return true; } -bool ASTJsonConverter::visit(Return const& _node) +bool ASTJsonConverter::visit(Return const&) { - addJsonNode("return", {});; + addJsonNode("Return", {}, true);; return true; } -bool ASTJsonConverter::visit(VariableDefinition const& _node) +bool ASTJsonConverter::visit(VariableDefinition const&) { - addJsonNode("variable_definition", {}, true); + addJsonNode("VariableDefinition", {}, true); return true; } -bool ASTJsonConverter::visit(ExpressionStatement const& _node) +bool ASTJsonConverter::visit(ExpressionStatement const&) { - addJsonNode("expression_statement", {}, true); + addJsonNode("ExpressionStatement", {}, true); return true; } bool ASTJsonConverter::visit(Expression const& _node) { - addJsonNode("expression", + addJsonNode("Expression", { - make_pair("type", _node.getType()->toString()), + make_pair("type", getType(_node)), make_pair("lvalue", boost::lexical_cast(_node.isLValue())), - make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue())), - }, + make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue()))}, true); - // writeLine("Expression"); - // printType(_node); - // printSourcePart(_node); return true; } bool ASTJsonConverter::visit(Assignment const& _node) { - addJsonNode("assignment", {make_pair("operator", Token::toString(_node.getAssignmentOperator()))}, true); - // writeLine(string("Assignment using operator ") + Token::toString(_node.getAssignmentOperator())); - // printType(_node); - // printSourcePart(_node); + addJsonNode("Assignment", + {make_pair("operator", Token::toString(_node.getAssignmentOperator())), + make_pair("type", getType(_node))}, + true); return true; } bool ASTJsonConverter::visit(UnaryOperation const& _node) { - addJsonNode("unary_op", + addJsonNode("UnaryOperation", {make_pair("prefix", boost::lexical_cast(_node.isPrefixOperation())), - make_pair("operator", Token::toString(_node.getOperator()))}, + make_pair("operator", Token::toString(_node.getOperator())), + make_pair("type", getType(_node))}, true); - - // writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") + - // ") " + Token::toString(_node.getOperator())); - // printType(_node); - // printSourcePart(_node); return true; } bool ASTJsonConverter::visit(BinaryOperation const& _node) { - addJsonNode("binary_op", - {make_pair("operator", Token::toString(_node.getOperator()))}, + addJsonNode("BinaryOperation", + {make_pair("operator", Token::toString(_node.getOperator())), + make_pair("type", getType(_node))}, true); - // writeLine(string("BinaryOperation using operator ") + Token::toString(_node.getOperator())); - // printType(_node); - // printSourcePart(_node); return true; } bool ASTJsonConverter::visit(FunctionCall const& _node) { - addJsonNode("function_call", - {make_pair("type_conversion", boost::lexical_cast(_node.isTypeConversion()))}, + addJsonNode("FunctionCall", + {make_pair("type_conversion", boost::lexical_cast(_node.isTypeConversion())), + make_pair("type", getType(_node))}, true); - // writeLine("FunctionCall"); - // printType(_node); - // printSourcePart(_node); return true; } bool ASTJsonConverter::visit(NewExpression const& _node) { - addJsonNode("new_expression", {}, true); - // writeLine("NewExpression"); - // printType(_node); - // printSourcePart(_node); + addJsonNode("NewExpression", {make_pair("type", getType(_node))}, true); return true; } bool ASTJsonConverter::visit(MemberAccess const& _node) { - addJsonNode("member_access", {make_pair("member_name", _node.getMemberName())}, true); - // writeLine("MemberAccess to member " + _node.getMemberName()); - // printType(_node); - // printSourcePart(_node); + addJsonNode("MemberAccess", + {make_pair("member_name", _node.getMemberName()), + make_pair("type", getType(_node))}, + true); return true; } bool ASTJsonConverter::visit(IndexAccess const& _node) { - addJsonNode("index_access", {}, true); - // printType(_node); - // printSourcePart(_node); + addJsonNode("IndexAccess", {make_pair("type", getType(_node))}, true); return true; } -bool ASTJsonConverter::visit(PrimaryExpression const& _node) +bool ASTJsonConverter::visit(PrimaryExpression const&) { - // writeLine("PrimaryExpression"); - // printType(_node); - // printSourcePart(_node); return true; } bool ASTJsonConverter::visit(Identifier const& _node) { - addJsonNode("identifier", {make_pair("value", _node.getName())}); - // writeLine(string("Identifier ") + _node.getName()); - // printType(_node); - // printSourcePart(_node); + addJsonNode("Identifier", + {make_pair("value", _node.getName()), make_pair("type", getType(_node))}); return true; } bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) { - addJsonNode("elementary_typename_expression", - {make_pair("value", Token::toString(_node.getTypeToken()))}); - // writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.getTypeToken())); - // printType(_node); - // printSourcePart(_node); + addJsonNode("ElementaryTypenameExpression", + {make_pair("value", Token::toString(_node.getTypeToken())), make_pair("type", getType(_node))}); return true; } bool ASTJsonConverter::visit(Literal const& _node) { char const* tokenString = Token::toString(_node.getToken()); - addJsonNode("literal", - { - make_pair("string", (tokenString) ? tokenString : "null"), - make_pair("value", _node.getValue())}); - - // char const* tokenString = Token::toString(_node.getToken()); - // if (!tokenString) - // tokenString = "[no token]"; - // writeLine(string("Literal, token: ") + tokenString + " value: " + _node.getValue()); - // printType(_node); - // printSourcePart(_node); + addJsonNode("Literal", + {make_pair("string", (tokenString) ? tokenString : "null"), + make_pair("value", _node.getValue()), + make_pair("type", getType(_node))}); return true; } @@ -431,7 +403,7 @@ void ASTJsonConverter::endVisit(Break const&) void ASTJsonConverter::endVisit(Return const&) { - + goUp(); } void ASTJsonConverter::endVisit(VariableDefinition const&) @@ -504,12 +476,9 @@ void ASTJsonConverter::endVisit(Literal const&) } -void ASTJsonConverter::printType(Expression const& _expression) +string const ASTJsonConverter::getType(Expression const& _expression) { - // if (_expression.getType()) - // *m_ostream << getIndentation() << " Type: " << _expression.getType()->toString() << "\n"; - // else - // *m_ostream << getIndentation() << " Type unknown.\n"; + return (_expression.getType()) ? _expression.getType()->toString() : "Unknown"; } diff --git a/ASTJsonConverter.h b/ASTJsonConverter.h index 6db625fed..69030f399 100644 --- a/ASTJsonConverter.h +++ b/ASTJsonConverter.h @@ -114,21 +114,20 @@ public: void endVisit(Literal const&) override; private: - void addJsonNode(std::string const& _typeName, + void addKeyValue(Json::Value& _obj, std::string const& _key, std::string const& _val); + void addJsonNode(std::string const& _nodeName, std::initializer_list> _list, bool _hasChildren); - void printType(Expression const& _expression); + std::string const getType(Expression const& _expression); inline void goUp() { - std::cout << "goUp" << std::endl; - m_jsonNodePtrs.pop(); - m_depth--; - if (m_depth < 0) + if (m_jsonNodePtrs.empty()) BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal error")); + m_jsonNodePtrs.pop(); }; Json::Value m_astJson; - std::stack m_jsonNodePtrs; + std::stack m_jsonNodePtrs; std::string m_source; ASTNode const* m_ast; int m_depth; From 839f7778b5b9c9e0dbaa1b3ca212a616b523c61c Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 16 Jan 2015 11:44:55 +0100 Subject: [PATCH 5/5] Style fixes and refactoring in ASTJsonConverter --- ASTJsonConverter.cpp | 63 +++++++++++++++++--------------------------- ASTJsonConverter.h | 9 +++---- 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/ASTJsonConverter.cpp b/ASTJsonConverter.cpp index 70821a8f0..04ddee0a7 100644 --- a/ASTJsonConverter.cpp +++ b/ASTJsonConverter.cpp @@ -48,15 +48,15 @@ void ASTJsonConverter::addJsonNode(string const& _nodeName, Json::Value node; node["name"] = _nodeName; - if (_list.size() !=0) + if (_list.size() != 0) { Json::Value attrs; - for (auto &e: _list) + for (auto& e: _list) addKeyValue(attrs, e.first, e.second); node["attributes"] = attrs; } - (*m_jsonNodePtrs.top()).append(node); + m_jsonNodePtrs.top()->append(node); if (_hasChildren) { @@ -82,7 +82,6 @@ void ASTJsonConverter::print(ostream& _stream) _stream << m_astJson; } - bool ASTJsonConverter::visit(ImportDirective const& _node) { addJsonNode("Import", { make_pair("file", _node.getIdentifier())}); @@ -91,13 +90,13 @@ bool ASTJsonConverter::visit(ImportDirective const& _node) bool ASTJsonConverter::visit(ContractDefinition const& _node) { - addJsonNode("Contract", { make_pair("name", _node.getName())}, true); + addJsonNode("Contract", { make_pair("name", _node.getName()) }, true); return true; } bool ASTJsonConverter::visit(StructDefinition const& _node) { - addJsonNode("Struct", { make_pair("name", _node.getName())}, true); + addJsonNode("Struct", { make_pair("name", _node.getName()) }, true); return true; } @@ -112,7 +111,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) addJsonNode("Function", { make_pair("name", _node.getName()), make_pair("public", boost::lexical_cast(_node.isPublic())), - make_pair("const", boost::lexical_cast(_node.isDeclaredConst()))}, + make_pair("const", boost::lexical_cast(_node.isDeclaredConst())) }, true); return true; } @@ -217,10 +216,9 @@ bool ASTJsonConverter::visit(ExpressionStatement const&) bool ASTJsonConverter::visit(Expression const& _node) { addJsonNode("Expression", - { - make_pair("type", getType(_node)), + { make_pair("type", getType(_node)), make_pair("lvalue", boost::lexical_cast(_node.isLValue())), - make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue()))}, + make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue())) }, true); return true; } @@ -228,8 +226,8 @@ bool ASTJsonConverter::visit(Expression const& _node) bool ASTJsonConverter::visit(Assignment const& _node) { addJsonNode("Assignment", - {make_pair("operator", Token::toString(_node.getAssignmentOperator())), - make_pair("type", getType(_node))}, + { make_pair("operator", Token::toString(_node.getAssignmentOperator())), + make_pair("type", getType(_node)) }, true); return true; } @@ -237,9 +235,9 @@ bool ASTJsonConverter::visit(Assignment const& _node) bool ASTJsonConverter::visit(UnaryOperation const& _node) { addJsonNode("UnaryOperation", - {make_pair("prefix", boost::lexical_cast(_node.isPrefixOperation())), + { make_pair("prefix", boost::lexical_cast(_node.isPrefixOperation())), make_pair("operator", Token::toString(_node.getOperator())), - make_pair("type", getType(_node))}, + make_pair("type", getType(_node)) }, true); return true; } @@ -247,7 +245,7 @@ bool ASTJsonConverter::visit(UnaryOperation const& _node) bool ASTJsonConverter::visit(BinaryOperation const& _node) { addJsonNode("BinaryOperation", - {make_pair("operator", Token::toString(_node.getOperator())), + { make_pair("operator", Token::toString(_node.getOperator())), make_pair("type", getType(_node))}, true); return true; @@ -256,30 +254,30 @@ bool ASTJsonConverter::visit(BinaryOperation const& _node) bool ASTJsonConverter::visit(FunctionCall const& _node) { addJsonNode("FunctionCall", - {make_pair("type_conversion", boost::lexical_cast(_node.isTypeConversion())), - make_pair("type", getType(_node))}, + { make_pair("type_conversion", boost::lexical_cast(_node.isTypeConversion())), + make_pair("type", getType(_node)) }, true); return true; } bool ASTJsonConverter::visit(NewExpression const& _node) { - addJsonNode("NewExpression", {make_pair("type", getType(_node))}, true); + addJsonNode("NewExpression", { make_pair("type", getType(_node)) }, true); return true; } bool ASTJsonConverter::visit(MemberAccess const& _node) { addJsonNode("MemberAccess", - {make_pair("member_name", _node.getMemberName()), - make_pair("type", getType(_node))}, + { make_pair("member_name", _node.getMemberName()), + make_pair("type", getType(_node)) }, true); return true; } bool ASTJsonConverter::visit(IndexAccess const& _node) { - addJsonNode("IndexAccess", {make_pair("type", getType(_node))}, true); + addJsonNode("IndexAccess", { make_pair("type", getType(_node)) }, true); return true; } @@ -291,14 +289,14 @@ bool ASTJsonConverter::visit(PrimaryExpression const&) bool ASTJsonConverter::visit(Identifier const& _node) { addJsonNode("Identifier", - {make_pair("value", _node.getName()), make_pair("type", getType(_node))}); + { make_pair("value", _node.getName()), make_pair("type", getType(_node)) }); return true; } bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) { addJsonNode("ElementaryTypenameExpression", - {make_pair("value", Token::toString(_node.getTypeToken())), make_pair("type", getType(_node))}); + { make_pair("value", Token::toString(_node.getTypeToken())), make_pair("type", getType(_node)) }); return true; } @@ -306,15 +304,14 @@ bool ASTJsonConverter::visit(Literal const& _node) { char const* tokenString = Token::toString(_node.getToken()); addJsonNode("Literal", - {make_pair("string", (tokenString) ? tokenString : "null"), + { make_pair("string", (tokenString) ? tokenString : "null"), make_pair("value", _node.getValue()), - make_pair("type", getType(_node))}); + make_pair("type", getType(_node)) }); return true; } void ASTJsonConverter::endVisit(ImportDirective const&) { - } void ASTJsonConverter::endVisit(ContractDefinition const&) @@ -343,22 +340,18 @@ void ASTJsonConverter::endVisit(VariableDeclaration const&) void ASTJsonConverter::endVisit(TypeName const&) { - } void ASTJsonConverter::endVisit(ElementaryTypeName const&) { - } void ASTJsonConverter::endVisit(UserDefinedTypeName const&) { - } void ASTJsonConverter::endVisit(Mapping const&) { - } void ASTJsonConverter::endVisit(Statement const&) @@ -378,7 +371,6 @@ void ASTJsonConverter::endVisit(IfStatement const&) void ASTJsonConverter::endVisit(BreakableStatement const&) { - } void ASTJsonConverter::endVisit(WhileStatement const&) @@ -393,12 +385,10 @@ void ASTJsonConverter::endVisit(ForStatement const&) void ASTJsonConverter::endVisit(Continue const&) { - } void ASTJsonConverter::endVisit(Break const&) { - } void ASTJsonConverter::endVisit(Return const&) @@ -458,29 +448,24 @@ void ASTJsonConverter::endVisit(IndexAccess const&) void ASTJsonConverter::endVisit(PrimaryExpression const&) { - } void ASTJsonConverter::endVisit(Identifier const&) { - } void ASTJsonConverter::endVisit(ElementaryTypeNameExpression const&) { - } void ASTJsonConverter::endVisit(Literal const&) { - } -string const ASTJsonConverter::getType(Expression const& _expression) +string ASTJsonConverter::getType(Expression const& _expression) { return (_expression.getType()) ? _expression.getType()->toString() : "Unknown"; } - } } diff --git a/ASTJsonConverter.h b/ASTJsonConverter.h index 69030f399..7d9b9bc04 100644 --- a/ASTJsonConverter.h +++ b/ASTJsonConverter.h @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace dev @@ -39,8 +40,7 @@ namespace solidity class ASTJsonConverter: public ASTConstVisitor { public: - /// Create a converter for the given abstract syntax tree. If the source is specified, - /// the corresponding parts of the source are printed with each node. + /// Create a converter to JSON for the given abstract syntax tree. ASTJsonConverter(ASTNode const& _ast); /// Output the json representation of the AST to _stream. void print(std::ostream& _stream); @@ -118,11 +118,10 @@ private: void addJsonNode(std::string const& _nodeName, std::initializer_list> _list, bool _hasChildren); - std::string const getType(Expression const& _expression); + std::string getType(Expression const& _expression); inline void goUp() { - if (m_jsonNodePtrs.empty()) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal error")); + solAssert(!m_jsonNodePtrs.empty(), "Uneven json nodes stack. Internal error."); m_jsonNodePtrs.pop(); };