1
2
3
4
5
6 #include <cpp2cm/cpp2cm/Map.hpp>
7 #include <sngcpp/symbols/ClassTemplateSpecializationSymbol.hpp>
8 #include <sngcpp/symbols/DerivedTypeSymbol.hpp>
9 #include <sngcpp/symbols/TypedefSymbol.hpp>
10 #include <sngcpp/symbols/ExternalTypeSymbol.hpp>
11 #include <sngcm/ast/Identifier.hpp>
12 #include <sngcm/ast/TypeExpr.hpp>
13 #include <sngcm/ast/Template.hpp>
14 #include <sngcm/ast/Expression.hpp>
15 #include <sngcm/ast/Class.hpp>
16 #include <soulng/util/Util.hpp>
17
18 namespace cpp2cm {
19
20 using namespace soulng::util;
21
22 std::u32string GetFullName(sngcm::ast::Node* node)
23 {
24 if (!node) return std::u32string();
25 std::u32string fullName = GetFullName(node->Parent());
26 if (!fullName.empty())
27 {
28 fullName.append(1, '.');
29 }
30 if (node->GetNodeType() == sngcm::ast::NodeType::namespaceNode)
31 {
32 fullName.append(static_cast<sngcm::ast::NamespaceNode*>(node)->Id()->Str());
33 }
34 else if (node->GetNodeType() == sngcm::ast::NodeType::classNode)
35 {
36 fullName.append(static_cast<sngcm::ast::ClassNode*>(node)->Id()->Str());
37 }
38 else
39 {
40 int x = 0;
41 }
42 return fullName;
43 }
44
45 sngcm::ast::Node* MakeQualifiedIdNode(const std::u32string& fullName)
46 {
47 sngcm::ast::Node* result = nullptr;
48 if (!fullName.empty())
49 {
50 std::vector<std::u32string> components = Split(fullName, '.');
51 while (!components.empty())
52 {
53 if (result)
54 {
55 result = new sngcm::ast::DotNode(soulng::lexer::Span(), result, new sngcm::ast::IdentifierNode(soulng::lexer::Span(), components.back()));
56 }
57 else
58 {
59 result = new sngcm::ast::IdentifierNode(soulng::lexer::Span(), components.back());
60 }
61 components.pop_back();
62 }
63 }
64 if (!result)
65 {
66 result = new sngcm::ast::IdentifierNode(soulng::lexer::Span(), U"NOT_CONVERTED");
67 }
68 return result;
69 }
70
71 Map::Map() : symbolTable(nullptr), currentContext(nullptr)
72 {
73 InitNameNodeTypeMap();
74 InitSimpleTypeMap();
75 ClearNamespaceImports();
76 }
77
78 void Map::InitNameNodeTypeMap()
79 {
80 nameNodeTypeMap[U"bool"] = sngcm::ast::NodeType::boolNode;
81 nameNodeTypeMap[U"sbyte"] = sngcm::ast::NodeType::sbyteNode;
82 nameNodeTypeMap[U"byte"] = sngcm::ast::NodeType::byteNode;
83 nameNodeTypeMap[U"short"] = sngcm::ast::NodeType::shortNode;
84 nameNodeTypeMap[U"ushort"] = sngcm::ast::NodeType::ushortNode;
85 nameNodeTypeMap[U"int"] = sngcm::ast::NodeType::intNode;
86 nameNodeTypeMap[U"uint"] = sngcm::ast::NodeType::uintNode;
87 nameNodeTypeMap[U"long"] = sngcm::ast::NodeType::longNode;
88 nameNodeTypeMap[U"ulong"] = sngcm::ast::NodeType::ulongNode;
89 nameNodeTypeMap[U"float"] = sngcm::ast::NodeType::floatNode;
90 nameNodeTypeMap[U"double"] = sngcm::ast::NodeType::doubleNode;
91 nameNodeTypeMap[U"char"] = sngcm::ast::NodeType::charNode;
92 nameNodeTypeMap[U"wchar"] = sngcm::ast::NodeType::wcharNode;
93 nameNodeTypeMap[U"uchar"] = sngcm::ast::NodeType::ucharNode;
94 nameNodeTypeMap[U"void"] = sngcm::ast::NodeType::voidNode;
95 }
96
97 void Map::InitSimpleTypeMap()
98 {
99 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char_] = sngcm::ast::NodeType::charNode;
100 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::charNode;
101 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::charNode;
102 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char16] = sngcm::ast::NodeType::wcharNode;
103 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char16 | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::wcharNode;
104 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char16 | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::wcharNode;
105 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char32] = sngcm::ast::NodeType::ucharNode;
106 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char32 | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::ucharNode;
107 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::char32 | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::ucharNode;
108 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::wchar] = sngcm::ast::NodeType::ucharNode;
109 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::wchar | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::ucharNode;
110 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::wchar | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::ucharNode;
111 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::bool_] = sngcm::ast::NodeType::boolNode;
112 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::short_] = sngcm::ast::NodeType::shortNode;
113 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::short_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::shortNode;
114 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::short_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::shortNode;
115 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::short_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::shortNode;
116 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::short_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::ushortNode;
117 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::short_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::ushortNode;
118 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::intNode;
119 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::intNode;
120 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::int_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::intNode;
121 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::uintNode;
122 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::int_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::uintNode;
123 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::long_] = sngcm::ast::NodeType::longNode;
124 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::long_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::longNode;
125 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::long_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::longNode;
126 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::long_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::longNode;
127 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::longLong_] = sngcm::ast::NodeType::longNode;
128 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::longLong_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::longNode;
129 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::longLong_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_] = sngcm::ast::NodeType::longNode;
130 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::longLong_ | sngcpp::ast::SimpleTypeSpecifierFlags::signed_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::longNode;
131 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::long_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::ulongNode;
132 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::long_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::ulongNode;
133 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::longLong_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_] = sngcm::ast::NodeType::ulongNode;
134 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::longLong_ | sngcpp::ast::SimpleTypeSpecifierFlags::unsigned_ | sngcpp::ast::SimpleTypeSpecifierFlags::int_] = sngcm::ast::NodeType::ulongNode;
135 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::float_] = sngcm::ast::NodeType::floatNode;
136 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::double_] = sngcm::ast::NodeType::doubleNode;
137 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::double_ | sngcpp::ast::SimpleTypeSpecifierFlags::long_] = sngcm::ast::NodeType::doubleNode;
138 simpleTypeMap[sngcpp::ast::SimpleTypeSpecifierFlags::void_] = sngcm::ast::NodeType::voidNode;
139 }
140
141 sngcm::ast::Node* Map::CreateNode(sngcm::ast::NodeType nodeType)
142 {
143 if (nodeType != sngcm::ast::NodeType::maxNode)
144 {
145 return sngcm::ast::NodeFactory::Instance().CreateNode(nodeType, soulng::lexer::Span());
146 }
147 return nullptr;
148 }
149
150 sngcm::ast::Node* Map::CreateNode(const std::u32string& name)
151 {
152 auto it = nameNodeTypeMap.find(name);
153 if (it != nameNodeTypeMap.cend())
154 {
155 sngcm::ast::NodeType nodeType = it->second;
156 return CreateNode(nodeType);
157 }
158 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), name);
159 }
160
161 void Map::MapNs(const std::u32string& source, const std::u32string& target)
162 {
163 nsMap[source] = target;
164 }
165
166 std::u32string Map::GetNs(const std::u32string& source) const
167 {
168 auto it = nsMap.find(source);
169 if (it != nsMap.cend())
170 {
171 return it->second;
172 }
173 return source;
174 }
175
176 void Map::AddSourceXmlDoc(sngxml::dom::Document* sourceXmlDoc, const std::u32string& projectName)
177 {
178 sourceXmlDocs.push_back(sourceXmlDoc);
179 projectSourceXmlDocMap[projectName] = sourceXmlDoc;
180 }
181
182 void Map::SetSymbolTable(sngcpp::symbols::SymbolTable* symbolTable_)
183 {
184 symbolTable = symbolTable_;
185 }
186
187 sngcm::ast::NodeType Map::MapSimpleType(sngcpp::ast::SimpleTypeSpecifierFlags flags)
188 {
189 sngcm::ast::NodeType nodeType = sngcm::ast::NodeType::maxNode;
190 auto it = simpleTypeMap.find(flags);
191 if (it != simpleTypeMap.cend())
192 {
193 nodeType = it->second;
194 }
195 return nodeType;
196 }
197
198 sngcm::ast::NodeType Map::MapSimpleType(sngcpp::symbols::SimpleTypeSymbol* simpleTypeSymbol)
199 {
200 return MapSimpleType(simpleTypeSymbol->Flags());
201 }
202
203 sngcm::ast::Node* Map::MakeDerivedType(sngcm::ast::Node* node, const std::std::vector<sngcpp::symbols::Derivation>&derivations)
204 {
205 bool hasConst = false;
206 bool lvalueRef = false;
207 bool rvalueRef = false;
208 for (auto derivation : derivations)
209 {
210 switch (derivation)
211 {
212 case sngcpp::symbols::Derivation::const_: hasConst = true; break;
213 case sngcpp::symbols::Derivation::lvalueRef: lvalueRef = true; break;
214 case sngcpp::symbols::Derivation::rvalueRef: rvalueRef = true; break;
215 case sngcpp::symbols::Derivation::ptr: node = new sngcm::ast::PointerNode(soulng::lexer::Span(), node); break;
216 case sngcpp::symbols::Derivation::base: break;
217 default:
218 {
219 return nullptr;
220 }
221 }
222 }
223 if (lvalueRef)
224 {
225 node = new sngcm::ast::LValueRefNode(soulng::lexer::Span(), node);
226 }
227 else if (rvalueRef)
228 {
229 node = new sngcm::ast::RValueRefNode(soulng::lexer::Span(), node);
230 }
231 if (hasConst)
232 {
233 node = new sngcm::ast::ConstNode(soulng::lexer::Span(), node);
234 }
235 return node;
236 }
237
238 sngcm::ast::IdentifierNode* Map::MapFullTypeName(sngcpp::symbols::TypeSymbol* type)
239 {
240 std::u32string fullTypeName;
241 std::u32string fullNamespaceName;
242 std::vector<sngcpp::symbols::Symbol*> parents;
243 bool nonNamespaceParent = false;
244 sngcpp::symbols::Symbol* parent = type->Parent();
245 while (parent)
246 {
247 parents.push_back(parent);
248 parent = parent->Parent();
249 }
250 int n = parents.size();
251 for (int i = n - 1; i >= 0; --i)
252 {
253 sngcpp::symbols::Symbol* parent = parents[i];
254 if (parent->IsNamespaceSymbol())
255 {
256 if (!parent->Name().empty())
257 {
258 std::u32string mappedNs = GetNs(parent->Name());
259 if (!mappedNs.empty())
260 {
261 if (!fullTypeName.empty())
262 {
263 fullTypeName.append(1, '.');
264 }
265 fullTypeName.append(mappedNs);
266 if (!fullNamespaceName.empty())
267 {
268 fullNamespaceName.append(1, '.');
269 }
270 fullNamespaceName.append(mappedNs);
271 }
272 }
273 }
274 else
275 {
276 if (!fullTypeName.empty())
277 {
278 fullTypeName.append(1, '.');
279 }
280 fullTypeName.append(parent->Name());
281 nonNamespaceParent = true;
282 }
283 }
284 std::u32string currentNamespaceName = GetFullName(currentContext->currentNamespace);
285 if (!nonNamespaceParent && currentNamespaceName == fullNamespaceName)
286 {
287 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), type->Name());
288 }
289 if (!fullTypeName.empty())
290 {
291 fullTypeName.append(1, '.');
292 }
293 fullTypeName.append(type->Name());
294 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), fullTypeName);
295 }
296
297 sngcm::ast::Node* Map::MapType(sngcpp::symbols::TypeSymbol* type, sngxml::dom::Document*& sourceXmlDoc)
298 {
299 if (!sourceXmlDoc)
300 {
301 auto it = projectSourceXmlDocMap.find(type->ProjectName());
302 if (it != projectSourceXmlDocMap.cend())
303 {
304 sourceXmlDoc = it->second;
305 }
306 }
307 if (type->IsClassTemplateSpecializationSymbol())
308 {
309 sngcpp::symbols::ClassTemplateSpecializationSymbol* specialization = static_cast<sngcpp::symbols::ClassTemplateSpecializationSymbol*>(type);
310 sngcpp::symbols::TypeSymbol* primaryType = specialization->PrimaryClassTemplateSymbol();
311 std::unique_ptr<sngcm::ast::Node> primaryNode(MapType(primaryType, sourceXmlDoc));
312 if (!primaryNode)
313 {
314 primaryNode.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), U"NOT_CONVERTED"));
315 }
316 std::unique_ptr<sngcm::ast::TemplateIdNode> templateIdNode(new sngcm::ast::TemplateIdNode(soulng::lexer::Span(), primaryNode.release()));
317 for (const auto& templateArgumentType : specialization->TemplateArgumentSymbols())
318 {
319 std::unique_ptr<sngcm::ast::Node> templateArgumentNode(MapType(templateArgumentType, sourceXmlDoc));
320 if (!templateArgumentNode)
321 {
322 templateArgumentNode.reset(new sngcm::ast::IdentifierNode(soulng::lexer::Span(), U"NOT_CONVERTED"));
323 }
324 templateIdNode->AddTemplateArgument(templateArgumentNode.release());
325 }
326 return templateIdNode.release();
327 }
328 else if (type->IsClassTypeSymbol())
329 {
330 sngcpp::symbols::ClassTypeSymbol* classTypeSymbol = static_cast<sngcpp::symbols::ClassTypeSymbol*>(type);
331 if (classTypeSymbol->ProjectName() != currentProjectName)
332 {
333 if (sourceXmlDoc)
334 {
335 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(classTypeSymbol->Id());
336 if (element)
337 {
338 std::u32string target = element->GetAttribute(U"target");
339 if (!target.empty())
340 {
341 target = RemoveNamespace(target);
342 return CreateNode(target);
343 }
344 }
345 }
346 }
347 sngcm::ast::Node* parentNode = nullptr;
348 sngcpp::symbols::Symbol* parent = classTypeSymbol->Parent();
349 auto it = currentContext->containerMap.find(parent);
350 if (it != currentContext->containerMap.cend())
351 {
352 parentNode = it->second;
353 }
354 if (parentNode == currentContext->currentContainerNode)
355 {
356 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), classTypeSymbol->Name());
357 }
358 else if (parentNode == nullptr)
359 {
360 return MapFullTypeName(classTypeSymbol);
361 }
362 else if (currentContext->currentContainerNode != nullptr)
363 {
364 std::u32string fullName = GetFullName(currentContext->currentContainerNode);
365 if (!fullName.empty())
366 {
367 fullName.append(1, '.');
368 }
369 fullName.append(classTypeSymbol->Name());
370 return MakeQualifiedIdNode(fullName);
371 }
372 }
373 else if (type->IsEnumTypeSymbol())
374 {
375 sngcpp::symbols::EnumTypeSymbol* enumTypeSymbol = static_cast<sngcpp::symbols::EnumTypeSymbol*>(type);
376 if (enumTypeSymbol->ProjectName() != currentProjectName)
377 {
378 if (sourceXmlDoc)
379 {
380 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(enumTypeSymbol->Id());
381 if (element)
382 {
383 std::u32string target = element->GetAttribute(U"target");
384 if (!target.empty())
385 {
386 target = RemoveNamespace(target);
387 return CreateNode(target);
388 }
389 }
390 }
391 }
392 sngcm::ast::Node* parentNode = nullptr;
393 sngcpp::symbols::Symbol* parent = enumTypeSymbol->Parent();
394 auto it = currentContext->containerMap.find(parent);
395 if (it != currentContext->containerMap.cend())
396 {
397 parentNode = it->second;
398 }
399 if (parentNode == currentContext->currentContainerNode)
400 {
401 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), enumTypeSymbol->Name());
402 }
403 else if (parentNode == nullptr)
404 {
405 return MapFullTypeName(enumTypeSymbol);
406 }
407 else if (currentContext->currentContainerNode != nullptr)
408 {
409 std::u32string fullName = GetFullName(currentContext->currentContainerNode);
410 if (!fullName.empty())
411 {
412 fullName.append(1, '.');
413 }
414 fullName.append(enumTypeSymbol->Name());
415 return MakeQualifiedIdNode(fullName);
416 }
417 }
418 else if (type->IsSimpleTypeSymbol())
419 {
420 sngcpp::symbols::SimpleTypeSymbol* simpleTypeSymbol = static_cast<sngcpp::symbols::SimpleTypeSymbol*>(type);
421 sngcm::ast::NodeType nodeType = MapSimpleType(simpleTypeSymbol);
422 return CreateNode(nodeType);
423 }
424 else if (type->IsDerivedTypeSymbol())
425 {
426 sngcpp::symbols::DerivedTypeSymbol* derivedTypeSymbol = static_cast<sngcpp::symbols::DerivedTypeSymbol*>(type);
427 sngcm::ast::Node* node = MapType(derivedTypeSymbol->BaseType(), sourceXmlDoc);
428 if (node)
429 {
430 return MakeDerivedType(node, derivedTypeSymbol->Derivations());
431 }
432 }
433 else if (type->IsExternalTypeSymbol())
434 {
435 sngcpp::symbols::ExternalTypeSymbol* externalTypeSymbol = static_cast<sngcpp::symbols::ExternalTypeSymbol*>(type);
436 if (sourceXmlDoc)
437 {
438 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(externalTypeSymbol->Id());
439 if (element)
440 {
441 std::u32string target = element->GetAttribute(U"target");
442 if (!target.empty())
443 {
444 target = RemoveNamespace(target);
445 return CreateNode(target);
446 }
447 }
448 }
449 }
450 else if (type->IsTypedefSymbol())
451 {
452 sngcpp::symbols::TypedefSymbol* typedefSymbol = static_cast<sngcpp::symbols::TypedefSymbol*>(type);
453 if (sourceXmlDoc)
454 {
455 std::u32string id = typedefSymbol->Id();
456 if (!typedefSymbol->PrimaryId().empty())
457 {
458 id = typedefSymbol->PrimaryId();
459 }
460 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(id);
461 if (element)
462 {
463 std::u32string target = element->GetAttribute(U"target");
464 if (!target.empty())
465 {
466 if (typedefSymbol->Parent()->IsTypeSymbol())
467 {
468 sngxml::dom::Document* sxmldoc = nullptr;
469 sngcm::ast::Node* parentNode = MapType(static_cast<sngcpp::symbols::TypeSymbol*>(typedefSymbol->Parent()), sxmldoc);
470 sngcm::ast::DotNode* dotNode = new sngcm::ast::DotNode(soulng::lexer::Span(), parentNode, static_cast<sngcm::ast::IdentifierNode*>(CreateNode(target)));
471 return dotNode;
472 }
473 target = RemoveNamespace(target);
474 return CreateNode(target);
475 }
476 }
477 }
478 }
479 else if (type->IsTemplateParameterSymbol())
480 {
481 return CreateNode(type->Name());
482 }
483 return nullptr;
484 }
485
486 sngcm::ast::IdentifierNode* Map::MapMemberSymbol(sngcpp::symbols::Symbol* memberSymbol, std::u32string& args)
487 {
488 sngcpp::symbols::Symbol* parent = memberSymbol->Parent();
489 if (!parent) return nullptr;
490 if (parent->ProjectName() == currentProjectName)
491 {
492 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), memberSymbol->Name());
493 }
494 std::u32string memberId = memberSymbol->Id();
495 if (memberSymbol->IsCallableSymbol())
496 {
497 sngcpp::symbols::CallableSymbol* callableSymbol = static_cast<sngcpp::symbols::CallableSymbol*>(memberSymbol);
498 memberId = callableSymbol->FunctionId();
499 }
500 auto it = projectSourceXmlDocMap.find(parent->ProjectName());
501 if (it != projectSourceXmlDocMap.cend())
502 {
503 sngxml::dom::Document* sourceXmlDoc = it->second;
504 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(memberId);
505 if (element)
506 {
507 std::u32string target = element->GetAttribute(U"target");
508 if (!target.empty())
509 {
510 args = element->GetAttribute(U"args");
511 target = RemoveNamespace(target);
512 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), target);
513 }
514 }
515 }
516 for (sngxml::dom::Document* sourceXmlDoc : sourceXmlDocs)
517 {
518 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(memberId);
519 if (element)
520 {
521 std::u32string target = element->GetAttribute(U"target");
522 if (!target.empty())
523 {
524 args = element->GetAttribute(U"args");
525 target = RemoveNamespace(target);
526 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), target);
527 }
528 }
529 }
530 return nullptr;
531 }
532
533 sngcm::ast::IdentifierNode* Map::MapFunctionSymbol(sngcpp::symbols::CallableSymbol* callableSymbol, std::u32string& args)
534 {
535 std::u32string functionId = callableSymbol->FunctionId();
536 auto it = projectSourceXmlDocMap.find(callableSymbol->ProjectName());
537 if (it != projectSourceXmlDocMap.cend())
538 {
539 sngxml::dom::Document* sourceXmlDoc = it->second;
540 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(functionId);
541 if (element)
542 {
543 std::u32string target = element->GetAttribute(U"target");
544 if (!target.empty())
545 {
546 args = element->GetAttribute(U"args");
547 target = RemoveNamespace(target);
548 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), target);
549 }
550 }
551 }
552 for (sngxml::dom::Document* sourceXmlDoc : sourceXmlDocs)
553 {
554 sngxml::dom::Element* element = sourceXmlDoc->GetElementById(functionId);
555 if (element)
556 {
557 std::u32string target = element->GetAttribute(U"target");
558 if (!target.empty())
559 {
560 args = element->GetAttribute(U"args");
561 target = RemoveNamespace(target);
562 return new sngcm::ast::IdentifierNode(soulng::lexer::Span(), target);
563 }
564 }
565 }
566 return nullptr;
567 }
568
569 void Map::ClearNamespaceImports()
570 {
571 namespaceImports.clear();
572 namespaceImports.insert(U"System");
573 namespaceImports.insert(U"System.Collections");
574 }
575
576 std::u32string Map::RemoveNamespace(const std::u32string& qid)
577 {
578 if (qid.find(':') != std::string::npos)
579 {
580 std::vector<std::u32string> components = Split(qid, ':');
581 std::u32string namespacePart = components.front();
582 namespaceImports.insert(namespacePart);
583 return components.back();
584 }
585 std::vector<std::u32string> components = Split(qid, '.');
586 if (!components.empty())
587 {
588 std::u32string namespacePart;
589 for (int i = 0; i < components.size() - 1; ++i)
590 {
591 if (namespacePart.empty())
592 {
593 namespacePart = components[i];
594 }
595 else
596 {
597 namespacePart.append(1, '.').append(components[i]);
598 }
599 }
600 if (!namespacePart.empty())
601 {
602 namespaceImports.insert(namespacePart);
603 }
604 return components.back();
605 }
606 return qid;
607 }
608
609 sngcm::ast::Specifiers MapSpecifiers(sngcpp::ast::Specifier specifiers)
610 {
611 sngcm::ast::Specifiers mappedSpecifiers = sngcm::ast::Specifiers::none;
612 if ((specifiers & sngcpp::ast::Specifier::static_) != sngcpp::ast::Specifier::none)
613 {
614 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::static_;
615 }
616 if ((specifiers & sngcpp::ast::Specifier::constExpr) != sngcpp::ast::Specifier::none)
617 {
618 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::constexpr_;
619 }
620 if ((specifiers & sngcpp::ast::Specifier::const_) != sngcpp::ast::Specifier::none)
621 {
622 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::const_;
623 }
624 if ((specifiers & sngcpp::ast::Specifier::default_) != sngcpp::ast::Specifier::none)
625 {
626 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::default_;
627 }
628 if ((specifiers & sngcpp::ast::Specifier::delete_) != sngcpp::ast::Specifier::none)
629 {
630 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::suppress_;
631 }
632 if ((specifiers & sngcpp::ast::Specifier::explicit_) != sngcpp::ast::Specifier::none)
633 {
634 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::explicit_;
635 }
636 if ((specifiers & sngcpp::ast::Specifier::inline_) != sngcpp::ast::Specifier::none)
637 {
638 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::inline_;
639 }
640 if ((specifiers & sngcpp::ast::Specifier::override_) != sngcpp::ast::Specifier::none)
641 {
642 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::override_;
643 }
644 if ((specifiers & sngcpp::ast::Specifier::private_) != sngcpp::ast::Specifier::none)
645 {
646 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::private_;
647 }
648 if ((specifiers & sngcpp::ast::Specifier::protected_) != sngcpp::ast::Specifier::none)
649 {
650 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::protected_;
651 }
652 if ((specifiers & sngcpp::ast::Specifier::public_) != sngcpp::ast::Specifier::none)
653 {
654 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::public_;
655 }
656 if ((specifiers & sngcpp::ast::Specifier::pure_) != sngcpp::ast::Specifier::none)
657 {
658 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::abstract_;
659 }
660 if ((specifiers & sngcpp::ast::Specifier::virtual_) != sngcpp::ast::Specifier::none)
661 {
662 mappedSpecifiers = mappedSpecifiers | sngcm::ast::Specifiers::virtual_;
663 }
664 if ((mappedSpecifiers & sngcm::ast::Specifiers::abstract_) != sngcm::ast::Specifiers::none)
665 {
666 if ((mappedSpecifiers & sngcm::ast::Specifiers::virtual_) != sngcm::ast::Specifiers::none)
667 {
668 mappedSpecifiers = mappedSpecifiers & ~sngcm::ast::Specifiers::virtual_;
669 }
670 }
671 return mappedSpecifiers;
672 }
673
674 sngcm::ast::Specifiers MapAccess(sngcpp::symbols::SymbolAccess access)
675 {
676 switch (access)
677 {
678 case sngcpp::symbols::SymbolAccess::private_: return sngcm::ast::Specifiers::private_;
679 case sngcpp::symbols::SymbolAccess::protected_: return sngcm::ast::Specifiers::protected_;
680 case sngcpp::symbols::SymbolAccess::public_: return sngcm::ast::Specifiers::public_;
681 }
682 return sngcm::ast::Specifiers::none;
683 }
684
685 }