1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sngcm/ast/Namespace.hpp>
  7 #include <sngcm/ast/Identifier.hpp>
  8 #include <sngcm/ast/Visitor.hpp>
  9 #include <sngcm/ast/Function.hpp>
 10 #include <soulng/util/Unicode.hpp>
 11 #include <soulng/util/Sha1.hpp>
 12 #include <boost/uuid/random_generator.hpp>
 13 
 14 namespace sngcm { namespace ast {
 15 
 16 using namespace soulng::unicode;
 17 using namespace soulng::util;
 18 
 19 NamespaceNode::NamespaceNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::namespaceNodespan_moduleId_)id()flags()
 20 {
 21 }
 22 
 23 NamespaceNode::NamespaceNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_) : Node(NodeType::namespaceNodespan_moduleId_)id(id_)flags()
 24 {
 25     if (id == nullptr)
 26     {
 27         SetUnnamedNs();
 28         Sha1 sha1;
 29         boost::uuids::uuid randomUuid = boost::uuids::random_generator()();
 30         for (uint8_t x : randomUuid)
 31         {
 32             sha1.Process(x);
 33         }
 34         id.reset(new IdentifierNode(span_moduleId_U"unnamed_ns_" + ToUtf32(sha1.GetDigest())));
 35     }
 36     id->SetParent(this);
 37 }
 38 
 39 IdentifierNode* NamespaceNode::Id() const
 40 {
 41     return id.get();
 42 }
 43 
 44 Node* NamespaceNode::Clone(CloneContext& cloneContext) const
 45 {
 46     NamespaceNode* clone = nullptr;
 47     if (IsUnnamedNs())
 48     {
 49         clone = new NamespaceNode(GetSpan()ModuleId()nullptr);
 50     }
 51     else
 52     {
 53         clone = new NamespaceNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(id->Clone(cloneContext)));
 54     }
 55     clone->flags = flags;
 56     int n = members.Count();
 57     for (int i = 0; i < n; ++i)
 58     {
 59         Node* member = members[i];
 60         if (cloneContext.MakeTestUnits() && member->GetNodeType() == NodeType::functionNode&&(  static_cast<FunctionNode*>(member)->GetSpecifiers() & Specifiers::unit_test_) != Specifiers::none)
 61         {
 62             FunctionNode* unitTestFunction = static_cast<FunctionNode*>(member->Clone(cloneContext));
 63             unitTestFunction->SetParent(const_cast<NamespaceNode*>(this));
 64             cloneContext.AddUnitTestFunction(unitTestFunction);
 65         }
 66         else
 67         {
 68             clone->AddMember(member->Clone(cloneContext));
 69         }
 70     }
 71     return clone;
 72 }
 73 
 74 void NamespaceNode::Accept(Visitor& visitor)
 75 {
 76     visitor.Visit(*this);
 77 }
 78 
 79 void NamespaceNode::Write(AstWriter& writer)
 80 {
 81     Node::Write(writer);
 82     writer.Write(id.get());
 83     writer.GetBinaryWriter().Write(static_cast<int8_t>(flags));
 84     members.Write(writer);
 85 }
 86 
 87 void NamespaceNode::Read(AstReader& reader)
 88 {
 89     Node::Read(reader);
 90     id.reset(reader.ReadIdentifierNode());
 91     id->SetParent(this);
 92     flags = static_cast<NsFlags>(reader.GetBinaryReader().ReadSByte());
 93     members.Read(reader);
 94     members.SetParent(this);
 95 }
 96 
 97 void NamespaceNode::AddMember(Node* member)
 98 {
 99     member->SetParent(this);
100     members.Add(member);
101     if (member->GetNodeType() == NodeType::namespaceNode)
102     {
103         NamespaceNode* ns = static_cast<NamespaceNode*>(member);
104         if (ns->IsUnnamedNs() || ns->HasUnnamedNs())
105         {
106             SetHasUnnamedNs();
107         }
108     }
109 }
110 
111 AliasNode::AliasNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::aliasNodespan_moduleId_)id()qid()
112 {
113 }
114 
115 AliasNode::AliasNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* id_IdentifierNode* qid_) : Node(NodeType::aliasNodespan_moduleId_)id(id_)qid(qid_)
116 {
117     id->SetParent(this);
118     qid->SetParent(this);
119 }
120 
121 Node* AliasNode::Clone(CloneContext& cloneContext) const
122 {
123     AliasNode* clone = new AliasNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(id->Clone(cloneContext))static_cast<IdentifierNode*>(qid->Clone(cloneContext)));
124     return clone;
125 }
126 
127 void AliasNode::Accept(Visitor& visitor)
128 {
129     visitor.Visit(*this);
130 }
131 
132 void AliasNode::Write(AstWriter& writer)
133 {
134     Node::Write(writer);
135     writer.Write(id.get());
136     writer.Write(qid.get());
137 }
138 
139 void AliasNode::Read(AstReader& reader)
140 {
141     Node::Read(reader);
142     id.reset(reader.ReadIdentifierNode());
143     id->SetParent(this);
144     qid.reset(reader.ReadIdentifierNode());
145     qid->SetParent(this);
146 }
147 
148 IdentifierNode* AliasNode::Id() const
149 {
150     return id.get();
151 }
152 
153 IdentifierNode* AliasNode::Qid() const
154 {
155     return qid.get();
156 }
157 
158 NamespaceImportNode::NamespaceImportNode(const Span& span_const boost::uuids::uuid& moduleId_) : Node(NodeType::namespaceImportNodespan_moduleId_)ns()
159 {
160 }
161 
162 NamespaceImportNode::NamespaceImportNode(const Span& span_const boost::uuids::uuid& moduleId_IdentifierNode* ns_) : Node(NodeType::namespaceImportNodespan_moduleId_)ns(ns_)
163 {
164     ns->SetParent(this);
165 }
166 
167 Node* NamespaceImportNode::Clone(CloneContext& cloneContext) const
168 {
169     NamespaceImportNode* clone = new NamespaceImportNode(GetSpan()ModuleId()static_cast<IdentifierNode*>(ns->Clone(cloneContext)));
170     return clone;
171 }
172 
173 void NamespaceImportNode::Accept(Visitor& visitor)
174 {
175     visitor.Visit(*this);
176 }
177 
178 void NamespaceImportNode::Write(AstWriter& writer)
179 {
180     Node::Write(writer);
181     writer.Write(ns.get());
182 }
183 
184 void NamespaceImportNode::Read(AstReader& reader)
185 {
186     Node::Read(reader);
187     ns.reset(reader.ReadIdentifierNode());
188     ns->SetParent(this);
189 }
190 
191 IdentifierNode* NamespaceImportNode::Ns() const
192 {
193     return ns.get();
194 }
195 
196 } } // namespace sngcm::ast