1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   4 // =================================
   5 
   6 #include <sngcm/ast/Concept.hpp>
   7 #include <sngcm/ast/Identifier.hpp>
   8 #include <sngcm/ast/Visitor.hpp>
   9 #include <soulng/util/Unicode.hpp>
  10 #include <boost/uuid/nil_generator.hpp>
  11 
  12 namespace sngcm { namespace ast {
  13 
  14 using namespace soulng::unicode;
  15 
  16 ConstraintNode::ConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_) : Node(nodeType_span_moduleId_)
  17 {
  18 }
  19 
  20 ParenthesizedConstraintNode::ParenthesizedConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : ConstraintNode(NodeType::parenthesizedConstraintNodespan_moduleId_)
  21 {
  22 }
  23 
  24 ParenthesizedConstraintNode::ParenthesizedConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* constraint_) :
  25     ConstraintNode(NodeType::parenthesizedConstraintNodespan_moduleId_)constraint(constraint_)
  26 {
  27 }
  28 
  29 Node* ParenthesizedConstraintNode::Clone(CloneContext& cloneContext) const
  30 {
  31     ParenthesizedConstraintNode* clone = new ParenthesizedConstraintNode(GetSpan()ModuleId()static_cast<ConstraintNode*>(constraint->Clone(cloneContext)));
  32     return clone;
  33 }
  34 
  35 void ParenthesizedConstraintNode::Accept(Visitor& visitor)
  36 {
  37     visitor.Visit(*this);
  38 }
  39 
  40 void ParenthesizedConstraintNode::Write(AstWriter& writer)
  41 {
  42     ConstraintNode::Write(writer);
  43     writer.Write(constraint.get());
  44 }
  45 
  46 void ParenthesizedConstraintNode::Read(AstReader& reader)
  47 {
  48     ConstraintNode::Read(reader);
  49     constraint.reset(reader.ReadConstraintNode());
  50 }
  51 
  52 std::string ParenthesizedConstraintNode::ToString() const
  53 {
  54     return "(" + constraint->ToString() + ")";
  55 }
  56 
  57 BinaryConstraintNode::BinaryConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_) : ConstraintNode(nodeType_span_moduleId_)left()right()
  58 {
  59 }
  60 
  61 BinaryConstraintNode::BinaryConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* left_ConstraintNode* right_) :
  62     ConstraintNode(nodeType_span_moduleId_)left(left_)right(right_)
  63 {
  64     left->SetParent(this);
  65     right->SetParent(this);
  66 }
  67 
  68 void BinaryConstraintNode::Write(AstWriter& writer)
  69 {
  70     ConstraintNode::Write(writer);
  71     writer.Write(left.get());
  72     writer.Write(right.get());
  73 }
  74 
  75 void BinaryConstraintNode::Read(AstReader& reader)
  76 {
  77     ConstraintNode::Read(reader);
  78     left.reset(reader.ReadConstraintNode());
  79     left->SetParent(this);
  80     right.reset(reader.ReadConstraintNode());
  81     right->SetParent(this);
  82 }
  83 
  84 DisjunctiveConstraintNode::DisjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : BinaryConstraintNode(NodeType::disjunctiveConstraintNodespan_moduleId_)
  85 {
  86 }
  87 
  88 DisjunctiveConstraintNode::DisjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* left_ConstraintNode* right_) :
  89     BinaryConstraintNode(NodeType::disjunctiveConstraintNodespan_moduleId_left_right_)
  90 {
  91 }
  92 
  93 Node* DisjunctiveConstraintNode::Clone(CloneContext& cloneContext) const
  94 {
  95     DisjunctiveConstraintNode* clone = new DisjunctiveConstraintNode(GetSpan()ModuleId()static_cast<ConstraintNode*>(Left()->Clone(cloneContext))static_cast<ConstraintNode*>(Right()->Clone(cloneContext)));
  96     return clone;
  97 }
  98 
  99 void DisjunctiveConstraintNode::Accept(Visitor& visitor)
 100 {
 101     visitor.Visit(*this);
 102 }
 103 
 104 std::string DisjunctiveConstraintNode::ToString() const
 105 {
 106     return Left()->ToString() + " or " + Right()->ToString();
 107 }
 108 
 109 ConjunctiveConstraintNode::ConjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : BinaryConstraintNode(NodeType::conjunctiveConstraintNodespan_moduleId_)
 110 {
 111 }
 112 
 113 ConjunctiveConstraintNode::ConjunctiveConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* left_ConstraintNode* right_) :
 114     BinaryConstraintNode(NodeType::conjunctiveConstraintNodespan_moduleId_left_right_)
 115 {
 116 }
 117 
 118 Node* ConjunctiveConstraintNode::Clone(CloneContext& cloneContext) const
 119 {
 120     ConjunctiveConstraintNode* clone = new ConjunctiveConstraintNode(GetSpan()ModuleId()static_cast<ConstraintNode*>(Left()->Clone(cloneContext))static_cast<ConstraintNode*>(Right()->Clone(cloneContext)));
 121     return clone;
 122 }
 123 
 124 void ConjunctiveConstraintNode::Accept(Visitor& visitor)
 125 {
 126     visitor.Visit(*this);
 127 }
 128 
 129 std::string ConjunctiveConstraintNode::ToString() const
 130 {
 131     return Left()->ToString() + " and " + Right()->ToString();
 132 }
 133 
 134 
 135 WhereConstraintNode::WhereConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 136     ConstraintNode(NodeType::whereConstraintNodespan_moduleId_)constraint()headerConstraint(false)semicolon(false)
 137 {
 138 }
 139 
 140 WhereConstraintNode::WhereConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_ConstraintNode* constraint_) :
 141     ConstraintNode(NodeType::whereConstraintNodespan_moduleId_)constraint(constraint_)headerConstraint(false)semicolon(false)
 142 {
 143     constraint->SetParent(this);
 144 }
 145 
 146 Node* WhereConstraintNode::Clone(CloneContext& cloneContext) const
 147 {
 148     WhereConstraintNode* clone = new WhereConstraintNode(GetSpan()ModuleId()static_cast<ConstraintNode*>(constraint->Clone(cloneContext)));
 149     if (headerConstraint)
 150     {
 151         clone->SetHeaderConstraint();
 152     }
 153     if (semicolon)
 154     {
 155         clone->SetSemicolon();
 156     }
 157     return clone;
 158 }
 159 
 160 void WhereConstraintNode::Accept(Visitor& visitor)
 161 {
 162     visitor.Visit(*this);
 163 }
 164 
 165 void WhereConstraintNode::Write(AstWriter& writer)
 166 {
 167     ConstraintNode::Write(writer);
 168     writer.Write(constraint.get());
 169     writer.GetBinaryWriter().Write(headerConstraint);
 170     writer.GetBinaryWriter().Write(semicolon);
 171 }
 172 
 173 void WhereConstraintNode::Read(AstReader& reader)
 174 {
 175     ConstraintNode::Read(reader);
 176     constraint.reset(reader.ReadConstraintNode());
 177     constraint->SetParent(this);
 178     headerConstraint = reader.GetBinaryReader().ReadBool();
 179     semicolon = reader.GetBinaryReader().ReadBool();
 180 }
 181 
 182 std::string WhereConstraintNode::ToString() const
 183 {
 184     return "where " + constraint->ToString();
 185 }
 186 
 187 PredicateConstraintNode::PredicateConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 188     ConstraintNode(NodeType::predicateConstraintNodespan_moduleId_)invokeExpr()
 189 {
 190 }
 191 
 192 PredicateConstraintNode::PredicateConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* invokeExpr_) :
 193     ConstraintNode(NodeType::predicateConstraintNodespan_moduleId_)invokeExpr(invokeExpr_)
 194 {
 195     invokeExpr->SetParent(this);
 196 }
 197 
 198 Node* PredicateConstraintNode::Clone(CloneContext& cloneContext) const
 199 {
 200     PredicateConstraintNode* clone = new PredicateConstraintNode(GetSpan()ModuleId()invokeExpr->Clone(cloneContext));
 201     return clone;
 202 }
 203 
 204 void PredicateConstraintNode::Accept(Visitor& visitor)
 205 {
 206     visitor.Visit(*this);
 207 }
 208 
 209 void PredicateConstraintNode::Write(AstWriter& writer)
 210 {
 211     ConstraintNode::Write(writer);
 212     writer.Write(invokeExpr.get());
 213 }
 214 
 215 void PredicateConstraintNode::Read(AstReader& reader)
 216 {
 217     ConstraintNode::Read(reader);
 218     invokeExpr.reset(reader.ReadNode());
 219     invokeExpr->SetParent(this);
 220 }
 221 
 222 std::string PredicateConstraintNode::ToString() const
 223 {
 224     return invokeExpr->ToString();
 225 }
 226 
 227 IsConstraintNode::IsConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 228     ConstraintNode(NodeType::isConstraintNodespan_moduleId_)typeExpr()conceptOrTypeName()
 229 {
 230 }
 231 
 232 IsConstraintNode::IsConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeExpr_Node* conceptOrTypeName_) :
 233     ConstraintNode(NodeType::isConstraintNodespan_moduleId_)typeExpr(typeExpr_)conceptOrTypeName(conceptOrTypeName_)
 234 {
 235     typeExpr->SetParent(this);
 236     conceptOrTypeName->SetParent(this);
 237 }
 238 
 239 Node* IsConstraintNode::Clone(CloneContext& cloneContext) const
 240 {
 241     IsConstraintNode* clone = new IsConstraintNode(GetSpan()ModuleId()typeExpr->Clone(cloneContext)conceptOrTypeName->Clone(cloneContext));
 242     return clone;
 243 }
 244 
 245 void IsConstraintNode::Accept(Visitor& visitor)
 246 {
 247     visitor.Visit(*this);
 248 }
 249 
 250 void IsConstraintNode::Write(AstWriter& writer)
 251 {
 252     ConstraintNode::Write(writer);
 253     writer.Write(typeExpr.get());
 254     writer.Write(conceptOrTypeName.get());
 255 }
 256 
 257 void IsConstraintNode::Read(AstReader& reader)
 258 {
 259     ConstraintNode::Read(reader);
 260     typeExpr.reset(reader.ReadNode());
 261     typeExpr->SetParent(this);
 262     conceptOrTypeName.reset(reader.ReadNode());
 263     conceptOrTypeName->SetParent(this);
 264 }
 265 
 266 std::string IsConstraintNode::ToString() const
 267 {
 268     return typeExpr->ToString() + " is " + conceptOrTypeName->ToString();
 269 }
 270 
 271 MultiParamConstraintNode::MultiParamConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 272     ConstraintNode(NodeType::multiParamConstraintNodespan_moduleId_)conceptId()typeExprs()
 273 {
 274 }
 275 
 276 MultiParamConstraintNode::MultiParamConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* conceptId_) :
 277     ConstraintNode(NodeType::multiParamConstraintNodespan_moduleId_)conceptId(conceptId_)typeExprs()
 278 {
 279     conceptId->SetParent(this);
 280 }
 281 
 282 Node* MultiParamConstraintNode::Clone(CloneContext& cloneContext) const
 283 {
 284     MultiParamConstraintNode* clone = new MultiParamConstraintNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(conceptId->Clone(cloneContext)));
 285     int n = typeExprs.Count();
 286     for (int i = 0; i < n; ++i)
 287     {
 288         clone->AddTypeExpr(typeExprs[i]->Clone(cloneContext));
 289     }
 290     return clone;
 291 }
 292 
 293 void MultiParamConstraintNode::Accept(Visitor& visitor)
 294 {
 295     visitor.Visit(*this);
 296 }
 297 
 298 void MultiParamConstraintNode::Write(AstWriter& writer)
 299 {
 300     ConstraintNode::Write(writer);
 301     writer.Write(conceptId.get());
 302     typeExprs.Write(writer);
 303 }
 304 
 305 void MultiParamConstraintNode::Read(AstReader& reader)
 306 {
 307     ConstraintNode::Read(reader);
 308     conceptId.reset(reader.ReadIdentifierNode());
 309     conceptId->SetParent(this);
 310     typeExprs.Read(reader);
 311     typeExprs.SetParent(this);
 312 }
 313 
 314 void MultiParamConstraintNode::AddTypeExpr(Node* typeExpr)
 315 {
 316     typeExpr->SetParent(this);
 317     typeExprs.Add(typeExpr);
 318 }
 319 
 320 std::string MultiParamConstraintNode::ToString() const
 321 {
 322     std::string s = conceptId->ToString();
 323     s.append(1'<');
 324     int n = typeExprs.Count();
 325     for (int i = 0; i < n; ++i)
 326     {
 327         if (i > 0)
 328         {
 329             s.append(", ");
 330         }
 331         s.append(typeExprs[i]->ToString());
 332     }
 333     s.append(1'>');
 334     return s;
 335 }
 336 
 337 TypeNameConstraintNode::TypeNameConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 338     ConstraintNode(NodeType::typeNameConstraintNodespan_moduleId_)typeId()
 339 {
 340 }
 341 
 342 TypeNameConstraintNode::TypeNameConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeId_) :
 343     ConstraintNode(NodeType::typeNameConstraintNodespan_moduleId_)typeId(typeId_)
 344 {
 345     typeId->SetParent(this);
 346 }
 347 
 348 Node* TypeNameConstraintNode::Clone(CloneContext& cloneContext) const
 349 {
 350     TypeNameConstraintNode* clone = new TypeNameConstraintNode(GetSpan()ModuleId()typeId->Clone(cloneContext));
 351     return clone;
 352 }
 353 
 354 void TypeNameConstraintNode::Accept(Visitor& visitor)
 355 {
 356     visitor.Visit(*this);
 357 }
 358 
 359 void TypeNameConstraintNode::Write(AstWriter& writer)
 360 {
 361     ConstraintNode::Write(writer);
 362     writer.Write(typeId.get());
 363 }
 364 
 365 void TypeNameConstraintNode::Read(AstReader& reader)
 366 {
 367     ConstraintNode::Read(reader);
 368     typeId.reset(reader.ReadNode());
 369 }
 370 
 371 std::string TypeNameConstraintNode::ToString() const
 372 {
 373     return "typename " + typeId->ToString();
 374 }
 375 
 376 SignatureConstraintNode::SignatureConstraintNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_) : ConstraintNode(nodeType_span_moduleId_)
 377 {
 378 }
 379 
 380 ConstructorConstraintNode::ConstructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 381     SignatureConstraintNode(NodeType::constructorConstraintNodespan_moduleId_)typeParamId()parameters()
 382 {
 383 }
 384 
 385 ConstructorConstraintNode::ConstructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* typeParamId_) :
 386     SignatureConstraintNode(NodeType::constructorConstraintNodespan_moduleId_)typeParamId(typeParamId_)parameters()
 387 {
 388     typeParamId->SetParent(this);
 389 }
 390 
 391 Node* ConstructorConstraintNode::Clone(CloneContext& cloneContext) const
 392 {
 393     ConstructorConstraintNode* clone = new ConstructorConstraintNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(typeParamId->Clone(cloneContext)));
 394     int n = parameters.Count();
 395     for (int i = 0; i < n; ++i)
 396     {
 397         clone->AddParameter(static_cast<ParameterNode*>(parameters[i]->Clone(cloneContext)));
 398     }
 399     return clone;
 400 }
 401 
 402 void ConstructorConstraintNode::Accept(Visitor& visitor)
 403 {
 404     visitor.Visit(*this);
 405 }
 406 
 407 void ConstructorConstraintNode::Write(AstWriter& writer)
 408 {
 409     SignatureConstraintNode::Write(writer);
 410     writer.Write(typeParamId.get());
 411     parameters.Write(writer);
 412 }
 413 
 414 void ConstructorConstraintNode::Read(AstReader& reader)
 415 {
 416     SignatureConstraintNode::Read(reader);
 417     typeParamId.reset(static_cast<IdentifierNode*>(reader.ReadNode()));
 418     typeParamId->SetParent(this);
 419     parameters.Read(reader);
 420     parameters.SetParent(this);
 421 }
 422 
 423 std::string ConstructorConstraintNode::ToString() const
 424 {
 425     std::string s = typeParamId->ToString();
 426     s.append(1'(');
 427     int n = parameters.Count();
 428     for (int i = 0; i < n; ++i)
 429     {
 430         if (i > 0)
 431         {
 432             s.append(", ");
 433         }
 434         ParameterNode* p = parameters[i];
 435         s.append(p->TypeExpr()->ToString());
 436     }
 437     s.append(1')');
 438     return s;
 439 }
 440 
 441 void ConstructorConstraintNode::AddParameter(ParameterNode* parameter)
 442 {
 443     parameter->SetParent(this);
 444     parameters.Add(parameter);
 445 }
 446 
 447 DestructorConstraintNode::DestructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 448     SignatureConstraintNode(NodeType::destructorConstraintNodespan_moduleId_)typeParamId()
 449 {
 450 }
 451 
 452 DestructorConstraintNode::DestructorConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* typeParamId_) :
 453     SignatureConstraintNode(NodeType::destructorConstraintNodespan_moduleId_)typeParamId(typeParamId_)
 454 {
 455     typeParamId->SetParent(this);
 456 }
 457 
 458 Node* DestructorConstraintNode::Clone(CloneContext& cloneContext) const
 459 {
 460     DestructorConstraintNode* clone = new DestructorConstraintNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(typeParamId->Clone(cloneContext)));
 461     return clone;
 462 }
 463 
 464 void DestructorConstraintNode::Accept(Visitor& visitor)
 465 {
 466     visitor.Visit(*this);
 467 }
 468 
 469 void DestructorConstraintNode::Write(AstWriter& writer)
 470 {
 471     SignatureConstraintNode::Write(writer);
 472     writer.Write(typeParamId.get());
 473 }
 474 
 475 void DestructorConstraintNode::Read(AstReader& reader)
 476 {
 477     SignatureConstraintNode::Read(reader);
 478     typeParamId.reset(reader.ReadIdentifierNode());
 479     typeParamId->SetParent(this);
 480 }
 481 
 482 std::string DestructorConstraintNode::ToString() const
 483 {
 484     std::string s = "~" + typeParamId->ToString();
 485     s.append("()");
 486     return s;
 487 }
 488 
 489 MemberFunctionConstraintNode::MemberFunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 490     SignatureConstraintNode(NodeType::memberFunctionConstraintNodespan_moduleId_)returnTypeExpr()typeParamId()groupId()parameters()
 491 {
 492 }
 493 
 494 MemberFunctionConstraintNode::MemberFunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* returnTypeExpr_IdentifierNode* typeParamId_const std::u32string& groupId_) :
 495     SignatureConstraintNode(NodeType::memberFunctionConstraintNodespan_moduleId_)returnTypeExpr(returnTypeExpr_)typeParamId(typeParamId_)groupId(groupId_)parameters()
 496 {
 497     returnTypeExpr->SetParent(this);
 498     typeParamId->SetParent(this);
 499 }
 500 
 501 Node* MemberFunctionConstraintNode::Clone(CloneContext& cloneContext) const
 502 {
 503     MemberFunctionConstraintNode* clone = new MemberFunctionConstraintNode(GetSpan()ModuleId()returnTypeExpr->Clone(cloneContext)static_cast<IdentifierNode*>(typeParamId->Clone(cloneContext))groupId);
 504     int n = parameters.Count();
 505     for (int i = 0; i < n; ++i)
 506     {
 507         clone->AddParameter(static_cast<ParameterNode*>(parameters[i]->Clone(cloneContext)));
 508     }
 509     return clone;
 510 }
 511 
 512 void MemberFunctionConstraintNode::Accept(Visitor& visitor)
 513 {
 514     visitor.Visit(*this);
 515 }
 516 
 517 void MemberFunctionConstraintNode::Write(AstWriter& writer)
 518 {
 519     SignatureConstraintNode::Write(writer);
 520     writer.Write(returnTypeExpr.get());
 521     writer.Write(typeParamId.get());
 522     writer.GetBinaryWriter().Write(groupId);
 523     parameters.Write(writer);
 524 }
 525 
 526 void MemberFunctionConstraintNode::Read(AstReader& reader)
 527 {
 528     SignatureConstraintNode::Read(reader);
 529     returnTypeExpr.reset(reader.ReadNode());
 530     returnTypeExpr->SetParent(this);
 531     typeParamId.reset(reader.ReadIdentifierNode());
 532     typeParamId->SetParent(this);
 533     groupId = reader.GetBinaryReader().ReadUtf32String();
 534     parameters.Read(reader);
 535     parameters.SetParent(this);
 536 }
 537 
 538 void MemberFunctionConstraintNode::AddParameter(ParameterNode* parameter)
 539 {
 540     parameter->SetParent(this);
 541     parameters.Add(parameter);
 542 }
 543 
 544 std::string MemberFunctionConstraintNode::ToString() const
 545 {
 546     std::string s;
 547     if (returnTypeExpr)
 548     {
 549         s.append(returnTypeExpr->ToString()).append(" ");
 550     }
 551     s.append(typeParamId->ToString());
 552     s.append(".").append(ToUtf8(groupId));
 553     s.append(1'(');
 554     int n = parameters.Count();
 555     for (int i = 0; i < n; ++i)
 556     {
 557         if (i > 0)
 558         {
 559             s.append(", ");
 560         }
 561         ParameterNode* p = parameters[i];
 562         s.append(p->TypeExpr()->ToString());
 563     }
 564     s.append(1')');
 565     return s;
 566 }
 567 
 568 FunctionConstraintNode::FunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) :
 569     SignatureConstraintNode(NodeType::functionConstraintNodespan_moduleId_)returnTypeExpr()groupId()parameters()
 570 {
 571 }
 572 
 573 FunctionConstraintNode::FunctionConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_Node* returnTypeExpr_const std::u32string& groupId_)
 574     : SignatureConstraintNode(NodeType::functionConstraintNodespan_moduleId_)returnTypeExpr(returnTypeExpr_)groupId(groupId_)parameters()
 575 {
 576     returnTypeExpr->SetParent(this);
 577 }
 578 
 579 Node* FunctionConstraintNode::Clone(CloneContext& cloneContext) const
 580 {
 581     FunctionConstraintNode* clone = new FunctionConstraintNode(GetSpan()ModuleId()returnTypeExpr->Clone(cloneContext)groupId);
 582     int n = parameters.Count();
 583     for (int i = 0; i < n; ++i)
 584     {
 585         clone->AddParameter(static_cast<ParameterNode*>(parameters[i]->Clone(cloneContext)));
 586     }
 587     return clone;
 588 }
 589 
 590 void FunctionConstraintNode::Accept(Visitor& visitor)
 591 {
 592     visitor.Visit(*this);
 593 }
 594 
 595 void FunctionConstraintNode::Write(AstWriter& writer)
 596 {
 597     SignatureConstraintNode::Write(writer);
 598     writer.Write(returnTypeExpr.get());
 599     writer.GetBinaryWriter().Write(groupId);
 600     parameters.Write(writer);
 601 }
 602 
 603 void FunctionConstraintNode::Read(AstReader& reader)
 604 {
 605     SignatureConstraintNode::Read(reader);
 606     returnTypeExpr.reset(reader.ReadNode());
 607     returnTypeExpr->SetParent(this);
 608     groupId = reader.GetBinaryReader().ReadUtf32String();
 609     parameters.Read(reader);
 610     parameters.SetParent(this);
 611 }
 612 
 613 void FunctionConstraintNode::AddParameter(ParameterNode* parameter)
 614 {
 615     parameter->SetParent(this);
 616     parameters.Add(parameter);
 617 }
 618 
 619 std::string FunctionConstraintNode::ToString() const
 620 {
 621     std::string s;
 622     if (returnTypeExpr)
 623     {
 624         s.append(returnTypeExpr->ToString()).append(" ");
 625     }
 626     s.append(ToUtf8(groupId));
 627     s.append(1'(');
 628     int n = parameters.Count();
 629     for (int i = 0; i < n; ++i)
 630     {
 631         if (i > 0)
 632         {
 633             s.append(", ");
 634         }
 635         ParameterNode* p = parameters[i];
 636         s.append(p->TypeExpr()->ToString());
 637     }
 638     s.append(1')');
 639     return s;
 640 }
 641 
 642 AxiomStatementNode::AxiomStatementNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::axiomStatementNodespan_moduleId_)expression()text()
 643 {
 644 }
 645 
 646 AxiomStatementNode::AxiomStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* expression_const std::u32string& text_) :
 647     Node(NodeType::axiomStatementNodespan_moduleId_)expression(expression_)text(text_)
 648 {
 649     expression->SetParent(this);
 650 }
 651 
 652 Node* AxiomStatementNode::Clone(CloneContext& cloneContext) const
 653 {
 654     AxiomStatementNode* clone = new AxiomStatementNode(GetSpan()ModuleId()expression->Clone(cloneContext)text);
 655     return clone;
 656 }
 657 
 658 void AxiomStatementNode::Accept(Visitor& visitor)
 659 {
 660     visitor.Visit(*this);
 661 }
 662 
 663 void AxiomStatementNode::Write(AstWriter& writer)
 664 {
 665     Node::Write(writer);
 666     writer.Write(expression.get());
 667     writer.GetBinaryWriter().Write(text);
 668 }
 669 
 670 void AxiomStatementNode::Read(AstReader& reader)
 671 {
 672     Node::Read(reader);
 673     expression.reset(reader.ReadNode());
 674     expression->SetParent(this);
 675     text = reader.GetBinaryReader().ReadUtf32String();
 676 }
 677 
 678 std::string AxiomStatementNode::ToString() const
 679 {
 680     return ToUtf8(text);
 681 }
 682 
 683 AxiomNode::AxiomNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::axiomNodespan_moduleId_)id()parameters()statements()
 684 {
 685 }
 686 
 687 AxiomNode::AxiomNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_) :
 688     Node(NodeType::axiomNodespan_moduleId_)id(id_)parameters()statements()
 689 {
 690     id->SetParent(this);
 691 }
 692 
 693 Node* AxiomNode::Clone(CloneContext& cloneContext) const
 694 {
 695     AxiomNode* clone = new AxiomNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(id->Clone(cloneContext)));
 696     int np = parameters.Count();
 697     for (int i = 0; i < np; ++i)
 698     {
 699         clone->AddParameter(static_cast<ParameterNode*>(parameters[i]->Clone(cloneContext)));
 700     }
 701     int ns = statements.Count();
 702     for (int i = 0; i < ns; ++i)
 703     {
 704         clone->AddStatement(static_cast<AxiomStatementNode*>(statements[i]->Clone(cloneContext)));
 705     }
 706     clone->SetBeginBraceSpan(beginBraceSpan);
 707     clone->SetEndBraceSpan(endBraceSpan);
 708     return clone;
 709 }
 710 
 711 void AxiomNode::Accept(Visitor& visitor)
 712 {
 713     visitor.Visit(*this);
 714 }
 715 
 716 void AxiomNode::Write(AstWriter& writer)
 717 {
 718     Node::Write(writer);
 719     writer.Write(id.get());
 720     parameters.Write(writer);
 721     statements.Write(writer);
 722     bool convertExternal = ModuleId() == writer.SpanConversionModuleId();
 723     writer.Write(beginBraceSpanconvertExternal);
 724     writer.Write(endBraceSpanconvertExternal);
 725 }
 726 
 727 void AxiomNode::Read(AstReader& reader)
 728 {
 729     Node::Read(reader);
 730     id.reset(reader.ReadIdentifierNode());
 731     id->SetParent(this);
 732     parameters.Read(reader);
 733     parameters.SetParent(this);
 734     statements.Read(reader);
 735     statements.SetParent(this);
 736     beginBraceSpan = reader.ReadSpan();
 737     endBraceSpan = reader.ReadSpan();
 738 }
 739 
 740 void AxiomNode::AddParameter(ParameterNode* parameter)
 741 {
 742     parameter->SetParent(this);
 743     parameters.Add(parameter);
 744 }
 745 
 746 void AxiomNode::AddStatement(AxiomStatementNode* statement)
 747 {
 748     statement->SetParent(this);
 749     statements.Add(statement);
 750 }
 751 
 752 ConceptIdNode::ConceptIdNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::conceptIdNodespan_moduleId_)id()typeParameters()
 753 {
 754 }
 755 
 756 ConceptIdNode::ConceptIdNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_) : Node(NodeType::conceptIdNodespan_moduleId_)id(id_)typeParameters()
 757 {
 758     id->SetParent(this);
 759 }
 760 
 761 Node* ConceptIdNode::Clone(CloneContext& cloneContext) const
 762 {
 763     ConceptIdNode* clone = new ConceptIdNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(id->Clone(cloneContext)));
 764     int n = typeParameters.Count();
 765     for (int i = 0; i < n; ++i)
 766     {
 767         clone->AddTypeParameter(typeParameters[i]->Clone(cloneContext));
 768     }
 769     return clone;
 770 }
 771 
 772 void ConceptIdNode::Accept(Visitor& visitor)
 773 {
 774     visitor.Visit(*this);
 775 }
 776 
 777 void ConceptIdNode::Write(AstWriter& writer)
 778 {
 779     Node::Write(writer);
 780     writer.Write(id.get());
 781     typeParameters.Write(writer);
 782 }
 783 
 784 void ConceptIdNode::Read(AstReader& reader)
 785 {
 786     Node::Read(reader);
 787     id.reset(reader.ReadIdentifierNode());
 788     id->SetParent(this);
 789     typeParameters.Read(reader);
 790     typeParameters.SetParent(this);
 791 }
 792 
 793 void ConceptIdNode::AddTypeParameter(Node* typeParameter)
 794 {
 795     typeParameter->SetParent(this);
 796     typeParameters.Add(typeParameter);
 797 }
 798 
 799 std::string ConceptIdNode::ToString() const
 800 {
 801     std::string s = id->ToString();
 802     s.append(1'<');
 803     int n = typeParameters.Count();
 804     for (int i = 0; i < n; ++i)
 805     {
 806         if (i > 0)
 807         {
 808             s.append(", ");
 809         }
 810         s.append(typeParameters[i]->ToString());
 811     }
 812     s.append(1'>');
 813     return s;
 814 }
 815 
 816 ConceptNode::ConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::conceptNodespan_moduleId_)specifiers(Specifiers::none)id()typeParameters()refinement()constraints()axioms()
 817 {
 818 }
 819 
 820 ConceptNode::ConceptNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_) : Node(nodeType_span_moduleId_)specifiers(Specifiers::none)id()typeParameters()refinement()constraints()axioms()
 821 {
 822 }
 823 
 824 ConceptNode::ConceptNode(const Span& span_const boost::uuids::uuid& moduleId_Specifiers specifiers_IdentifierNode* id_) :
 825     Node(NodeType::conceptNodespan_moduleId_)specifiers(specifiers_)id(id_)typeParameters()refinement()constraints()axioms()
 826 {
 827     id->SetParent(this);
 828 }
 829 
 830 ConceptNode::ConceptNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_Specifiers specifiers_IdentifierNode* id_) :
 831     Node(nodeType_span_moduleId_)specifiers(specifiers_)id(id_)typeParameters()refinement()constraints()axioms()
 832 {
 833     id->SetParent(this);
 834 }
 835 
 836 Node* ConceptNode::Clone(CloneContext& cloneContext) const
 837 {
 838     ConceptNode* clone = new ConceptNode(GetSpan()ModuleId()specifiersstatic_cast<IdentifierNode*>(id->Clone(cloneContext)));
 839     int nt = typeParameters.Count();
 840     for (int i = 0; i < nt; ++i)
 841     {
 842         clone->AddTypeParameter(static_cast<IdentifierNode*>(typeParameters[i]->Clone(cloneContext)));
 843     }
 844     if (refinement)
 845     {
 846         clone->SetRefinement(static_cast<ConceptIdNode*>(refinement->Clone(cloneContext)));
 847     }
 848     int nc = constraints.Count();
 849     for (int i = 0; i < nc; ++i)
 850     {
 851         clone->AddConstraint(static_cast<ConstraintNode*>(constraints[i]->Clone(cloneContext)));
 852     }
 853     int na = axioms.Count();
 854     for (int i = 0; i < na; ++i)
 855     {
 856         clone->AddAxiom(static_cast<AxiomNode*>(axioms[i]->Clone(cloneContext)));
 857     }
 858     clone->SetBeginBraceSpan(beginBraceSpan);
 859     clone->SetEndBraceSpan(endBraceSpan);
 860     return clone;
 861 }
 862 
 863 void ConceptNode::Accept(Visitor& visitor)
 864 {
 865     visitor.Visit(*this);
 866 }
 867 
 868 void ConceptNode::Write(AstWriter& writer)
 869 {
 870     Node::Write(writer);
 871     writer.Write(specifiers);
 872     writer.Write(id.get());
 873     typeParameters.Write(writer);
 874     bool hasRefinement = refinement != nullptr;
 875     writer.GetBinaryWriter().Write(hasRefinement);
 876     if (hasRefinement)
 877     {
 878         writer.Write(refinement.get());
 879     }
 880     constraints.Write(writer);
 881     axioms.Write(writer);
 882     bool convertExternal = ModuleId() == writer.SpanConversionModuleId();
 883     writer.Write(beginBraceSpanconvertExternal);
 884     writer.Write(endBraceSpanconvertExternal);
 885 }
 886 
 887 void ConceptNode::Read(AstReader& reader)
 888 {
 889     Node::Read(reader);
 890     specifiers = reader.ReadSpecifiers();
 891     id.reset(reader.ReadIdentifierNode());
 892     id->SetParent(this);
 893     typeParameters.Read(reader);
 894     typeParameters.SetParent(this);
 895     bool hasRefinement = reader.GetBinaryReader().ReadBool();
 896     if (hasRefinement)
 897     {
 898         refinement.reset(reader.ReadConceptIdNode());
 899         refinement->SetParent(this);
 900     }
 901     constraints.Read(reader);
 902     constraints.SetParent(this);
 903     axioms.Read(reader);
 904     axioms.SetParent(this);
 905     beginBraceSpan = reader.ReadSpan();
 906     endBraceSpan = reader.ReadSpan();
 907 }
 908 
 909 void ConceptNode::AddTypeParameter(IdentifierNode* typeParameter)
 910 {
 911     typeParameter->SetParent(this);
 912     typeParameters.Add(typeParameter);
 913 }
 914 
 915 void ConceptNode::SetRefinement(ConceptIdNode* refinement_)
 916 {
 917     refinement.reset(refinement_);
 918     refinement->SetParent(this);
 919 }
 920 
 921 void ConceptNode::AddConstraint(ConstraintNode* constraint)
 922 {
 923     constraint->SetParent(this);
 924     constraints.Add(constraint);
 925 }
 926 
 927 void ConceptNode::AddAxiom(AxiomNode* axiom_)
 928 {
 929     axiom_->SetParent(this);
 930     axioms.Add(axiom_);
 931 }
 932 
 933 IntrinsicConstraintNode::IntrinsicConstraintNode(NodeType nodeType_) : ConstraintNode(nodeType_Span()boost::uuids::nil_uuid())
 934 {
 935 }
 936 
 937 SameConstraintNode::SameConstraintNode() : IntrinsicConstraintNode(NodeType::sameConstraintNode)
 938 {
 939 }
 940 
 941 SameConstraintNode::SameConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : IntrinsicConstraintNode(NodeType::sameConstraintNode)
 942 {
 943 }
 944 
 945 void SameConstraintNode::Accept(Visitor& visitor)
 946 {
 947     visitor.Visit(*this);
 948 }
 949 
 950 Node* SameConstraintNode::Clone(CloneContext& cloneContext) const
 951 {
 952     return new SameConstraintNode();
 953 }
 954 
 955 DerivedConstraintNode::DerivedConstraintNode() : IntrinsicConstraintNode(NodeType::derivedConstraintNode)
 956 {
 957 }
 958 
 959 DerivedConstraintNode::DerivedConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : IntrinsicConstraintNode(NodeType::derivedConstraintNode)
 960 {
 961 }
 962 
 963 void DerivedConstraintNode::Accept(Visitor& visitor)
 964 {
 965     visitor.Visit(*this);
 966 }
 967 
 968 Node* DerivedConstraintNode::Clone(CloneContext& cloneContext) const
 969 {
 970     return new DerivedConstraintNode();
 971 }
 972 
 973 ConvertibleConstraintNode::ConvertibleConstraintNode() : IntrinsicConstraintNode(NodeType::convertibleConstraintNode)
 974 {
 975 }
 976 
 977 ConvertibleConstraintNode::ConvertibleConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : IntrinsicConstraintNode(NodeType::convertibleConstraintNode)
 978 {
 979 }
 980 
 981 void ConvertibleConstraintNode::Accept(Visitor& visitor)
 982 {
 983     visitor.Visit(*this);
 984 }
 985 
 986 Node* ConvertibleConstraintNode::Clone(CloneContext& cloneContext) const
 987 {
 988     return new ConvertibleConstraintNode();
 989 }
 990 
 991 ExplicitlyConvertibleConstraintNode::ExplicitlyConvertibleConstraintNode() : IntrinsicConstraintNode(NodeType::explicitlyConvertibleConstraintNode)
 992 {
 993 }
 994 
 995 ExplicitlyConvertibleConstraintNode::ExplicitlyConvertibleConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : IntrinsicConstraintNode(NodeType::explicitlyConvertibleConstraintNode)
 996 {
 997 }
 998 
 999 void ExplicitlyConvertibleConstraintNode::Accept(Visitor& visitor)
