Spicy
struct.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <algorithm>
6 #include <functional>
7 #include <optional>
8 #include <set>
9 #include <utility>
10 #include <vector>
11 
12 #include <hilti/ast/attribute.h>
13 #include <hilti/ast/declaration.h>
14 #include <hilti/ast/declarations/expression.h>
15 #include <hilti/ast/declarations/field.h>
16 #include <hilti/ast/expression.h>
17 #include <hilti/ast/expressions/grouping.h>
18 #include <hilti/ast/expressions/keyword.h>
19 #include <hilti/ast/expressions/unresolved-operator.h>
20 #include <hilti/ast/function.h>
21 #include <hilti/ast/id.h>
22 #include <hilti/ast/operators/reference.h>
23 #include <hilti/ast/scope.h>
24 #include <hilti/ast/type.h>
25 #include <hilti/ast/types/function.h>
26 #include <hilti/ast/types/reference.h>
27 #include <hilti/ast/types/unknown.h>
28 
29 namespace hilti::type {
30 
33 public:
34  Struct(std::vector<Declaration> fields, Meta m = Meta())
35  : TypeBase(nodes(node::none, std::move(fields)), std::move(m)) {}
36 
37  struct AnonymousStruct {};
38  Struct(AnonymousStruct _, std::vector<Declaration> fields, Meta m = Meta())
39  : TypeBase(nodes(node::none, std::move(fields)), std::move(m)), _anon_struct(++_anon_struct_counter) {}
40 
41  Struct(const std::vector<type::function::Parameter>& params, std::vector<Declaration> fields, Meta m = Meta())
42  : TypeBase(nodes(node::none, std::move(fields),
43  util::transform(params,
44  [](auto p) {
45  p.setIsTypeParameter();
46  return Declaration(p);
47  })),
48  std::move(m)) {}
49 
50  Struct(Wildcard /*unused*/, Meta m = Meta()) : TypeBase(nodes(node::none), std::move(m)), _wildcard(true) {}
51 
52  NodeRef selfRef() const {
53  if ( children()[0].isA<Declaration>() )
54  return NodeRef(children()[0]);
55  else
56  return {};
57  }
58 
59  auto hasFinalizer() const { return field("~finally").has_value(); }
60  auto parameters() const { return childrenOfType<type::function::Parameter>(); }
61  auto parameterRefs() const { return childRefsOfType<type::function::Parameter>(); }
62 
63  auto fields() const { return childrenOfType<declaration::Field>(); }
64 
65  hilti::optional_ref<const declaration::Field> field(const ID& id) const {
66  for ( const auto& f : fields() ) {
67  if ( f.id() == id )
68  return f;
69  }
70 
71  return {};
72  }
73 
74  hilti::node::Set<const declaration::Field> fields(const ID& id) const {
76  for ( const auto& f : fields() ) {
77  if ( f.id() == id )
78  x.insert(f);
79  }
80 
81  return x;
82  }
83 
84  void addField(Declaration f) {
85  assert(f.isA<declaration::Field>());
86  addChild(std::move(f));
87  }
88 
89  bool operator==(const Struct& other) const { return fields() == other.fields(); }
90 
92  auto isEqual(const Type& other) const {
93  if ( auto x = other.tryAs<type::Struct>() ) {
94  // Anonymous structs only compare successfully to themselves.
95  if ( _anon_struct >= 0 || x->_anon_struct >= 0 )
96  return _anon_struct == x->_anon_struct;
97  }
98 
99  return node::isEqual(this, other);
100  }
101 
103  auto _isResolved(ResolvedState* rstate) const {
104  const auto& cs = children();
105 
106  return std::all_of(cs.begin(), cs.end(), [&](const auto& c) {
107  if ( auto f = c.template tryAs<declaration::Field>() )
108  return f->isResolved(rstate);
109 
110  else if ( auto p = c.template tryAs<type::function::Parameter>() )
111  return p->isResolved(rstate);
112 
113  return true;
114  });
115  }
116 
118  auto typeParameters() const {
119  std::vector<Node> params;
120  for ( const auto& f : fields() )
121  params.emplace_back(f.type());
122  return params;
123  }
125  auto isWildcard() const { return _wildcard; }
126 
128  auto properties() const { return node::Properties{}; }
129 
136  static void setSelf(Node* n) {
137  assert(n->isA<type::Struct>());
138  Expression self =
139  expression::Keyword(expression::keyword::Kind::Self, type::ValueReference(NodeRef(*n)), n->meta());
140  Declaration d = declaration::Expression("self", std::move(self), declaration::Linkage::Private, n->meta());
141  n->children()[0] = d;
142  }
143 
144 private:
145  bool _wildcard = false;
146  int64_t _anon_struct = -1;
147 
148  static int64_t _anon_struct_counter;
149 };
150 
151 } // namespace hilti::type
Definition: declaration.h:53
const Node none
Definition: node.cc:14
Definition: keyword.h:38
const auto & children() const
Definition: node.h:471
void addChild(Node n)
Definition: node.h:460
Definition: struct.h:32
auto isWildcard() const
Definition: struct.h:125
auto properties() const
Definition: struct.h:128
auto isEqual(const Type &other) const
Definition: struct.h:92
Definition: type.h:38
Definition: meta.h:19
Definition: reference.h:82
auto typeParameters() const
Definition: struct.h:118
Definition: type.h:160
auto _isResolved(ResolvedState *rstate) const
Definition: struct.h:103
Definition: expression.h:16
Definition: optional-ref.h:22
Definition: node.h:40
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:97
Definition: type.h:206
Definition: node.h:111
Definition: node-ref.h:45
Definition: type.h:33
Definition: type.h:277
Definition: field.h:20
static void setSelf(Node *n)
Definition: struct.h:136
Definition: type.h:26
Definition: id.h:18