aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2019-01-10 23:28:39 +0800
committerchriseth <chris@ethereum.org>2019-01-18 03:36:48 +0800
commit2fcfb216b5dcb5cec2d70d2ee7647df47c8166ca (patch)
tree7e2db049befab49b3b0a22a9e325ca4f10614337 /libsolidity/analysis
parent44237211d1032c739636ab60a558521d60023b88 (diff)
downloaddexon-solidity-2fcfb216b5dcb5cec2d70d2ee7647df47c8166ca.tar.gz
dexon-solidity-2fcfb216b5dcb5cec2d70d2ee7647df47c8166ca.tar.zst
dexon-solidity-2fcfb216b5dcb5cec2d70d2ee7647df47c8166ca.zip
Syntax for meta type information.
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/GlobalContext.cpp9
-rw-r--r--libsolidity/analysis/TypeChecker.cpp40
-rw-r--r--libsolidity/analysis/TypeChecker.h2
-rw-r--r--libsolidity/analysis/ViewPureChecker.cpp4
4 files changed, 53 insertions, 2 deletions
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<shared_ptr<MagicVariableDeclaration const>>{
make_shared<MagicVariableDeclaration>("sha256", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::SHA256, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("sha3", make_shared<FunctionType>(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::KECCAK256, false, StateMutability::Pure)),
make_shared<MagicVariableDeclaration>("suicide", make_shared<FunctionType>(strings{"address payable"}, strings{}, FunctionType::Kind::Selfdestruct)),
- make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::Transaction))
+ make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::Transaction)),
+ make_shared<MagicVariableDeclaration>("type", make_shared<FunctionType>(
+ 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<ASTPointer<Expression const>> 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<TypeType const&>(*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<TypeType const&>(*firstArgType).actualType())};
+}
+
void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance)
{
auto base = dynamic_cast<ContractDefinition const*>(&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<MagicType const*>(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<MagicMember> static const payableMembers{
{MagicType::Kind::Message, "value"}