Ensure contract order in suggestion is equal to inheritance order

This commit is contained in:
Mathias Baumann 2020-03-02 16:21:03 +01:00
parent c42f4d8335
commit b2b45cc97b
3 changed files with 20 additions and 10 deletions

View File

@ -565,18 +565,17 @@ void OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverridePr
void OverrideChecker::overrideListError( void OverrideChecker::overrideListError(
OverrideProxy const& _item, OverrideProxy const& _item,
set<ContractDefinition const*, CompareByID> _secondary, vector<ContractDefinition const*> _secondary,
string const& _message1, string const& _message1,
string const& _message2 string const& _message2
) )
{ {
// Using a set rather than a vector so the order is always the same vector<string> names;
set<string> names;
SecondarySourceLocation ssl; SecondarySourceLocation ssl;
for (Declaration const* c: _secondary) for (Declaration const* c: _secondary)
{ {
ssl.append("This contract: ", c->location()); ssl.append("This contract: ", c->location());
names.insert("\"" + c->name() + "\""); names.emplace_back("\"" + c->name() + "\"");
} }
string contractSingularPlural = "contract "; string contractSingularPlural = "contract ";
if (_secondary.size() > 1) if (_secondary.size() > 1)
@ -823,18 +822,28 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign
missingContracts = expectedContracts - specifiedContracts; missingContracts = expectedContracts - specifiedContracts;
if (!missingContracts.empty()) if (!missingContracts.empty())
{
vector<ContractDefinition const*> sortedMissingContracts;
for (size_t i = _item.contract().annotation().linearizedBaseContracts.size() - 1; i > 0; i--)
{
auto contract = _item.contract().annotation().linearizedBaseContracts[i];
if (missingContracts.count(contract))
sortedMissingContracts.emplace_back(contract);
}
overrideListError( overrideListError(
_item, _item,
missingContracts, sortedMissingContracts,
_item.astNodeNameCapitalized() + " needs to specify overridden ", _item.astNodeNameCapitalized() + " needs to specify overridden ",
"" ""
); );
}
auto surplusContracts = specifiedContracts - expectedContracts; auto surplusContracts = specifiedContracts - expectedContracts;
if (!surplusContracts.empty()) if (!surplusContracts.empty())
overrideListError( overrideListError(
_item, _item,
surplusContracts, util::convertContainer<vector<ContractDefinition const*>>(surplusContracts),
"Invalid ", "Invalid ",
"specified in override list: " "specified in override list: "
); );

View File

@ -157,7 +157,7 @@ private:
void checkOverride(OverrideProxy const& _overriding, OverrideProxy const& _super); void checkOverride(OverrideProxy const& _overriding, OverrideProxy const& _super);
void overrideListError( void overrideListError(
OverrideProxy const& _item, OverrideProxy const& _item,
std::set<ContractDefinition const*, CompareByID> _secondary, std::vector<ContractDefinition const*> _secondary,
std::string const& _message1, std::string const& _message1,
std::string const& _message2 std::string const& _message2
); );

View File

@ -14,7 +14,7 @@ interface SuperB {
function test5() external returns (uint256); function test5() external returns (uint256);
} }
interface Sub is SuperA, SuperB { interface Sub is SuperB, SuperA {
function test1() external returns (uint256); function test1() external returns (uint256);
function test2() external override returns (uint256); function test2() external override returns (uint256);
function test3() external override(SuperA) returns (uint256); function test3() external override(SuperA) returns (uint256);
@ -25,7 +25,8 @@ interface Sub is SuperA, SuperB {
// ---- // ----
// TypeError: (572-616): Overriding function is missing "override" specifier. // TypeError: (572-616): Overriding function is missing "override" specifier.
// TypeError: (572-616): Overriding function is missing "override" specifier. // TypeError: (572-616): Overriding function is missing "override" specifier.
// TypeError: (572-616): Function needs to specify overridden contracts "SuperA" and "SuperB". // TypeError: (572-616): Function needs to specify overridden contracts "SuperB" and "SuperA".
// TypeError: (647-655): Function needs to specify overridden contracts "SuperA" and "SuperB". // TypeError: (647-655): Function needs to specify overridden contracts "SuperB" and "SuperA".
// TypeError: (705-721): Function needs to specify overridden contract "SuperB". // TypeError: (705-721): Function needs to specify overridden contract "SuperB".
// TypeError: (771-787): Function needs to specify overridden contract "SuperA". // TypeError: (771-787): Function needs to specify overridden contract "SuperA".
// Warning: (837-861): Override specifier list order differs from inheritance order.