mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add userDefinedFunctionType helper function
This commit is contained in:
parent
577a5bb7a4
commit
5cf88593fd
@ -1740,14 +1740,7 @@ bool TypeChecker::visit(UnaryOperation const& _operation)
|
||||
if (userDefinedOperatorResult)
|
||||
_operation.annotation().userDefinedFunction = userDefinedOperatorResult;
|
||||
|
||||
FunctionType const* userDefinedFunctionType = nullptr;
|
||||
if (userDefinedOperatorResult)
|
||||
userDefinedFunctionType = &dynamic_cast<FunctionType const&>(
|
||||
userDefinedOperatorResult.get()->libraryFunction() ?
|
||||
*userDefinedOperatorResult.get()->typeViaContractName() :
|
||||
*userDefinedOperatorResult.get()->type()
|
||||
);
|
||||
|
||||
FunctionType const* userDefinedFunctionType = _operation.userDefinedFunctionType();
|
||||
TypeResult builtinResult = subExprType->unaryOperatorResult(op);
|
||||
|
||||
solAssert(!builtinResult || !userDefinedOperatorResult);
|
||||
@ -1790,20 +1783,14 @@ 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->operatorDefinition(
|
||||
Result<FunctionDefinition const*> operatorDefinitionResult = leftType->operatorDefinition(
|
||||
_operation.getOperator(),
|
||||
*currentDefinitionScope(),
|
||||
false // _unaryOperation
|
||||
);
|
||||
if (userDefinedOperatorResult)
|
||||
_operation.annotation().userDefinedFunction = userDefinedOperatorResult;
|
||||
FunctionType const* userDefinedFunctionType = nullptr;
|
||||
if (userDefinedOperatorResult)
|
||||
userDefinedFunctionType = &dynamic_cast<FunctionType const&>(
|
||||
userDefinedOperatorResult.get()->libraryFunction() ?
|
||||
*userDefinedOperatorResult.get()->typeViaContractName() :
|
||||
*userDefinedOperatorResult.get()->type()
|
||||
);
|
||||
if (operatorDefinitionResult)
|
||||
_operation.annotation().userDefinedFunction = operatorDefinitionResult;
|
||||
FunctionType const* userDefinedFunctionType = _operation.userDefinedFunctionType();
|
||||
_operation.annotation().isPure =
|
||||
*_operation.leftExpression().annotation().isPure &&
|
||||
*_operation.rightExpression().annotation().isPure &&
|
||||
@ -1812,12 +1799,12 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
||||
TypeResult builtinResult = leftType->binaryOperatorResult(_operation.getOperator(), rightType);
|
||||
|
||||
// Either the operator is user-defined or built-in.
|
||||
solAssert(!userDefinedOperatorResult || !builtinResult);
|
||||
solAssert(!operatorDefinitionResult || !builtinResult);
|
||||
|
||||
Type const* commonType = leftType;
|
||||
if (builtinResult)
|
||||
commonType = builtinResult.get();
|
||||
else if (userDefinedOperatorResult)
|
||||
else if (operatorDefinitionResult)
|
||||
{
|
||||
Type const* normalizedParameterType = userDefinedFunctionType->parameterTypes().at(0);
|
||||
Type const* normalizedLeftType = leftType;
|
||||
@ -1860,7 +1847,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation)
|
||||
" and " +
|
||||
rightType->humanReadableName() + "." +
|
||||
(!builtinResult.message().empty() ? " " + builtinResult.message() : "") +
|
||||
(!userDefinedOperatorResult.message().empty() ? " " + userDefinedOperatorResult.message() : "")
|
||||
(!operatorDefinitionResult.message().empty() ? " " + operatorDefinitionResult.message() : "")
|
||||
);
|
||||
|
||||
_operation.annotation().commonType = commonType;
|
||||
|
@ -907,6 +907,34 @@ OperationAnnotation& UnaryOperation::annotation() const
|
||||
return initAnnotation<OperationAnnotation>();
|
||||
}
|
||||
|
||||
FunctionType const* UnaryOperation::userDefinedFunctionType() const
|
||||
{
|
||||
if (!annotation().userDefinedFunction.set())
|
||||
return nullptr;
|
||||
|
||||
FunctionDefinition const* userDefinedFunction = *annotation().userDefinedFunction;
|
||||
solAssert(userDefinedFunction);
|
||||
return dynamic_cast<FunctionType const*>(
|
||||
userDefinedFunction->libraryFunction() ?
|
||||
userDefinedFunction->typeViaContractName() :
|
||||
userDefinedFunction->type()
|
||||
);
|
||||
}
|
||||
|
||||
FunctionType const* BinaryOperation::userDefinedFunctionType() const
|
||||
{
|
||||
if (!annotation().userDefinedFunction.set())
|
||||
return nullptr;
|
||||
|
||||
FunctionDefinition const* userDefinedFunction = *annotation().userDefinedFunction;
|
||||
solAssert(userDefinedFunction);
|
||||
return dynamic_cast<FunctionType const*>(
|
||||
userDefinedFunction->libraryFunction() ?
|
||||
userDefinedFunction->typeViaContractName() :
|
||||
userDefinedFunction->type()
|
||||
);
|
||||
}
|
||||
|
||||
BinaryOperationAnnotation& BinaryOperation::annotation() const
|
||||
{
|
||||
return initAnnotation<BinaryOperationAnnotation>();
|
||||
|
@ -2068,6 +2068,8 @@ public:
|
||||
bool isPrefixOperation() const { return m_isPrefix; }
|
||||
Expression const& subExpression() const { return *m_subExpression; }
|
||||
|
||||
FunctionType const* userDefinedFunctionType() const;
|
||||
|
||||
OperationAnnotation& annotation() const override;
|
||||
|
||||
private:
|
||||
@ -2101,6 +2103,8 @@ public:
|
||||
Expression const& rightExpression() const { return *m_right; }
|
||||
Token getOperator() const { return m_operator; }
|
||||
|
||||
FunctionType const* userDefinedFunctionType() const;
|
||||
|
||||
BinaryOperationAnnotation& annotation() const override;
|
||||
|
||||
private:
|
||||
|
@ -420,9 +420,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
|
||||
"Only file-level functions and library functions can be bound to a user type operator."
|
||||
);
|
||||
|
||||
FunctionType const* functionType = dynamic_cast<FunctionType const*>(
|
||||
function->libraryFunction() ? function->typeViaContractName() : function->type()
|
||||
);
|
||||
FunctionType const* functionType = _unaryOperation.userDefinedFunctionType();
|
||||
solAssert(functionType);
|
||||
|
||||
functionType = dynamic_cast<FunctionType const&>(*functionType).asBoundFunction();
|
||||
@ -548,9 +546,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
||||
function->isFree() || function->libraryFunction(),
|
||||
"Only file-level functions and library functions can be bound to a user type operator."
|
||||
);
|
||||
FunctionType const* functionType = dynamic_cast<FunctionType const*>(
|
||||
function->libraryFunction() ? function->typeViaContractName() : function->type()
|
||||
);
|
||||
FunctionType const* functionType = _binaryOperation.userDefinedFunctionType();
|
||||
solAssert(functionType);
|
||||
functionType = dynamic_cast<FunctionType const&>(*functionType).asBoundFunction();
|
||||
solAssert(functionType);
|
||||
|
@ -685,9 +685,7 @@ bool IRGeneratorForStatements::visit(UnaryOperation const& _unaryOperation)
|
||||
"Only file-level functions and library functions can be bound to a user type operator."
|
||||
);
|
||||
|
||||
FunctionType const* functionType = dynamic_cast<FunctionType const*>(
|
||||
function->libraryFunction() ? function->typeViaContractName() : function->type()
|
||||
);
|
||||
FunctionType const* functionType = _unaryOperation.userDefinedFunctionType();
|
||||
solAssert(functionType);
|
||||
functionType = dynamic_cast<FunctionType const&>(*functionType).asBoundFunction();
|
||||
solAssert(functionType);
|
||||
@ -832,9 +830,7 @@ bool IRGeneratorForStatements::visit(BinaryOperation const& _binOp)
|
||||
"Only file-level functions and library functions can be bound to a user type operator."
|
||||
);
|
||||
|
||||
FunctionType const* functionType = dynamic_cast<FunctionType const*>(
|
||||
function->libraryFunction() ? function->typeViaContractName() : function->type()
|
||||
);
|
||||
FunctionType const* functionType = _binOp.userDefinedFunctionType();
|
||||
solAssert(functionType);
|
||||
functionType = dynamic_cast<FunctionType const&>(*functionType).asBoundFunction();
|
||||
solAssert(functionType);
|
||||
|
Loading…
Reference in New Issue
Block a user