From 2fcfb216b5dcb5cec2d70d2ee7647df47c8166ca Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 10 Jan 2019 16:28:39 +0100 Subject: Syntax for meta type information. --- libsolidity/analysis/GlobalContext.cpp | 9 ++++++- libsolidity/analysis/TypeChecker.cpp | 40 ++++++++++++++++++++++++++++++++ libsolidity/analysis/TypeChecker.h | 2 ++ libsolidity/analysis/ViewPureChecker.cpp | 4 +++- 4 files changed, 53 insertions(+), 2 deletions(-) (limited to 'libsolidity/analysis') diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp index cd5fe07d..2276d783 100644 --- a/libsolidity/analysis/GlobalContext.cpp +++ b/libsolidity/analysis/GlobalContext.cpp @@ -61,7 +61,14 @@ m_magicVariables(vector>{ make_shared("sha256", make_shared(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA256, false, StateMutability::Pure)), make_shared("sha3", make_shared(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::KECCAK256, false, StateMutability::Pure)), make_shared("suicide", make_shared(strings{"address payable"}, strings{}, FunctionType::Kind::Selfdestruct)), - make_shared("tx", make_shared(MagicType::Kind::Transaction)) + make_shared("tx", make_shared(MagicType::Kind::Transaction)), + make_shared("type", make_shared( + strings{"address"} /* accepts any contract type, handled by the type checker */, + strings{} /* returns a MagicType, handled by the type checker */, + FunctionType::Kind::MetaType, + false, + StateMutability::Pure + )), }) { } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 507a2c94..4cdfcc0c 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -199,6 +199,38 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c return components; } +TypePointers TypeChecker::typeCheckMetaTypeFunctionAndRetrieveReturnType(FunctionCall const& _functionCall) +{ + vector> arguments = _functionCall.arguments(); + if (arguments.size() != 1) + { + m_errorReporter.typeError( + _functionCall.location(), + "This function takes one argument, but " + + toString(arguments.size()) + + " were provided." + ); + return {}; + } + TypePointer firstArgType = type(*arguments.front()); + if ( + firstArgType->category() != Type::Category::TypeType || + dynamic_cast(*firstArgType).actualType()->category() != TypeType::Category::Contract + ) + { + m_errorReporter.typeError( + arguments.front()->location(), + "Invalid type for argument in function call. " + "Contract type required, but " + + type(*arguments.front())->toString(true) + + " provided." + ); + return {}; + } + + return {MagicType::metaType(dynamic_cast(*firstArgType).actualType())}; +} + void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) { auto base = dynamic_cast(&dereference(_inheritance.name())); @@ -1822,6 +1854,9 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) returnTypes = functionType->returnParameterTypes(); break; } + case FunctionType::Kind::MetaType: + returnTypes = typeCheckMetaTypeFunctionAndRetrieveReturnType(_functionCall); + break; default: { typeCheckFunctionCall(_functionCall, functionType); @@ -2062,8 +2097,13 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (tt->actualType()->category() == Type::Category::Enum) annotation.isPure = true; if (auto magicType = dynamic_cast(exprType.get())) + { if (magicType->kind() == MagicType::Kind::ABI) annotation.isPure = true; + else if (magicType->kind() == MagicType::Kind::MetaType) + if (memberName == "creationCode" || memberName == "runtimeCode") + annotation.isPure = true; + } return false; } diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index b60c571a..d5f3645c 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -81,6 +81,8 @@ private: bool _abiEncoderV2 ); + TypePointers typeCheckMetaTypeFunctionAndRetrieveReturnType(FunctionCall const& _functionCall); + /// Performs type checks and determines result types for type conversion FunctionCall nodes. TypePointer typeCheckTypeConversionAndRetrieveReturnType( FunctionCall const& _functionCall diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index eb019481..7df7ac17 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -338,7 +338,9 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess) {MagicType::Kind::ABI, "encodeWithSignature"}, {MagicType::Kind::Block, "blockhash"}, {MagicType::Kind::Message, "data"}, - {MagicType::Kind::Message, "sig"} + {MagicType::Kind::Message, "sig"}, + {MagicType::Kind::MetaType, "creationCode"}, + {MagicType::Kind::MetaType, "runtimeCode"} }; set static const payableMembers{ {MagicType::Kind::Message, "value"} -- cgit