aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2019-01-18 07:16:06 +0800
committerGitHub <noreply@github.com>2019-01-18 07:16:06 +0800
commit2ec997e697e306dd54165aad365406ee88c534cb (patch)
tree5e943e23d38e332de3eedd33be11f2cf9df5fd69 /libsolidity/ast
parent0711873a2f13d7b0f27e268fcd0a7683665f339d (diff)
parent2a92403690a4998ab097503231ac39f854b9c76c (diff)
downloaddexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.gz
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.bz2
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.lz
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.xz
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.tar.zst
dexon-solidity-2ec997e697e306dd54165aad365406ee88c534cb.zip
Merge pull request #5775 from ethereum/codeAccess
Provide access to code of contract types.
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/AST.cpp5
-rw-r--r--libsolidity/ast/AST.h4
-rw-r--r--libsolidity/ast/Types.cpp50
-rw-r--r--libsolidity/ast/Types.h19
4 files changed, 69 insertions, 9 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index f379d758..4cf8b1e8 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -138,6 +138,11 @@ bool ContractDefinition::constructorIsPublic() const
return !f || f->isPublic();
}
+bool ContractDefinition::canBeDeployed() const
+{
+ return constructorIsPublic() && annotation().unimplementedFunctions.empty();
+}
+
FunctionDefinition const* ContractDefinition::fallbackFunction() const
{
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 9ac065ea..cd986050 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -408,6 +408,10 @@ public:
FunctionDefinition const* constructor() const;
/// @returns true iff the constructor of this contract is public (or non-existing).
bool constructorIsPublic() const;
+ /// @returns true iff the contract can be deployed, i.e. is not abstract and has a
+ /// public constructor.
+ /// Should only be called after the type checker has run.
+ bool canBeDeployed() const;
/// Returns the fallback function or nullptr if no fallback function was specified.
FunctionDefinition const* fallbackFunction() const;
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index cc978b4a..081c7fb6 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -2626,6 +2626,7 @@ string FunctionType::richIdentifier() const
case Kind::ABIEncodeWithSelector: id += "abiencodewithselector"; break;
case Kind::ABIEncodeWithSignature: id += "abiencodewithsignature"; break;
case Kind::ABIDecode: id += "abidecode"; break;
+ case Kind::MetaType: id += "metatype"; break;
}
id += "_" + stateMutabilityToString(m_stateMutability);
id += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes);
@@ -3037,7 +3038,8 @@ bool FunctionType::isPure() const
m_kind == Kind::ABIEncodePacked ||
m_kind == Kind::ABIEncodeWithSelector ||
m_kind == Kind::ABIEncodeWithSignature ||
- m_kind == Kind::ABIDecode;
+ m_kind == Kind::ABIDecode ||
+ m_kind == Kind::MetaType;
}
TypePointers FunctionType::parseElementaryTypeVector(strings const& _types)
@@ -3305,6 +3307,14 @@ string ModuleType::toString(bool) const
return string("module \"") + m_sourceUnit.annotation().path + string("\"");
}
+shared_ptr<MagicType> MagicType::metaType(TypePointer _type)
+{
+ solAssert(_type && _type->category() == Type::Category::Contract, "Only contracts supported for now.");
+ auto t = make_shared<MagicType>(Kind::MetaType);
+ t->m_typeArgument = std::move(_type);
+ return t;
+}
+
string MagicType::richIdentifier() const
{
switch (m_kind)
@@ -3317,6 +3327,9 @@ string MagicType::richIdentifier() const
return "t_magic_transaction";
case Kind::ABI:
return "t_magic_abi";
+ case Kind::MetaType:
+ solAssert(m_typeArgument, "");
+ return "t_magic_meta_type_" + m_typeArgument->richIdentifier();
}
return "";
}
@@ -3403,12 +3416,27 @@ MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
StateMutability::Pure
)}
});
- default:
- solAssert(false, "Unknown kind of magic.");
+ case Kind::MetaType:
+ {
+ solAssert(
+ m_typeArgument && m_typeArgument->category() == Type::Category::Contract,
+ "Only contracts supported for now"
+ );
+ ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_typeArgument).contractDefinition();
+ if (contract.canBeDeployed())
+ return MemberList::MemberMap({
+ {"creationCode", std::make_shared<ArrayType>(DataLocation::Memory)},
+ {"runtimeCode", std::make_shared<ArrayType>(DataLocation::Memory)}
+ });
+ else
+ return {};
+ }
}
+ solAssert(false, "Unknown kind of magic.");
+ return {};
}
-string MagicType::toString(bool) const
+string MagicType::toString(bool _short) const
{
switch (m_kind)
{
@@ -3420,7 +3448,17 @@ string MagicType::toString(bool) const
return "tx";
case Kind::ABI:
return "abi";
- default:
- solAssert(false, "Unknown kind of magic.");
+ case Kind::MetaType:
+ solAssert(m_typeArgument, "");
+ return "type(" + m_typeArgument->toString(_short) + ")";
}
+ solAssert(false, "Unknown kind of magic.");
+ return {};
+}
+
+TypePointer MagicType::typeArgument() const
+{
+ solAssert(m_kind == Kind::MetaType, "");
+ solAssert(m_typeArgument, "");
+ return m_typeArgument;
}
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index bee00661..53109de1 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -989,6 +989,7 @@ public:
ABIEncodeWithSignature,
ABIDecode,
GasLeft, ///< gasleft()
+ MetaType ///< type(...)
};
Category category() const override { return Category::Function; }
@@ -1299,16 +1300,23 @@ private:
};
/**
- * Special type for magic variables (block, msg, tx), similar to a struct but without any reference
- * (it always references a global singleton by name).
+ * Special type for magic variables (block, msg, tx, type(...)), similar to a struct but without any reference.
*/
class MagicType: public Type
{
public:
- enum class Kind { Block, Message, Transaction, ABI };
+ enum class Kind {
+ Block, ///< "block"
+ Message, ///< "msg"
+ Transaction, ///< "tx"
+ ABI, ///< "abi"
+ MetaType ///< "type(...)"
+ };
Category category() const override { return Category::Magic; }
explicit MagicType(Kind _kind): m_kind(_kind) {}
+ /// Factory function for meta type
+ static std::shared_ptr<MagicType> metaType(TypePointer _type);
TypeResult binaryOperatorResult(Token, TypePointer const&) const override
{
@@ -1327,8 +1335,13 @@ public:
Kind kind() const { return m_kind; }
+ TypePointer typeArgument() const;
+
private:
Kind m_kind;
+ /// Contract type used for contract metadata magic.
+ TypePointer m_typeArgument;
+
};
/**