15 #include <type_traits> 24 #include <hilti/ast/doc-string.h> 25 #include <hilti/ast/meta.h> 26 #include <hilti/ast/node-ref.h> 27 #include <hilti/ast/scope.h> 28 #include <hilti/base/type_erase.h> 29 #include <hilti/base/util.h> 46 using PropertyValue = std::variant<bool, const char*, double, int, int64_t, unsigned int, uint64_t, std::string>;
49 inline std::string to_string(
const PropertyValue& v) {
51 auto operator()(
bool s) {
return std::string(s ?
"true" :
"false"); }
52 auto operator()(
const char* s) {
return util::escapeUTF8(s); }
53 auto operator()(
double d) {
return util::fmt(
"%.6f", d); }
54 auto operator()(
int i) {
return util::fmt(
"%d", i); }
55 auto operator()(int64_t i) {
return util::fmt(
"%" PRId64, i); }
56 auto operator()(
const std::string& s) {
return util::escapeUTF8(s); }
57 auto operator()(
unsigned int u) {
return util::fmt(
"%u", u); }
58 auto operator()(uint64_t u) {
return util::fmt(
"%" PRIu64, u); }
61 return std::visit(Visitor(), v);
75 return static_cast<std::underlying_type_t<ErrorPriority>
>(x) <
76 static_cast<std::underlying_type_t<ErrorPriority>
>(y);
88 bool operator<(
const Error& other)
const {
89 return std::tie(message, location) < std::tie(other.
message, other.
location);
98 using Properties = std::map<std::string, node::detail::PropertyValue>;
101 #include <hilti/autogen/__node.h> 112 class Node final :
public node::detail::Node {
115 template<typename T, typename std::enable_if_t<std::is_base_of<trait::isNode, T>::value>* =
nullptr>
118 Node(
const Node& other) : node::detail::Node::Node(other), _scope(other._scope) {}
121 : node::detail::Node::Node(std::move(other)),
122 _control_ptr(std::move(other._control_ptr)),
123 _scope(std::move(other._scope)),
124 _errors(std::move(other._errors)) {
126 _control_ptr->_node =
this;
133 _control_ptr->_node =
nullptr;
143 uint64_t
rid()
const {
return _control_ptr ? _control_ptr->_rid : 0; }
150 std::string
renderedRid()
const {
return rid() ? util::fmt(
"%%%" PRIu64, rid()) :
"%???"; };
160 _scope = make_intrusive<Scope>();
177 _scope = make_intrusive<Scope>();
181 std::vector<node::Error>
errors()
const {
189 bool hasErrors()
const {
return _errors && _errors->size(); }
205 void addError(std::string msg, std::vector<std::string> context = {}) {
206 addError(std::move(msg),
location(), std::move(context));
219 addError(std::move(msg),
location(), priority, std::move(context));
244 error.
message = std::move(msg);
246 error.
context = std::move(context);
250 _errors = std::make_unique<std::vector<node::Error>>();
252 _errors->push_back(std::move(error));
259 void destroyChildren();
268 std::string render(
bool include_location =
true)
const;
280 void print(std::ostream& out,
bool compact =
false)
const;
286 std::string print()
const;
295 std::cerr <<
"Assertion failure: Node expected to be a " <<
typeid(T).name() <<
" but is a " 296 << typeid_().name() << std::endl;
297 util::abort_with_backtrace();
302 operator std::string()
const {
return print(); }
313 node::detail::ErasedBase::operator=(n);
322 _scope = std::move(n._scope);
323 node::detail::ErasedBase::operator=(std::move(n));
334 node::detail::ErasedBase::operator=(to_node(t));
344 if ( ! _control_ptr )
345 _control_ptr = make_intrusive<node_ref::detail::Control>(
this);
352 std::unique_ptr<std::vector<node::Error>> _errors =
nullptr;
376 for (
auto& c : children )
377 addChild(std::move(c));
391 return _children[i].as<T>();
402 _children[i].template assertIsA<T>();
416 auto end_ = (end < 0) ? _children.end() : _children.begin() + end;
429 auto end_ = (end < 0) ? _children.end() : _children.begin() + end;
431 std::vector<NodeRef> refs;
432 for (
auto c = _children.begin(); c != end_; c = std::next(c) )
433 refs.emplace_back(*c);
455 std::vector<NodeRef> childRefsOfType()
const;
462 if ( _meta.location() && ! n.
location() ) {
464 m.setLocation(_meta.location());
465 n.setMeta(std::move(m));
468 _children.push_back(std::move(n));
476 auto&
meta()
const {
return _meta; }
483 std::vector<::hilti::Node> _children;
502 _doc = std::move(doc);
508 std::optional<DocString> _doc;
537 using BaseIterator = std::vector<Node>::const_iterator;
540 using value_type = BaseIterator::value_type;
541 using difference_type = BaseIterator::difference_type;
542 using pointer = BaseIterator::pointer;
543 using reference = BaseIterator::reference;
544 using iterator_category = BaseIterator::iterator_category;
552 const Node& node()
const {
return *_iter; }
556 const T& operator*()
const {
return value(); }
557 const T* operator->()
const {
return &value(); }
558 bool operator==(
const RangeIterator& other)
const {
return _iter == other._iter; }
559 bool operator!=(
const RangeIterator& other)
const {
return ! (*
this == other); }
582 difference_type operator-(
const RangeIterator& other)
const {
return _iter - other._iter; }
587 const T& value()
const {
return (*_iter).template as<std::remove_const_t<T>>(); }
604 Range(std::vector<Node>::const_iterator begin, std::vector<Node>::const_iterator end) : _begin(begin), _end(end) {}
606 explicit Range(
const std::vector<Node>& nodes) :
Range(nodes.begin(), nodes.end()) {}
612 auto begin()
const {
return const_iterator(_begin); }
613 auto end()
const {
return const_iterator(_end); }
614 size_t size()
const {
return static_cast<size_t>(_end - _begin); }
615 const T& front()
const {
return *_begin; }
616 bool empty()
const {
return _begin == _end; }
624 for (
auto i = _begin; i != _end; i++ )
630 const T& operator[](
size_t i)
const {
631 assert(
static_cast<typename RangeIterator<T>::difference_type
>(i) < std::distance(_begin, _end));
632 return *(_begin + i);
635 bool operator==(
const Range& other)
const {
636 if (
this == &other )
639 if ( size() != other.size() )
643 auto y = other._begin;
644 while ( x != _end ) {
645 if ( ! (*x++ == *y++) )
652 Range& operator=(
const Range& other) =
default;
653 Range& operator=(
Range&& other) noexcept =
default;
668 using BaseIterator =
typename std::vector<std::reference_wrapper<const T>>::const_iterator;
672 using value_type = T;
673 using difference_type =
typename BaseIterator::difference_type;
674 using pointer =
typename BaseIterator::pointer;
675 using reference =
typename BaseIterator::reference;
676 using iterator_category =
typename BaseIterator::iterator_category;
678 explicit SetIterator(BaseIterator i) : _iter(std::move(i)) {}
684 const Node& node()
const {
return *_iter; }
688 const T& operator*()
const {
return value(); }
689 const T* operator->()
const {
return &value(); }
690 bool operator==(
const SetIterator& other)
const {
return _iter == other._iter; }
691 bool operator!=(
const SetIterator& other)
const {
return ! (*
this == other); }
714 difference_type operator-(
const SetIterator& other)
const {
return _iter - other._iter; }
719 const T& value()
const {
return ((*_iter).get()); }
737 Set(
const Set& other) =
default;
738 Set(
Set&& other) noexcept =
default;
741 auto begin()
const {
return const_iterator(_set.begin()); }
742 auto end()
const {
return const_iterator(_set.end()); }
743 size_t size()
const {
return _set.size(); }
744 bool empty()
const {
return _set.empty(); }
745 void insert(
const T& t) { _set.push_back(t); }
753 for (
auto i = begin(); i != end(); i++ )
759 const T& operator[](
size_t i)
const {
return *(begin() + i); }
761 bool operator==(
const Set& other)
const {
762 if (
this == &other )
765 if ( size() != other.size() )
769 auto y = other.begin();
770 while ( x != end() ) {
771 if ( ! (*x++ == *y++) )
778 Set& operator=(
const Set& other) =
default;
779 Set& operator=(
Set&& other) noexcept =
default;
782 std::vector<std::reference_wrapper<const T>> _set;
794 template<
typename T, IF_SAME(T, Node)>
795 inline Node to_node(
const T& n) {
801 Node to_node(std::optional<T> t) {
803 return to_node(std::move(*t));
813 std::vector<Node> nodes(std::vector<T> t) {
816 for (
const auto& i : t )
817 v.emplace_back(std::move(i));
827 std::vector<Node> nodes(std::list<T> t) {
829 for (
const auto& i : t )
830 v.emplace_back(std::move(i));
843 for (
const auto& i : t )
844 v.emplace_back(std::move(i));
851 std::vector<Node> nodes(T t) {
852 return {to_node(std::move(t))};
859 template<
typename T,
typename... Ts>
860 std::vector<Node> nodes(T t, Ts... ts) {
861 return util::concat(std::move(nodes(t)), nodes(std::move(ts)...));
871 template<
typename T,
typename Other, IF_DERIVED_FROM(T, trait::isNode), IF_DERIVED_FROM(Other, trait::isNode)>
872 bool isEqual(
const T* this_,
const Other& other) {
873 if (
const auto o = other.template tryAs<T>() )
883 template<
typename X,
typename F>
886 for (
const auto& i : x ) {
898 template<
typename X,
typename F>
901 for (
const auto& i : x ) {
913 template<
typename X,
typename F>
915 using Y =
typename std::invoke_result_t<F, X&>;
918 for (
const auto& i : x )
928 template<
typename X,
typename F>
930 using Y =
typename std::invoke_result_t<F, X&>;
933 for (
const auto& i : x )
943 inline std::ostream& operator<<(std::ostream& out,
const Node& n) {
951 for (
auto c = _children.begin(); c != _children.end(); c = std::next(c) ) {
952 if (
auto t = c->tryAs<T>() )
961 typename std::vector<NodeRef> n;
962 for (
auto c = _children.begin(); c != _children.end(); c = std::next(c) ) {
982 detail::flattenedChildren(n, &dst);
std::vector< T > copy() const
Definition: node.h:622
ErrorPriority priority
Definition: node.h:84
std::vector< std::string > context
Definition: node.h:83
uint64_t rid() const
Definition: node.h:143
bool pruneWalk() const
Definition: node.h:480
IntrusivePtr< Scope > scope() const
Definition: node.h:158
NodeBase(Meta meta)
Definition: node.h:367
void assertIsA()
Definition: node.h:293
void addError(std::string msg, const Location &l, std::vector< std::string > context={})
Definition: node.h:230
Node & operator=(const T &t)
Definition: node.h:333
Definition: doc-string.h:15
void clearDocumentation()
Definition: node.h:497
const Node none
Definition: node.cc:14
auto filter(const hilti::node::Range< X > &x, F f)
Definition: node.h:884
auto childRefs(int begin, int end)
Definition: node.h:428
bool hasErrors() const
Definition: node.h:189
Definition: optional.h:79
const auto & children() const
Definition: node.h:472
static None create()
Definition: node.h:521
void addChild(Node n)
Definition: node.h:461
void clearScope()
Definition: node.h:171
auto & children()
Definition: node.h:474
void addError(std::string msg, std::vector< std::string > context={})
Definition: node.h:205
void setScope(IntrusivePtr< Scope > new_scope)
Definition: node.h:168
const Location & location() const
Definition: node.h:289
const std::optional< DocString > & documentation() const
Definition: node.h:494
Location location
Definition: node.h:82
Node & operator=(Node &&n) noexcept
Definition: node.h:321
std::vector< NodeRef > childRefsOfType() const
Definition: node.h:960
std::vector< T > copy() const
Definition: node.h:751
std::string renderedRid() const
Definition: node.h:150
void clearErrors()
Definition: node.h:192
void addError(std::string msg, Location l, node::ErrorPriority priority, std::vector< std::string > context={})
Definition: node.h:242
auto properties() const
Definition: node.h:515
std::vector< node::Error > errors() const
Definition: node.h:181
Definition: intrusive-ptr.h:69
auto children(int begin, int end) const
Definition: node.h:415
Definition: type_erase.h:30
void setMeta(Meta m)
Definition: node.h:478
void print(std::ostream &out, bool compact=false) const
Definition: node.cc:133
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:98
std::string message
Definition: node.h:81
hilti::node::Set< T > childrenOfType() const
Definition: node.h:949
const T & child(int i) const
Definition: node.h:390
NodeBase(std::vector< Node > children, Meta meta)
Definition: node.h:375
Definition: node-ref.h:45
Definition: location.h:18
void addError(std::string msg, node::ErrorPriority priority, std::vector< std::string > context={})
Definition: node.h:218
Node & operator=(const Node &n)
Definition: node.h:308
void setDocumentation(DocString doc)
Definition: node.h:500
ErrorPriority
Definition: node.h:67
auto & meta() const
Definition: node.h:476
Definition: location.h:94
Node(T t)
Definition: node.h:116
void assertChildIsA(int i)
Definition: node.h:401