mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4098 from ethereum/typedResults
Introduce Result<T> for type checker functions
This commit is contained in:
commit
57eb68a8df
66
libdevcore/Result.h
Normal file
66
libdevcore/Result.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
|
||||
/// Simple generic result that holds a value and an optional error message.
|
||||
/// Results can be implicitly converted to and created from the type of
|
||||
/// the value they hold. The class is mainly designed for a result type of
|
||||
/// bool or pointer type. The idea is that the default constructed value of
|
||||
/// the result type is interpreted as an error value.
|
||||
///
|
||||
/// Result<bool> check()
|
||||
/// {
|
||||
/// if (false)
|
||||
/// return Result<bool>("Error message.")
|
||||
/// return true;
|
||||
/// }
|
||||
///
|
||||
|
||||
template <class ResultType>
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
Result(ResultType _value): Result(_value, std::string{}) {}
|
||||
Result(std::string _message): Result(ResultType{}, std::move(_message)) {}
|
||||
|
||||
/// @{
|
||||
/// @name Wrapper functions
|
||||
/// Wrapper functions that provide implicit conversions to and explicit retrieval of
|
||||
/// the value this result holds.
|
||||
operator ResultType const&() const { return m_value; }
|
||||
ResultType const& get() const { return m_value; }
|
||||
/// @}
|
||||
|
||||
/// @returns the error message (can be empty).
|
||||
std::string const& message() const { return m_message; }
|
||||
|
||||
private:
|
||||
explicit Result(ResultType _value, std::string _message):
|
||||
m_value(std::move(_value)),
|
||||
m_message(std::move(_message))
|
||||
{}
|
||||
|
||||
ResultType m_value;
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
}
|
@ -41,7 +41,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation)
|
||||
auto right = type(_operation.rightExpression());
|
||||
if (left && right)
|
||||
{
|
||||
auto commonType = left->binaryOperatorResult(_operation.getOperator(), right);
|
||||
TypePointer commonType = left->binaryOperatorResult(_operation.getOperator(), right);
|
||||
if (!commonType)
|
||||
m_errorReporter.fatalTypeError(
|
||||
_operation.location(),
|
||||
|
@ -466,7 +466,7 @@ string AddressType::richIdentifier() const
|
||||
return "t_address";
|
||||
}
|
||||
|
||||
bool AddressType::isImplicitlyConvertibleTo(Type const& _other) const
|
||||
BoolResult AddressType::isImplicitlyConvertibleTo(Type const& _other) const
|
||||
{
|
||||
if (_other.category() != category())
|
||||
return false;
|
||||
@ -475,7 +475,7 @@ bool AddressType::isImplicitlyConvertibleTo(Type const& _other) const
|
||||
return other.m_stateMutability <= m_stateMutability;
|
||||
}
|
||||
|
||||
bool AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
|
||||
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
|
||||
@ -504,13 +504,13 @@ u256 AddressType::literalValue(Literal const* _literal) const
|
||||
return u256(_literal->valueWithoutUnderscores());
|
||||
}
|
||||
|
||||
TypePointer AddressType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult AddressType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||
}
|
||||
|
||||
|
||||
TypePointer AddressType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult AddressType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
// Addresses can only be compared.
|
||||
if (!TokenTraits::isCompareOp(_operator))
|
||||
@ -576,7 +576,7 @@ string IntegerType::richIdentifier() const
|
||||
return "t_" + string(isSigned() ? "" : "u") + "int" + to_string(numBits());
|
||||
}
|
||||
|
||||
bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (_convertTo.category() == category())
|
||||
{
|
||||
@ -597,7 +597,7 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
return _convertTo.category() == category() ||
|
||||
_convertTo.category() == Category::Address ||
|
||||
@ -607,18 +607,18 @@ bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
_convertTo.category() == Category::FixedPoint;
|
||||
}
|
||||
|
||||
TypePointer IntegerType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult IntegerType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
// "delete" is ok for all integer types
|
||||
if (_operator == Token::Delete)
|
||||
return make_shared<TupleType>();
|
||||
return TypeResult{make_shared<TupleType>()};
|
||||
// we allow +, -, ++ and --
|
||||
else if (_operator == Token::Add || _operator == Token::Sub ||
|
||||
_operator == Token::Inc || _operator == Token::Dec ||
|
||||
_operator == Token::BitNot)
|
||||
return shared_from_this();
|
||||
return TypeResult{shared_from_this()};
|
||||
else
|
||||
return TypePointer();
|
||||
return TypeResult{""};
|
||||
}
|
||||
|
||||
bool IntegerType::operator==(Type const& _other) const
|
||||
@ -651,7 +651,7 @@ bigint IntegerType::maxValue() const
|
||||
return (bigint(1) << m_bits) - 1;
|
||||
}
|
||||
|
||||
TypePointer IntegerType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult IntegerType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
if (
|
||||
_other->category() != Category::RationalNumber &&
|
||||
@ -704,7 +704,7 @@ string FixedPointType::richIdentifier() const
|
||||
return "t_" + string(isSigned() ? "" : "u") + "fixed" + to_string(m_totalBits) + "x" + to_string(m_fractionalDigits);
|
||||
}
|
||||
|
||||
bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (_convertTo.category() == category())
|
||||
{
|
||||
@ -717,18 +717,18 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
return _convertTo.category() == category() || _convertTo.category() == Category::Integer;
|
||||
}
|
||||
|
||||
TypePointer FixedPointType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult FixedPointType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
switch(_operator)
|
||||
{
|
||||
case Token::Delete:
|
||||
// "delete" is ok for all fixed types
|
||||
return make_shared<TupleType>();
|
||||
return TypeResult(make_shared<TupleType>());
|
||||
case Token::Add:
|
||||
case Token::Sub:
|
||||
case Token::Inc:
|
||||
@ -771,7 +771,7 @@ bigint FixedPointType::minIntegerValue() const
|
||||
return bigint(0);
|
||||
}
|
||||
|
||||
TypePointer FixedPointType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult FixedPointType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
auto commonType = Type::commonType(shared_from_this(), _other);
|
||||
|
||||
@ -957,7 +957,7 @@ tuple<bool, rational> RationalNumberType::isValidLiteral(Literal const& _literal
|
||||
return make_tuple(true, value);
|
||||
}
|
||||
|
||||
bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
switch (_convertTo.category())
|
||||
{
|
||||
@ -995,7 +995,7 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
}
|
||||
}
|
||||
|
||||
bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (isImplicitlyConvertibleTo(_convertTo))
|
||||
return true;
|
||||
@ -1008,7 +1008,7 @@ bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return false;
|
||||
}
|
||||
|
||||
TypePointer RationalNumberType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult RationalNumberType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
rational value;
|
||||
switch (_operator)
|
||||
@ -1029,10 +1029,10 @@ TypePointer RationalNumberType::unaryOperatorResult(Token _operator) const
|
||||
default:
|
||||
return TypePointer();
|
||||
}
|
||||
return make_shared<RationalNumberType>(value);
|
||||
return TypeResult(make_shared<RationalNumberType>(value));
|
||||
}
|
||||
|
||||
TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult RationalNumberType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
if (_other->category() == Category::Integer || _other->category() == Category::FixedPoint)
|
||||
{
|
||||
@ -1214,7 +1214,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointe
|
||||
if (value.numerator() != 0 && max(mostSignificantBit(abs(value.numerator())), mostSignificantBit(abs(value.denominator()))) > 4096)
|
||||
return TypePointer();
|
||||
|
||||
return make_shared<RationalNumberType>(value);
|
||||
return TypeResult(make_shared<RationalNumberType>(value));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1354,7 +1354,7 @@ StringLiteralType::StringLiteralType(Literal const& _literal):
|
||||
{
|
||||
}
|
||||
|
||||
bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (auto fixedBytes = dynamic_cast<FixedBytesType const*>(&_convertTo))
|
||||
return size_t(fixedBytes->numBytes()) >= m_value.size();
|
||||
@ -1409,7 +1409,7 @@ FixedBytesType::FixedBytesType(unsigned _bytes): m_bytes(_bytes)
|
||||
);
|
||||
}
|
||||
|
||||
bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (_convertTo.category() != category())
|
||||
return false;
|
||||
@ -1417,7 +1417,7 @@ bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return convertTo.m_bytes >= m_bytes;
|
||||
}
|
||||
|
||||
bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
return (_convertTo.category() == Category::Integer && numBytes() * 8 == dynamic_cast<IntegerType const&>(_convertTo).numBits()) ||
|
||||
(_convertTo.category() == Category::Address && numBytes() == 20) ||
|
||||
@ -1425,18 +1425,18 @@ bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
_convertTo.category() == category();
|
||||
}
|
||||
|
||||
TypePointer FixedBytesType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult FixedBytesType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
// "delete" and "~" is okay for FixedBytesType
|
||||
if (_operator == Token::Delete)
|
||||
return make_shared<TupleType>();
|
||||
return TypeResult(make_shared<TupleType>());
|
||||
else if (_operator == Token::BitNot)
|
||||
return shared_from_this();
|
||||
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
TypePointer FixedBytesType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult FixedBytesType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
if (TokenTraits::isShiftOp(_operator))
|
||||
{
|
||||
@ -1452,7 +1452,7 @@ TypePointer FixedBytesType::binaryOperatorResult(Token _operator, TypePointer co
|
||||
|
||||
// FixedBytes can be compared and have bitwise operators applied to them
|
||||
if (TokenTraits::isCompareOp(_operator) || TokenTraits::isBitOp(_operator))
|
||||
return commonType;
|
||||
return TypeResult(commonType);
|
||||
|
||||
return TypePointer();
|
||||
}
|
||||
@ -1486,14 +1486,14 @@ u256 BoolType::literalValue(Literal const* _literal) const
|
||||
solAssert(false, "Bool type constructed from non-boolean literal.");
|
||||
}
|
||||
|
||||
TypePointer BoolType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult BoolType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
if (_operator == Token::Delete)
|
||||
return make_shared<TupleType>();
|
||||
return TypeResult(make_shared<TupleType>());
|
||||
return (_operator == Token::Not) ? shared_from_this() : TypePointer();
|
||||
}
|
||||
|
||||
TypePointer BoolType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult BoolType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
if (category() != _other->category())
|
||||
return TypePointer();
|
||||
@ -1503,7 +1503,7 @@ TypePointer BoolType::binaryOperatorResult(Token _operator, TypePointer const& _
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (*this == _convertTo)
|
||||
return true;
|
||||
@ -1520,7 +1520,7 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (auto const* addressType = dynamic_cast<AddressType const*>(&_convertTo))
|
||||
return isPayable() || (addressType->stateMutability() < StateMutability::Payable);
|
||||
@ -1533,14 +1533,14 @@ bool ContractType::isPayable() const
|
||||
return fallbackFunction && fallbackFunction->isPayable();
|
||||
}
|
||||
|
||||
TypePointer ContractType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult ContractType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
if (isSuper())
|
||||
return TypePointer{};
|
||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||
}
|
||||
|
||||
TypePointer ReferenceType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult ReferenceType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
if (_operator != Token::Delete)
|
||||
return TypePointer();
|
||||
@ -1551,7 +1551,7 @@ TypePointer ReferenceType::unaryOperatorResult(Token _operator) const
|
||||
case DataLocation::CallData:
|
||||
return TypePointer();
|
||||
case DataLocation::Memory:
|
||||
return make_shared<TupleType>();
|
||||
return TypeResult(make_shared<TupleType>());
|
||||
case DataLocation::Storage:
|
||||
return m_isPointer ? TypePointer() : make_shared<TupleType>();
|
||||
}
|
||||
@ -1605,7 +1605,7 @@ string ReferenceType::identifierLocationSuffix() const
|
||||
return id;
|
||||
}
|
||||
|
||||
bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
BoolResult ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
{
|
||||
if (_convertTo.category() != category())
|
||||
return false;
|
||||
@ -1645,7 +1645,7 @@ bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
}
|
||||
}
|
||||
|
||||
bool ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
BoolResult ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
{
|
||||
if (isImplicitlyConvertibleTo(_convertTo))
|
||||
return true;
|
||||
@ -2006,7 +2006,7 @@ vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::stateVar
|
||||
return variablesAndOffsets;
|
||||
}
|
||||
|
||||
bool StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
BoolResult StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const
|
||||
{
|
||||
if (_convertTo.category() != category())
|
||||
return false;
|
||||
@ -2249,7 +2249,7 @@ bool StructType::recursive() const
|
||||
return *m_recursive;
|
||||
}
|
||||
|
||||
TypePointer EnumType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult EnumType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
|
||||
}
|
||||
@ -2291,7 +2291,7 @@ size_t EnumType::numberOfMembers() const
|
||||
return m_enum.members().size();
|
||||
};
|
||||
|
||||
bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
return _convertTo == *this || _convertTo.category() == Category::Integer;
|
||||
}
|
||||
@ -2308,7 +2308,7 @@ unsigned EnumType::memberValue(ASTString const& _member) const
|
||||
solAssert(false, "Requested unknown enum value " + _member);
|
||||
}
|
||||
|
||||
bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const
|
||||
BoolResult TupleType::isImplicitlyConvertibleTo(Type const& _other) const
|
||||
{
|
||||
if (auto tupleType = dynamic_cast<TupleType const*>(&_other))
|
||||
{
|
||||
@ -2648,14 +2648,14 @@ bool FunctionType::operator==(Type const& _other) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FunctionType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult FunctionType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (m_kind == Kind::External && _convertTo == AddressType::address())
|
||||
return true;
|
||||
return _convertTo.category() == category();
|
||||
}
|
||||
|
||||
bool FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
BoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
if (_convertTo.category() != category())
|
||||
return false;
|
||||
@ -2680,14 +2680,14 @@ bool FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
return true;
|
||||
}
|
||||
|
||||
TypePointer FunctionType::unaryOperatorResult(Token _operator) const
|
||||
TypeResult FunctionType::unaryOperatorResult(Token _operator) const
|
||||
{
|
||||
if (_operator == Token::Delete)
|
||||
return make_shared<TupleType>();
|
||||
return TypeResult(make_shared<TupleType>());
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
TypePointer FunctionType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
TypeResult FunctionType::binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
if (_other->category() != category() || !(_operator == Token::Equal || _operator == Token::NotEqual))
|
||||
return TypePointer();
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <libdevcore/Common.h>
|
||||
#include <libdevcore/CommonIO.h>
|
||||
#include <libdevcore/Result.h>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/rational.hpp>
|
||||
@ -50,6 +51,8 @@ using TypePointer = std::shared_ptr<Type const>;
|
||||
using FunctionTypePointer = std::shared_ptr<FunctionType const>;
|
||||
using TypePointers = std::vector<TypePointer>;
|
||||
using rational = boost::rational<dev::bigint>;
|
||||
using TypeResult = Result<TypePointer>;
|
||||
using BoolResult = Result<bool>;
|
||||
|
||||
inline rational makeRational(bigint const& _numerator, bigint const& _denominator)
|
||||
{
|
||||
@ -63,6 +66,7 @@ inline rational makeRational(bigint const& _numerator, bigint const& _denominato
|
||||
|
||||
enum class DataLocation { Storage, CallData, Memory };
|
||||
|
||||
|
||||
/**
|
||||
* Helper class to compute storage offsets of members of structs and contracts.
|
||||
*/
|
||||
@ -189,19 +193,19 @@ public:
|
||||
/// @returns an escaped identifier (will not contain any parenthesis or commas)
|
||||
static std::string escapeIdentifier(std::string const& _identifier);
|
||||
|
||||
virtual bool isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
|
||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
virtual BoolResult isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
|
||||
virtual BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
{
|
||||
return isImplicitlyConvertibleTo(_convertTo);
|
||||
}
|
||||
/// @returns the resulting type of applying the given unary operator or an empty pointer if
|
||||
/// this is not possible.
|
||||
/// The default implementation does not allow any unary operator.
|
||||
virtual TypePointer unaryOperatorResult(Token) const { return TypePointer(); }
|
||||
virtual TypeResult unaryOperatorResult(Token) const { return TypePointer(); }
|
||||
/// @returns the resulting type of applying the given binary operator or an empty pointer if
|
||||
/// this is not possible.
|
||||
/// The default implementation allows comparison operators if a common type exists
|
||||
virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
virtual TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const
|
||||
{
|
||||
return TokenTraits::isCompareOp(_operator) ? commonType(shared_from_this(), _other) : TypePointer();
|
||||
}
|
||||
@ -336,10 +340,10 @@ public:
|
||||
explicit AddressType(StateMutability _stateMutability);
|
||||
|
||||
std::string richIdentifier() const override;
|
||||
bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
|
||||
bool operator==(Type const& _other) const override;
|
||||
|
||||
@ -381,10 +385,10 @@ public:
|
||||
explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);
|
||||
|
||||
std::string richIdentifier() const override;
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
|
||||
bool operator==(Type const& _other) const override;
|
||||
|
||||
@ -423,10 +427,10 @@ public:
|
||||
explicit FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, Modifier _modifier = Modifier::Unsigned);
|
||||
|
||||
std::string richIdentifier() const override;
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
|
||||
bool operator==(Type const& _other) const override;
|
||||
|
||||
@ -476,11 +480,10 @@ public:
|
||||
explicit RationalNumberType(rational const& _value, TypePointer const& _compatibleBytesType = TypePointer()):
|
||||
m_value(_value), m_compatibleBytesType(_compatibleBytesType)
|
||||
{}
|
||||
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
@ -536,8 +539,8 @@ public:
|
||||
|
||||
explicit StringLiteralType(Literal const& _literal);
|
||||
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override
|
||||
{
|
||||
return TypePointer();
|
||||
}
|
||||
@ -570,12 +573,12 @@ public:
|
||||
|
||||
explicit FixedBytesType(unsigned _bytes);
|
||||
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
|
||||
unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
|
||||
unsigned storageBytes() const override { return m_bytes; }
|
||||
@ -601,8 +604,8 @@ public:
|
||||
BoolType() {}
|
||||
Category category() const override { return Category::Bool; }
|
||||
std::string richIdentifier() const override { return "t_bool"; }
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override;
|
||||
|
||||
unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }
|
||||
unsigned storageBytes() const override { return 1; }
|
||||
@ -624,8 +627,8 @@ public:
|
||||
explicit ReferenceType(DataLocation _location): m_location(_location) {}
|
||||
DataLocation location() const { return m_location; }
|
||||
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override
|
||||
{
|
||||
return TypePointer();
|
||||
}
|
||||
@ -702,8 +705,8 @@ public:
|
||||
m_length(_length)
|
||||
{}
|
||||
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(const Type& _other) const override;
|
||||
unsigned calldataEncodedSize(bool _padded) const override;
|
||||
@ -757,10 +760,10 @@ public:
|
||||
explicit ContractType(ContractDefinition const& _contract, bool _super = false):
|
||||
m_contract(_contract), m_super(_super) {}
|
||||
/// Contracts can be implicitly converted only to base contracts.
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
/// Contracts can only be explicitly converted to address types and base contracts.
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
unsigned calldataEncodedSize(bool _padded ) const override
|
||||
@ -821,7 +824,7 @@ public:
|
||||
Category category() const override { return Category::Struct; }
|
||||
explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):
|
||||
ReferenceType(_location), m_struct(_struct) {}
|
||||
bool isImplicitlyConvertibleTo(const Type& _convertTo) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(const Type& _convertTo) const override;
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
unsigned calldataEncodedSize(bool _padded) const override;
|
||||
@ -876,7 +879,7 @@ class EnumType: public Type
|
||||
public:
|
||||
Category category() const override { return Category::Enum; }
|
||||
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
unsigned calldataEncodedSize(bool _padded) const override
|
||||
@ -889,7 +892,7 @@ public:
|
||||
std::string canonicalName() const override;
|
||||
bool isValueType() const override { return true; }
|
||||
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer encodingType() const override
|
||||
{
|
||||
return std::make_shared<IntegerType>(8 * int(storageBytes()));
|
||||
@ -917,10 +920,10 @@ class TupleType: public Type
|
||||
public:
|
||||
Category category() const override { return Category::Tuple; }
|
||||
explicit TupleType(std::vector<TypePointer> const& _types = std::vector<TypePointer>()): m_components(_types) {}
|
||||
bool isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _other) const override;
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
std::string toString(bool) const override;
|
||||
bool canBeStored() const override { return false; }
|
||||
u256 storageSize() const override;
|
||||
@ -1065,10 +1068,10 @@ public:
|
||||
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypePointer unaryOperatorResult(Token _operator) const override;
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override;
|
||||
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||
TypeResult unaryOperatorResult(Token _operator) const override;
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override;
|
||||
std::string canonicalName() const override;
|
||||
std::string toString(bool _short) const override;
|
||||
unsigned calldataEncodedSize(bool _padded) const override;
|
||||
@ -1197,7 +1200,7 @@ public:
|
||||
std::string toString(bool _short) const override;
|
||||
std::string canonicalName() const override;
|
||||
bool canLiveOutsideStorage() const override { return false; }
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
TypePointer encodingType() const override
|
||||
{
|
||||
return std::make_shared<IntegerType>(256);
|
||||
@ -1230,7 +1233,7 @@ public:
|
||||
explicit TypeType(TypePointer const& _actualType): m_actualType(_actualType) {}
|
||||
TypePointer const& actualType() const { return m_actualType; }
|
||||
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
bool canBeStored() const override { return false; }
|
||||
@ -1255,7 +1258,7 @@ public:
|
||||
Category category() const override { return Category::Modifier; }
|
||||
explicit ModifierType(ModifierDefinition const& _modifier);
|
||||
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
bool canBeStored() const override { return false; }
|
||||
u256 storageSize() const override;
|
||||
bool canLiveOutsideStorage() const override { return false; }
|
||||
@ -1281,7 +1284,7 @@ public:
|
||||
|
||||
explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}
|
||||
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
std::string richIdentifier() const override;
|
||||
bool operator==(Type const& _other) const override;
|
||||
bool canBeStored() const override { return false; }
|
||||
@ -1308,7 +1311,7 @@ public:
|
||||
|
||||
explicit MagicType(Kind _kind): m_kind(_kind) {}
|
||||
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override
|
||||
{
|
||||
return TypePointer();
|
||||
}
|
||||
@ -1339,9 +1342,9 @@ public:
|
||||
Category category() const override { return Category::InaccessibleDynamic; }
|
||||
|
||||
std::string richIdentifier() const override { return "t_inaccessible"; }
|
||||
bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||
bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||
TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
BoolResult isImplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||
BoolResult isExplicitlyConvertibleTo(Type const&) const override { return false; }
|
||||
TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); }
|
||||
unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
|
||||
bool canBeStored() const override { return false; }
|
||||
bool canLiveOutsideStorage() const override { return false; }
|
||||
|
Loading…
Reference in New Issue
Block a user