Implement virtual keyword

This commit is contained in:
Mathias Baumann
2019-11-14 11:49:39 +01:00
parent 7d4e4b6088
commit 5b8ff78176
88 changed files with 395 additions and 314 deletions
+15 -11
View File
@@ -245,15 +245,14 @@ void ContractLevelChecker::checkIllegalOverrides(ContractDefinition const& _cont
for (FunctionDefinition const* function: _contract.definedFunctions())
{
if (function->isConstructor())
continue;
if (contains_if(modSet, MatchByName{function->name()}))
m_errorReporter.typeError(function->location(), "Override changes modifier to function.");
// Skip if not overridable
if (!function->isOverridable())
continue;
// No inheriting functions found
if (funcSet.find(function) == funcSet.cend() && function->overrides())
if (!funcSet.count(function) && function->overrides())
m_errorReporter.typeError(
function->overrides()->location(),
"Function has override specified but does not override anything."
@@ -279,6 +278,12 @@ bool ContractLevelChecker::checkFunctionOverride(FunctionDefinition const& _func
success = false;
}
if (!_super.virtualSemantics())
{
overrideError( _super, _function, "Trying to override non-virtual function. Did you forget to add \"virtual\"?", "Overriding function is here:");
success = false;
}
if (!functionType->hasEqualReturnTypes(*superType))
{
overrideError(_function, _super, "Overriding function return types differ.");
@@ -343,11 +348,11 @@ void ContractLevelChecker::overrideListError(FunctionDefinition const& function,
);
}
void ContractLevelChecker::overrideError(CallableDeclaration const& function, CallableDeclaration const& super, string message)
void ContractLevelChecker::overrideError(CallableDeclaration const& function, CallableDeclaration const& super, string message, string secondaryMsg)
{
m_errorReporter.typeError(
function.location(),
SecondarySourceLocation().append("Overridden function is here:", super.location()),
SecondarySourceLocation().append(secondaryMsg, super.location()),
message
);
}
@@ -653,10 +658,10 @@ void ContractLevelChecker::checkAmbiguousOverrides(ContractDefinition const& _co
continue;
// Not an overridable function
if (!(*it)->isOverridable())
if ((*it)->isConstructor())
{
for (begin++; begin != end; begin++)
solAssert(!(*begin)->isOverridable(), "All functions in range expected to be non-overridable!");
solAssert((*begin)->isConstructor(), "All functions in range expected to be constructors!");
continue;
}
@@ -785,8 +790,7 @@ void ContractLevelChecker::checkOverrideList(FunctionMultiSet const& _funcSet, F
for (auto [begin, end] = _funcSet.equal_range(&_function); begin != end; begin++)
{
// Validate the override
if (!checkFunctionOverride(_function, **begin))
break;
checkFunctionOverride(_function, **begin);
expectedContracts.insert((*begin)->annotation().contract);
}
+1 -1
View File
@@ -75,7 +75,7 @@ private:
/// Also stores the direct super function in the AST annotations.
bool checkFunctionOverride(FunctionDefinition const& _function, FunctionDefinition const& _super);
void overrideListError(FunctionDefinition const& function, std::set<ContractDefinition const*, LessFunction> _secondary, std::string const& _message1, std::string const& _message2);
void overrideError(CallableDeclaration const& function, CallableDeclaration const& super, std::string message);
void overrideError(CallableDeclaration const& function, CallableDeclaration const& super, std::string message, std::string secondaryMsg = "Overridden function is here:");
void checkAbstractFunctions(ContractDefinition const& _contract);
/// Checks that the base constructor arguments are properly provided.
/// Fills the list of unimplemented functions in _contract's annotations.
+3
View File
@@ -327,6 +327,9 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
{
bool isLibraryFunction = _function.inContractKind() == ContractDefinition::ContractKind::Library;
if (_function.markedVirtual() && _function.annotation().contract->isInterface())
m_errorReporter.warning(_function.location(), "Interface functions are implicitly \"virtual\"");
if (_function.isPayable())
{
if (isLibraryFunction)