Spicy
computed.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <functional>
6 #include <utility>
7 #include <vector>
8 
9 #include <hilti/ast/declaration.h>
10 #include <hilti/ast/declarations/type.h>
11 #include <hilti/ast/node_ref.h>
12 #include <hilti/ast/type.h>
13 #include <hilti/ast/types/unknown.h>
14 
15 namespace hilti {
16 namespace type {
17 
28 class Computed : public TypeBase,
34 public:
35  using Callback = std::function<Type(Node&)>;
36  using Callback2 = std::function<Type(Node&, Node&)>;
37  Computed(NodeRef r, Meta m = Meta()) : TypeBase(nodes(node::none), std::move(m)), _node(std::move(r)) {}
38  Computed(NodeRef r, Callback cb, Meta m = Meta())
39  : TypeBase(nodes(node::none), std::move(m)), _node(std::move(r)), _callback(std::move(cb)) {}
40  Computed(Expression e, Meta m = Meta()) : TypeBase(nodes(std::move(e)), std::move(m)) {}
41  Computed(NodeRef r1, NodeRef r2, Callback2 cb, Meta m = Meta())
42  : TypeBase(nodes(node::none), std::move(m)),
43  _node(std::move(r1)),
44  _node2(std::move(r2)),
45  _callback2(std::move(cb)) {}
46  Computed(Expression e, Callback cb, Meta m = Meta())
47  : TypeBase(nodes(std::move(e)), std::move(m)), _callback(std::move(cb)) {}
48  Computed(Type t, Meta m = Meta()) : TypeBase(nodes(std::move(t)), std::move(m)) {}
49  Computed(Type t, Callback cb, Meta m = Meta())
50  : TypeBase(nodes(std::move(t)), std::move(m)), _callback(std::move(cb)) {}
51  Computed(Type t, Node n, Callback2 cb2, Meta m = Meta())
52  : TypeBase(nodes(std::move(t), std::move(n)), std::move(m)), _callback2(std::move(cb2)) {}
53 
54  Type type() const {
55  if ( _node ) {
56  if ( _callback )
57  return type::effectiveType(_callback(*_node));
58  else if ( _callback2 ) {
59  assert(_node2);
60  return type::effectiveType(_callback2(*_node, *_node2));
61  }
62  else
63  return type::effectiveType(_node->template as<Type>());
64  }
65 
66  if ( auto e = childs()[0].tryAs<Expression>() ) {
67  if ( _callback )
68  return type::effectiveType(_callback(const_cast<Node&>(childs()[0])));
69  else if ( _callback2 )
70  return type::effectiveType(_callback2(const_cast<Node&>(childs()[0]), const_cast<Node&>(childs()[1])));
71 
72  if ( ! _change_constness_to.has_value() )
73  return e->type();
74 
75  if ( *_change_constness_to )
76  return type::constant(e->type());
77 
78  return type::nonConstant(e->type());
79  }
80 
81  if ( auto t = childs()[0].tryAs<Type>() ) {
82  if ( _callback )
83  return type::effectiveType(_callback(const_cast<Node&>(childs()[0])));
84  else if ( _callback2 )
85  return type::effectiveType(_callback2(const_cast<Node&>(childs()[0]), const_cast<Node&>(childs()[1])));
86  else
87  return *t;
88  }
89 
90  return type::unknown;
91  }
92 
93  bool operator==(const Computed& other) const { return type() == other.type(); }
94 
96  bool isEqual(const Type& other) const { return type() == other; }
98  Type effectiveType() const { return type::effectiveType(type()); }
99 
100  std::vector<Node> typeParameters() const { return type().typeParameters(); }
101  bool isWildcard() const { return type().isWildcard(); }
102  Type iteratorType(bool const_) const { return type().iteratorType(const_); }
103  Type viewType() const { return type().viewType(); }
104  Type dereferencedType() const { return type().dereferencedType(); }
105  Type elementType() const { return type().elementType(); }
106 
108  auto properties() const {
109  node::Properties props;
110  if ( _node )
111  props.insert({"resolved", _node.renderedRid()});
112 
113  if ( _node2 )
114  props.insert({"resolved2", _node2.renderedRid()});
115 
116  props.insert({"rid", _node.renderedRid()});
117  return props;
118  }
119 
120 private:
121  NodeRef _node;
122  NodeRef _node2;
123  Callback _callback;
124  Callback2 _callback2;
125  std::optional<bool> _change_constness_to;
126 };
127 
128 } // namespace type
129 } // namespace hilti
std::string renderedRid() const
Definition: node_ref.h:68
auto & childs() const
Definition: node.h:445
Type effectiveType() const
Definition: computed.h:98
const Node none
Definition: node.cc:12
Definition: computed.h:28
Definition: meta.h:18
Definition: type.h:25
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:83
Definition: type.h:152
Definition: type.h:33
Definition: node.h:97
Definition: node_ref.h:44
auto properties() const
Definition: computed.h:108
bool isEqual(const Type &other) const
Definition: computed.h:96