diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index 7ca134c5d..6d13243af 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -144,9 +144,7 @@ bool DeclarationContainer::registerDeclaration( vector DeclarationContainer::resolveName( ASTString const& _name, - bool _recursive, - bool _alsoInvisible, - bool _onlyVisibleAsUnqualifiedNames + ResolvingSettings _settings ) const { solAssert(!_name.empty(), "Attempt to resolve empty name."); @@ -154,22 +152,22 @@ vector DeclarationContainer::resolveName( if (m_declarations.count(_name)) { - if (_onlyVisibleAsUnqualifiedNames) + if (_settings.onlyVisibleAsUnqualifiedNames) result += m_declarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector; else result += m_declarations.at(_name); } - if (_alsoInvisible && m_invisibleDeclarations.count(_name)) + if (_settings.alsoInvisible && m_invisibleDeclarations.count(_name)) { - if (_onlyVisibleAsUnqualifiedNames) + if (_settings.onlyVisibleAsUnqualifiedNames) result += m_invisibleDeclarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector; else result += m_invisibleDeclarations.at(_name); } - if (result.empty() && _recursive && m_enclosingContainer) - result = m_enclosingContainer->resolveName(_name, true, _alsoInvisible, _onlyVisibleAsUnqualifiedNames); + if (result.empty() && _settings.recursive && m_enclosingContainer) + result = m_enclosingContainer->resolveName(_name, _settings); return result; } @@ -209,7 +207,10 @@ void DeclarationContainer::populateHomonyms(back_insert_iterator _it) for (auto [name, location]: m_homonymCandidates) { - vector const& declarations = m_enclosingContainer->resolveName(name, true, true); + ResolvingSettings settings; + settings.recursive = true; + settings.alsoInvisible = true; + vector const& declarations = m_enclosingContainer->resolveName(name, move(settings)); if (!declarations.empty()) _it = make_pair(location, declarations); } diff --git a/libsolidity/analysis/DeclarationContainer.h b/libsolidity/analysis/DeclarationContainer.h index 2dbed0098..279ee1806 100644 --- a/libsolidity/analysis/DeclarationContainer.h +++ b/libsolidity/analysis/DeclarationContainer.h @@ -27,9 +27,27 @@ #include #include +#include + namespace solidity::frontend { +/** + * Settings for how the function DeclarationContainer::resolveName operates. + */ +struct ResolvingSettings +{ + /// if true and there are no matching declarations in the current container, + /// recursively searches the enclosing containers as well. + bool recursive = false; + /// if true, include invisible declaration in the results. + bool alsoInvisible = false; + /// if true, do not include declarations which can never actually be referenced using their + /// name alone (without being qualified with the name of scope in which they are declared). + bool onlyVisibleAsUnqualifiedNames = false; +}; + + /** * Container that stores mappings between names and declarations. It also contains a link to the * enclosing scope. @@ -58,18 +76,8 @@ public: /// Finds all declarations that in the current scope can be referred to using specified name. /// @param _name the name to look for. - /// @param _recursive if true and there are no matching declarations in the current container, - /// recursively searches the enclosing containers as well. - /// @param _alsoInvisible if true, include invisible declaration in the results. - /// @param _onlyVisibleAsUnqualifiedNames if true, do not include declarations which can never - /// actually be referenced using their name alone (without being qualified with the name - /// of scope in which they are declared). - std::vector resolveName( - ASTString const& _name, - bool _recursive = false, - bool _alsoInvisible = false, - bool _onlyVisibleAsUnqualifiedNames = false - ) const; + /// @param _settings see ResolvingSettings + std::vector resolveName(ASTString const& _name, ResolvingSettings _settings = ResolvingSettings{}) const; ASTNode const* enclosingNode() const { return m_enclosingNode; } DeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; } std::map> const& declarations() const { return m_declarations; } diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 239aadf45..63a19a4cb 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -83,7 +83,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, mapsymbolAliases().empty()) for (auto const& alias: imp->symbolAliases()) { - auto declarations = scope->second->resolveName(alias.symbol->name(), false); + auto declarations = scope->second->resolveName(alias.symbol->name()); if (declarations.empty()) { m_errorReporter.declarationError( @@ -176,12 +176,15 @@ vector NameAndTypeResolver::resolveName(ASTString const& _na auto iterator = m_scopes.find(_scope); if (iterator == end(m_scopes)) return vector({}); - return iterator->second->resolveName(_name, false); + return iterator->second->resolveName(_name); } vector NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const { - return m_currentScope->resolveName(_name, true, _includeInvisibles); + ResolvingSettings settings; + settings.recursive = true; + settings.alsoInvisible = _includeInvisibles; + return m_currentScope->resolveName(_name, move(settings)); } Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector const& _path) const @@ -197,12 +200,11 @@ std::vector NameAndTypeResolver::pathFromCurrentScopeWithAll solAssert(!_path.empty(), ""); vector pathDeclarations; - vector candidates = m_currentScope->resolveName( - _path.front(), - /* _recursive */ true, - /* _alsoInvisible */ false, - /* _onlyVisibleAsUnqualifiedNames */ true - ); + ResolvingSettings settings; + settings.recursive = true; + settings.alsoInvisible = false; + settings.onlyVisibleAsUnqualifiedNames = true; + vector candidates = m_currentScope->resolveName(_path.front(), move(settings)); for (size_t i = 1; i < _path.size() && candidates.size() == 1; i++) { @@ -211,7 +213,7 @@ std::vector NameAndTypeResolver::pathFromCurrentScopeWithAll pathDeclarations.push_back(candidates.front()); - candidates = m_scopes.at(candidates.front())->resolveName(_path[i], false); + candidates = m_scopes.at(candidates.front())->resolveName(_path[i]); } if (candidates.size() == 1) {