mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Settings struct for name resolution.
This commit is contained in:
parent
ed039abb97
commit
e2675002ca
@ -144,9 +144,7 @@ bool DeclarationContainer::registerDeclaration(
|
|||||||
|
|
||||||
vector<Declaration const*> DeclarationContainer::resolveName(
|
vector<Declaration const*> DeclarationContainer::resolveName(
|
||||||
ASTString const& _name,
|
ASTString const& _name,
|
||||||
bool _recursive,
|
ResolvingSettings _settings
|
||||||
bool _alsoInvisible,
|
|
||||||
bool _onlyVisibleAsUnqualifiedNames
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
solAssert(!_name.empty(), "Attempt to resolve empty name.");
|
solAssert(!_name.empty(), "Attempt to resolve empty name.");
|
||||||
@ -154,22 +152,22 @@ vector<Declaration const*> DeclarationContainer::resolveName(
|
|||||||
|
|
||||||
if (m_declarations.count(_name))
|
if (m_declarations.count(_name))
|
||||||
{
|
{
|
||||||
if (_onlyVisibleAsUnqualifiedNames)
|
if (_settings.onlyVisibleAsUnqualifiedNames)
|
||||||
result += m_declarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector;
|
result += m_declarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector;
|
||||||
else
|
else
|
||||||
result += m_declarations.at(_name);
|
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;
|
result += m_invisibleDeclarations.at(_name) | ranges::views::filter(&Declaration::isVisibleAsUnqualifiedName) | ranges::to_vector;
|
||||||
else
|
else
|
||||||
result += m_invisibleDeclarations.at(_name);
|
result += m_invisibleDeclarations.at(_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.empty() && _recursive && m_enclosingContainer)
|
if (result.empty() && _settings.recursive && m_enclosingContainer)
|
||||||
result = m_enclosingContainer->resolveName(_name, true, _alsoInvisible, _onlyVisibleAsUnqualifiedNames);
|
result = m_enclosingContainer->resolveName(_name, _settings);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -209,7 +207,10 @@ void DeclarationContainer::populateHomonyms(back_insert_iterator<Homonyms> _it)
|
|||||||
|
|
||||||
for (auto [name, location]: m_homonymCandidates)
|
for (auto [name, location]: m_homonymCandidates)
|
||||||
{
|
{
|
||||||
vector<Declaration const*> const& declarations = m_enclosingContainer->resolveName(name, true, true);
|
ResolvingSettings settings;
|
||||||
|
settings.recursive = true;
|
||||||
|
settings.alsoInvisible = true;
|
||||||
|
vector<Declaration const*> const& declarations = m_enclosingContainer->resolveName(name, move(settings));
|
||||||
if (!declarations.empty())
|
if (!declarations.empty())
|
||||||
_it = make_pair(location, declarations);
|
_it = make_pair(location, declarations);
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,27 @@
|
|||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
#include <liblangutil/SourceLocation.h>
|
#include <liblangutil/SourceLocation.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace solidity::frontend
|
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
|
* Container that stores mappings between names and declarations. It also contains a link to the
|
||||||
* enclosing scope.
|
* enclosing scope.
|
||||||
@ -58,18 +76,8 @@ public:
|
|||||||
|
|
||||||
/// Finds all declarations that in the current scope can be referred to using specified name.
|
/// Finds all declarations that in the current scope can be referred to using specified name.
|
||||||
/// @param _name the name to look for.
|
/// @param _name the name to look for.
|
||||||
/// @param _recursive if true and there are no matching declarations in the current container,
|
/// @param _settings see ResolvingSettings
|
||||||
/// recursively searches the enclosing containers as well.
|
std::vector<Declaration const*> resolveName(ASTString const& _name, ResolvingSettings _settings = ResolvingSettings{}) const;
|
||||||
/// @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<Declaration const*> resolveName(
|
|
||||||
ASTString const& _name,
|
|
||||||
bool _recursive = false,
|
|
||||||
bool _alsoInvisible = false,
|
|
||||||
bool _onlyVisibleAsUnqualifiedNames = false
|
|
||||||
) const;
|
|
||||||
ASTNode const* enclosingNode() const { return m_enclosingNode; }
|
ASTNode const* enclosingNode() const { return m_enclosingNode; }
|
||||||
DeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; }
|
DeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; }
|
||||||
std::map<ASTString, std::vector<Declaration const*>> const& declarations() const { return m_declarations; }
|
std::map<ASTString, std::vector<Declaration const*>> const& declarations() const { return m_declarations; }
|
||||||
|
@ -83,7 +83,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, So
|
|||||||
if (!imp->symbolAliases().empty())
|
if (!imp->symbolAliases().empty())
|
||||||
for (auto const& alias: imp->symbolAliases())
|
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())
|
if (declarations.empty())
|
||||||
{
|
{
|
||||||
m_errorReporter.declarationError(
|
m_errorReporter.declarationError(
|
||||||
@ -176,12 +176,15 @@ vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _na
|
|||||||
auto iterator = m_scopes.find(_scope);
|
auto iterator = m_scopes.find(_scope);
|
||||||
if (iterator == end(m_scopes))
|
if (iterator == end(m_scopes))
|
||||||
return vector<Declaration const*>({});
|
return vector<Declaration const*>({});
|
||||||
return iterator->second->resolveName(_name, false);
|
return iterator->second->resolveName(_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const
|
vector<Declaration const*> 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<ASTString> const& _path) const
|
Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector<ASTString> const& _path) const
|
||||||
@ -197,12 +200,11 @@ std::vector<Declaration const*> NameAndTypeResolver::pathFromCurrentScopeWithAll
|
|||||||
solAssert(!_path.empty(), "");
|
solAssert(!_path.empty(), "");
|
||||||
vector<Declaration const*> pathDeclarations;
|
vector<Declaration const*> pathDeclarations;
|
||||||
|
|
||||||
vector<Declaration const*> candidates = m_currentScope->resolveName(
|
ResolvingSettings settings;
|
||||||
_path.front(),
|
settings.recursive = true;
|
||||||
/* _recursive */ true,
|
settings.alsoInvisible = false;
|
||||||
/* _alsoInvisible */ false,
|
settings.onlyVisibleAsUnqualifiedNames = true;
|
||||||
/* _onlyVisibleAsUnqualifiedNames */ true
|
vector<Declaration const*> candidates = m_currentScope->resolveName(_path.front(), move(settings));
|
||||||
);
|
|
||||||
|
|
||||||
for (size_t i = 1; i < _path.size() && candidates.size() == 1; i++)
|
for (size_t i = 1; i < _path.size() && candidates.size() == 1; i++)
|
||||||
{
|
{
|
||||||
@ -211,7 +213,7 @@ std::vector<Declaration const*> NameAndTypeResolver::pathFromCurrentScopeWithAll
|
|||||||
|
|
||||||
pathDeclarations.push_back(candidates.front());
|
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)
|
if (candidates.size() == 1)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user