Spicy
unit.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <memory>
6 #include <optional>
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 #include <hilti/ast/expressions/type.h>
12 
13 #include <spicy/ast/types/unit-item.h>
14 #include <spicy/ast/types/unit-items/field.h>
15 #include <spicy/ast/types/unit-items/property.h>
16 #include <spicy/ast/types/unit-items/switch.h>
17 #include <spicy/ast/types/unit-items/unresolved-field.h>
18 #include <spicy/compiler/detail/codegen/grammar.h>
19 
20 namespace spicy {
21 
22 namespace detail::codegen {
23 class Grammar;
24 } // namespace detail::codegen
25 
26 namespace type {
27 
28 namespace detail {
37 struct AssignIndices {
44  std::vector<unit::Item> assignIndices(std::vector<unit::Item> items);
45 
46  uint64_t _next_index = 0;
47 };
48 } // namespace detail
49 
52  public hilti::TypeBase,
56 public:
57  Unit(std::vector<type::function::Parameter> p, std::vector<unit::Item> i,
58  const std::optional<AttributeSet>& /* attrs */ = {}, Meta m = Meta())
59  : TypeBase(hilti::nodes(std::move(p), assignIndices(std::move(i))), std::move(m)) {
60  _state().flags += type::Flag::NoInheritScope;
61  }
62 
63  Unit(Wildcard /*unused*/, Meta m = Meta()) : TypeBase(std::move(m)), _wildcard(true) {
64  _state().flags += type::Flag::NoInheritScope;
65  }
66 
67  auto parameters() const { return childsOfType<type::function::Parameter>(); }
68  auto items() const { return childsOfType<unit::Item>(); }
69 
70  std::optional<AttributeSet> attributes() const {
71  auto x = childsOfType<AttributeSet>();
72  if ( x.size() )
73  return x[0];
74  else
75  return {};
76  }
77 
78  auto types() const {
79  std::vector<Type> types;
80  for ( auto c : childs() )
81  types.push_back(c.as<unit::Item>().itemType());
82 
83  return types;
84  }
85 
87  std::optional<Type> contextType() const {
88  if ( auto context = propertyItem("%context") )
89  return context->expression()->as<hilti::expression::Type_>().typeValue();
90  else
91  return {};
92  }
93 
98  std::optional<unit::Item> field(const ID& id) const;
99 
103  template<typename T>
104  auto items() const {
105  std::vector<T> v;
106  for ( const auto& c : childs() ) {
107  if ( auto x = c.tryAs<T>() )
108  v.push_back(*x);
109  }
110  return v;
111  }
112 
117  std::optional<unit::item::Property> propertyItem(const std::string& name) const {
118  for ( auto i : items<unit::item::Property>() ) {
119  if ( i.id() == name )
120  return i;
121  }
122 
123  return {};
124  }
125 
127  auto propertyItems(const std::string& name) const {
128  std::vector<unit::item::Property> props;
129 
130  for ( const auto& i : items<unit::item::Property>() ) {
131  if ( i.id() == name )
132  props.push_back(i);
133  }
134 
135  return props;
136  }
137 
142  auto isPublic() const { return _public; };
143 
153  bool usesRandomAccess() const { return propertyItem("%random-access").has_value(); }
154 
162  bool supportsSinks() const { return isPublic(); }
163 
171  bool supportsFilters() const { return isPublic(); }
172 
180  bool isFilter() const { return propertyItem("%filter").has_value(); }
181 
184  assert(_grammar);
185  return *_grammar;
186  }
187 
188  bool operator==(const Unit& other) const { return typeID() == other.typeID(); }
189 
190  // Type interface.
191  auto isEqual(const Type& other) const { return node::isEqual(this, other); }
192 
193  // type::trait::Parameterized interface.
194  auto typeParameters() const { return childs(); }
195  auto isWildcard() const { return _wildcard; }
196 
197  // Node interface.
198  auto properties() const { return node::Properties{{"public", _public}}; }
199 
207  static Unit setPublic(const Unit& unit, bool p) {
208  auto x = Type(unit)._clone().as<Unit>();
209  x._public = p;
210  return x;
211  }
212 
220  static Unit addItems(const Unit& unit, std::vector<unit::Item> items) {
221  auto x = Type(unit)._clone().as<Unit>();
222  auto new_items = x.assignIndices(items);
223 
224  for ( auto i : new_items )
225  x.childs().emplace_back(std::move(i));
226 
227  return x;
228  }
229 
237  static Unit addAttributes(const Unit& unit, AttributeSet attrs) {
238  auto x = Type(unit)._clone().as<Unit>();
239  x.childs().push_back(std::move(attrs));
240  return x;
241  }
242 
250  static Unit setGrammar(const Unit& unit, std::shared_ptr<spicy::detail::codegen::Grammar> g) {
251  auto x = Type(unit)._clone().as<Unit>();
252  x._grammar = std::move(g);
253  return x;
254  }
255 
256 private:
257  bool _public = false;
258  bool _wildcard = false;
259  std::shared_ptr<spicy::detail::codegen::Grammar> _grammar;
260 };
261 
262 
263 } // namespace type
264 } // namespace spicy
Definition: type.h:14
bool supportsSinks() const
Definition: unit.h:162
std::vector< unit::Item > assignIndices(std::vector< unit::Item > items)
Definition: unit.cc:34
std::vector< T > childs(int begin, int end) const
Definition: node.h:373
bool supportsFilters() const
Definition: unit.h:171
auto items() const
Definition: unit.h:104
const spicy::detail::codegen::Grammar & grammar() const
Definition: unit.h:183
auto propertyItems(const std::string &name) const
Definition: unit.h:127
Definition: unit.h:51
type::Flags flags() const
Definition: type.h:159
std::optional< unit::item::Property > propertyItem(const std::string &name) const
Definition: unit.h:117
Definition: meta.h:18
Definition: attribute.h:159
static Unit addAttributes(const Unit &unit, AttributeSet attrs)
Definition: unit.h:237
auto isPublic() const
Definition: unit.h:142
bool usesRandomAccess() const
Definition: unit.h:153
std::optional< ID > typeID() const
Definition: type.h:163
Definition: type.h:152
bool isFilter() const
Definition: unit.h:180
std::optional< Type > contextType() const
Definition: unit.h:87
Definition: type.h:23
static Unit setPublic(const Unit &unit, bool p)
Definition: unit.h:207
Definition: type.h:249
Definition: grammar.h:21
static Unit addItems(const Unit &unit, std::vector< unit::Item > items)
Definition: unit.h:220
static Unit setGrammar(const Unit &unit, std::shared_ptr< spicy::detail::codegen::Grammar > g)
Definition: unit.h:250
Definition: id.h:18
Definition: type.h:28