mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Rename Type::userDefinedOperator to Type::operatorDefinition
This commit is contained in:
parent
7983167732
commit
d730e92dde
@ -1731,13 +1731,15 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
|
|||||||
|
|
||||||
|
|
||||||
// Check if the operator is built-in or user-defined.
|
// Check if the operator is built-in or user-defined.
|
||||||
Result<FunctionDefinition const*> userDefinedOperatorResult = subExprType->userDefinedOperator(
|
Result<FunctionDefinition const*> userDefinedOperatorResult = subExprType->operatorDefinition(
|
||||||
_operation.getOperator(),
|
_operation.getOperator(),
|
||||||
*currentDefinitionScope(),
|
*currentDefinitionScope(),
|
||||||
true // _unaryOperation
|
true // _unaryOperation
|
||||||
);
|
);
|
||||||
|
|
||||||
if (userDefinedOperatorResult)
|
if (userDefinedOperatorResult)
|
||||||
_operation.annotation().userDefinedFunction = userDefinedOperatorResult;
|
_operation.annotation().userDefinedFunction = userDefinedOperatorResult;
|
||||||
|
|
||||||
FunctionType const* userDefinedFunctionType = nullptr;
|
FunctionType const* userDefinedFunctionType = nullptr;
|
||||||
if (userDefinedOperatorResult)
|
if (userDefinedOperatorResult)
|
||||||
userDefinedFunctionType = &dynamic_cast<FunctionType const&>(
|
userDefinedFunctionType = &dynamic_cast<FunctionType const&>(
|
||||||
@ -1788,7 +1790,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
|||||||
_operation.annotation().isConstant = false;
|
_operation.annotation().isConstant = false;
|
||||||
|
|
||||||
// Check if the operator is built-in or user-defined.
|
// Check if the operator is built-in or user-defined.
|
||||||
Result<FunctionDefinition const*> userDefinedOperatorResult = leftType->userDefinedOperator(
|
Result<FunctionDefinition const*> userDefinedOperatorResult = leftType->operatorDefinition(
|
||||||
_operation.getOperator(),
|
_operation.getOperator(),
|
||||||
*currentDefinitionScope(),
|
*currentDefinitionScope(),
|
||||||
false // _unaryOperation
|
false // _unaryOperation
|
||||||
@ -1867,11 +1869,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
|||||||
TypeProvider::boolean() :
|
TypeProvider::boolean() :
|
||||||
commonType;
|
commonType;
|
||||||
|
|
||||||
|
if (_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
|
||||||
if (
|
|
||||||
!userDefinedOperatorResult &&
|
|
||||||
(_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
string operation = _operation.getOperator() == Token::Exp ? "exponentiation" : "shift";
|
string operation = _operation.getOperator() == Token::Exp ? "exponentiation" : "shift";
|
||||||
if (
|
if (
|
||||||
@ -3832,8 +3830,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
solAssert(m_errorReporter.hasErrors());
|
solAssert(m_errorReporter.hasErrors());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
solAssert(_usingFor.typeName()->annotation().type);
|
Type const* usingForType = _usingFor.typeName()->annotation().type;
|
||||||
if (Declaration const* typeDefinition = _usingFor.typeName()->annotation().type->typeDefinition())
|
solAssert(usingForType);
|
||||||
|
if (Declaration const* typeDefinition = usingForType->typeDefinition())
|
||||||
{
|
{
|
||||||
if (typeDefinition->scope() != m_currentSourceUnit)
|
if (typeDefinition->scope() != m_currentSourceUnit)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
@ -3867,9 +3866,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
solAssert(_usingFor.typeName()->annotation().type);
|
Type const* usingForType = _usingFor.typeName()->annotation().type;
|
||||||
|
solAssert(usingForType);
|
||||||
|
|
||||||
if (_usingFor.typeName()->annotation().type->category() == Type::Category::Enum)
|
if (usingForType->category() == Type::Category::Enum)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
9921_error,
|
9921_error,
|
||||||
_usingFor.location(),
|
_usingFor.location(),
|
||||||
@ -3878,7 +3878,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
|
|
||||||
Type const* normalizedType = TypeProvider::withLocationIfReference(
|
Type const* normalizedType = TypeProvider::withLocationIfReference(
|
||||||
DataLocation::Storage,
|
DataLocation::Storage,
|
||||||
_usingFor.typeName()->annotation().type
|
usingForType
|
||||||
);
|
);
|
||||||
solAssert(normalizedType);
|
solAssert(normalizedType);
|
||||||
|
|
||||||
@ -3909,7 +3909,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
3100_error,
|
3100_error,
|
||||||
path->location(),
|
path->location(),
|
||||||
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
||||||
"cannot be bound to the type \"" + _usingFor.typeName()->annotation().type->canonicalName() +
|
"cannot be bound to the type \"" + usingForType->canonicalName() +
|
||||||
"\" because the type cannot be implicitly converted to the first argument" +
|
"\" because the type cannot be implicitly converted to the first argument" +
|
||||||
" of the function (\"" + functionType->selfType()->humanReadableName() + "\")" +
|
" of the function (\"" + functionType->selfType()->humanReadableName() + "\")" +
|
||||||
(
|
(
|
||||||
@ -3920,7 +3920,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
);
|
);
|
||||||
else if (operator_)
|
else if (operator_)
|
||||||
{
|
{
|
||||||
if (!_usingFor.typeName()->annotation().type->typeDefinition())
|
TypePointers const& parameterTypes = functionType->parameterTypesIncludingSelf();
|
||||||
|
size_t const parameterCount = parameterTypes.size();
|
||||||
|
if (!usingForType->typeDefinition())
|
||||||
{
|
{
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
5332_error,
|
5332_error,
|
||||||
@ -3937,9 +3939,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
TokenTraits::isCompareOp(*operator_)
|
TokenTraits::isCompareOp(*operator_)
|
||||||
) &&
|
) &&
|
||||||
(
|
(
|
||||||
functionType->parameterTypesIncludingSelf().size() != 2 ||
|
parameterCount != 2 ||
|
||||||
*functionType->parameterTypesIncludingSelf().at(0) !=
|
*parameterTypes.at(0) !=
|
||||||
*functionType->parameterTypesIncludingSelf().at(1)
|
*parameterTypes.at(1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
@ -3947,7 +3949,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
path->location(),
|
path->location(),
|
||||||
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
||||||
"needs to have two parameters of type " +
|
"needs to have two parameters of type " +
|
||||||
_usingFor.typeName()->annotation().type->canonicalName() +
|
usingForType->canonicalName() +
|
||||||
" and the same data location to be used for the operator " +
|
" and the same data location to be used for the operator " +
|
||||||
TokenTraits::friendlyName(*operator_) +
|
TokenTraits::friendlyName(*operator_) +
|
||||||
"."
|
"."
|
||||||
@ -3956,10 +3958,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
!TokenTraits::isBinaryOp(*operator_) &&
|
!TokenTraits::isBinaryOp(*operator_) &&
|
||||||
TokenTraits::isUnaryOp(*operator_) &&
|
TokenTraits::isUnaryOp(*operator_) &&
|
||||||
(
|
(
|
||||||
functionType->parameterTypesIncludingSelf().size() != 1 ||
|
parameterCount != 1 ||
|
||||||
(
|
(
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->parameterTypesIncludingSelf().front()) !=
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, parameterTypes.front()) !=
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -3968,27 +3970,27 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
path->location(),
|
path->location(),
|
||||||
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
||||||
"needs to have exactly one parameter of type " +
|
"needs to have exactly one parameter of type " +
|
||||||
_usingFor.typeName()->annotation().type->canonicalName() +
|
usingForType->canonicalName() +
|
||||||
" to be used for the operator " +
|
" to be used for the operator " +
|
||||||
TokenTraits::friendlyName(*operator_) +
|
TokenTraits::friendlyName(*operator_) +
|
||||||
"."
|
"."
|
||||||
);
|
);
|
||||||
else if (
|
else if (
|
||||||
(
|
(
|
||||||
functionType->parameterTypesIncludingSelf().size() == 2 &&
|
parameterCount == 2 &&
|
||||||
(
|
(
|
||||||
(*functionType->parameterTypesIncludingSelf().at(0) != *functionType->parameterTypesIncludingSelf().at(1)) ||
|
(*parameterTypes.at(0) != *parameterTypes.at(1)) ||
|
||||||
(
|
(
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->parameterTypesIncludingSelf().at(0)) !=
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, parameterTypes.at(0)) !=
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) ||
|
) ||
|
||||||
(
|
(
|
||||||
functionType->parameterTypesIncludingSelf().size() == 1 &&
|
parameterCount == 1 &&
|
||||||
(
|
(
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->parameterTypesIncludingSelf().at(0)) !=
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, parameterTypes.at(0)) !=
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -4003,8 +4005,8 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
"."
|
"."
|
||||||
);
|
);
|
||||||
else if (
|
else if (
|
||||||
functionType->parameterTypesIncludingSelf().size() != 1 &&
|
parameterCount != 1 &&
|
||||||
functionType->parameterTypesIncludingSelf().size() != 2
|
parameterCount != 2
|
||||||
)
|
)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
8112_error,
|
8112_error,
|
||||||
@ -4015,11 +4017,13 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
" and the same data location to be used for the operator " +
|
" and the same data location to be used for the operator " +
|
||||||
TokenTraits::friendlyName(*operator_) +
|
TokenTraits::friendlyName(*operator_) +
|
||||||
"."
|
"."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TypePointers const& returnParameterTypes = functionType->returnParameterTypes();
|
||||||
|
size_t const returnParameterCount = returnParameterTypes.size();
|
||||||
if (
|
if (
|
||||||
TokenTraits::isCompareOp(*operator_) &&
|
TokenTraits::isCompareOp(*operator_) &&
|
||||||
(functionType->returnParameterTypes().size() != 1 || *functionType->returnParameterTypes().front() != *TypeProvider::boolean())
|
(returnParameterCount != 1 || *returnParameterTypes.front() != *TypeProvider::boolean())
|
||||||
)
|
)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
7995_error,
|
7995_error,
|
||||||
@ -4033,10 +4037,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
else if (!TokenTraits::isCompareOp(*operator_))
|
else if (!TokenTraits::isCompareOp(*operator_))
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
functionType->returnParameterTypes().size() != 1 ||
|
returnParameterCount != 1 ||
|
||||||
(
|
(
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->returnParameterTypes().front()) !=
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, returnParameterTypes.front()) !=
|
||||||
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
|
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
@ -4044,12 +4048,12 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
|
|||||||
path->location(),
|
path->location(),
|
||||||
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
|
||||||
"needs to return exactly one value of type " +
|
"needs to return exactly one value of type " +
|
||||||
_usingFor.typeName()->annotation().type->canonicalName() +
|
usingForType->canonicalName() +
|
||||||
" to be used for the operator " +
|
" to be used for the operator " +
|
||||||
TokenTraits::friendlyName(*operator_) +
|
TokenTraits::friendlyName(*operator_) +
|
||||||
"."
|
"."
|
||||||
);
|
);
|
||||||
else if (*functionType->returnParameterTypes().front() != *functionType->parameterTypesIncludingSelf().front())
|
else if (*returnParameterTypes.front() != *parameterTypes.front())
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3605_error,
|
3605_error,
|
||||||
path->location(),
|
path->location(),
|
||||||
|
@ -386,7 +386,7 @@ vector<UsingForDirective const*> usingForDirectivesForType(Type const& _type, AS
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<FunctionDefinition const*> Type::userDefinedOperator(Token _token, ASTNode const& _scope, bool _unaryOperation) const
|
Result<FunctionDefinition const*> Type::operatorDefinition(Token _token, ASTNode const& _scope, bool _unaryOperation) const
|
||||||
{
|
{
|
||||||
if (!typeDefinition() || !util::contains(overridableOperators, _token))
|
if (!typeDefinition() || !util::contains(overridableOperators, _token))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -409,12 +409,12 @@ Result<FunctionDefinition const*> Type::userDefinedOperator(Token _token, ASTNod
|
|||||||
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedType))
|
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedType))
|
||||||
normalizedType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedType);
|
normalizedType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedType);
|
||||||
|
|
||||||
Type const* normalizedParameterType = functionType->parameterTypes().front();
|
Type const* normalizedFirstParameterType = functionType->parameterTypes().front();
|
||||||
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedParameterType))
|
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedFirstParameterType))
|
||||||
normalizedParameterType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedParameterType);
|
normalizedFirstParameterType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedFirstParameterType);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
*normalizedType == *normalizedParameterType &&
|
*normalizedType == *normalizedFirstParameterType &&
|
||||||
(
|
(
|
||||||
(_unaryOperation && function.parameterList().parameters().size() == 1) ||
|
(_unaryOperation && function.parameterList().parameters().size() == 1) ||
|
||||||
(!_unaryOperation && function.parameterList().parameters().size() == 2)
|
(!_unaryOperation && function.parameterList().parameters().size() == 2)
|
||||||
|
@ -377,7 +377,7 @@ public:
|
|||||||
/// Clears all internally cached values (if any).
|
/// Clears all internally cached values (if any).
|
||||||
virtual void clearCache() const;
|
virtual void clearCache() const;
|
||||||
|
|
||||||
util::Result<FunctionDefinition const*> userDefinedOperator(Token _token, ASTNode const& _scope, bool _unaryOperation) const;
|
util::Result<FunctionDefinition const*> operatorDefinition(Token _token, ASTNode const& _scope, bool _unaryOperation) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @returns a member list containing all members added to this type by `using for` directives.
|
/// @returns a member list containing all members added to this type by `using for` directives.
|
||||||
|
Loading…
Reference in New Issue
Block a user