nixd
Loading...
Searching...
No Matches
Attrs.h
Go to the documentation of this file.
1#pragma once
2
3#include "Basic.h"
4#include "Simple.h"
5
6#include <map>
7
8namespace nixf {
9
10class AttrName : public Node {
11public:
13
14private:
15 const AttrNameKind Kind;
16 const std::shared_ptr<Identifier> ID;
17 const std::shared_ptr<ExprString> String;
18 const std::shared_ptr<Interpolation> Interp;
19
20public:
21 [[nodiscard]] AttrNameKind kind() const { return Kind; }
22
23 AttrName(std::shared_ptr<Identifier> ID, LexerCursorRange Range)
24 : Node(NK_AttrName, Range), Kind(ANK_ID), ID(std::move(ID)) {
25 assert(this->ID && "ID must not be null");
26 }
27
28 AttrName(std::shared_ptr<ExprString> String)
29 : Node(NK_AttrName, String->range()), Kind(ANK_String),
30 String(std::move(String)) {
31 assert(this->String && "String must not be null");
32 }
33
34 AttrName(std::shared_ptr<Interpolation> Interp)
35 : Node(NK_AttrName, Interp->range()), Kind(ANK_Interpolation),
36 Interp(std::move(Interp)) {
37 assert(this->Interp && "Interpolation must not be null");
38 }
39
40 [[nodiscard]] bool isStatic() const {
41 if (Kind == ANK_ID)
42 return true;
43 if (Kind == ANK_Interpolation)
44 return false;
45
46 assert(Kind == ANK_String);
47 return string().isLiteral();
48 }
49
50 [[nodiscard]] const std::string &staticName() const {
51 assert(isStatic() && "must be static");
52 if (Kind == ANK_ID)
53 return id()->name();
54 assert(Kind == ANK_String);
55 return string().literal();
56 }
57
58 [[nodiscard]] const Interpolation &interpolation() const {
59 assert(Kind == ANK_Interpolation);
60 assert(Interp && "Interpolation must not be null");
61 return *Interp;
62 }
63
64 [[nodiscard]] const std::shared_ptr<Identifier> &id() const {
65 assert(Kind == ANK_ID);
66 return ID;
67 }
68
69 [[nodiscard]] const ExprString &string() const {
70 assert(Kind == ANK_String);
71 assert(String && "String must not be null");
72 return *String;
73 }
74
75 [[nodiscard]] ChildVector children() const override {
76 switch (Kind) {
77 case ANK_ID:
78 return {ID.get()};
79 case ANK_String:
80 return {String.get()};
82 return {Interp.get()};
83 default:
84 assert(false && "invalid AttrNameKind");
85 }
86 __builtin_unreachable();
87 }
88};
89
90class AttrPath : public Node {
91 const std::vector<std::shared_ptr<AttrName>> Names;
92 const std::vector<std::shared_ptr<Dot>> Dots;
93
94public:
95 AttrPath(LexerCursorRange Range, std::vector<std::shared_ptr<AttrName>> Names,
96 std::vector<std::shared_ptr<Dot>> Dots)
97 : Node(NK_AttrPath, Range), Names(std::move(Names)),
98 Dots(std::move(Dots)) {}
99
100 [[nodiscard]] const std::vector<std::shared_ptr<AttrName>> &names() const {
101 return Names;
102 }
103
104 [[nodiscard]] ChildVector children() const override {
105 ChildVector Children;
106 Children.reserve(Names.size() + Dots.size());
107 for (const auto &Name : Names)
108 Children.push_back(Name.get());
109 for (const auto &Dot : Dots)
110 Children.emplace_back(Dot.get());
111 return Children;
112 }
113};
114
115class Binding : public Node {
116 const std::shared_ptr<AttrPath> Path;
117 const std::shared_ptr<Expr> Value;
118
119public:
120 Binding(LexerCursorRange Range, std::shared_ptr<AttrPath> Path,
121 std::shared_ptr<Expr> Value)
122 : Node(NK_Binding, Range), Path(std::move(Path)),
123 Value(std::move(Value)) {
124 assert(this->Path && "Path must not be null");
125 // Value can be null, if missing in the syntax.
126 }
127
128 [[nodiscard]] const AttrPath &path() const {
129 assert(Path && "Path must not be null");
130 return *Path;
131 }
132
133 [[nodiscard]] const std::shared_ptr<Expr> &value() const { return Value; }
134
135 [[nodiscard]] ChildVector children() const override {
136 return {Path.get(), Value.get()};
137 }
138};
139
140class Inherit : public Node {
141 const std::vector<std::shared_ptr<AttrName>> Names;
142 const std::shared_ptr<Expr> E;
143
144public:
145 Inherit(LexerCursorRange Range, std::vector<std::shared_ptr<AttrName>> Names,
146 std::shared_ptr<Expr> E)
147 : Node(NK_Inherit, Range), Names(std::move(Names)), E(std::move(E)) {}
148
149 [[nodiscard]] const std::vector<std::shared_ptr<AttrName>> &names() const {
150 return Names;
151 }
152
153 [[nodiscard]] bool hasExpr() { return E != nullptr; }
154
155 [[nodiscard]] const std::shared_ptr<Expr> &expr() const { return E; }
156
157 [[nodiscard]] ChildVector children() const override {
158 ChildVector Children;
159 Children.reserve(Names.size() + 1);
160 for (const auto &Name : Names) {
161 Children.push_back(Name.get());
162 }
163 Children.push_back(E.get());
164 return Children;
165 }
166};
167
168class Binds : public Node {
169 const std::vector<std::shared_ptr<Node>> Bindings;
170
171public:
172 Binds(LexerCursorRange Range, std::vector<std::shared_ptr<Node>> Bindings)
173 : Node(NK_Binds, Range), Bindings(std::move(Bindings)) {}
174
175 [[nodiscard]] const std::vector<std::shared_ptr<Node>> &bindings() const {
176 return Bindings;
177 }
178
179 [[nodiscard]] ChildVector children() const override {
180 ChildVector Children;
181 Children.reserve(Bindings.size());
182 for (const auto &Binding : Bindings) {
183 Children.push_back(Binding.get());
184 }
185 return Children;
186 }
187};
188
190public:
191 enum class AttributeKind {
192 /// a = b;
193 Plain,
194 /// inherit a b c;
195 Inherit,
196 /// inherit (expr) a b c
198 };
199
200private:
201 const std::shared_ptr<Node> Key;
202 const std::shared_ptr<Expr> Value;
203 AttributeKind Kind;
204
205public:
206 Attribute(std::shared_ptr<Node> Key, std::shared_ptr<Expr> Value,
207 AttributeKind Kind)
208 : Key(std::move(Key)), Value(std::move(Value)), Kind(Kind) {
209 assert(this->Key && "Key must not be null");
210 }
211
212 [[nodiscard]] Node &key() const { return *Key; }
213
214 [[nodiscard]] Expr *value() const { return Value.get(); }
215
216 [[nodiscard]] AttributeKind kind() const { return Kind; }
217
218 [[nodiscard]] bool fromInherit() const {
219 return Kind == AttributeKind::InheritFrom || Kind == AttributeKind::Inherit;
220 }
221};
222
223/// \brief Attribute set after deduplication.
224///
225/// Represeting the attribute set suitable for variable lookups, evaluation.
226///
227/// The attrset cannot have duplicate keys, and keys will be desugared to strict
228/// K-V form.
229///
230/// e.g. `{ a.b.c = 1 }` -> `{ a = { b = { c = 1; }; }; }`
232private:
233 // These fields are in-complete during semantic analysis.
234 // So they explicitly marked as mutable
235 /*mutable*/ std::map<std::string, Attribute> Static;
236 /*mutable*/ std::vector<Attribute> Dynamic;
237
238 const Misc *Recursive;
239
240 friend class Sema;
241
242public:
243 SemaAttrs(Misc *Recursive) : Recursive(Recursive) {}
244 SemaAttrs(std::map<std::string, Attribute> Static,
245 std::vector<Attribute> Dynamic, Misc *Recursive)
246 : Static(std::move(Static)), Dynamic(std::move(Dynamic)),
247 Recursive(Recursive) {}
248
249 /// \brief Static attributes, do not require evaluation to get the key.
250 ///
251 /// e.g. `{ a = 1; b = 2; }`
252 [[nodiscard]] const std::map<std::string, Attribute> &staticAttrs() const {
253 return Static;
254 }
255
256 /// \brief Dynamic attributes, require evaluation to get the key.
257 ///
258 /// e.g. `{ "${asdasda}" = "asdasd"; }`
259 [[nodiscard]] const std::vector<Attribute> &dynamicAttrs() const {
260 return Dynamic;
261 }
262
263 /// \brief If the attribute set is `rec`.
264 [[nodiscard]] bool isRecursive() const { return Recursive; }
265};
266
267class ExprAttrs : public Expr {
268 const std::shared_ptr<Binds> Body;
269 const std::shared_ptr<Misc> Rec;
270 SemaAttrs SA; // Let this mutable for "Sema" class only.
271 friend class Sema;
272
273public:
274 ExprAttrs(LexerCursorRange Range, std::shared_ptr<Binds> Body,
275 std::shared_ptr<Misc> Rec, SemaAttrs SA)
276 : Expr(NK_ExprAttrs, Range), Body(std::move(Body)), Rec(std::move(Rec)),
277 SA(std::move(SA)) {}
278
279 [[nodiscard]] const Binds *binds() const { return Body.get(); }
280 [[nodiscard]] const Misc *rec() const { return Rec.get(); }
281
282 [[nodiscard]] bool isRecursive() const { return Rec != nullptr; }
283
284 [[nodiscard]] const SemaAttrs &sema() const { return SA; }
285
286 [[nodiscard]] ChildVector children() const override {
287 return {Body.get(), Rec.get()};
288 }
289};
290
291} // namespace nixf
const std::string & staticName() const
Definition Attrs.h:50
AttrName(std::shared_ptr< Interpolation > Interp)
Definition Attrs.h:34
const std::shared_ptr< Identifier > & id() const
Definition Attrs.h:64
AttrName(std::shared_ptr< ExprString > String)
Definition Attrs.h:28
AttrNameKind kind() const
Definition Attrs.h:21
const ExprString & string() const
Definition Attrs.h:69
bool isStatic() const
Definition Attrs.h:40
const Interpolation & interpolation() const
Definition Attrs.h:58
ChildVector children() const override
Definition Attrs.h:75
@ ANK_Interpolation
Definition Attrs.h:12
AttrName(std::shared_ptr< Identifier > ID, LexerCursorRange Range)
Definition Attrs.h:23
AttrPath(LexerCursorRange Range, std::vector< std::shared_ptr< AttrName > > Names, std::vector< std::shared_ptr< Dot > > Dots)
Definition Attrs.h:95
ChildVector children() const override
Definition Attrs.h:104
const std::vector< std::shared_ptr< AttrName > > & names() const
Definition Attrs.h:100
Node & key() const
Definition Attrs.h:212
Expr * value() const
Definition Attrs.h:214
AttributeKind kind() const
Definition Attrs.h:216
bool fromInherit() const
Definition Attrs.h:218
@ InheritFrom
inherit (expr) a b c
Attribute(std::shared_ptr< Node > Key, std::shared_ptr< Expr > Value, AttributeKind Kind)
Definition Attrs.h:206
const AttrPath & path() const
Definition Attrs.h:128
Binding(LexerCursorRange Range, std::shared_ptr< AttrPath > Path, std::shared_ptr< Expr > Value)
Definition Attrs.h:120
ChildVector children() const override
Definition Attrs.h:135
const std::shared_ptr< Expr > & value() const
Definition Attrs.h:133
ChildVector children() const override
Definition Attrs.h:179
Binds(LexerCursorRange Range, std::vector< std::shared_ptr< Node > > Bindings)
Definition Attrs.h:172
const std::vector< std::shared_ptr< Node > > & bindings() const
Definition Attrs.h:175
Holds a "." in the language.
Definition Basic.h:126
bool isRecursive() const
Definition Attrs.h:282
ChildVector children() const override
Definition Attrs.h:286
const SemaAttrs & sema() const
Definition Attrs.h:284
const Misc * rec() const
Definition Attrs.h:280
ExprAttrs(LexerCursorRange Range, std::shared_ptr< Binds > Body, std::shared_ptr< Misc > Rec, SemaAttrs SA)
Definition Attrs.h:274
const Binds * binds() const
Definition Attrs.h:279
bool isLiteral() const
Definition Simple.h:130
const std::string & literal() const
Definition Simple.h:135
const std::shared_ptr< Expr > & expr() const
Definition Attrs.h:155
const std::vector< std::shared_ptr< AttrName > > & names() const
Definition Attrs.h:149
ChildVector children() const override
Definition Attrs.h:157
bool hasExpr()
Definition Attrs.h:153
Inherit(LexerCursorRange Range, std::vector< std::shared_ptr< AttrName > > Names, std::shared_ptr< Expr > E)
Definition Attrs.h:145
${expr} construct
Definition Simple.h:38
Misc node, used for parentheses, keywords, etc.
Definition Basic.h:106
boost::container::small_vector< Node *, 8 > ChildVector
Definition Basic.h:42
LexerCursorRange range() const
Definition Basic.h:35
Attribute set after deduplication.
Definition Attrs.h:231
SemaAttrs(std::map< std::string, Attribute > Static, std::vector< Attribute > Dynamic, Misc *Recursive)
Definition Attrs.h:244
SemaAttrs(Misc *Recursive)
Definition Attrs.h:243
bool isRecursive() const
If the attribute set is rec.
Definition Attrs.h:264
const std::vector< Attribute > & dynamicAttrs() const
Dynamic attributes, require evaluation to get the key.
Definition Attrs.h:259
const std::map< std::string, Attribute > & staticAttrs() const
Static attributes, do not require evaluation to get the key.
Definition Attrs.h:252