Types for UserDefinedValueType

This commit is contained in:
hrkrshnn 2021-08-12 17:06:38 +02:00
parent 9f7426b4a9
commit 15452371d4
4 changed files with 117 additions and 1 deletions

View File

@ -578,3 +578,8 @@ MappingType const* TypeProvider::mapping(Type const* _keyType, Type const* _valu
{
return createAndGet<MappingType>(_keyType, _valueType);
}
UserDefinedValueType const* TypeProvider::userDefinedValueType(UserDefinedValueTypeDefinition const& _definition)
{
return createAndGet<UserDefinedValueType>(_definition);
}

View File

@ -201,6 +201,8 @@ public:
static MappingType const* mapping(Type const* _keyType, Type const* _valueType);
static UserDefinedValueType const* userDefinedValueType(UserDefinedValueTypeDefinition const& _definition);
private:
/// Global TypeProvider instance.
static TypeProvider& instance()

View File

@ -2533,6 +2533,36 @@ unsigned EnumType::memberValue(ASTString const& _member) const
solAssert(false, "Requested unknown enum value " + _member);
}
Type const& UserDefinedValueType::underlyingType() const
{
Type const* type = m_definition.underlyingType()->annotation().type;
solAssert(type, "");
return *type;
}
string UserDefinedValueType::richIdentifier() const
{
return "t_userDefinedValueType" + parenthesizeIdentifier(m_definition.name()) + to_string(m_definition.id());
}
bool UserDefinedValueType::operator==(Type const& _other) const
{
if (_other.category() != category())
return false;
UserDefinedValueType const& other = dynamic_cast<UserDefinedValueType const&>(_other);
return other.definition() == definition();
}
string UserDefinedValueType::toString(bool /* _short */) const
{
return "user defined type " + definition().name();
}
vector<tuple<string, Type const*>> UserDefinedValueType::makeStackItems() const
{
return underlyingType().stackItems();
}
BoolResult TupleType::isImplicitlyConvertibleTo(Type const& _other) const
{
if (auto tupleType = dynamic_cast<TupleType const*>(&_other))
@ -2884,6 +2914,8 @@ string FunctionType::richIdentifier() const
case Kind::GasLeft: id += "gasleft"; break;
case Kind::Event: id += "event"; break;
case Kind::Error: id += "error"; break;
case Kind::Wrap: id += "wrap"; break;
case Kind::Unwrap: id += "unwrap"; break;
case Kind::SetGas: id += "setgas"; break;
case Kind::SetValue: id += "setvalue"; break;
case Kind::BlockHash: id += "blockhash"; break;
@ -3754,6 +3786,34 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons
for (ASTPointer<EnumValue> const& enumValue: enumDef.members())
members.emplace_back(enumValue.get(), enumType);
}
else if (m_actualType->category() == Category::UserDefinedValueType)
{
auto& userDefined = dynamic_cast<UserDefinedValueType const&>(*m_actualType);
members.emplace_back(
"wrap",
TypeProvider::function(
TypePointers{&userDefined.underlyingType()},
TypePointers{&userDefined},
strings{string{}},
strings{string{}},
FunctionType::Kind::Wrap,
false, /*_arbitraryParameters */
StateMutability::Pure
)
);
members.emplace_back(
"unwrap",
TypeProvider::function(
TypePointers{&userDefined},
TypePointers{&userDefined.underlyingType()},
strings{string{}},
strings{string{}},
FunctionType::Kind::Unwrap,
false, /* _arbitraryParameters */
StateMutability::Pure
)
);
}
else if (
auto const* arrayType = dynamic_cast<ArrayType const*>(m_actualType);
arrayType && arrayType->isByteArray()

View File

@ -174,7 +174,7 @@ public:
enum class Category
{
Address, Integer, RationalNumber, StringLiteral, Bool, FixedPoint, Array, ArraySlice,
FixedBytes, Contract, Struct, Function, Enum, Tuple,
FixedBytes, Contract, Struct, Function, Enum, UserDefinedValueType, Tuple,
Mapping, TypeType, Modifier, Magic, Module,
InaccessibleDynamic
};
@ -1082,6 +1082,53 @@ private:
EnumDefinition const& m_enum;
};
/**
* The type of a UserDefinedValueType.
*/
class UserDefinedValueType: public Type
{
public:
explicit UserDefinedValueType(UserDefinedValueTypeDefinition const& _definition):
m_definition(_definition)
{}
Category category() const override { return Category::UserDefinedValueType; }
Type const& underlyingType() const;
UserDefinedValueTypeDefinition const& definition() const { return m_definition; }
TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
Type const* encodingType() const override { return &underlyingType(); }
TypeResult interfaceType(bool /* _inLibrary */) const override {return &underlyingType(); }
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;
unsigned calldataEncodedSize(bool _padded) const override { return underlyingType().calldataEncodedSize(_padded); }
bool leftAligned() const override { return underlyingType().leftAligned(); }
bool canBeStored() const override { return underlyingType().canBeStored(); }
u256 storageSize() const override { return underlyingType().storageSize(); }
bool isValueType() const override
{
solAssert(underlyingType().isValueType(), "");
return true;
}
bool nameable() const override
{
solAssert(underlyingType().nameable(), "");
return true;
}
std::string toString(bool _short) const override;
std::string canonicalName() const override { solAssert(false, ""); }
std::string signatureInExternalFunction(bool) const override { solAssert(false, ""); }
protected:
std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
private:
UserDefinedValueTypeDefinition const& m_definition;
};
/**
* Type that can hold a finite sequence of values of different types.
* In some cases, the components are empty pointers (when used as placeholders).
@ -1150,6 +1197,8 @@ public:
RIPEMD160, ///< CALL to special contract for ripemd160
Event, ///< syntactic sugar for LOG*
Error, ///< creating an error instance in revert or require
Wrap, ///< customType.wrap(...) for user defined value types
Unwrap, ///< customType.unwrap(...) for user defined value types
SetGas, ///< modify the default gas value for the function call
SetValue, ///< modify the default value transfer for the function call
BlockHash, ///< BLOCKHASH