Spicy
visitor-util.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <optional>
6 #include <utility>
7 #include <vector>
8 
9 #include <hilti/ast/node.h>
10 #include <hilti/base/logger.h>
11 #include <hilti/base/util.h>
12 
13 namespace hilti::visitor {
14 
19 template<typename N>
20 using Path = std::vector<std::reference_wrapper<N>>;
21 
23 template<typename N>
24 N& current(const Path<N>& path) {
25  if ( path.empty() )
26  logger().internalError("empty path in visitor");
27 
28  return (*(path.end() - 1)).get();
29 }
30 
38 inline const Node& parent(const Path<const Node>& path, int parent_nr = 1) {
39  if ( path.size() < 1 + parent_nr )
40  throw std::out_of_range("node does not have requested parent");
41 
42  return (*(path.end() - 1 - parent_nr)).get();
43 }
44 
52 inline Node& parent(const Path<Node>& path, int parent_nr = 1) {
53  if ( path.size() < 1 + parent_nr )
54  throw std::out_of_range("node does not have requested parent");
55 
56  return (*(path.end() - 1 - parent_nr)).get();
57 }
58 
63 template<typename T, IF_NOT_SAME(T, Node)>
64 std::optional<const T> findParent(const Path<Node>& path) {
65  for ( auto i = path.rbegin() + 1; i != path.rend(); i++ ) {
66  if ( auto t = (*i).get().tryAs<T>() )
67  return std::move(t);
68  }
69 
70  return {};
71 }
72 
77 template<typename T, IF_NOT_SAME(T, Node)>
78 std::optional<const T> findParent(const Path<const Node>& path) {
79  for ( auto i = path.rbegin() + 1; i != path.rend(); i++ ) {
80  if ( auto t = (*i).get().tryAs<T>() )
81  return std::move(t);
82  }
83 
84  return {};
85 }
86 
87 
88 } // namespace hilti::visitor
Definition: operator.h:22
N & current(const Path< N > &path)
Definition: visitor-util.h:24
std::vector< std::reference_wrapper< N > > Path
Definition: visitor-util.h:20
const Node & parent(const Path< const Node > &path, int parent_nr=1)
Definition: visitor-util.h:38
Definition: node.h:112
std::optional< const T > findParent(const Path< Node > &path)
Definition: visitor-util.h:64