From 9524ca5e3199c2a069ff7e7b532450cb04dc3346 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 29 Apr 2015 15:52:56 +0200 Subject: [PATCH] Utility class to find a suitable AST node for a given location. --- libevmcore/SourceLocation.h | 25 +++++++++++++++++ libsolidity/ASTUtils.cpp | 48 +++++++++++++++++++++++++++++++++ libsolidity/ASTUtils.h | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 libsolidity/ASTUtils.cpp create mode 100644 libsolidity/ASTUtils.h diff --git a/libevmcore/SourceLocation.h b/libevmcore/SourceLocation.h index c373e9cf3..abe291d0f 100644 --- a/libevmcore/SourceLocation.h +++ b/libevmcore/SourceLocation.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace dev { @@ -45,6 +46,9 @@ struct SourceLocation bool operator==(SourceLocation const& _other) const { return start == _other.start && end == _other.end;} bool operator!=(SourceLocation const& _other) const { return !operator==(_other); } + inline bool operator<(SourceLocation const& _other) const; + inline bool contains(SourceLocation const& _other) const; + inline bool intersects(SourceLocation const& _other) const; bool isEmpty() const { return start == -1 && end == -1; } @@ -61,4 +65,25 @@ inline std::ostream& operator<<(std::ostream& _out, SourceLocation const& _locat return _out << *_location.sourceName << "[" << _location.start << "," << _location.end << ")"; } +bool SourceLocation::operator<(SourceLocation const& _other) const +{ + if (!!sourceName != !!_other.sourceName) + return int(!!sourceName) < int(!!_other.sourceName); + return make_tuple(*sourceName, start, end) < make_tuple(*_other.sourceName, _other.start, _other.end); +} + +bool SourceLocation::contains(SourceLocation const& _other) const +{ + if (isEmpty() || _other.isEmpty() || !sourceName || !_other.sourceName || *sourceName != *_other.sourceName) + return false; + return start <= _other.start && _other.end <= end; +} + +bool SourceLocation::intersects(SourceLocation const& _other) const +{ + if (isEmpty() || _other.isEmpty() || !sourceName || !_other.sourceName || *sourceName != *_other.sourceName) + return false; + return _other.start < end && start < _other.end; +} + } diff --git a/libsolidity/ASTUtils.cpp b/libsolidity/ASTUtils.cpp new file mode 100644 index 000000000..081d6b317 --- /dev/null +++ b/libsolidity/ASTUtils.cpp @@ -0,0 +1,48 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** + * @author Christian + * @date 2015 + * Utilities to work with the AST. + */ + +#include + +using namespace std; +using namespace dev; +using namespace dev::solidity; + + + +ASTNode const* LocationFinder::leastUpperBound() +{ + m_bestMatch = nullptr; + for (ASTNode const* rootNode: m_rootNodes) + rootNode->accept(*this); + + return m_bestMatch; +} + +bool LocationFinder::visitNode(const ASTNode& _node) +{ + if (_node.getLocation().contains(m_location)) + { + m_bestMatch = &_node; + return true; + } + return false; +} diff --git a/libsolidity/ASTUtils.h b/libsolidity/ASTUtils.h new file mode 100644 index 000000000..f2b90ea53 --- /dev/null +++ b/libsolidity/ASTUtils.h @@ -0,0 +1,54 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** + * @author Christian + * @date 2015 + * Utilities to work with the AST. + */ + +#pragma once + +#include +#include + +namespace dev +{ +namespace solidity +{ + +class LocationFinder: private ASTConstVisitor +{ +public: + LocationFinder(SourceLocation const& _location, std::vector _rootNodes): + m_rootNodes(_rootNodes), m_location(_location) + { + } + + /// @returns the "closest" (in the sense of most-leafward) AST node which is a descendant of + /// _node and whose source location contains _location. + ASTNode const* leastUpperBound(); + +private: + bool visitNode(ASTNode const& _node); + + std::vector m_rootNodes; + SourceLocation m_location; + ASTNode const* m_bestMatch = nullptr; +}; + +} +}