1
2
3
4
5
6 #include <sngcm/ast/Class.hpp>
7 #include <sngcm/ast/Visitor.hpp>
8 #include <sngcm/ast/Identifier.hpp>
9
10 namespace sngcm { namespace ast {
11
12 ClassNode::ClassNode(const Span& span_, const boost::uuids::uuid& moduleId_) :
13 Node(NodeType::classNode, span_, moduleId_), specifiers(Specifiers::none), id(), templateParameters(), baseClassOrInterfaces(), members()
14 {
15 }
16
17 ClassNode::ClassNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, IdentifierNode* id_, AttributesNode* attributes_) :
18 Node(NodeType::classNode, span_, moduleId_), specifiers(specifiers_), id(id_), templateParameters(), baseClassOrInterfaces(), members(), attributes(attributes_)
19 {
20 }
21
22 Node* ClassNode::Clone(CloneContext& cloneContext) const
23 {
24 AttributesNode* clonedAttributes = nullptr;
25 if (attributes)
26 {
27 clonedAttributes = static_cast<AttributesNode*>(attributes->Clone(cloneContext));
28 }
29 ClassNode* clone = new ClassNode(GetSpan(), ModuleId(), specifiers, static_cast<IdentifierNode*>(id->Clone(cloneContext)), clonedAttributes);
30 if (!cloneContext.InstantiateClassNode())
31 {
32 int tn = templateParameters.Count();
33 for (int i = 0; i < tn; ++i)
34 {
35 clone->AddTemplateParameter(static_cast<TemplateParameterNode*>(templateParameters[i]->Clone(cloneContext)));
36 }
37 }
38 int bn = baseClassOrInterfaces.Count();
39 for (int i = 0; i < bn; ++i)
40 {
41 clone->AddBaseClassOrInterface(baseClassOrInterfaces[i]->Clone(cloneContext));
42 }
43 if (constraint)
44 {
45 clone->SetConstraint(static_cast<WhereConstraintNode*>(constraint->Clone(cloneContext)));
46 }
47 int mn = members.Count();
48 for (int i = 0; i < mn; ++i)
49 {
50 clone->AddMember(members[i]->Clone(cloneContext));
51 }
52 clone->SetSpecifierSpan(specifierSpan);
53 clone->SetClassSpan(classSpan);
54 clone->SetBeginBraceSpan(beginBraceSpan);
55 clone->SetEndBraceSpan(endBraceSpan);
56 return clone;
57 }
58
59 void ClassNode::Accept(Visitor& visitor)
60 {
61 visitor.Visit(*this);
62 }
63
64 void ClassNode::Write(AstWriter& writer)
65 {
66 Node::Write(writer);
67 bool hasAttributes = attributes != nullptr;
68 writer.GetBinaryWriter().Write(hasAttributes);
69 if (hasAttributes)
70 {
71 writer.Write(attributes.get());
72 }
73 writer.Write(specifiers);
74 writer.Write(id.get());
75 templateParameters.Write(writer);
76 baseClassOrInterfaces.Write(writer);
77 members.Write(writer);
78 bool convertExternal = ModuleId() == writer.SpanConversionModuleId();
79 writer.Write(specifierSpan, convertExternal);
80 writer.Write(classSpan, convertExternal);
81 writer.Write(beginBraceSpan, convertExternal);
82 writer.Write(endBraceSpan, convertExternal);
83 }
84
85 void ClassNode::Read(AstReader& reader)
86 {
87 Node::Read(reader);
88 bool hasAttributes = reader.GetBinaryReader().ReadBool();
89 if (hasAttributes)
90 {
91 attributes.reset(reader.ReadAttributesNode());
92 }
93 specifiers = reader.ReadSpecifiers();
94 id.reset(reader.ReadIdentifierNode());
95 id->SetParent(this);
96 templateParameters.Read(reader);
97 templateParameters.SetParent(this);
98 baseClassOrInterfaces.Read(reader);
99 baseClassOrInterfaces.SetParent(this);
100 members.Read(reader);
101 members.SetParent(this);
102 specifierSpan = reader.ReadSpan();
103 classSpan = reader.ReadSpan();
104 beginBraceSpan = reader.ReadSpan();
105 endBraceSpan = reader.ReadSpan();
106 }
107
108 void ClassNode::AddTemplateParameter(TemplateParameterNode* templateParameter)
109 {
110 templateParameter->SetParent(this);
111 templateParameters.Add(templateParameter);
112 }
113
114 void ClassNode::AddBaseClassOrInterface(Node* baseClassOrInterface)
115 {
116 baseClassOrInterface->SetParent(this);
117 baseClassOrInterfaces.Add(baseClassOrInterface);
118 }
119
120 void ClassNode::SetConstraint(WhereConstraintNode* whereConstraint)
121 {
122 constraint.reset(whereConstraint);
123 constraint->SetParent(this);
124 }
125
126 void ClassNode::AddMember(Node* member)
127 {
128 member->SetParent(this);
129 members.Add(member);
130 }
131
132 void ClassNode::ArrangeMembers()
133 {
134 std::unique_ptr<Node> staticConstructor;
135 NodeList<Node> constructors;
136 std::unique_ptr<Node> destructor;
137 NodeList<Node> virtualMembers;
138 NodeList<Node> protectedMembers;
139 NodeList<Node> privateMembers;
140 int n = members.Count();
141 for (int i = 0; i < n; ++i)
142 {
143 Node* member = members[i];
144 if (member->GetNodeType() == NodeType::staticConstructorNode)
145 {
146 staticConstructor.reset(members.Release(i));
147 }
148 else if (member->GetNodeType() == NodeType::constructorNode)
149 {
150 constructors.Add(members.Release(i));
151 }
152 else if (member->GetNodeType() == NodeType::destructorNode)
153 {
154 destructor.reset(members.Release(i));
155 }
156 else
157 {
158 Specifiers specifiers = member->GetSpecifiers();
159 if ((specifiers&( Specifiers::abstract_ | Specifiers::override_ | Specifiers::virtual_)) != Specifiers::none)
160 {
161 virtualMembers.Add(members.Release(i));
162 }
163 else if ((specifiers & Specifiers::protected_) != Specifiers::none)
164 {
165 protectedMembers.Add(members.Release(i));
166 }
167 else if ((specifiers & Specifiers::private_) != Specifiers::none)
168 {
169 privateMembers.Add(members.Release(i));
170 }
171 }
172 }
173 members.RemoveEmpty();
174 int index = 0;
175 if (staticConstructor)
176 {
177 members.Insert(index, staticConstructor.release());
178 ++index;
179 }
180 int nc = constructors.Count();
181 if (nc > 0)
182 {
183 for (int i = 0; i < nc; ++i)
184 {
185 members.Insert(index, constructors.Release(i));
186 ++index;
187 }
188 }
189 if (destructor)
190 {
191 members.Insert(index, destructor.release());
192 ++index;
193 }
194 if (virtualMembers.Count() > 0 || protectedMembers.Count() > 0 || privateMembers.Count() > 0)
195 {
196 for (int i = 0; i < virtualMembers.Count(); ++i)
197 {
198 members.Add(virtualMembers.Release(i));
199 }
200 for (int i = 0; i < protectedMembers.Count(); ++i)
201 {
202 members.Add(protectedMembers.Release(i));
203 }
204 for (int i = 0; i < privateMembers.Count(); ++i)
205 {
206 members.Add(privateMembers.Release(i));
207 }
208 }
209 }
210
211 InitializerNode::InitializerNode(NodeType nodeType_, const Span& span_, const boost::uuids::uuid& moduleId_) : Node(nodeType_, span_, moduleId_)
212 {
213 }
214
215 void InitializerNode::Write(AstWriter& writer)
216 {
217 Node::Write(writer);
218 arguments.Write(writer);
219 }
220
221 void InitializerNode::Read(AstReader& reader)
222 {
223 Node::Read(reader);
224 arguments.Read(reader);
225 arguments.SetParent(this);
226 }
227
228 void InitializerNode::AddArgument(Node* argument)
229 {
230 argument->SetParent(this);
231 arguments.Add(argument);
232 }
233
234 ThisInitializerNode::ThisInitializerNode(const Span& span_, const boost::uuids::uuid& moduleId_) : InitializerNode(NodeType::thisInitializerNode, span_, moduleId_)
235 {
236 }
237
238 Node* ThisInitializerNode::Clone(CloneContext& cloneContext) const
239 {
240 ThisInitializerNode* clone = new ThisInitializerNode(GetSpan(), ModuleId());
241 int n = Arguments().Count();
242 for (int i = 0; i < n; ++i)
243 {
244 clone->AddArgument(Arguments()[i]->Clone(cloneContext));
245 }
246 return clone;
247 }
248
249 void ThisInitializerNode::Accept(Visitor& visitor)
250 {
251 visitor.Visit(*this);
252 }
253
254 BaseInitializerNode::BaseInitializerNode(const Span& span_, const boost::uuids::uuid& moduleId_) : InitializerNode(NodeType::baseInitializerNode, span_, moduleId_)
255 {
256 }
257
258 Node* BaseInitializerNode::Clone(CloneContext& cloneContext) const
259 {
260 BaseInitializerNode* clone = new BaseInitializerNode(GetSpan(), ModuleId());
261 int n = Arguments().Count();
262 for (int i = 0; i < n; ++i)
263 {
264 clone->AddArgument(Arguments()[i]->Clone(cloneContext));
265 }
266 return clone;
267 }
268
269 void BaseInitializerNode::Accept(Visitor& visitor)
270 {
271 visitor.Visit(*this);
272 }
273
274 MemberInitializerNode::MemberInitializerNode(const Span& span_, const boost::uuids::uuid& moduleId_) : InitializerNode(NodeType::memberInitializerNode, span_, moduleId_), memberId()
275 {
276 }
277
278 MemberInitializerNode::MemberInitializerNode(const Span& span_, const boost::uuids::uuid& moduleId_, IdentifierNode* memberId_) :
279 InitializerNode(NodeType::memberInitializerNode, span_, moduleId_), memberId(memberId_)
280 {
281 memberId->SetParent(this);
282 }
283
284 Node* MemberInitializerNode::Clone(CloneContext& cloneContext) const
285 {
286 MemberInitializerNode* clone = new MemberInitializerNode(GetSpan(), ModuleId(), static_cast<IdentifierNode*>(memberId->Clone(cloneContext)));
287 int n = Arguments().Count();
288 for (int i = 0; i < n; ++i)
289 {
290 clone->AddArgument(Arguments()[i]->Clone(cloneContext));
291 }
292 return clone;
293 }
294
295 void MemberInitializerNode::Accept(Visitor& visitor)
296 {
297 visitor.Visit(*this);
298 }
299
300 void MemberInitializerNode::Write(AstWriter& writer)
301 {
302 InitializerNode::Write(writer);
303 writer.Write(memberId.get());
304 }
305
306 void MemberInitializerNode::Read(AstReader& reader)
307 {
308 InitializerNode::Read(reader);
309 memberId.reset(reader.ReadIdentifierNode());
310 memberId->SetParent(this);
311 }
312
313 StaticConstructorNode::StaticConstructorNode(const Span& span_, const boost::uuids::uuid& moduleId_) :
314 FunctionNode(NodeType::staticConstructorNode, span_, moduleId_, Specifiers::none, nullptr, U"@static_constructor", nullptr), initializers()
315 {
316 }
317
318 StaticConstructorNode::StaticConstructorNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, AttributesNode* attributes_) :
319 FunctionNode(NodeType::staticConstructorNode, span_, moduleId_, specifiers_, nullptr, U"@static_constructor", attributes_), initializers()
320 {
321 }
322
323 Node* StaticConstructorNode::Clone(CloneContext& cloneContext) const
324 {
325 StaticConstructorNode* clone = new StaticConstructorNode(GetSpan(), ModuleId(), GetSpecifiers(), nullptr);
326 int n = initializers.Count();
327 for (int i = 0; i < n; ++i)
328 {
329 clone->AddInitializer(static_cast<InitializerNode*>(initializers[i]->Clone(cloneContext)));
330 }
331 clone->classId.reset(static_cast<IdentifierNode*>(classId->Clone(cloneContext)));
332 CloneContent(clone, cloneContext);
333 return clone;
334 }
335
336 void StaticConstructorNode::Accept(Visitor& visitor)
337 {
338 visitor.Visit(*this);
339 }
340
341 void StaticConstructorNode::Write(AstWriter& writer)
342 {
343 FunctionNode::Write(writer);
344 initializers.Write(writer);
345 writer.Write(classId.get());
346 }
347
348 void StaticConstructorNode::Read(AstReader& reader)
349 {
350 FunctionNode::Read(reader);
351 initializers.Read(reader);
352 initializers.SetParent(this);
353 classId.reset(reader.ReadIdentifierNode());
354 }
355
356 void StaticConstructorNode::AddInitializer(InitializerNode* initializer)
357 {
358 initializer->SetParent(this);
359 initializers.Add(initializer);
360 }
361
362 ConstructorNode::ConstructorNode(const Span& span_, const boost::uuids::uuid& moduleId_) : FunctionNode(NodeType::constructorNode, span_, moduleId_, Specifiers::none, nullptr, U"@constructor", nullptr), initializers()
363 {
364 }
365
366 ConstructorNode::ConstructorNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, AttributesNode* attributes_) : FunctionNode(NodeType::constructorNode, span_, moduleId_, specifiers_, nullptr, U"@constructor", attributes_), initializers()
367 {
368 }
369
370 Node* ConstructorNode::Clone(CloneContext& cloneContext) const
371 {
372 ConstructorNode* clone = new ConstructorNode(GetSpan(), ModuleId(), GetSpecifiers(), nullptr);
373 int n = initializers.Count();
374 for (int i = 0; i < n; ++i)
375 {
376 clone->AddInitializer(static_cast<InitializerNode*>(initializers[i]->Clone(cloneContext)));
377 }
378 clone->classId.reset(static_cast<IdentifierNode*>(classId->Clone(cloneContext)));
379 CloneContent(clone, cloneContext);
380 return clone;
381 }
382
383 void ConstructorNode::Accept(Visitor& visitor)
384 {
385 visitor.Visit(*this);
386 }
387
388 void ConstructorNode::Write(AstWriter& writer)
389 {
390 FunctionNode::Write(writer);
391 initializers.Write(writer);
392 writer.Write(classId.get());
393 }
394
395 void ConstructorNode::Read(AstReader& reader)
396 {
397 FunctionNode::Read(reader);
398 initializers.Read(reader);
399 initializers.SetParent(this);
400 classId.reset(reader.ReadIdentifierNode());
401 }
402
403 void ConstructorNode::AddInitializer(InitializerNode* initializer)
404 {
405 initializer->SetParent(this);
406 initializers.Add(initializer);
407 }
408
409 DestructorNode::DestructorNode(const Span& span_, const boost::uuids::uuid& moduleId_) : FunctionNode(NodeType::destructorNode, span_, moduleId_)
410 {
411 }
412
413 DestructorNode::DestructorNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, AttributesNode* attributes_) :
414 FunctionNode(NodeType::destructorNode, span_, moduleId_, specifiers_, nullptr, U"@destructor", attributes_)
415 {
416 }
417
418 Node* DestructorNode::Clone(CloneContext& cloneContext) const
419 {
420 DestructorNode* clone = new DestructorNode(GetSpan(), ModuleId(), GetSpecifiers(), nullptr);
421 clone->classId.reset(static_cast<IdentifierNode*>(classId->Clone(cloneContext)));
422 CloneContent(clone, cloneContext);
423 return clone;
424 }
425
426 void DestructorNode::Accept(Visitor& visitor)
427 {
428 visitor.Visit(*this);
429 }
430
431 void DestructorNode::Write(AstWriter& writer)
432 {
433 FunctionNode::Write(writer);
434 writer.Write(classId.get());
435 }
436
437 void DestructorNode::Read(AstReader& reader)
438 {
439 FunctionNode::Read(reader);
440 classId.reset(reader.ReadIdentifierNode());
441 }
442
443 MemberFunctionNode::MemberFunctionNode(const Span& span_, const boost::uuids::uuid& moduleId_) : FunctionNode(NodeType::memberFunctionNode, span_, moduleId_)
444 {
445 }
446
447 MemberFunctionNode::MemberFunctionNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, Node* returnTypeExpr_, const std::u32string& groupId_, AttributesNode* attributes_) :
448 FunctionNode(NodeType::memberFunctionNode, span_, moduleId_, specifiers_, returnTypeExpr_, groupId_, attributes_)
449 {
450 }
451
452 Node* MemberFunctionNode::Clone(CloneContext& cloneContext) const
453 {
454 MemberFunctionNode* clone = new MemberFunctionNode(GetSpan(), ModuleId());
455 CloneContent(clone, cloneContext);
456 if (IsConst())
457 {
458 clone->SetConst();
459 }
460 return clone;
461 }
462
463 void MemberFunctionNode::Accept(Visitor& visitor)
464 {
465 visitor.Visit(*this);
466 }
467
468 ConversionFunctionNode::ConversionFunctionNode(const Span& span_, const boost::uuids::uuid& moduleId_) : FunctionNode(NodeType::conversionFunctionNode, span_, moduleId_)
469 {
470 }
471
472 ConversionFunctionNode::ConversionFunctionNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, Node* returnTypeExpr_, AttributesNode* attributes_) :
473 FunctionNode(NodeType::conversionFunctionNode, span_, moduleId_, specifiers_, returnTypeExpr_, U"@operator_conv", attributes_)
474 {
475 }
476
477 Node* ConversionFunctionNode::Clone(CloneContext& cloneContext) const
478 {
479 ConversionFunctionNode* clone = new ConversionFunctionNode(GetSpan(), ModuleId());
480 CloneContent(clone, cloneContext);
481 if (IsConst())
482 {
483 clone->SetConst();
484 }
485 return clone;
486 }
487
488 void ConversionFunctionNode::Accept(Visitor& visitor)
489 {
490 visitor.Visit(*this);
491 }
492
493 MemberVariableNode::MemberVariableNode(const Span& span_, const boost::uuids::uuid& moduleId_) : Node(NodeType::memberVariableNode, span_, moduleId_), specifiers()
494 {
495 }
496
497 MemberVariableNode::MemberVariableNode(const Span& span_, const boost::uuids::uuid& moduleId_, Specifiers specifiers_, Node* typeExpr_, IdentifierNode* id_, AttributesNode* attributes_) :
498 Node(NodeType::memberVariableNode, span_, moduleId_), specifiers(specifiers_), typeExpr(typeExpr_), id(id_), attributes(attributes_)
499 {
500 typeExpr->SetParent(this);
501 id->SetParent(this);
502 }
503
504 Node* MemberVariableNode::Clone(CloneContext& cloneContext) const
505 {
506 AttributesNode* clonedAttributes = nullptr;
507 if (attributes)
508 {
509 clonedAttributes = static_cast<AttributesNode*>(attributes->Clone(cloneContext));
510 }
511 MemberVariableNode* clone = new MemberVariableNode(GetSpan(), ModuleId(), specifiers, typeExpr->Clone(cloneContext), static_cast<IdentifierNode*>(id->Clone(cloneContext)), clonedAttributes);
512 clone->SetSpecifierSpan(specifierSpan);
513 return clone;
514 }
515
516 void MemberVariableNode::Accept(Visitor& visitor)
517 {
518 visitor.Visit(*this);
519 }
520
521 void MemberVariableNode::Write(AstWriter& writer)
522 {
523 Node::Write(writer);
524 bool hasAttributes = attributes != nullptr;
525 writer.GetBinaryWriter().Write(hasAttributes);
526 if (hasAttributes)
527 {
528 writer.Write(attributes.get());
529 }
530 writer.Write(specifiers);
531 writer.Write(typeExpr.get());
532 writer.Write(id.get());
533 bool convertExternal = ModuleId() == writer.SpanConversionModuleId();
534 writer.Write(specifierSpan, convertExternal);
535 }
536
537 void MemberVariableNode::Read(AstReader& reader)
538 {
539 Node::Read(reader);
540 bool hasAttributes = reader.GetBinaryReader().ReadBool();
541 if (hasAttributes)
542 {
543 attributes.reset(reader.ReadAttributesNode());
544 }
545 specifiers = reader.ReadSpecifiers();
546 typeExpr.reset(reader.ReadNode());
547 typeExpr->SetParent(this);
548 id.reset(reader.ReadIdentifierNode());
549 id->SetParent(this);
550 specifierSpan = reader.ReadSpan();
551 }
552
553 } }