mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix shadowing struct types by struct member names
This commit is contained in:
@@ -26,6 +26,9 @@
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolutil/StringUtils.h>
|
||||
|
||||
#include <range/v3/view/filter.hpp>
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::frontend;
|
||||
@@ -139,16 +142,35 @@ bool DeclarationContainer::registerDeclaration(
|
||||
return registerDeclaration(_declaration, nullptr, nullptr, _invisible, _update);
|
||||
}
|
||||
|
||||
vector<Declaration const*> DeclarationContainer::resolveName(ASTString const& _name, bool _recursive, bool _alsoInvisible) const
|
||||
vector<Declaration const*> DeclarationContainer::resolveName(
|
||||
ASTString const& _name,
|
||||
bool _recursive,
|
||||
bool _alsoInvisible,
|
||||
bool _onlyVisibleAsUnqualifiedNames
|
||||
) const
|
||||
{
|
||||
solAssert(!_name.empty(), "Attempt to resolve empty name.");
|
||||
vector<Declaration const*> result;
|
||||
|
||||
if (m_declarations.count(_name))
|
||||
result = m_declarations.at(_name);
|
||||
{
|
||||
if (_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))
|
||||
result += m_invisibleDeclarations.at(_name);
|
||||
{
|
||||
if (_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);
|
||||
result = m_enclosingContainer->resolveName(_name, true, _alsoInvisible, _onlyVisibleAsUnqualifiedNames);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,10 @@ class DeclarationContainer
|
||||
public:
|
||||
using Homonyms = std::vector<std::pair<langutil::SourceLocation const*, std::vector<Declaration const*>>>;
|
||||
|
||||
explicit DeclarationContainer(
|
||||
ASTNode const* _enclosingNode = nullptr,
|
||||
DeclarationContainer* _enclosingContainer = nullptr
|
||||
):
|
||||
m_enclosingNode(_enclosingNode), m_enclosingContainer(_enclosingContainer)
|
||||
DeclarationContainer() = default;
|
||||
explicit DeclarationContainer(ASTNode const* _enclosingNode, DeclarationContainer* _enclosingContainer):
|
||||
m_enclosingNode(_enclosingNode),
|
||||
m_enclosingContainer(_enclosingContainer)
|
||||
{
|
||||
if (_enclosingContainer)
|
||||
_enclosingContainer->m_innerContainers.emplace_back(this);
|
||||
@@ -57,7 +56,20 @@ public:
|
||||
bool registerDeclaration(Declaration const& _declaration, ASTString const* _name, langutil::SourceLocation const* _location, bool _invisible, bool _update);
|
||||
bool registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update);
|
||||
|
||||
std::vector<Declaration const*> resolveName(ASTString const& _name, bool _recursive = false, bool _alsoInvisible = false) const;
|
||||
/// 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<Declaration const*> resolveName(
|
||||
ASTString const& _name,
|
||||
bool _recursive = false,
|
||||
bool _alsoInvisible = false,
|
||||
bool _onlyVisibleAsUnqualifiedNames = false
|
||||
) const;
|
||||
ASTNode const* enclosingNode() const { return m_enclosingNode; }
|
||||
DeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; }
|
||||
std::map<ASTString, std::vector<Declaration const*>> const& declarations() const { return m_declarations; }
|
||||
@@ -80,8 +92,8 @@ public:
|
||||
void populateHomonyms(std::back_insert_iterator<Homonyms> _it) const;
|
||||
|
||||
private:
|
||||
ASTNode const* m_enclosingNode;
|
||||
DeclarationContainer const* m_enclosingContainer;
|
||||
ASTNode const* m_enclosingNode = nullptr;
|
||||
DeclarationContainer const* m_enclosingContainer = nullptr;
|
||||
std::vector<DeclarationContainer const*> m_innerContainers;
|
||||
std::map<ASTString, std::vector<Declaration const*>> m_declarations;
|
||||
std::map<ASTString, std::vector<Declaration const*>> m_invisibleDeclarations;
|
||||
|
||||
@@ -182,7 +182,13 @@ vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString c
|
||||
Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector<ASTString> const& _path) const
|
||||
{
|
||||
solAssert(!_path.empty(), "");
|
||||
vector<Declaration const*> candidates = m_currentScope->resolveName(_path.front(), true);
|
||||
vector<Declaration const*> candidates = m_currentScope->resolveName(
|
||||
_path.front(),
|
||||
/* _recursive */ true,
|
||||
/* _alsoInvisible */ false,
|
||||
/* _onlyVisibleAsUnqualifiedNames */ true
|
||||
);
|
||||
|
||||
for (size_t i = 1; i < _path.size() && candidates.size() == 1; i++)
|
||||
{
|
||||
if (!m_scopes.count(candidates.front()))
|
||||
@@ -627,7 +633,10 @@ void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope)
|
||||
solAssert(dynamic_cast<SourceUnit const*>(&_subScope), "Unexpected scope type.");
|
||||
else
|
||||
{
|
||||
bool newlyAdded = m_scopes.emplace(&_subScope, make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get())).second;
|
||||
bool newlyAdded = m_scopes.emplace(
|
||||
&_subScope,
|
||||
make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get())
|
||||
).second;
|
||||
solAssert(newlyAdded, "Unable to add new scope.");
|
||||
}
|
||||
m_currentScope = &_subScope;
|
||||
|
||||
Reference in New Issue
Block a user