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