solidity/ASTPrinter.cpp

446 lines
8.3 KiB
C++
Raw Normal View History

2014-10-13 15:13:48 +00:00
/*
2014-10-16 12:08:54 +00:00
This file is part of cpp-ethereum.
2014-10-13 15:13:48 +00:00
2014-10-16 12:08:54 +00:00
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.
2014-10-13 15:13:48 +00:00
2014-10-16 12:08:54 +00:00
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.
2014-10-13 15:13:48 +00:00
2014-10-16 12:08:54 +00:00
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
2014-10-13 15:13:48 +00:00
*/
/**
* @author Christian <c@ethdev.com>
* @date 2014
* Pretty-printer for the abstract syntax tree (the "pretty" is arguable), used for debugging.
*/
#include <libsolidity/ASTPrinter.h>
#include <libsolidity/AST.h>
2014-10-24 17:06:30 +00:00
using namespace std;
2014-10-16 12:08:54 +00:00
namespace dev
{
namespace solidity
{
2014-10-24 17:06:30 +00:00
ASTPrinter::ASTPrinter(ASTPointer<ASTNode> const& _ast, string const& _source):
2014-10-22 22:24:07 +00:00
m_indentation(0), m_source(_source), m_ast(_ast)
{
}
2014-10-24 17:06:30 +00:00
void ASTPrinter::print(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)
{
2014-10-24 17:06:30 +00:00
writeLine(string("ElementaryTypeName ") + Token::toString(_node.getTypeName()));
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");
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(Assignment& _node)
{
2014-10-24 17:06:30 +00:00
writeLine(string("Assignment using operator ") + Token::toString(_node.getAssignmentOperator()));
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(UnaryOperation& _node)
{
2014-10-24 17:06:30 +00:00
writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") +
2014-10-16 12:08:54 +00:00
") " + Token::toString(_node.getOperator()));
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(BinaryOperation& _node)
{
2014-10-24 17:06:30 +00:00
writeLine(string("BinaryOperation using operator ") + Token::toString(_node.getOperator()));
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(FunctionCall& _node)
{
writeLine("FunctionCall");
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(MemberAccess& _node)
{
writeLine("MemberAccess to member " + _node.getMemberName());
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(IndexAccess& _node)
{
writeLine("IndexAccess");
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(PrimaryExpression& _node)
{
writeLine("PrimaryExpression");
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
2014-10-13 13:07:21 +00:00
bool ASTPrinter::visit(Identifier& _node)
{
2014-10-24 17:06:30 +00:00
writeLine(string("Identifier ") + _node.getName());
2014-10-16 15:57:27 +00:00
printType(_node);
2014-10-13 13:07:21 +00:00
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(ElementaryTypeNameExpression& _node)
{
2014-10-24 17:06:30 +00:00
writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.getTypeToken()));
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
bool ASTPrinter::visit(Literal& _node)
{
char const* tokenString = Token::toString(_node.getToken());
2014-10-24 14:43:11 +00:00
if (!tokenString)
2014-10-16 21:49:45 +00:00
tokenString = "[no token]";
2014-10-24 17:06:30 +00:00
writeLine(string("Literal, token: ") + tokenString + " value: " + _node.getValue());
2014-10-16 15:57:27 +00:00
printType(_node);
printSourcePart(_node);
return goDeeper();
}
void ASTPrinter::endVisit(ASTNode&)
{
m_indentation--;
}
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--;
}
2014-10-13 13:07:21 +00:00
void ASTPrinter::endVisit(Identifier&)
{
m_indentation--;
}
void ASTPrinter::endVisit(ElementaryTypeNameExpression&)
{
m_indentation--;
}
void ASTPrinter::endVisit(Literal&)
{
m_indentation--;
}
void ASTPrinter::printSourcePart(ASTNode const& _node)
{
2014-10-16 12:08:54 +00:00
if (!m_source.empty())
{
Location const& location(_node.getLocation());
*m_ostream << getIndentation() << " Source: |"
2014-10-24 17:06:30 +00:00
<< m_source.substr(location.start, location.end - location.start) << "|" << endl;
}
}
2014-10-16 15:57:27 +00:00
void ASTPrinter::printType(Expression const& _expression)
{
if (_expression.getType())
*m_ostream << getIndentation() << " Type: " << _expression.getType()->toString() << "\n";
else
*m_ostream << getIndentation() << " Type unknown.\n";
}
2014-10-24 17:06:30 +00:00
string ASTPrinter::getIndentation() const
{
2014-10-24 17:06:30 +00:00
return string(m_indentation * 2, ' ');
}
2014-10-24 17:06:30 +00:00
void ASTPrinter::writeLine(string const& _line)
{
2014-10-24 17:06:30 +00:00
*m_ostream << getIndentation() << _line << endl;
}
2014-10-16 12:08:54 +00:00
}
}