1000 {
1001     visitor.Visit(*this);
1002 }
1003 
1004 Node* ExplicitlyConvertibleConstraintNode::Clone(CloneContext& cloneContext) const
1005 {
1006     return new ExplicitlyConvertibleConstraintNode();
1007 }
1008 
1009 CommonConstraintNode::CommonConstraintNode() : IntrinsicConstraintNode(NodeType::commonConstraintNode)
1010 {
1011 }
1012 
1013 CommonConstraintNode::CommonConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : IntrinsicConstraintNode(NodeType::commonConstraintNode)
1014 {
1015 }
1016 
1017 void CommonConstraintNode::Accept(Visitor& visitor)
1018 {
1019     visitor.Visit(*this);
1020 }
1021 
1022 Node* CommonConstraintNode::Clone(CloneContext& cloneContext) const
1023 {
1024     return new CommonConstraintNode();
1025 }
1026 
1027 NonreferenceTypeConstraintNode::NonreferenceTypeConstraintNode() : IntrinsicConstraintNode(NodeType::nonreferenceTypeConstraintNode)
1028 {
1029 }
1030 
1031 NonreferenceTypeConstraintNode::NonreferenceTypeConstraintNode(const Span& span_const boost::uuids::uuid& moduleId_) : IntrinsicConstraintNode(NodeType::nonreferenceTypeConstraintNode)
1032 {
1033 }
1034 
1035 void NonreferenceTypeConstraintNode::Accept(Visitor& visitor)
1036 {
1037     visitor.Visit(*this);
1038 }
1039 
1040 Node* NonreferenceTypeConstraintNode::Clone(CloneContext& cloneContext) const
1041 {
1042     return new NonreferenceTypeConstraintNode();
1043 }
1044 
1045 SameConceptNode::SameConceptNode() : ConceptNode(NodeType::sameConceptNodeSpan()boost::uuids::nil_uuid()Specifiers::public_new IdentifierNode(Span()boost::uuids::nil_uuid()U"Same"))
1046 {
1047     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"T"));
1048     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"U"));
1049     AddConstraint(new SameConstraintNode());
1050 }
1051 
1052 SameConceptNode::SameConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) : ConceptNode(NodeType::sameConceptNodespan_moduleId_)
1053 {
1054 }
1055 
1056 DerivedConceptNode::DerivedConceptNode() : ConceptNode(NodeType::derivedConceptNodeSpan()boost::uuids::nil_uuid()Specifiers::public_new IdentifierNode(Span()boost::uuids::nil_uuid()U"Derived"))
1057 {
1058     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"T"));
1059     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"U"));
1060     AddConstraint(new DerivedConstraintNode());
1061 }
1062 
1063 DerivedConceptNode::DerivedConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) : ConceptNode(NodeType::derivedConceptNodespan_moduleId_)
1064 {
1065 }
1066 
1067 ConvertibleConceptNode::ConvertibleConceptNode() : ConceptNode(NodeType::convertibleConceptNodeSpan()boost::uuids::nil_uuid()Specifiers::public_new IdentifierNode(Span()boost::uuids::nil_uuid()U"Convertible"))
1068 {
1069     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"T"));
1070     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"U"));
1071     AddConstraint(new ConvertibleConstraintNode());
1072 }
1073 
1074 ConvertibleConceptNode::ConvertibleConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) : ConceptNode(NodeType::convertibleConceptNodespan_moduleId_)
1075 {
1076 }
1077 
1078 ExplicitlyConvertibleConceptNode::ExplicitlyConvertibleConceptNode() :
1079     ConceptNode(NodeType::explicitlyConvertibleConceptNodeSpan()boost::uuids::nil_uuid()Specifiers::public_new IdentifierNode(Span()boost::uuids::nil_uuid()U"ExplicitlyConvertible"))
1080 {
1081     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"T"));
1082     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"U"));
1083     AddConstraint(new ExplicitlyConvertibleConstraintNode());
1084 }
1085 
1086 ExplicitlyConvertibleConceptNode::ExplicitlyConvertibleConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) :
1087     ConceptNode(NodeType::explicitlyConvertibleConceptNodespan_moduleId_)
1088 {
1089 }
1090 
1091 CommonConceptNode::CommonConceptNode() :
1092     ConceptNode(NodeType::commonConceptNodeSpan()boost::uuids::nil_uuid()Specifiers::public_new IdentifierNode(Span()boost::uuids::nil_uuid()U"Common"))
1093 {
1094     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"T"));
1095     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"U"));
1096     AddConstraint(new CommonConstraintNode());
1097 }
1098 
1099 CommonConceptNode::CommonConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) : ConceptNode(NodeType::commonConceptNodespan_moduleId_)
1100 {
1101 }
1102 
1103 NonreferenceTypeConceptNode::NonreferenceTypeConceptNode() :
1104     ConceptNode(NodeType::nonreferenceTypeConceptNodeSpan()boost::uuids::nil_uuid()Specifiers::public_new IdentifierNode(Span()boost::uuids::nil_uuid()U"NonreferenceType"))
1105 {
1106     AddTypeParameter(new IdentifierNode(Span()boost::uuids::nil_uuid()U"T"));
1107     AddConstraint(new NonreferenceTypeConstraintNode());
1108 }
1109 
1110 NonreferenceTypeConceptNode::NonreferenceTypeConceptNode(const Span& span_const boost::uuids::uuid& moduleId_) : ConceptNode(NodeType::nonreferenceTypeConceptNodespan_moduleId_)
1111 {
1112 }
1113 
1114 } } // namespace sngcm::ast