1
2
3
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::namespaceNode, span_, moduleId_), id(), flags()
20 {
21 }
22
23 NamespaceNode::NamespaceNode(const Span& span_, const boost::uuids::uuid& moduleId_, IdentifierNode* id_) : Node(NodeType::namespaceNode, span_, 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::aliasNode, span_, moduleId_), id(), qid()
112 {
113 }
114
115 AliasNode::AliasNode(const Span& span_, const boost::uuids::uuid& moduleId_, IdentifierNode* id_, IdentifierNode* qid_) : Node(NodeType::aliasNode, span_, 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::namespaceImportNode, span_, moduleId_), ns()
159 {
160 }
161
162 NamespaceImportNode::NamespaceImportNode(const Span& span_, const boost::uuids::uuid& moduleId_, IdentifierNode* ns_) : Node(NodeType::namespaceImportNode, span_, 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 } }