[libsolidity] ASTUtils: Adds helper to quickly locate closest ASTNode match for a byte offset into a SourceUnit.

This commit is contained in:
Christian Parpart 2021-05-10 13:04:38 +02:00
parent 07b9270185
commit c7cdba8ceb
2 changed files with 41 additions and 1 deletions

View File

@ -17,6 +17,7 @@
// SPDX-License-Identifier: GPL-3.0
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/ast/ASTUtils.h>
#include <libsolutil/Algorithms.h>
@ -24,6 +25,40 @@
namespace solidity::frontend
{
namespace
{
class ASTNodeLocator: public ASTConstVisitor
{
public:
explicit ASTNodeLocator(int _pos): m_offsetInFile{_pos}, m_innermostMatch{nullptr} {}
bool visitNode(ASTNode const& _node) override
{
// In the AST parent location always covers the whole child location.
// The parent is visited first so to get the innermost node we simply
// take the last one that still contains the offset.
if (!_node.location().containsOffset(m_offsetInFile))
return false;
m_innermostMatch = &_node;
return true;
}
int const m_offsetInFile;
ASTNode const* m_innermostMatch;
};
}
ASTNode const* locateInnermostASTNode(int _pos, SourceUnit const& _sourceUnit)
{
ASTNodeLocator locator{_pos};
_sourceUnit.accept(locator);
return locator.m_innermostMatch;
}
bool isConstantVariableRecursive(VariableDeclaration const& _varDecl)
{
solAssert(_varDecl.isConstant(), "Constant variable expected");

View File

@ -21,9 +21,11 @@
namespace solidity::frontend
{
class VariableDeclaration;
class ASTNode;
class Declaration;
class Expression;
class SourceUnit;
class VariableDeclaration;
/// Find the topmost referenced constant variable declaration when the given variable
/// declaration value is an identifier. Works only for constant variable declarations.
@ -33,4 +35,7 @@ VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration cons
/// Returns true if the constant variable declaration is recursive.
bool isConstantVariableRecursive(VariableDeclaration const& _varDecl);
/// Teturns the innermost AST node that covers the given location or nullptr if not found.
ASTNode const* locateInnermostASTNode(int _pos, SourceUnit const& _sourceUnit);
}