Merge pull request #13182 from ethereum/identifierPath_declarations

Add all path declarations in IdentifierPath annotation
This commit is contained in:
Mathias L. Baumann 2022-06-27 12:35:50 +02:00 committed by GitHub
commit 2397f09b79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 6 deletions

View File

@ -185,8 +185,18 @@ vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString c
}
Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector<ASTString> const& _path) const
{
if (auto declarations = pathFromCurrentScopeWithAllDeclarations(_path); !declarations.empty())
return declarations.back();
return nullptr;
}
std::vector<Declaration const*> NameAndTypeResolver::pathFromCurrentScopeWithAllDeclarations(std::vector<ASTString> const& _path) const
{
solAssert(!_path.empty(), "");
vector<Declaration const*> pathDeclarations;
vector<Declaration const*> candidates = m_currentScope->resolveName(
_path.front(),
/* _recursive */ true,
@ -197,13 +207,19 @@ Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector<ASTString> c
for (size_t i = 1; i < _path.size() && candidates.size() == 1; i++)
{
if (!m_scopes.count(candidates.front()))
return nullptr;
return {};
pathDeclarations.push_back(candidates.front());
candidates = m_scopes.at(candidates.front())->resolveName(_path[i], false);
}
if (candidates.size() == 1)
return candidates.front();
{
pathDeclarations.push_back(candidates.front());
return pathDeclarations;
}
else
return nullptr;
return {};
}
void NameAndTypeResolver::warnHomonymDeclarations() const

View File

@ -93,6 +93,10 @@ public:
/// Should only be called during the initial resolving phase.
/// @note Returns a null pointer if any component in the path was not unique or not found.
Declaration const* pathFromCurrentScope(std::vector<ASTString> const& _path) const;
/// Resolves a path starting from the "current" scope, but also searches parent scopes.
/// Should only be called during the initial resolving phase.
/// @note Returns an empty vector if any component in the path was non-unique or not found. Otherwise, all declarations along the path are returned.
std::vector<Declaration const*> pathFromCurrentScopeWithAllDeclarations(std::vector<ASTString> const& _path) const;
/// Generate and store warnings about declarations with the same name.
void warnHomonymDeclarations() const;

View File

@ -173,14 +173,15 @@ void ReferencesResolver::endVisit(ModifierDefinition const&)
void ReferencesResolver::endVisit(IdentifierPath const& _path)
{
Declaration const* declaration = m_resolver.pathFromCurrentScope(_path.path());
if (!declaration)
std::vector<Declaration const*> declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(_path.path());
if (declarations.empty())
{
m_errorReporter.fatalDeclarationError(7920_error, _path.location(), "Identifier not found or not unique.");
return;
}
_path.annotation().referencedDeclaration = declaration;
_path.annotation().referencedDeclaration = declarations.back();
_path.annotation().pathDeclarations = std::move(declarations);
}
bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)

View File

@ -256,6 +256,9 @@ struct IdentifierPathAnnotation: ASTAnnotation
Declaration const* referencedDeclaration = nullptr;
/// What kind of lookup needs to be done (static, virtual, super) find the declaration.
util::SetOnce<VirtualLookup> requiredLookup;
/// Declaration of each path element.
std::vector<Declaration const*> pathDeclarations;
};
struct ExpressionAnnotation: ASTAnnotation