1
2
3
4
5
6 #include <sngcpp/symbols/ContainerSymbol.hpp>
7 #include <sngcpp/symbols/FunctionSymbol.hpp>
8 #include <sngcpp/symbols/ClassTypeSymbol.hpp>
9 #include <sngcpp/symbols/NamespaceSymbol.hpp>
10 #include <sngcpp/symbols/EnumerationSymbol.hpp>
11 #include <sngcpp/symbols/TypedefSymbol.hpp>
12 #include <sngcpp/symbols/VariableSymbol.hpp>
13 #include <sngcpp/symbols/GrammarSymbol.hpp>
14 #include <soulng/util/Unicode.hpp>
15 #include <algorithm>
16
17 namespace sngcpp { namespace symbols {
18
19 using namespace soulng::unicode;
20
21 ContainerSymbol::ContainerSymbol(const Span& span_, const std::u32string& name_) : Symbol(span_, name_), containerScope(this)
22 {
23 }
24
25 void ContainerSymbol::AddMember(std::std::unique_ptr<Symbol>&&member)
26 {
27 if (member->IsInstallSymbol())
28 {
29 containerScope.Install(member.get());
30 member->SetParent(this);
31 members.push_back(std::move(member));
32 }
33 else
34 {
35 if (member->IsFunctionSymbol())
36 {
37 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(member.get());
38 FunctionGroupSymbol* functionGroup = MakeFunctionGroupSymbol(member->GetSpan(), functionSymbol->GroupName());
39 functionGroup->AddFunction(std::unique_ptr<FunctionSymbol>(static_cast<FunctionSymbol*>(member.release())));
40 }
41 else if (member->IsFunctionDeclarationSymbol())
42 {
43 FunctionDeclarationSymbol* functionDeclarationSymbol = static_cast<FunctionDeclarationSymbol*>(member.get());
44 FunctionGroupSymbol* functionGroup = MakeFunctionGroupSymbol(member->GetSpan(), functionDeclarationSymbol->GroupName());
45 functionGroup->AddFunctionDeclaration(std::unique_ptr<FunctionDeclarationSymbol>(static_cast<FunctionDeclarationSymbol*>(member.release())));
46 }
47 else if (member->IsClassTypeSymbol())
48 {
49 ClassGroupSymbol* classGroup = MakeClassGroupSymbol(member->GetSpan(), member->Name());
50 classGroup->AddClass(std::unique_ptr<ClassTypeSymbol>(static_cast<ClassTypeSymbol*>(member.release())));
51 }
52 else
53 {
54 throw std::runtime_error("function or class type symbol expected");
55 }
56 }
57 }
58
59 FunctionGroupSymbol* ContainerSymbol::MakeFunctionGroupSymbol(const Span& span_, const std::u32string& groupName)
60 {
61 Symbol* symbol = containerScope.Lookup(groupName);
62 if (!symbol)
63 {
64 FunctionGroupSymbol* functionGroupSymbol = new FunctionGroupSymbol(span_, groupName);
65 AddMember(std::unique_ptr<Symbol>(functionGroupSymbol));
66 return functionGroupSymbol;
67 }
68 else if (symbol->IsFunctionGroupSymbol())
69 {
70 return static_cast<FunctionGroupSymbol*>(symbol);
71 }
72 else
73 {
74 throw std::runtime_error("symbol '" + ToUtf8(groupName) + "' conflicts with function group of the same name");
75 }
76 }
77
78 ClassGroupSymbol* ContainerSymbol::MakeClassGroupSymbol(const Span& span_, const std::u32string& groupName)
79 {
80 Symbol* symbol = containerScope.Lookup(groupName);
81 if (!symbol)
82 {
83 ClassGroupSymbol* classGroupSymbol = new ClassGroupSymbol(span_, groupName);
84 AddMember(std::unique_ptr<Symbol>(classGroupSymbol));
85 return classGroupSymbol;
86 }
87 else if (symbol->IsClassGroupSymbol())
88 {
89 return static_cast<ClassGroupSymbol*>(symbol);
90 }
91 else
92 {
93 throw std::runtime_error("symbol '" + ToUtf8(groupName) + "' conflicts with class group of the same name");
94 }
95 }
96
97 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Namespaces()
98 {
99 std::unique_ptr<sngxml::dom::Element> namespacesElement;
100 std::vector<NamespaceSymbol*> namespaces;
101 for (const std::std::unique_ptr<Symbol>&member : members)
102 {
103 if (member->IsNamespaceSymbol())
104 {
105 namespaces.push_back(static_cast<NamespaceSymbol*>(member.get()));
106 }
107 }
108 if (!namespaces.empty())
109 {
110 namespacesElement.reset(new sngxml::dom::Element(U"namespaces"));
111 std::sort(namespaces.begin(), namespaces.end(), ByName());
112 for (NamespaceSymbol* ns : namespaces)
113 {
114 std::unique_ptr<sngxml::dom::Element> namespaceElement = ns->ToDomElement();
115 namespacesElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(namespaceElement.release()));
116 }
117 }
118 return namespacesElement;
119 }
120
121 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Classes()
122 {
123 std::unique_ptr<sngxml::dom::Element> classesElement;
124 std::vector<ClassTypeSymbol*> classes;
125 for (const std::std::unique_ptr<Symbol>&member : members)
126 {
127 if (member->IsClassGroupSymbol())
128 {
129 ClassGroupSymbol* classGroup = static_cast<ClassGroupSymbol*>(member.get());
130 for (const std::std::unique_ptr<ClassTypeSymbol>&cls : classGroup->Classes())
131 {
132 classes.push_back(cls.get());
133 }
134 }
135 }
136 if (!classes.empty())
137 {
138 classesElement.reset(new sngxml::dom::Element(U"classes"));
139 std::sort(classes.begin(), classes.end(), ByName());
140 for (ClassTypeSymbol* cls : classes)
141 {
142 std::unique_ptr<sngxml::dom::Element> classElement = cls->ToDomElement();
143 classesElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(classElement.release()));
144 }
145 }
146 return classesElement;
147 }
148
149 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Constructors()
150 {
151 std::unique_ptr<sngxml::dom::Element> constructorsElement;
152 std::vector<ConstructorSymbol*> constructors;
153 for (const std::std::unique_ptr<Symbol>&member : members)
154 {
155 if (member->IsFunctionGroupSymbol())
156 {
157 FunctionGroupSymbol* functionroup = static_cast<FunctionGroupSymbol*>(member.get());
158 for (const std::std::unique_ptr<FunctionSymbol>&function : functionroup->Functions())
159 {
160 if (function->IsConstructorSymbol())
161 {
162 constructors.push_back(static_cast<ConstructorSymbol*>(function.get()));
163 }
164 }
165 }
166 }
167 if (!constructors.empty())
168 {
169 constructorsElement.reset(new sngxml::dom::Element(U"constructors"));
170 std::sort(constructors.begin(), constructors.end(), ByName());
171 for (ConstructorSymbol* constructor : constructors)
172 {
173 std::unique_ptr<sngxml::dom::Element> constructorElement = constructor->ToDomElement();
174 constructorsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(constructorElement.release()));
175 }
176 }
177 return constructorsElement;
178 }
179
180 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Functions()
181 {
182 std::unique_ptr<sngxml::dom::Element> functionsElement;
183 std::vector<FunctionSymbol*> functions;
184 for (const std::std::unique_ptr<Symbol>&member : members)
185 {
186 if (member->IsFunctionGroupSymbol())
187 {
188 FunctionGroupSymbol* functionGroup = static_cast<FunctionGroupSymbol*>(member.get());
189 for (const std::std::unique_ptr<FunctionSymbol>&function : functionGroup->Functions())
190 {
191 if (function->IsFunctionSymbol() && !function->IsConstructorSymbol())
192 {
193 functions.push_back(function.get());
194 }
195 }
196 }
197 }
198 if (!functions.empty())
199 {
200 functionsElement.reset(new sngxml::dom::Element(U"functions"));
201 std::sort(functions.begin(), functions.end(), ByName());
202 for (FunctionSymbol* function : functions)
203 {
204 std::unique_ptr<sngxml::dom::Element> functionElement = function->ToDomElement();
205 functionsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(functionElement.release()));
206 }
207 }
208 return functionsElement;
209 }
210
211 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::EnumTypes()
212 {
213 std::unique_ptr<sngxml::dom::Element> enumTypesElement;
214 std::vector<EnumTypeSymbol*> enumTypes;
215 for (const std::std::unique_ptr<Symbol>&member : members)
216 {
217 if (member->IsEnumTypeSymbol())
218 {
219 EnumTypeSymbol* enumType = static_cast<EnumTypeSymbol*>(member.get());
220 enumTypes.push_back(enumType);
221 }
222 }
223 if (!enumTypes.empty())
224 {
225 enumTypesElement.reset(new sngxml::dom::Element(U"enumTypes"));
226 std::sort(enumTypes.begin(), enumTypes.end(), ByName());
227 for (EnumTypeSymbol* enumType : enumTypes)
228 {
229 std::unique_ptr<sngxml::dom::Element> enumTypeElement = enumType->ToDomElement();
230 enumTypesElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(enumTypeElement.release()));
231 }
232 }
233 return enumTypesElement;
234 }
235
236 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Enumerators()
237 {
238 std::unique_ptr<sngxml::dom::Element> enumeratorsElement;
239 std::vector<EnumeratorSymbol*> enumerators;
240 for (const std::std::unique_ptr<Symbol>&member : members)
241 {
242 if (member->IsEnumeratorSymbol())
243 {
244 EnumeratorSymbol* enumerator = static_cast<EnumeratorSymbol*>(member.get());
245 enumerators.push_back(enumerator);
246 }
247 }
248 if (!enumerators.empty())
249 {
250 enumeratorsElement.reset(new sngxml::dom::Element(U"enumerators"));
251 for (EnumeratorSymbol* enumerator : enumerators)
252 {
253 std::unique_ptr<sngxml::dom::Element> enumeratorElement = enumerator->ToDomElement();
254 enumeratorsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(enumeratorElement.release()));
255 }
256 }
257 return enumeratorsElement;
258 }
259
260 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Typedefs()
261 {
262 std::unique_ptr<sngxml::dom::Element> typedefsElement;
263 std::vector<TypedefSymbol*> typedefs;
264 for (const std::std::unique_ptr<Symbol>&member : members)
265 {
266 if (member->IsTypedefSymbol())
267 {
268 TypedefSymbol* typedef_ = static_cast<TypedefSymbol*>(member.get());
269 typedefs.push_back(typedef_);
270 }
271 }
272 if (!typedefs.empty())
273 {
274 typedefsElement.reset(new sngxml::dom::Element(U"typedefs"));
275 std::sort(typedefs.begin(), typedefs.end(), ByName());
276 for (TypedefSymbol* typedef_ : typedefs)
277 {
278 std::unique_ptr<sngxml::dom::Element> typedefElement = typedef_->ToDomElement();
279 typedefsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(typedefElement.release()));
280 }
281 }
282 return typedefsElement;
283 }
284
285 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Variables()
286 {
287 std::unique_ptr<sngxml::dom::Element> variablesElement;
288 std::vector<VariableSymbol*> variables;
289 for (const std::std::unique_ptr<Symbol>&member : members)
290 {
291 if (member->IsVariableSymbol())
292 {
293 VariableSymbol* variable = static_cast<VariableSymbol*>(member.get());
294 variables.push_back(variable);
295 }
296 }
297 if (!variables.empty())
298 {
299 variablesElement.reset(new sngxml::dom::Element(U"variables"));
300 std::sort(variables.begin(), variables.end(), ByName());
301 for (VariableSymbol* variable : variables)
302 {
303 std::unique_ptr<sngxml::dom::Element> variableElement = variable->ToDomElement();
304 variablesElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(variableElement.release()));
305 }
306 }
307 return variablesElement;
308 }
309
310 std::std::unique_ptr<sngxml::dom::Element>ContainerSymbol::Grammars()
311 {
312 std::unique_ptr<sngxml::dom::Element> grammarsElement;
313 std::vector<GrammarSymbol*> grammars;
314 for (const std::std::unique_ptr<Symbol>&member : members)
315 {
316 if (member->IsGrammarSymbol())
317 {
318 GrammarSymbol* grammar = static_cast<GrammarSymbol*>(member.get());
319 grammars.push_back(grammar);
320 }
321 }
322 if (!grammars.empty())
323 {
324 grammarsElement.reset(new sngxml::dom::Element(U"grammars"));
325 std::sort(grammars.begin(), grammars.end(), ByName());
326 for (GrammarSymbol* grammar : grammars)
327 {
328 std::unique_ptr<sngxml::dom::Element> grammarElement = grammar->ToDomElement();
329 grammarsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(grammarElement.release()));
330 }
331 }
332 return grammarsElement;
333 }
334
335 } }