diff options
author | chriseth <c@ethdev.com> | 2017-01-17 17:47:44 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2017-01-19 20:23:57 +0800 |
commit | 3fed790a56cea7bae481d01c15949aa500823968 (patch) | |
tree | 743218058ccf6527513b628657f70af3487750db /libsolidity/ast/Types.cpp | |
parent | ba7dcbc15ef3ee900a4adc00e421983d6256c91c (diff) | |
download | dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.tar dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.tar.gz dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.tar.bz2 dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.tar.lz dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.tar.xz dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.tar.zst dexon-solidity-3fed790a56cea7bae481d01c15949aa500823968.zip |
Type identifiers.
Diffstat (limited to 'libsolidity/ast/Types.cpp')
-rw-r--r-- | libsolidity/ast/Types.cpp | 189 |
1 files changed, 186 insertions, 3 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 03ff8471..9e722474 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -272,7 +272,15 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier): solAssert( m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0, "Invalid bit number for integer type: " + dev::toString(_bits) - ); + ); +} + +string IntegerType::identifier() const +{ + if (isAddress()) + return "t_address"; + else + return "t_" + string(isSigned() ? "" : "u") + "int" + std::to_string(numBits()); } bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -412,7 +420,12 @@ FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPoint m_fractionalBits % 8 == 0, "Invalid bit number(s) for fixed type: " + dev::toString(_integerBits) + "x" + dev::toString(_fractionalBits) - ); + ); +} + +string FixedPointType::identifier() const +{ + return "t_" + string(isSigned() ? "" : "u") + "fixed" + std::to_string(integerBits()) + "x" + std::to_string(fractionalBits()); } bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -770,6 +783,11 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ } } +string RationalNumberType::identifier() const +{ + return "t_rational_" + m_value.numerator().str() + "_by_" + m_value.denominator().str(); +} + bool RationalNumberType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -909,6 +927,13 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const return false; } +string StringLiteralType::identifier() const +{ + // Since we have to return a valid identifier and the string itself may contain + // anything, we hash it. + return "t_stringliteral_" + toHex(keccak256(m_value).asBytes()); +} + bool StringLiteralType::operator==(const Type& _other) const { if (_other.category() != category()) @@ -1002,6 +1027,11 @@ MemberList::MemberMap FixedBytesType::nativeMembers(const ContractDefinition*) c return MemberList::MemberMap{MemberList::Member{"length", make_shared<IntegerType>(8)}}; } +string FixedBytesType::identifier() const +{ + return "t_bytes" + std::to_string(m_bytes); +} + bool FixedBytesType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -1115,6 +1145,20 @@ string ReferenceType::stringForReferencePart() const return ""; } +string ReferenceType::identifierLocationSuffix() const +{ + string id; + if (location() == DataLocation::Storage) + id += "_storage"; + else if (location() == DataLocation::Memory) + id += "_memory"; + else + id += "_calldata"; + if (isPointer()) + id += "_ptr"; + return id; +} + bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const { if (_convertTo.category() != category()) @@ -1170,6 +1214,26 @@ bool ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const return true; } +string ArrayType::identifier() const +{ + string id; + if (isString()) + id += "t_string"; + else if (isByteArray()) + id += "t_bytes"; + else + { + id = baseType()->identifier(); + if (isDynamicallySized()) + id += "_arraydyn"; + else + id += string("_array") + length().str(); + } + id += identifierLocationSuffix(); + + return id; +} + bool ArrayType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -1184,7 +1248,7 @@ bool ArrayType::operator==(Type const& _other) const return false; if (*other.baseType() != *baseType()) return false; - return isDynamicallySized() || length() == other.length(); + return isDynamicallySized() || length() == other.length(); } unsigned ArrayType::calldataEncodedSize(bool _padded) const @@ -1356,6 +1420,11 @@ TypePointer ArrayType::copyForLocation(DataLocation _location, bool _isPointer) return copy; } +string ContractType::identifier() const +{ + return (m_super ? "t_super_" : "t_contract_") + m_contract.name() + "_" + std::to_string(m_contract.id()); +} + bool ContractType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -1465,6 +1534,11 @@ bool StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const return this->m_struct == convertTo.m_struct; } +string StructType::identifier() const +{ + return "t_struct_" + m_struct.name() + "_" + std::to_string(m_struct.id()) + identifierLocationSuffix(); +} + bool StructType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -1605,6 +1679,11 @@ TypePointer EnumType::unaryOperatorResult(Token::Value _operator) const return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer(); } +string EnumType::identifier() const +{ + return "t_enum_" + m_enum.name() + "_" + std::to_string(m_enum.id()); +} + bool EnumType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -1686,6 +1765,18 @@ bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const return false; } +string TupleType::identifier() const +{ + string id = "t_tuple" + std::to_string(components().size()) + "_"; + for (auto const& c: components()) + if (c) + id += c->identifier() + "_"; + else + id += "t_empty_"; + id += "tuple_end"; + return id; +} + bool TupleType::operator==(Type const& _other) const { if (auto tupleType = dynamic_cast<TupleType const*>(&_other)) @@ -1934,6 +2025,59 @@ TypePointers FunctionType::parameterTypes() const return TypePointers(m_parameterTypes.cbegin() + 1, m_parameterTypes.cend()); } +string FunctionType::identifier() const +{ + string id = "t_function_"; + switch (location()) + { + case Location::Internal: id += "internal"; break; + case Location::External: id += "external"; break; + case Location::CallCode: id += "callcode"; break; + case Location::DelegateCall: id += "delegatecall"; break; + case Location::Bare: id += "bare"; break; + case Location::BareCallCode: id += "barecallcode"; break; + case Location::BareDelegateCall: id += "baredelegatecall"; break; + case Location::Creation: id += "creation"; break; + case Location::Send: id += "send"; break; + case Location::SHA3: id += "sha3"; break; + case Location::Selfdestruct: id += "selfdestruct"; break; + case Location::ECRecover: id += "ecrecover"; break; + case Location::SHA256: id += "sha256"; break; + case Location::RIPEMD160: id += "ripemd160"; break; + case Location::Log0: id += "log0"; break; + case Location::Log1: id += "log1"; break; + case Location::Log2: id += "log2"; break; + case Location::Log3: id += "log3"; break; + case Location::Log4: id += "log4"; break; + case Location::Event: id += "event"; break; + case Location::SetGas: id += "setgas"; break; + case Location::SetValue: id += "setvalue"; break; + case Location::BlockHash: id += "blockhash"; break; + case Location::AddMod: id += "addmod"; break; + case Location::MulMod: id += "mulmod"; break; + case Location::ArrayPush: id += "arraypush"; break; + case Location::ByteArrayPush: id += "bytearraypush"; break; + case Location::ObjectCreation: id += "objectcreation"; break; + default: solAssert(false, "Unknown function location."); break; + } + if (isConstant()) + id += "_constant"; + id += "_param" + std::to_string(m_parameterTypes.size()) + "_"; + for (auto const& p: m_parameterTypes) + id += p->identifier() + "_"; + id += "return" + std::to_string(m_returnParameterTypes.size()) + "_"; + for (auto const& r: m_returnParameterTypes) + id += r->identifier() + "_"; + if (m_gasSet) + id += "gas_set_"; + if (m_valueSet) + id += "value_set_"; + if (bound()) + id += "bound_to" + selfType()->identifier() + "_"; + id += "function_end"; + return id; +} + bool FunctionType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -2354,6 +2498,11 @@ ASTPointer<ASTString> FunctionType::documentation() const return ASTPointer<ASTString>(); } +string MappingType::identifier() const +{ + return "t_mapping_" + m_keyType->identifier() + "_to_" + m_valueType->identifier() + "_mapping_end"; +} + bool MappingType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -2372,6 +2521,11 @@ string MappingType::canonicalName(bool) const return "mapping(" + keyType()->canonicalName(false) + " => " + valueType()->canonicalName(false) + ")"; } +string TypeType::identifier() const +{ + return "t_type_" + actualType()->identifier(); +} + bool TypeType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -2456,6 +2610,14 @@ u256 ModifierType::storageSize() const << errinfo_comment("Storage size of non-storable type type requested.")); } +string ModifierType::identifier() const +{ + string id = "t_modifier_param" + std::to_string(m_parameterTypes.size()) + "_"; + for (auto const& p: m_parameterTypes) + id += p->identifier() + "_"; + return id + "end_modifier"; +} + bool ModifierType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -2480,6 +2642,11 @@ string ModifierType::toString(bool _short) const return name + ")"; } +string ModuleType::identifier() const +{ + return "t_module_" + std::to_string(m_sourceUnit.id()); +} + bool ModuleType::operator==(Type const& _other) const { if (_other.category() != category()) @@ -2501,6 +2668,22 @@ string ModuleType::toString(bool) const return string("module \"") + m_sourceUnit.annotation().path + string("\""); } +string MagicType::identifier() const +{ + switch (m_kind) + { + case Kind::Block: + return "t_magic_block"; + case Kind::Message: + return "t_magic_message"; + case Kind::Transaction: + return "t_magic_transaction"; + default: + solAssert(false, "Unknown kind of magic"); + } + return ""; +} + bool MagicType::operator==(Type const& _other) const { if (_other.category() != category()) |