Rename Type::userDefinedOperator to Type::operatorDefinition

This commit is contained in:
wechman 2022-09-23 13:35:38 +02:00
parent 7983167732
commit d730e92dde
3 changed files with 48 additions and 44 deletions

View File

@ -1731,13 +1731,15 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
// Check if the operator is built-in or user-defined.
Result<FunctionDefinition const*> userDefinedOperatorResult = subExprType->userDefinedOperator(
Result<FunctionDefinition const*> userDefinedOperatorResult = subExprType->operatorDefinition(
_operation.getOperator(),
*currentDefinitionScope(),
true // _unaryOperation
);
if (userDefinedOperatorResult)
_operation.annotation().userDefinedFunction = userDefinedOperatorResult;
FunctionType const* userDefinedFunctionType = nullptr;
if (userDefinedOperatorResult)
userDefinedFunctionType = &dynamic_cast<FunctionType const&>(
@ -1788,7 +1790,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
_operation.annotation().isConstant = false;
// Check if the operator is built-in or user-defined.
Result<FunctionDefinition const*> userDefinedOperatorResult = leftType->userDefinedOperator(
Result<FunctionDefinition const*> userDefinedOperatorResult = leftType->operatorDefinition(
_operation.getOperator(),
*currentDefinitionScope(),
false // _unaryOperation
@ -1867,11 +1869,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
TypeProvider::boolean() :
commonType;
if (
!userDefinedOperatorResult &&
(_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
)
if (_operation.getOperator() == Token::Exp || _operation.getOperator() == Token::SHL)
{
string operation = _operation.getOperator() == Token::Exp ? "exponentiation" : "shift";
if (
@ -3832,8 +3830,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
solAssert(m_errorReporter.hasErrors());
return;
}
solAssert(_usingFor.typeName()->annotation().type);
if (Declaration const* typeDefinition = _usingFor.typeName()->annotation().type->typeDefinition())
Type const* usingForType = _usingFor.typeName()->annotation().type;
solAssert(usingForType);
if (Declaration const* typeDefinition = usingForType->typeDefinition())
{
if (typeDefinition->scope() != m_currentSourceUnit)
m_errorReporter.typeError(
@ -3867,9 +3866,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
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(
9921_error,
_usingFor.location(),
@ -3878,7 +3878,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
Type const* normalizedType = TypeProvider::withLocationIfReference(
DataLocation::Storage,
_usingFor.typeName()->annotation().type
usingForType
);
solAssert(normalizedType);
@ -3909,7 +3909,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
3100_error,
path->location(),
"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" +
" of the function (\"" + functionType->selfType()->humanReadableName() + "\")" +
(
@ -3920,7 +3920,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
);
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(
5332_error,
@ -3937,9 +3939,9 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
TokenTraits::isCompareOp(*operator_)
) &&
(
functionType->parameterTypesIncludingSelf().size() != 2 ||
*functionType->parameterTypesIncludingSelf().at(0) !=
*functionType->parameterTypesIncludingSelf().at(1)
parameterCount != 2 ||
*parameterTypes.at(0) !=
*parameterTypes.at(1)
)
)
m_errorReporter.typeError(
@ -3947,7 +3949,7 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
path->location(),
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
"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 " +
TokenTraits::friendlyName(*operator_) +
"."
@ -3956,10 +3958,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
!TokenTraits::isBinaryOp(*operator_) &&
TokenTraits::isUnaryOp(*operator_) &&
(
functionType->parameterTypesIncludingSelf().size() != 1 ||
parameterCount != 1 ||
(
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->parameterTypesIncludingSelf().front()) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
*TypeProvider::withLocationIfReference(DataLocation::Storage, parameterTypes.front()) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
)
)
)
@ -3968,27 +3970,27 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
path->location(),
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
"needs to have exactly one parameter of type " +
_usingFor.typeName()->annotation().type->canonicalName() +
usingForType->canonicalName() +
" to be used for the operator " +
TokenTraits::friendlyName(*operator_) +
"."
);
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, _usingFor.typeName()->annotation().type)
*TypeProvider::withLocationIfReference(DataLocation::Storage, parameterTypes.at(0)) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
)
)
) ||
(
functionType->parameterTypesIncludingSelf().size() == 1 &&
parameterCount == 1 &&
(
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->parameterTypesIncludingSelf().at(0)) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
*TypeProvider::withLocationIfReference(DataLocation::Storage, parameterTypes.at(0)) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
)
)
)
@ -4003,8 +4005,8 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
"."
);
else if (
functionType->parameterTypesIncludingSelf().size() != 1 &&
functionType->parameterTypesIncludingSelf().size() != 2
parameterCount != 1 &&
parameterCount != 2
)
m_errorReporter.typeError(
8112_error,
@ -4017,9 +4019,11 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
"."
);
TypePointers const& returnParameterTypes = functionType->returnParameterTypes();
size_t const returnParameterCount = returnParameterTypes.size();
if (
TokenTraits::isCompareOp(*operator_) &&
(functionType->returnParameterTypes().size() != 1 || *functionType->returnParameterTypes().front() != *TypeProvider::boolean())
(returnParameterCount != 1 || *returnParameterTypes.front() != *TypeProvider::boolean())
)
m_errorReporter.typeError(
7995_error,
@ -4033,10 +4037,10 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
else if (!TokenTraits::isCompareOp(*operator_))
{
if (
functionType->returnParameterTypes().size() != 1 ||
returnParameterCount != 1 ||
(
*TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->returnParameterTypes().front()) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, _usingFor.typeName()->annotation().type)
*TypeProvider::withLocationIfReference(DataLocation::Storage, returnParameterTypes.front()) !=
*TypeProvider::withLocationIfReference(DataLocation::Storage, usingForType)
)
)
m_errorReporter.typeError(
@ -4044,12 +4048,12 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor)
path->location(),
"The function \"" + joinHumanReadable(path->path(), ".") + "\" "+
"needs to return exactly one value of type " +
_usingFor.typeName()->annotation().type->canonicalName() +
usingForType->canonicalName() +
" to be used for the operator " +
TokenTraits::friendlyName(*operator_) +
"."
);
else if (*functionType->returnParameterTypes().front() != *functionType->parameterTypesIncludingSelf().front())
else if (*returnParameterTypes.front() != *parameterTypes.front())
m_errorReporter.typeError(
3605_error,
path->location(),

View File

@ -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))
return nullptr;
@ -409,12 +409,12 @@ Result<FunctionDefinition const*> Type::userDefinedOperator(Token _token, ASTNod
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedType))
normalizedType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedType);
Type const* normalizedParameterType = functionType->parameterTypes().front();
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedParameterType))
normalizedParameterType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedParameterType);
Type const* normalizedFirstParameterType = functionType->parameterTypes().front();
if (auto const* referenceType = dynamic_cast<ReferenceType const*>(normalizedFirstParameterType))
normalizedFirstParameterType = TypeProvider::withLocationIfReference(referenceType->location(), normalizedFirstParameterType);
if (
*normalizedType == *normalizedParameterType &&
*normalizedType == *normalizedFirstParameterType &&
(
(_unaryOperation && function.parameterList().parameters().size() == 1) ||
(!_unaryOperation && function.parameterList().parameters().size() == 2)

View File

@ -377,7 +377,7 @@ public:
/// Clears all internally cached values (if any).
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:
/// @returns a member list containing all members added to this type by `using for` directives.