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 {
19 namespace type {
20 
21 namespace enum_ {
24 public:
25  Label() : NodeBase({ID("<no id>")}, Meta()) {}
26  Label(ID id, Meta m = Meta()) : NodeBase(nodes(std::move(id)), std::move(m)) {}
27  Label(ID id, int v, Meta m = Meta()) : NodeBase(nodes(std::move(id)), std::move(m)), _value(v) {}
28 
29  // Recreate from an existing label, but setting type.
30  Label(const Label& other, NodeRef enum_type)
31  : NodeBase(nodes(other.id()), other.meta()), _etype(std::move(enum_type)), _value(other._value) {}
32 
33  const ID& id() const { return child<ID>(0); }
34  const auto& enumType() const { return _etype ? _etype->as<Type>() : type::auto_; }
35  auto value() const { return _value; }
36 
37  bool operator==(const Label& other) const { return id() == other.id() && value() == other.value(); }
38 
40  auto properties() const { return node::Properties{{"value", _value}, {"etype", _etype.rid()}}; }
41 
42 private:
43  NodeRef _etype;
44  int _value = -1;
45 };
46 
47 inline Node to_node(Label l) { return Node(std::move(l)); }
48 
49 } // namespace enum_
50 
53 public:
54  Enum(std::vector<enum_::Label> l, Meta m = Meta())
55  : TypeBase(nodes(_normalizeLabels(std::move(l))), std::move(m)) {}
56  Enum(Wildcard /*unused*/, Meta m = Meta()) : TypeBase(std::move(m)), _wildcard(true) {}
57 
58  std::vector<std::reference_wrapper<const enum_::Label>> labels() const;
59 
64  std::vector<std::reference_wrapper<const enum_::Label>> uniqueLabels() const;
65 
66  hilti::optional_ref<const enum_::Label> label(const ID& id) const {
67  for ( const auto& l : labels() ) {
68  if ( l.get().id() == id )
69  return l.get();
70  }
71 
72  return {};
73  }
74 
75  auto labelDeclarationRefs() { return childRefs(0, -1); }
76 
77  bool operator==(const Enum& other) const {
78  return children<Declaration>(0, -1) == other.children<Declaration>(0, -1);
79  }
80 
82  auto isEqual(const Type& other) const { return node::isEqual(this, other); }
84  auto _isResolved(ResolvedState* rstate) const { return _initialized; }
86  auto typeParameters() const {
87  std::vector<Node> params;
88  for ( auto&& c : uniqueLabels() )
89  params.emplace_back(c.get());
90 
91  return params;
92  }
94  auto isWildcard() const { return _wildcard; }
95 
97  auto properties() const { return node::Properties{}; }
98 
100  static void initLabelTypes(Node* n);
101 
102 private:
103  static std::vector<Declaration> _normalizeLabels(std::vector<enum_::Label> labels);
104 
105  bool _wildcard = false;
106  bool _initialized = false;
107 };
108 
109 } // namespace type
110 } // namespace hilti
Definition: declaration.h:53
auto childRefs(int begin, int end)
Definition: node.h:426
auto isEqual(const Type &other) const
Definition: enum.h:82
Definition: meta.h:18
auto _isResolved(ResolvedState *rstate) const
Definition: enum.h:84
Definition: type.h:159
Definition: optional-ref.h:22
auto properties() const
Definition: enum.h:97
auto typeParameters() const
Definition: enum.h:86
auto properties() const
Definition: enum.h:40
auto children(int begin, int end) const
Definition: node.h:413
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:99
Definition: type.h:198
Definition: enum.h:52
Definition: node.h:113
Definition: node-ref.h:44
Definition: type.h:33
Definition: type.h:269
auto & meta() const
Definition: node.h:474
uint64_t rid() const
Definition: node-ref.h:60
auto isWildcard() const
Definition: enum.h:94
Definition: enum.h:23
Definition: id.h:18
Definition: node.h:358