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