From 8756c4bf962e92c09deaf025b84fefeb7d068e8f Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 16 Oct 2014 17:57:27 +0200 Subject: [PATCH] Type information for AST printer. --- libsolidity/ASTPrinter.cpp | 19 +++++++++++++++++++ libsolidity/ASTPrinter.h | 1 + libsolidity/Types.cpp | 9 +++++++++ libsolidity/Types.h | 31 ++++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index c512bd3f9..066088009 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -172,6 +172,7 @@ bool ASTPrinter::visit(VariableDefinition& _node) bool ASTPrinter::visit(Expression& _node) { writeLine("Expression"); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -179,6 +180,7 @@ bool ASTPrinter::visit(Expression& _node) bool ASTPrinter::visit(Assignment& _node) { writeLine(std::string("Assignment using operator ") + Token::toString(_node.getAssignmentOperator())); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -187,6 +189,7 @@ bool ASTPrinter::visit(UnaryOperation& _node) { writeLine(std::string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") + ") " + Token::toString(_node.getOperator())); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -194,6 +197,7 @@ bool ASTPrinter::visit(UnaryOperation& _node) bool ASTPrinter::visit(BinaryOperation& _node) { writeLine(std::string("BinaryOperation using operator ") + Token::toString(_node.getOperator())); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -201,6 +205,7 @@ bool ASTPrinter::visit(BinaryOperation& _node) bool ASTPrinter::visit(FunctionCall& _node) { writeLine("FunctionCall"); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -208,6 +213,7 @@ bool ASTPrinter::visit(FunctionCall& _node) bool ASTPrinter::visit(MemberAccess& _node) { writeLine("MemberAccess to member " + _node.getMemberName()); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -215,6 +221,7 @@ bool ASTPrinter::visit(MemberAccess& _node) bool ASTPrinter::visit(IndexAccess& _node) { writeLine("IndexAccess"); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -222,6 +229,7 @@ bool ASTPrinter::visit(IndexAccess& _node) bool ASTPrinter::visit(PrimaryExpression& _node) { writeLine("PrimaryExpression"); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -229,6 +237,7 @@ bool ASTPrinter::visit(PrimaryExpression& _node) bool ASTPrinter::visit(Identifier& _node) { writeLine(std::string("Identifier ") + _node.getName()); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -236,6 +245,7 @@ bool ASTPrinter::visit(Identifier& _node) bool ASTPrinter::visit(ElementaryTypeNameExpression& _node) { writeLine(std::string("ElementaryTypeNameExpression ") + Token::toString(_node.getTypeToken())); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -246,6 +256,7 @@ bool ASTPrinter::visit(Literal& _node) if (tokenString == nullptr) tokenString = "[no token]"; writeLine(std::string("Literal, token: ") + tokenString + " value: " + _node.getValue()); + printType(_node); printSourcePart(_node); return goDeeper(); } @@ -410,6 +421,14 @@ void ASTPrinter::printSourcePart(ASTNode const& _node) } } +void ASTPrinter::printType(Expression const& _expression) +{ + if (_expression.getType()) + *m_ostream << getIndentation() << " Type: " << _expression.getType()->toString() << "\n"; + else + *m_ostream << getIndentation() << " Type unknown.\n"; +} + std::string ASTPrinter::getIndentation() const { return std::string(m_indentation * 2, ' '); diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h index e8d125a54..14592e2b9 100644 --- a/libsolidity/ASTPrinter.h +++ b/libsolidity/ASTPrinter.h @@ -102,6 +102,7 @@ public: private: void printSourcePart(ASTNode const& _node); + void printType(Expression const& _expression); std::string getIndentation() const; void writeLine(std::string const& _line); bool goDeeper() { m_indentation++; return true; } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 7634951a1..ca393b7b9 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -22,6 +22,7 @@ #include #include +#include namespace dev { @@ -130,6 +131,14 @@ bool IntegerType::acceptsUnaryOperator(Token::Value _operator) const return _operator == Token::DELETE || (!isAddress() && _operator == Token::BIT_NOT); } +std::string IntegerType::toString() const +{ + if (isAddress()) + return "address"; + std::string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint"); + return prefix + dev::toString(m_bits); +} + bool BoolType::isExplicitlyConvertibleTo(Type const& _convertTo) const { // conversion to integer is fine, but not to address diff --git a/libsolidity/Types.h b/libsolidity/Types.h index e0c09bdcf..82b549433 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -59,6 +59,8 @@ public: } virtual bool acceptsBinaryOperator(Token::Value) const { return false; } virtual bool acceptsUnaryOperator(Token::Value) const { return false; } + + virtual std::string toString() const = 0; }; class IntegerType: public Type @@ -68,7 +70,7 @@ public: { UNSIGNED, SIGNED, HASH, ADDRESS }; - virtual Category getCategory() const { return Category::INTEGER; } + virtual Category getCategory() const override { return Category::INTEGER; } static std::shared_ptr smallestTypeForLiteral(std::string const& _literal); @@ -79,6 +81,8 @@ public: virtual bool acceptsBinaryOperator(Token::Value _operator) const override; virtual bool acceptsUnaryOperator(Token::Value _operator) const override; + virtual std::string toString() const override; + int getNumBits() const { return m_bits; } bool isHash() const { return m_modifier == Modifier::HASH || m_modifier == Modifier::ADDRESS; } bool isAddress() const { return m_modifier == Modifier::ADDRESS; } @@ -106,15 +110,18 @@ public: { return _operator == Token::NOT || _operator == Token::DELETE; } + virtual std::string toString() const override { return "bool"; } }; class ContractType: public Type { public: - virtual Category getCategory() const { return Category::CONTRACT; } + virtual Category getCategory() const override { return Category::CONTRACT; } ContractType(ContractDefinition const& _contract): m_contract(_contract) {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const; + virtual std::string toString() const override { return "contract{...}"; } + private: ContractDefinition const& m_contract; }; @@ -122,7 +129,7 @@ private: class StructType: public Type { public: - virtual Category getCategory() const { return Category::STRUCT; } + virtual Category getCategory() const override { return Category::STRUCT; } StructType(StructDefinition const& _struct): m_struct(_struct) {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const; virtual bool acceptsUnaryOperator(Token::Value _operator) const override @@ -130,6 +137,9 @@ public: return _operator == Token::DELETE; } + + virtual std::string toString() const override { return "struct{...}"; } + private: StructDefinition const& m_struct; }; @@ -137,11 +147,13 @@ private: class FunctionType: public Type { public: - virtual Category getCategory() const { return Category::FUNCTION; } + virtual Category getCategory() const override { return Category::FUNCTION; } FunctionType(FunctionDefinition const& _function): m_function(_function) {} FunctionDefinition const& getFunction() const { return m_function; } + virtual std::string toString() const override { return "function(...)returns(...)"; } + private: FunctionDefinition const& m_function; }; @@ -149,8 +161,10 @@ private: class MappingType: public Type { public: - virtual Category getCategory() const { return Category::MAPPING; } + virtual Category getCategory() const override { return Category::MAPPING; } MappingType() {} + virtual std::string toString() const override { return "mapping(...=>...)"; } + private: //@todo }; @@ -159,18 +173,21 @@ private: class VoidType: public Type { public: - virtual Category getCategory() const { return Category::VOID; } + virtual Category getCategory() const override { return Category::VOID; } VoidType() {} + virtual std::string toString() const override { return "void"; } }; class TypeType: public Type { public: - virtual Category getCategory() const { return Category::TYPE; } + virtual Category getCategory() const override { return Category::TYPE; } TypeType(std::shared_ptr const& _actualType): m_actualType(_actualType) {} std::shared_ptr const& getActualType() const { return m_actualType; } + virtual std::string toString() const override { return "type(" + m_actualType->toString() + ")"; } + private: std::shared_ptr m_actualType; };