mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #1576 from ethereum/typeIdentifiers
Type identifiers.
This commit is contained in:
commit
12b002b3b8
@ -3,6 +3,7 @@
|
|||||||
Features:
|
Features:
|
||||||
* Compiler Interface: Contracts and libraries can be referenced with a `file:` prefix to make them unique.
|
* Compiler Interface: Contracts and libraries can be referenced with a `file:` prefix to make them unique.
|
||||||
* AST: Use deterministic node identifiers.
|
* AST: Use deterministic node identifiers.
|
||||||
|
* Type system: Introduce type identifier strings.
|
||||||
* Metadata: Do not include platform in the version number.
|
* Metadata: Do not include platform in the version number.
|
||||||
|
|
||||||
### 0.4.8 (2017-01-13)
|
### 0.4.8 (2017-01-13)
|
||||||
|
@ -34,11 +34,24 @@ using namespace std;
|
|||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace dev::solidity;
|
using namespace dev::solidity;
|
||||||
|
|
||||||
|
class IDDispenser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static size_t next() { return ++instance(); }
|
||||||
|
static void reset() { instance() = 0; }
|
||||||
|
private:
|
||||||
|
static size_t& instance()
|
||||||
|
{
|
||||||
|
static IDDispenser dispenser;
|
||||||
|
return dispenser.id;
|
||||||
|
}
|
||||||
|
size_t id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
ASTNode::ASTNode(SourceLocation const& _location):
|
ASTNode::ASTNode(SourceLocation const& _location):
|
||||||
|
m_id(IDDispenser::next()),
|
||||||
m_location(_location)
|
m_location(_location)
|
||||||
{
|
{
|
||||||
static size_t id = 0;
|
|
||||||
m_id = ++id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNode::~ASTNode()
|
ASTNode::~ASTNode()
|
||||||
@ -46,6 +59,11 @@ ASTNode::~ASTNode()
|
|||||||
delete m_annotation;
|
delete m_annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ASTNode::resetID()
|
||||||
|
{
|
||||||
|
IDDispenser::reset();
|
||||||
|
}
|
||||||
|
|
||||||
ASTAnnotation& ASTNode::annotation() const
|
ASTAnnotation& ASTNode::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
|
@ -59,6 +59,8 @@ public:
|
|||||||
|
|
||||||
/// @returns an identifier of this AST node that is unique for a single compilation run.
|
/// @returns an identifier of this AST node that is unique for a single compilation run.
|
||||||
size_t id() const { return m_id; }
|
size_t id() const { return m_id; }
|
||||||
|
/// Resets the global ID counter. This invalidates all previous IDs.
|
||||||
|
static void resetID();
|
||||||
|
|
||||||
virtual void accept(ASTVisitor& _visitor) = 0;
|
virtual void accept(ASTVisitor& _visitor) = 0;
|
||||||
virtual void accept(ASTConstVisitor& _visitor) const = 0;
|
virtual void accept(ASTConstVisitor& _visitor) const = 0;
|
||||||
@ -97,7 +99,7 @@ public:
|
|||||||
///@}
|
///@}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t m_id = 0;
|
size_t const m_id = 0;
|
||||||
/// Annotation - is specialised in derived classes, is created upon request (because of polymorphism).
|
/// Annotation - is specialised in derived classes, is created upon request (because of polymorphism).
|
||||||
mutable ASTAnnotation* m_annotation = nullptr;
|
mutable ASTAnnotation* m_annotation = nullptr;
|
||||||
|
|
||||||
|
@ -21,15 +21,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libsolidity/ast/Types.h>
|
#include <libsolidity/ast/Types.h>
|
||||||
#include <limits>
|
|
||||||
#include <boost/range/adaptor/reversed.hpp>
|
#include <libsolidity/interface/Utils.h>
|
||||||
#include <boost/range/adaptor/sliced.hpp>
|
#include <libsolidity/ast/AST.h>
|
||||||
|
|
||||||
#include <libdevcore/CommonIO.h>
|
#include <libdevcore/CommonIO.h>
|
||||||
#include <libdevcore/CommonData.h>
|
#include <libdevcore/CommonData.h>
|
||||||
#include <libdevcore/SHA3.h>
|
#include <libdevcore/SHA3.h>
|
||||||
#include <libdevcore/UTF8.h>
|
#include <libdevcore/UTF8.h>
|
||||||
#include <libsolidity/interface/Utils.h>
|
|
||||||
#include <libsolidity/ast/AST.h>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
#include <boost/range/adaptor/sliced.hpp>
|
||||||
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
@ -117,6 +124,51 @@ u256 const& MemberList::storageSize() const
|
|||||||
return m_storageOffsets->storageSize();
|
return m_storageOffsets->storageSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper functions for type identifier
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
string parenthesizeIdentifier(string const& _internal)
|
||||||
|
{
|
||||||
|
return "$_" + _internal + "_$";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Range>
|
||||||
|
string identifierList(Range const&& _list)
|
||||||
|
{
|
||||||
|
return parenthesizeIdentifier(boost::algorithm::join(_list, "_$_"));
|
||||||
|
}
|
||||||
|
|
||||||
|
string identifier(TypePointer const& _type)
|
||||||
|
{
|
||||||
|
return _type ? _type->identifier() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string identifierList(vector<TypePointer> const& _list)
|
||||||
|
{
|
||||||
|
return identifierList(_list | boost::adaptors::transformed(identifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
string identifierList(TypePointer const& _type)
|
||||||
|
{
|
||||||
|
return parenthesizeIdentifier(identifier(_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
string identifierList(TypePointer const& _type1, TypePointer const& _type2)
|
||||||
|
{
|
||||||
|
TypePointers list;
|
||||||
|
list.push_back(_type1);
|
||||||
|
list.push_back(_type2);
|
||||||
|
return identifierList(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
string parenthesizeUserIdentifier(string const& _internal)
|
||||||
|
{
|
||||||
|
return parenthesizeIdentifier(boost::algorithm::replace_all_copy(_internal, "$", "$$$"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
||||||
{
|
{
|
||||||
solAssert(Token::isElementaryTypeName(_type.token()),
|
solAssert(Token::isElementaryTypeName(_type.token()),
|
||||||
@ -272,7 +324,15 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
|
|||||||
solAssert(
|
solAssert(
|
||||||
m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0,
|
m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0,
|
||||||
"Invalid bit number for integer type: " + dev::toString(_bits)
|
"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
|
bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
@ -412,7 +472,12 @@ FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPoint
|
|||||||
m_fractionalBits % 8 == 0,
|
m_fractionalBits % 8 == 0,
|
||||||
"Invalid bit number(s) for fixed type: " +
|
"Invalid bit number(s) for fixed type: " +
|
||||||
dev::toString(_integerBits) + "x" + dev::toString(_fractionalBits)
|
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
|
bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
@ -770,6 +835,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
|
bool RationalNumberType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -909,6 +979,13 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return false;
|
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
|
bool StringLiteralType::operator==(const Type& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -1002,6 +1079,11 @@ MemberList::MemberMap FixedBytesType::nativeMembers(const ContractDefinition*) c
|
|||||||
return MemberList::MemberMap{MemberList::Member{"length", make_shared<IntegerType>(8)}};
|
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
|
bool FixedBytesType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -1115,6 +1197,20 @@ string ReferenceType::stringForReferencePart() const
|
|||||||
return "";
|
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
|
bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||||
{
|
{
|
||||||
if (_convertTo.category() != category())
|
if (_convertTo.category() != category())
|
||||||
@ -1170,6 +1266,27 @@ bool ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ArrayType::identifier() const
|
||||||
|
{
|
||||||
|
string id;
|
||||||
|
if (isString())
|
||||||
|
id = "t_string";
|
||||||
|
else if (isByteArray())
|
||||||
|
id = "t_bytes";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = "t_array";
|
||||||
|
id += identifierList(baseType());
|
||||||
|
if (isDynamicallySized())
|
||||||
|
id += "dyn";
|
||||||
|
else
|
||||||
|
id += length().str();
|
||||||
|
}
|
||||||
|
id += identifierLocationSuffix();
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
bool ArrayType::operator==(Type const& _other) const
|
bool ArrayType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -1184,7 +1301,7 @@ bool ArrayType::operator==(Type const& _other) const
|
|||||||
return false;
|
return false;
|
||||||
if (*other.baseType() != *baseType())
|
if (*other.baseType() != *baseType())
|
||||||
return false;
|
return false;
|
||||||
return isDynamicallySized() || length() == other.length();
|
return isDynamicallySized() || length() == other.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ArrayType::calldataEncodedSize(bool _padded) const
|
unsigned ArrayType::calldataEncodedSize(bool _padded) const
|
||||||
@ -1356,6 +1473,11 @@ TypePointer ArrayType::copyForLocation(DataLocation _location, bool _isPointer)
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ContractType::identifier() const
|
||||||
|
{
|
||||||
|
return (m_super ? "t_super" : "t_contract") + parenthesizeUserIdentifier(m_contract.name()) + std::to_string(m_contract.id());
|
||||||
|
}
|
||||||
|
|
||||||
bool ContractType::operator==(Type const& _other) const
|
bool ContractType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -1465,6 +1587,11 @@ bool StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
|||||||
return this->m_struct == convertTo.m_struct;
|
return this->m_struct == convertTo.m_struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string StructType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_struct" + parenthesizeUserIdentifier(m_struct.name()) + std::to_string(m_struct.id()) + identifierLocationSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
bool StructType::operator==(Type const& _other) const
|
bool StructType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -1605,6 +1732,11 @@ TypePointer EnumType::unaryOperatorResult(Token::Value _operator) const
|
|||||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string EnumType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_enum" + parenthesizeUserIdentifier(m_enum.name()) + std::to_string(m_enum.id());
|
||||||
|
}
|
||||||
|
|
||||||
bool EnumType::operator==(Type const& _other) const
|
bool EnumType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -1686,6 +1818,11 @@ bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string TupleType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_tuple" + identifierList(components());
|
||||||
|
}
|
||||||
|
|
||||||
bool TupleType::operator==(Type const& _other) const
|
bool TupleType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (auto tupleType = dynamic_cast<TupleType const*>(&_other))
|
if (auto tupleType = dynamic_cast<TupleType const*>(&_other))
|
||||||
@ -1934,6 +2071,53 @@ TypePointers FunctionType::parameterTypes() const
|
|||||||
return TypePointers(m_parameterTypes.cbegin() + 1, m_parameterTypes.cend());
|
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 += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes);
|
||||||
|
if (m_gasSet)
|
||||||
|
id += "gas";
|
||||||
|
if (m_valueSet)
|
||||||
|
id += "value";
|
||||||
|
if (bound())
|
||||||
|
id += "bound_to" + identifierList(selfType());
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
bool FunctionType::operator==(Type const& _other) const
|
bool FunctionType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -2338,7 +2522,7 @@ vector<string> const FunctionType::returnParameterTypeNames(bool _addDataLocatio
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer FunctionType::selfType() const
|
TypePointer const& FunctionType::selfType() const
|
||||||
{
|
{
|
||||||
solAssert(bound(), "Function is not bound.");
|
solAssert(bound(), "Function is not bound.");
|
||||||
solAssert(m_parameterTypes.size() > 0, "Function has no self type.");
|
solAssert(m_parameterTypes.size() > 0, "Function has no self type.");
|
||||||
@ -2354,6 +2538,11 @@ ASTPointer<ASTString> FunctionType::documentation() const
|
|||||||
return ASTPointer<ASTString>();
|
return ASTPointer<ASTString>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string MappingType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_mapping" + identifierList(m_keyType, m_valueType);
|
||||||
|
}
|
||||||
|
|
||||||
bool MappingType::operator==(Type const& _other) const
|
bool MappingType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -2372,6 +2561,11 @@ string MappingType::canonicalName(bool) const
|
|||||||
return "mapping(" + keyType()->canonicalName(false) + " => " + valueType()->canonicalName(false) + ")";
|
return "mapping(" + keyType()->canonicalName(false) + " => " + valueType()->canonicalName(false) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string TypeType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_type" + identifierList(actualType());
|
||||||
|
}
|
||||||
|
|
||||||
bool TypeType::operator==(Type const& _other) const
|
bool TypeType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -2456,6 +2650,11 @@ u256 ModifierType::storageSize() const
|
|||||||
<< errinfo_comment("Storage size of non-storable type type requested."));
|
<< errinfo_comment("Storage size of non-storable type type requested."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ModifierType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_modifier" + identifierList(m_parameterTypes);
|
||||||
|
}
|
||||||
|
|
||||||
bool ModifierType::operator==(Type const& _other) const
|
bool ModifierType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -2480,6 +2679,11 @@ string ModifierType::toString(bool _short) const
|
|||||||
return name + ")";
|
return name + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ModuleType::identifier() const
|
||||||
|
{
|
||||||
|
return "t_module_" + std::to_string(m_sourceUnit.id());
|
||||||
|
}
|
||||||
|
|
||||||
bool ModuleType::operator==(Type const& _other) const
|
bool ModuleType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
@ -2501,6 +2705,22 @@ string ModuleType::toString(bool) const
|
|||||||
return string("module \"") + m_sourceUnit.annotation().path + string("\"");
|
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
|
bool MagicType::operator==(Type const& _other) const
|
||||||
{
|
{
|
||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
|
@ -22,18 +22,21 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <boost/noncopyable.hpp>
|
|
||||||
#include <boost/rational.hpp>
|
|
||||||
#include <libdevcore/Common.h>
|
|
||||||
#include <libdevcore/CommonIO.h>
|
|
||||||
#include <libsolidity/interface/Exceptions.h>
|
#include <libsolidity/interface/Exceptions.h>
|
||||||
#include <libsolidity/ast/ASTForward.h>
|
#include <libsolidity/ast/ASTForward.h>
|
||||||
#include <libsolidity/parsing/Token.h>
|
#include <libsolidity/parsing/Token.h>
|
||||||
|
|
||||||
|
#include <libdevcore/Common.h>
|
||||||
|
#include <libdevcore/CommonIO.h>
|
||||||
#include <libdevcore/UndefMacros.h>
|
#include <libdevcore/UndefMacros.h>
|
||||||
|
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/rational.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
namespace solidity
|
namespace solidity
|
||||||
@ -155,6 +158,13 @@ public:
|
|||||||
static TypePointer commonType(TypePointer const& _a, TypePointer const& _b);
|
static TypePointer commonType(TypePointer const& _a, TypePointer const& _b);
|
||||||
|
|
||||||
virtual Category category() const = 0;
|
virtual Category category() const = 0;
|
||||||
|
/// @returns a valid solidity identifier such that two types should compare equal if and
|
||||||
|
/// only if they have the same identifier.
|
||||||
|
/// The identifier should start with "t_".
|
||||||
|
/// More complex identifier strings use "parentheses", where $_ is interpreted as as
|
||||||
|
/// "opening parenthesis", _$ as "closing parenthesis", _$_ as "comma" and any $ that
|
||||||
|
/// appears as part of a user-supplied identifier is escaped as _$$$_.
|
||||||
|
virtual std::string identifier() const = 0;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
|
virtual bool isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
{
|
{
|
||||||
@ -288,6 +298,7 @@ public:
|
|||||||
|
|
||||||
explicit IntegerType(int _bits, Modifier _modifier = Modifier::Unsigned);
|
explicit IntegerType(int _bits, Modifier _modifier = Modifier::Unsigned);
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
@ -329,6 +340,7 @@ public:
|
|||||||
|
|
||||||
explicit FixedPointType(int _integerBits, int _fractionalBits, Modifier _modifier = Modifier::Unsigned);
|
explicit FixedPointType(int _integerBits, int _fractionalBits, Modifier _modifier = Modifier::Unsigned);
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
@ -378,6 +390,7 @@ public:
|
|||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
|
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
@ -416,6 +429,7 @@ public:
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
|
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
@ -449,6 +463,7 @@ public:
|
|||||||
|
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
||||||
@ -476,6 +491,7 @@ class BoolType: public Type
|
|||||||
public:
|
public:
|
||||||
BoolType() {}
|
BoolType() {}
|
||||||
virtual Category category() const override { return Category::Bool; }
|
virtual Category category() const override { return Category::Bool; }
|
||||||
|
virtual std::string identifier() const override { return "t_bool"; }
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
|
||||||
|
|
||||||
@ -533,6 +549,8 @@ protected:
|
|||||||
TypePointer copyForLocationIfReference(TypePointer const& _type) const;
|
TypePointer copyForLocationIfReference(TypePointer const& _type) const;
|
||||||
/// @returns a human-readable description of the reference part of the type.
|
/// @returns a human-readable description of the reference part of the type.
|
||||||
std::string stringForReferencePart() const;
|
std::string stringForReferencePart() const;
|
||||||
|
/// @returns the suffix computed from the reference part to be used by identifier();
|
||||||
|
std::string identifierLocationSuffix() const;
|
||||||
|
|
||||||
DataLocation m_location = DataLocation::Storage;
|
DataLocation m_location = DataLocation::Storage;
|
||||||
bool m_isPointer = true;
|
bool m_isPointer = true;
|
||||||
@ -573,6 +591,7 @@ public:
|
|||||||
|
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(const Type& _other) const override;
|
virtual bool operator==(const Type& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override;
|
virtual unsigned calldataEncodedSize(bool _padded) const override;
|
||||||
virtual bool isDynamicallySized() const override { return m_hasDynamicLength; }
|
virtual bool isDynamicallySized() const override { return m_hasDynamicLength; }
|
||||||
@ -622,6 +641,7 @@ public:
|
|||||||
/// Contracts can be converted to themselves and to integers.
|
/// Contracts can be converted to themselves and to integers.
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded ) const override
|
virtual unsigned calldataEncodedSize(bool _padded ) const override
|
||||||
{
|
{
|
||||||
@ -677,6 +697,7 @@ public:
|
|||||||
explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):
|
explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):
|
||||||
ReferenceType(_location), m_struct(_struct) {}
|
ReferenceType(_location), m_struct(_struct) {}
|
||||||
virtual bool isImplicitlyConvertibleTo(const Type& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(const Type& _convertTo) const override;
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override;
|
virtual unsigned calldataEncodedSize(bool _padded) const override;
|
||||||
u256 memorySize() const;
|
u256 memorySize() const;
|
||||||
@ -720,6 +741,7 @@ public:
|
|||||||
virtual Category category() const override { return Category::Enum; }
|
virtual Category category() const override { return Category::Enum; }
|
||||||
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override
|
virtual unsigned calldataEncodedSize(bool _padded) const override
|
||||||
{
|
{
|
||||||
@ -760,6 +782,7 @@ public:
|
|||||||
virtual Category category() const override { return Category::Tuple; }
|
virtual Category category() const override { return Category::Tuple; }
|
||||||
explicit TupleType(std::vector<TypePointer> const& _types = std::vector<TypePointer>()): m_components(_types) {}
|
explicit TupleType(std::vector<TypePointer> const& _types = std::vector<TypePointer>()): m_components(_types) {}
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
||||||
virtual std::string toString(bool) const override;
|
virtual std::string toString(bool) const override;
|
||||||
@ -895,8 +918,9 @@ public:
|
|||||||
std::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }
|
std::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }
|
||||||
std::vector<std::string> const returnParameterTypeNames(bool _addDataLocation) const;
|
std::vector<std::string> const returnParameterTypeNames(bool _addDataLocation) const;
|
||||||
/// @returns the "self" parameter type for a bound function
|
/// @returns the "self" parameter type for a bound function
|
||||||
TypePointer selfType() const;
|
TypePointer const& selfType() const;
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
|
||||||
virtual std::string canonicalName(bool /*_addDataLocation*/) const override;
|
virtual std::string canonicalName(bool /*_addDataLocation*/) const override;
|
||||||
@ -995,6 +1019,7 @@ public:
|
|||||||
MappingType(TypePointer const& _keyType, TypePointer const& _valueType):
|
MappingType(TypePointer const& _keyType, TypePointer const& _valueType):
|
||||||
m_keyType(_keyType), m_valueType(_valueType) {}
|
m_keyType(_keyType), m_valueType(_valueType) {}
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
virtual std::string canonicalName(bool _addDataLocation) const override;
|
virtual std::string canonicalName(bool _addDataLocation) const override;
|
||||||
@ -1029,6 +1054,7 @@ public:
|
|||||||
TypePointer const& actualType() const { return m_actualType; }
|
TypePointer const& actualType() const { return m_actualType; }
|
||||||
|
|
||||||
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
virtual u256 storageSize() const override;
|
virtual u256 storageSize() const override;
|
||||||
@ -1056,6 +1082,7 @@ public:
|
|||||||
virtual u256 storageSize() const override;
|
virtual u256 storageSize() const override;
|
||||||
virtual bool canLiveOutsideStorage() const override { return false; }
|
virtual bool canLiveOutsideStorage() const override { return false; }
|
||||||
virtual unsigned sizeOnStack() const override { return 0; }
|
virtual unsigned sizeOnStack() const override { return 0; }
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
|
|
||||||
@ -1080,6 +1107,7 @@ public:
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
virtual bool canLiveOutsideStorage() const override { return true; }
|
virtual bool canLiveOutsideStorage() const override { return true; }
|
||||||
@ -1109,6 +1137,7 @@ public:
|
|||||||
return TypePointer();
|
return TypePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string identifier() const override;
|
||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual bool canBeStored() const override { return false; }
|
virtual bool canBeStored() const override { return false; }
|
||||||
virtual bool canLiveOutsideStorage() const override { return true; }
|
virtual bool canLiveOutsideStorage() const override { return true; }
|
||||||
@ -1132,6 +1161,7 @@ class InaccessibleDynamicType: public Type
|
|||||||
public:
|
public:
|
||||||
virtual Category category() const override { return Category::InaccessibleDynamic; }
|
virtual Category category() const override { return Category::InaccessibleDynamic; }
|
||||||
|
|
||||||
|
virtual std::string identifier() const override { return "t_inaccessible"; }
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
|
virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
|
virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
|
virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
|
||||||
|
@ -112,6 +112,7 @@ bool CompilerStack::parse()
|
|||||||
{
|
{
|
||||||
//reset
|
//reset
|
||||||
m_errors.clear();
|
m_errors.clear();
|
||||||
|
ASTNode::resetID();
|
||||||
m_parseSuccessful = false;
|
m_parseSuccessful = false;
|
||||||
|
|
||||||
if (SemVerVersion{string(VersionString)}.isPrerelease())
|
if (SemVerVersion{string(VersionString)}.isPrerelease())
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libsolidity/ast/Types.h>
|
#include <libsolidity/ast/Types.h>
|
||||||
|
#include <libsolidity/ast/AST.h>
|
||||||
|
#include <libdevcore/SHA3.h>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -86,6 +88,71 @@ BOOST_AUTO_TEST_CASE(storage_layout_arrays)
|
|||||||
BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared<FixedBytesType>(32), 9).storageSize() == 9);
|
BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared<FixedBytesType>(32), 9).storageSize() == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(type_identifiers)
|
||||||
|
{
|
||||||
|
ASTNode::resetID();
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("uint128")->identifier(), "t_uint128");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("int128")->identifier(), "t_int128");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("address")->identifier(), "t_address");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("uint8")->identifier(), "t_uint8");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("ufixed8x64")->identifier(), "t_ufixed8x64");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("fixed128x8")->identifier(), "t_fixed128x8");
|
||||||
|
BOOST_CHECK_EQUAL(RationalNumberType(rational(7, 1)).identifier(), "t_rational_7_by_1");
|
||||||
|
BOOST_CHECK_EQUAL(RationalNumberType(rational(200, 77)).identifier(), "t_rational_200_by_77");
|
||||||
|
BOOST_CHECK_EQUAL(RationalNumberType(rational(2 * 200, 2 * 77)).identifier(), "t_rational_200_by_77");
|
||||||
|
BOOST_CHECK_EQUAL(
|
||||||
|
StringLiteralType(Literal(SourceLocation{}, Token::StringLiteral, make_shared<string>("abc - def"))).identifier(),
|
||||||
|
"t_stringliteral_196a9142ee0d40e274a6482393c762b16dd8315713207365e1e13d8d85b74fc4"
|
||||||
|
);
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes8")->identifier(), "t_bytes8");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes32")->identifier(), "t_bytes32");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bool")->identifier(), "t_bool");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes")->identifier(), "t_bytes_storage_ptr");
|
||||||
|
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("string")->identifier(), "t_string_storage_ptr");
|
||||||
|
ArrayType largeintArray(DataLocation::Memory, Type::fromElementaryTypeName("int128"), u256("2535301200456458802993406410752"));
|
||||||
|
BOOST_CHECK_EQUAL(largeintArray.identifier(), "t_array$_t_int128_$2535301200456458802993406410752_memory_ptr");
|
||||||
|
TypePointer stringArray = make_shared<ArrayType>(DataLocation::Storage, Type::fromElementaryTypeName("string"), u256("20"));
|
||||||
|
TypePointer multiArray = make_shared<ArrayType>(DataLocation::Storage, stringArray);
|
||||||
|
BOOST_CHECK_EQUAL(multiArray->identifier(), "t_array$_t_array$_t_string_storage_$20_storage_$dyn_storage_ptr");
|
||||||
|
|
||||||
|
ContractDefinition c(SourceLocation{}, make_shared<string>("MyContract$"), {}, {}, {}, false);
|
||||||
|
BOOST_CHECK_EQUAL(c.type()->identifier(), "t_type$_t_contract$_MyContract$$$_$2_$");
|
||||||
|
BOOST_CHECK_EQUAL(ContractType(c, true).identifier(), "t_super$_MyContract$$$_$2");
|
||||||
|
|
||||||
|
StructDefinition s({}, make_shared<string>("Struct"), {});
|
||||||
|
BOOST_CHECK_EQUAL(s.type()->identifier(), "t_type$_t_struct$_Struct_$3_storage_ptr_$");
|
||||||
|
|
||||||
|
EnumDefinition e({}, make_shared<string>("Enum"), {});
|
||||||
|
BOOST_CHECK_EQUAL(e.type()->identifier(), "t_type$_t_enum$_Enum_$4_$");
|
||||||
|
|
||||||
|
TupleType t({e.type(), s.type(), stringArray, nullptr});
|
||||||
|
BOOST_CHECK_EQUAL(t.identifier(), "t_tuple$_t_type$_t_enum$_Enum_$4_$_$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$_t_array$_t_string_storage_$20_storage_ptr_$__$");
|
||||||
|
|
||||||
|
TypePointer sha3fun = make_shared<FunctionType>(strings{}, strings{}, FunctionType::Location::SHA3);
|
||||||
|
BOOST_CHECK_EQUAL(sha3fun->identifier(), "t_function_sha3$__$returns$__$");
|
||||||
|
|
||||||
|
FunctionType metaFun(TypePointers{sha3fun}, TypePointers{s.type()});
|
||||||
|
BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal$_t_function_sha3$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$");
|
||||||
|
|
||||||
|
TypePointer m = make_shared<MappingType>(Type::fromElementaryTypeName("bytes32"), s.type());
|
||||||
|
MappingType m2(Type::fromElementaryTypeName("uint64"), m);
|
||||||
|
BOOST_CHECK_EQUAL(m2.identifier(), "t_mapping$_t_uint64_$_t_mapping$_t_bytes32_$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$_$");
|
||||||
|
|
||||||
|
// TypeType is tested with contract
|
||||||
|
|
||||||
|
auto emptyParams = make_shared<ParameterList>(SourceLocation(), std::vector<ASTPointer<VariableDeclaration>>());
|
||||||
|
ModifierDefinition mod(SourceLocation{}, make_shared<string>("modif"), {}, emptyParams, {});
|
||||||
|
BOOST_CHECK_EQUAL(ModifierType(mod).identifier(), "t_modifier$__$");
|
||||||
|
|
||||||
|
SourceUnit su({}, {});
|
||||||
|
BOOST_CHECK_EQUAL(ModuleType(su).identifier(), "t_module_7");
|
||||||
|
BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Block).identifier(), "t_magic_block");
|
||||||
|
BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Message).identifier(), "t_magic_message");
|
||||||
|
BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Transaction).identifier(), "t_magic_transaction");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(InaccessibleDynamicType().identifier(), "t_inaccessible");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user