Spicy
enum.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <algorithm>
6 #include <set>
7 #include <utility>
8 #include <vector>
9 
10 #include <hilti/ast/declaration.h>
11 #include <hilti/ast/declarations/constant.h>
12 #include <hilti/ast/id.h>
13 #include <hilti/ast/type.h>
14 #include <hilti/ast/types/auto.h>
15 #include <hilti/ast/types/bool.h>
16 #include <hilti/ast/types/unknown.h>
17 
18 namespace hilti::type {
19 
20 namespace enum_ {
23 public:
24  Label() : NodeBase({ID("<no id>")}, Meta()) {}
25  Label(ID id, Meta m = Meta()) : NodeBase(nodes(std::move(id)), std::move(m)) {}
26  Label(ID id, int v, Meta m = Meta()) : NodeBase(nodes(std::move(id)), std::move(m)), _value(v) {}
27 
28  // Recreate from an existing label, but setting type.
29  Label(const Label& other, NodeRef enum_type)
30  : NodeBase(nodes(other.id()), other.meta()), _etype(std::move(enum_type)), _value(other._value) {}
31 
32  const ID& id() const { return child<ID>(0); }
33  const auto& enumType() const { return _etype ? _etype->as<Type>() : type::auto_; }
34  auto value() const { return _value; }
35 
36  bool operator==(const Label& other) const { return id() == other.id() && value() == other.value(); }
37 
39  auto properties() const { return node::Properties{{"value", _value}, {"etype", _etype.rid()}}; }
40 
41 private:
42  NodeRef _etype;
43  int _value = -1;
44 };
45 
46 inline Node to_node(Label l) { return Node(std::move(l)); }
47 
48 } // namespace enum_
49 
52 public:
53  Enum(std::vector<enum_::Label> l, Meta m = Meta())
54  : TypeBase(nodes(_normalizeLabels(std::move(l))), std::move(m)) {}
55  Enum(Wildcard /*unused*/, Meta m = Meta()) : TypeBase(std::move(m)), _wildcard(true) {}
56 
57  std::vector<std::reference_wrapper<const enum_::Label>> labels() const;
58 
63  std::vector<std::reference_wrapper<const enum_::Label>> uniqueLabels() const;
64 
65  hilti::optional_ref<const enum_::Label> label(const ID& id) const {
66  for ( const auto& l : labels() ) {
67  if ( l.get().id() == id )
68  return l.get();
69  }
70 
71  return {};
72  }
73 
74  auto labelDeclarationRefs() { return childRefs(0, -1); }
75 
76  bool operator==(const Enum& other) const {
77  return children<Declaration>(0, -1) == other.children<Declaration>(0, -1);
78  }
79 
81  auto isEqual(const Type& other) const { return node::isEqual(this, other); }
83  auto _isResolved(ResolvedState* rstate) const { return _initialized; }
85  auto typeParameters() const {
86  std::vector<Node> params;
87  for ( auto&& c : uniqueLabels() )
88  params.emplace_back(c.get());
89 
90  return params;
91  }
93  auto isWildcard() const { return _wildcard; }
94 
96  auto properties() const { return node::Properties{}; }
97 
99  static void initLabelTypes(Node* n);
100 
101 private:
102  static std::vector<Declaration> _normalizeLabels(std::vector<enum_::Label> labels);
103 
104  bool _wildcard = false;
105  bool _initialized = false;
106 };
107 
108 } // namespace hilti::type
Definition: type.h:34
Definition: declaration.h:54
auto childRefs(int begin, int end)
Definition: node.h:428
auto isEqual(const Type &other) const
Definition: enum.h:81
Definition: meta.h:19
auto _isResolved(ResolvedState *rstate) const
Definition: enum.h:83
Definition: type.h:160
Definition: optional-ref.h:22
auto properties() const
Definition: enum.h:96
auto typeParameters() const
Definition: enum.h:85
auto properties() const
Definition: enum.h:39
auto children(int begin, int end) const
Definition: node.h:415
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:98
Definition: type.h:206
Definition: enum.h:51
Definition: node.h:112
Definition: node-ref.h:45
Definition: type.h:33
Definition: type.h:277
auto & meta() const
Definition: node.h:476
uint64_t rid() const
Definition: node-ref.h:61
auto isWildcard() const
Definition: enum.h:93
Definition: enum.h:22
Definition: type.h:26
Definition: id.h:18
Definition: node.h:360