mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactor function override check to remove duplicate logic
This commit is contained in:
parent
f0dc572055
commit
a6949851f3
@ -277,21 +277,10 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr
|
|||||||
string const& name = function->name();
|
string const& name = function->name();
|
||||||
if (modifiers.count(name))
|
if (modifiers.count(name))
|
||||||
m_errorReporter.typeError(modifiers[name]->location(), "Override changes function to modifier.");
|
m_errorReporter.typeError(modifiers[name]->location(), "Override changes function to modifier.");
|
||||||
FunctionType functionType(*function);
|
|
||||||
// function should not change the return type
|
|
||||||
for (FunctionDefinition const* overriding: functions[name])
|
for (FunctionDefinition const* overriding: functions[name])
|
||||||
{
|
checkFunctionOverride(*overriding, *function);
|
||||||
FunctionType overridingType(*overriding);
|
|
||||||
if (!overridingType.hasEqualArgumentTypes(functionType))
|
|
||||||
continue;
|
|
||||||
if (
|
|
||||||
overriding->visibility() != function->visibility() ||
|
|
||||||
overriding->isDeclaredConst() != function->isDeclaredConst() ||
|
|
||||||
overriding->isPayable() != function->isPayable() ||
|
|
||||||
overridingType != functionType
|
|
||||||
)
|
|
||||||
overrideTypeError(*overriding, *function);
|
|
||||||
}
|
|
||||||
functions[name].push_back(function);
|
functions[name].push_back(function);
|
||||||
}
|
}
|
||||||
for (ModifierDefinition const* modifier: contract->functionModifiers())
|
for (ModifierDefinition const* modifier: contract->functionModifiers())
|
||||||
@ -308,6 +297,51 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TypeChecker::checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super)
|
||||||
|
{
|
||||||
|
FunctionType functionType(function);
|
||||||
|
FunctionType superType(super);
|
||||||
|
|
||||||
|
if (!functionType.hasEqualArgumentTypes(superType))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (function.visibility() != super.visibility())
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
function.location(),
|
||||||
|
"Overriding function visibility differs from " + super.fullyQualifiedName() + "."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (function.isDeclaredConst() && !super.isDeclaredConst())
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
function.location(),
|
||||||
|
"Overriding function should not be declared constant."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!function.isDeclaredConst() && super.isDeclaredConst())
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
function.location(),
|
||||||
|
"Overriding function should be declared constant."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (function.isPayable() && !super.isPayable())
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
function.location(),
|
||||||
|
"Overriding function should not be declared payable."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!function.isPayable() && super.isPayable())
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
function.location(),
|
||||||
|
"Overriding function should be declared payable."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (functionType != superType)
|
||||||
|
m_errorReporter.typeError(
|
||||||
|
function.location(),
|
||||||
|
"Overriding function return types differ from " + super.fullyQualifiedName() + "."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void TypeChecker::checkContractExternalTypeClashes(ContractDefinition const& _contract)
|
void TypeChecker::checkContractExternalTypeClashes(ContractDefinition const& _contract)
|
||||||
{
|
{
|
||||||
map<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
|
map<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations;
|
||||||
@ -1949,33 +1983,3 @@ void TypeChecker::requireLValue(Expression const& _expression)
|
|||||||
else if (!_expression.annotation().isLValue)
|
else if (!_expression.annotation().isLValue)
|
||||||
m_errorReporter.typeError(_expression.location(), "Expression has to be an lvalue.");
|
m_errorReporter.typeError(_expression.location(), "Expression has to be an lvalue.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeChecker::overrideTypeError(FunctionDefinition const& function, FunctionDefinition const& super)
|
|
||||||
{
|
|
||||||
string message;
|
|
||||||
|
|
||||||
if (function.visibility() != super.visibility())
|
|
||||||
message = "Overriding function visibility differs from " + super.fullyQualifiedName() + ".";
|
|
||||||
else if (function.isDeclaredConst() && !super.isDeclaredConst())
|
|
||||||
message = "Overriding function should not be declared constant.";
|
|
||||||
else if (!function.isDeclaredConst() && super.isDeclaredConst())
|
|
||||||
message = "Overriding function should be declared constant.";
|
|
||||||
else if (function.isPayable() && !super.isPayable())
|
|
||||||
message = "Overriding function should not be declared payable.";
|
|
||||||
else if (!function.isPayable() && super.isPayable())
|
|
||||||
message = "Overriding function should be declared payable.";
|
|
||||||
|
|
||||||
if (message.empty())
|
|
||||||
{
|
|
||||||
FunctionType functionType(function);
|
|
||||||
FunctionType superType(super);
|
|
||||||
|
|
||||||
if (functionType != superType)
|
|
||||||
message = "Overriding function return types differ from " + super.fullyQualifiedName() + ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.empty())
|
|
||||||
message = "Overriding function signature differs from " + super.fullyQualifiedName() + ".";
|
|
||||||
|
|
||||||
m_errorReporter.typeError(function.location(), message);
|
|
||||||
}
|
|
||||||
|
@ -62,6 +62,8 @@ private:
|
|||||||
/// arguments and that there is at most one constructor.
|
/// arguments and that there is at most one constructor.
|
||||||
void checkContractDuplicateFunctions(ContractDefinition const& _contract);
|
void checkContractDuplicateFunctions(ContractDefinition const& _contract);
|
||||||
void checkContractIllegalOverrides(ContractDefinition const& _contract);
|
void checkContractIllegalOverrides(ContractDefinition const& _contract);
|
||||||
|
/// Reports a type error with an appropiate message if overriden function signature differs.
|
||||||
|
void checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super);
|
||||||
void checkContractAbstractFunctions(ContractDefinition const& _contract);
|
void checkContractAbstractFunctions(ContractDefinition const& _contract);
|
||||||
void checkContractAbstractConstructors(ContractDefinition const& _contract);
|
void checkContractAbstractConstructors(ContractDefinition const& _contract);
|
||||||
/// Checks that different functions with external visibility end up having different
|
/// Checks that different functions with external visibility end up having different
|
||||||
@ -120,9 +122,6 @@ private:
|
|||||||
/// Runs type checks on @a _expression to infer its type and then checks that it is an LValue.
|
/// Runs type checks on @a _expression to infer its type and then checks that it is an LValue.
|
||||||
void requireLValue(Expression const& _expression);
|
void requireLValue(Expression const& _expression);
|
||||||
|
|
||||||
/// Reports a type error with an appropiate message when overriden function signature differs.
|
|
||||||
void overrideTypeError(FunctionDefinition const& function, FunctionDefinition const& super);
|
|
||||||
|
|
||||||
ContractDefinition const* m_scope = nullptr;
|
ContractDefinition const* m_scope = nullptr;
|
||||||
|
|
||||||
ErrorReporter& m_errorReporter;
|
ErrorReporter& m_errorReporter;
|
||||||
|
Loading…
Reference in New Issue
Block a user