Spicy
function.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <algorithm>
6 #include <utility>
7 #include <vector>
8 
9 #include <hilti/ast/declarations/parameter.h>
10 #include <hilti/ast/expressions/void.h>
11 #include <hilti/ast/id.h>
12 #include <hilti/ast/type.h>
13 #include <hilti/ast/types/error.h>
14 #include <hilti/ast/types/operand-list.h>
15 #include <hilti/base/util.h>
16 
17 namespace hilti {
18 namespace type {
19 
20 namespace function {
21 
26 enum class Flavor {
27  Hook,
28  Method,
29  Standard
30 };
31 
32 namespace detail {
33 constexpr util::enum_::Value<Flavor> flavors[] = {
34  {Flavor::Hook, "hook"},
35  {Flavor::Method, "method"},
36  {Flavor::Standard, "standard"},
37 };
38 } // namespace detail
39 
40 constexpr auto to_string(Flavor f) { return util::enum_::to_string(f, detail::flavors); }
41 
42 namespace flavor {
43 constexpr auto from_string(const std::string_view& s) { return util::enum_::from_string<Flavor>(s, detail::flavors); }
44 } // namespace flavor
45 
47 class Result : public NodeBase {
48 public:
49  Result(Type type, Meta m = Meta()) : NodeBase(nodes(std::move(type)), std::move(m)) {}
50 
51  Result() : NodeBase(nodes(node::none), Meta()) {}
52 
53  auto type() const { return type::effectiveType(child<Type>(0)); }
54 
56  auto properties() const { return node::Properties{}; }
57 
58  bool operator==(const Result& other) const { return type() == other.type(); }
59 };
60 
62 
63 namespace parameter {
64 using Kind = declaration::parameter::Kind;
65 } // namespace parameter
66 
67 } // namespace function
68 
70 public:
71  Function(Wildcard /*unused*/, Meta m = Meta())
72  : TypeBase({function::Result(type::Error(m))}, std::move(m)), _wildcard(true) {}
73  Function(function::Result result, const std::vector<function::Parameter>& params,
74  function::Flavor flavor = function::Flavor::Standard, Meta m = Meta())
75  : TypeBase(nodes(std::move(result), util::transform(params, [](const auto& p) { return Declaration(p); })),
76  std::move(m)),
77  _flavor(flavor) {}
78 
79  auto parameters() const { return childs<function::Parameter>(1, -1); }
80  const auto& result() const { return child<function::Result>(0); }
81  auto flavor() const { return _flavor; }
82 
83  const auto& operands() const {
84  if ( ! _cache.operands )
85  _cache.operands = type::OperandList::fromParameters(parameters());
86 
87  return *_cache.operands;
88  }
89 
90  bool operator==(const Function& other) const {
91  return result() == other.result() && parameters() == other.parameters();
92  }
93 
95  auto isEqual(const Type& other) const { return node::isEqual(this, other); }
97  auto typeParameters() const { return childs(); }
99  auto isWildcard() const { return _wildcard; }
100 
102  auto properties() const { return node::Properties{{"flavor", to_string(_flavor)}}; }
103 
104  void clearCache() { _cache.operands.reset(); }
105 
106 private:
107  bool _wildcard = false;
108  function::Flavor _flavor = function::Flavor::Standard;
109 
110  mutable struct { std::optional<hilti::type::OperandList> operands; } _cache;
111 };
112 
117 inline bool areEquivalent(const Function& f1, const Function& f2) {
118  if ( ! (f1.result() == f2.result()) )
119  return false;
120 
121  auto p1 = f1.parameters();
122  auto p2 = f2.parameters();
123  return std::equal(begin(p1), end(p1), begin(p2), end(p2),
124  [](const auto& p1, const auto& p2) { return areEquivalent(p1, p2); });
125 }
126 
127 } // namespace type
128 
129 inline Node to_node(type::function::Result t) { return Node(std::move(t)); }
130 
131 } // namespace hilti
Definition: function.h:69
Definition: error.h:13
auto properties() const
Definition: function.h:56
Definition: function.h:47
auto properties() const
Definition: function.h:102
const Node none
Definition: node.cc:12
auto isWildcard() const
Definition: function.h:99
Definition: meta.h:18
Definition: parameter.h:45
std::map< std::string, node::detail::PropertyValue > Properties
Definition: node.h:83
Definition: type.h:152
Definition: node.h:97
Definition: type.h:249
auto transform(const std::vector< X > &x, F f)
Definition: util.h:86
auto isEqual(const Type &other) const
Definition: function.h:95
auto typeParameters() const
Definition: function.h:97
Definition: node.h:318