1
2
3
4
5
6 #include <cmajor/symbols/Scope.hpp>
7 #include <cmajor/symbols/ContainerSymbol.hpp>
8 #include <cmajor/symbols/ClassTypeSymbol.hpp>
9 #include <cmajor/symbols/NamespaceSymbol.hpp>
10 #include <cmajor/symbols/FunctionSymbol.hpp>
11 #include <cmajor/symbols/Exception.hpp>
12 #include <cmajor/symbols/GlobalFlags.hpp>
13 #include <cmajor/symbols/Module.hpp>
14 #include <sngcm/ast/Identifier.hpp>
15 #include <soulng/util/TextUtils.hpp>
16 #include <soulng/util/Unicode.hpp>
17 #include <soulng/util/Util.hpp>
18 #include <algorithm>
19
20 namespace cmajor { namespace symbols {
21
22 using namespace soulng::unicode;
23 using namespace soulng::util;
24
25 Scope::~Scope()
26 {
27 }
28
29 ContainerScope::ContainerScope() : container(nullptr), parentScope(nullptr), symbolMap()
30 {
31 }
32
33 ContainerScope* ContainerScope::BaseScope() const
34 {
35 if (container)
36 {
37 if (container->GetSymbolType() == SymbolType::classTypeSymbol || container->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol)
38 {
39 ClassTypeSymbol* cls = static_cast<ClassTypeSymbol*>(container);
40 ClassTypeSymbol* baseClass = cls->BaseClass();
41 if (baseClass)
42 {
43 return baseClass->GetContainerScope();
44 }
45 }
46 }
47 return nullptr;
48 }
49
50 ContainerScope* ContainerScope::ParentScope() const
51 {
52 if (parentScope)
53 {
54 return parentScope;
55 }
56 if (container)
57 {
58 Symbol* parent = nullptr;
59 if (container->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol)
60 {
61 ClassTemplateSpecializationSymbol* specialization = static_cast<ClassTemplateSpecializationSymbol*>(container);
62 ClassTypeSymbol* classTemplate = specialization->GetClassTemplate();
63 parent = classTemplate->Parent();
64 }
65 else
66 {
67 parent = container->Parent();
68 }
69 if (parent)
70 {
71 if (!parent->GetModule()->IsRootModule() && parent->GetSymbolType() == SymbolType::namespaceSymbol)
72 {
73 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(parent);
74 Module* rootModule = GetRootModuleForCurrentThread();
75 NamespaceSymbol* mappedNs = rootModule->GetSymbolTable().GetMappedNs(ns);
76 if (mappedNs)
77 {
78 return mappedNs->GetContainerScope();
79 }
80 }
81 return parent->GetContainerScope();
82 }
83 }
84 return nullptr;
85 }
86
87 void ContainerScope::Install(Symbol* symbol)
88 {
89 auto it = symbolMap.find(symbol->Name());
90 if (symbol->GetSymbolType() != SymbolType::namespaceSymbol &&
91 symbol->GetSymbolType() != SymbolType::declarationBlock &&
92 it != symbolMap.cend())
93 {
94 Symbol* prev = it->second;
95 if (prev != symbol)
96 {
97 throw Exception("symbol '" + ToUtf8(symbol->Name()) + "' already defined", symbol->GetSpan(), symbol->SourceModuleId(), prev->GetSpan(), prev->SourceModuleId());
98 }
99 }
100 else
101 {
102 symbolMap[symbol->Name()] = symbol;
103 }
104 symbol->SetInstalled();
105 }
106
107 void ContainerScope::Uninstall(Symbol* symbol)
108 {
109 symbolMap.erase(symbol->Name());
110 symbol->ResetInstalled();
111 }
112
113 Symbol* ContainerScope::Lookup(const std::u32string& name) const
114 {
115 return Lookup(name, ScopeLookup::this_);
116 }
117
118 int CountQualifiedNameComponents(const std::u32string& qualifiedName)
119 {
120 int numComponents = 0;
121 int componentSize = 0;
122 int state = 0;
123 int angleBracketCount = 0;
124 for (char32_t c : qualifiedName)
125 {
126 switch (state)
127 {
128 case 0:
129 {
130 if (c == '.')
131 {
132 ++numComponents;
133 componentSize = 0;
134 }
135 else if (c == '<')
136 {
137 ++componentSize;
138 angleBracketCount = 1;
139 state = 1;
140 }
141 else
142 {
143 ++componentSize;
144 }
145 break;
146 }
147 case 1:
148 {
149 ++componentSize;
150 if (c == '<')
151 {
152 ++angleBracketCount;
153 }
154 else if (c == '>')
155 {
156 --angleBracketCount;
157 if (angleBracketCount == 0)
158 {
159 state = 0;
160 }
161 }
162 break;
163 }
164 }
165 }
166 if (componentSize > 0)
167 {
168 ++numComponents;
169 }
170 return numComponents;
171 }
172
173 std::std::vector<std::u32string>ParseQualifiedName(conststd::u32string&qualifiedName)
174 {
175 std::vector<std::u32string> components;
176 int state = 0;
177 std::u32string component;
178 int angleBracketCount = 0;
179 for (char32_t c : qualifiedName)
180 {
181 switch (state)
182 {
183 case 0:
184 {
185 if (c == '.')
186 {
187 components.push_back(component);
188 component.clear();
189 }
190 else if (c == '<')
191 {
192 component.append(1, c);
193 angleBracketCount = 1;
194 state = 1;
195 }
196 else
197 {
198 component.append(1, c);
199 }
200 break;
201 }
202 case 1:
203 {
204 component.append(1, c);
205 if (c == '<')
206 {
207 ++angleBracketCount;
208 }
209 else if (c == '>')
210 {
211 --angleBracketCount;
212 if (angleBracketCount == 0)
213 {
214 state = 0;
215 }
216 }
217 break;
218 }
219 }
220 }
221 if (!component.empty())
222 {
223 components.push_back(component);
224 }
225 return components;
226 }
227
228 std::std::vector<CCComponent>ParseCCName(conststd::u32string&qualifiedName)
229 {
230 std::vector<CCComponent> components;
231 int state = 0;
232 std::u32string str;
233 int angleBracketCount = 0;
234 CCComponentSeparator separator = CCComponentSeparator::dot;
235 for (char32_t c : qualifiedName)
236 {
237 switch (state)
238 {
239 case 0:
240 {
241 if (c == '.')
242 {
243 components.push_back(CCComponent(separator, str));
244 separator = CCComponentSeparator::dot;
245 str.clear();
246 }
247 else if (c == '-')
248 {
249 state = 2;
250 }
251 else if (c == '<')
252 {
253 str.append(1, c);
254 angleBracketCount = 1;
255 state = 1;
256 }
257 else
258 {
259 str.append(1, c);
260 }
261 break;
262 }
263 case 1:
264 {
265 str.append(1, c);
266 if (c == '<')
267 {
268 ++angleBracketCount;
269 }
270 else if (c == '>')
271 {
272 --angleBracketCount;
273 if (angleBracketCount == 0)
274 {
275 state = 0;
276 }
277 }
278 break;
279 }
280 case 2:
281 {
282 if (c == '>')
283 {
284 components.push_back(CCComponent(separator, str));
285 separator = CCComponentSeparator::arrow;
286 str.clear();
287 state = 0;
288 }
289 else if (c != '-')
290 {
291 state = 0;
292 }
293 break;
294 }
295 }
296 }
297 components.push_back(CCComponent(separator, str));
298 return components;
299 }
300
301 int CountCCComponents(const std::u32string& qualifiedName)
302 {
303 int numComponents = 0;
304 int state = 0;
305 int angleBracketCount = 0;
306 for (char32_t c : qualifiedName)
307 {
308 switch (state)
309 {
310 case 0:
311 {
312 if (c == '.')
313 {
314 ++numComponents;
315 }
316 else if (c == '-')
317 {
318 state = 2;
319 }
320 else if (c == '<')
321 {
322 angleBracketCount = 1;
323 state = 1;
324 }
325 break;
326 }
327 case 1:
328 {
329 if (c == '<')
330 {
331 ++angleBracketCount;
332 }
333 else if (c == '>')
334 {
335 --angleBracketCount;
336 if (angleBracketCount == 0)
337 {
338 state = 0;
339 }
340 }
341 break;
342 }
343 case 2:
344 {
345 if (c == '>')
346 {
347 ++numComponents;
348 state = 0;
349 }
350 else if (c != '-')
351 {
352 state = 0;
353 }
354 break;
355 }
356 }
357 }
358 ++numComponents;
359 return numComponents;
360 }
361
362 std::u32string MakeCCMatch(const std::std::vector<CCComponent>&components, conststd::u32string&last)
363 {
364 std::u32string ccMatch;
365 int n = components.size();
366 bool first = true;
367 for (int i = 0; i < n - 1; ++i)
368 {
369 const CCComponent& component = components[i];
370 if (first)
371 {
372 first = false;
373 }
374 else
375 {
376 if (component.separator == CCComponentSeparator::dot)
377 {
378 ccMatch.append(1, '.');
379 }
380 else if (component.separator == CCComponentSeparator::arrow)
381 {
382 ccMatch.append(U"->");
383 }
384 }
385 ccMatch.append(component.str);
386 }
387 const CCComponent& component = components[n - 1];
388 if (first)
389 {
390 first = false;
391 }
392 else
393 {
394 if (component.separator == CCComponentSeparator::dot)
395 {
396 ccMatch.append(1, '.');
397 }
398 else if (component.separator == CCComponentSeparator::arrow)
399 {
400 ccMatch.append(U"->");
401 }
402 }
403 ccMatch.append(last);
404 return ccMatch;
405 }
406
407 std::std::vector<CCSymbolEntry>MakeCCMatches(conststd::std::vector<CCComponent>&components, conststd::std::vector<CCSymbolEntry>&matches)
408 {
409 std::vector<CCSymbolEntry> ccMatches;
410 for (const CCSymbolEntry& match : matches)
411 {
412 ccMatches.push_back(CCSymbolEntry(match.symbol, match.ccPrefixLen, MakeCCMatch(components, match.replacement)));
413 }
414 return ccMatches;
415 }
416
417 void AddMatches(std::std::vector<CCSymbolEntry>&matches, std::std::vector<CCSymbolEntry>&matchesToAdd)
418 {
419 for (CCSymbolEntry& entry : matchesToAdd)
420 {
421 Symbol* s = entry.symbol;
422 bool found = false;
423 for (CCSymbolEntry& m : matches)
424 {
425 if (s == m.symbol)
426 {
427 found = true;
428 break;
429 }
430 }
431 if (!found)
432 {
433 matches.push_back(std::move(entry));
434 }
435 }
436 }
437
438 Symbol* ContainerScope::Lookup(const std::u32string& name, ScopeLookup lookup) const
439 {
440 int numQualifiedNameComponents = CountQualifiedNameComponents(name);
441 if (numQualifiedNameComponents > 1)
442 {
443 std::vector<std::u32string> components = ParseQualifiedName(name);
444 return LookupQualified(components, lookup);
445 }
446 else
447 {
448 auto it = symbolMap.find(name);
449 if (it != symbolMap.end())
450 {
451 Symbol* s = it->second;
452 return s;
453 }
454 if ((lookup & ScopeLookup::base) != ScopeLookup::none)
455 {
456 ContainerScope* baseScope = BaseScope();
457 if (baseScope)
458 {
459 Symbol* s = baseScope->Lookup(name, lookup);
460 if (s)
461 {
462 return s;
463 }
464 }
465 }
466 if ((lookup & ScopeLookup::parent) != ScopeLookup::none)
467 {
468 ContainerScope* parentScope = ParentScope();
469 if (parentScope)
470 {
471 Symbol* s = parentScope->Lookup(name, lookup);
472 if (s)
473 {
474 return s;
475 }
476 }
477 }
478 return nullptr;
479 }
480 }
481
482 Symbol* ContainerScope::LookupQualified(const std::std::vector<std::u32string>&components, ScopeLookuplookup) const
483 {
484 const ContainerScope* scope = this;
485 Symbol* s = nullptr;
486 int n = int(components.size());
487 bool allComponentsMatched = true;
488 for (int i = 0; i < n; ++i)
489 {
490 const std::u32string& component = components[i];
491 if (scope)
492 {
493 s = scope->Lookup(component, ScopeLookup::this_);
494 if (s)
495 {
496 scope = s->GetContainerScope();
497 }
498 else
499 {
500 allComponentsMatched = false;
501 }
502 }
503 }
504 if (!s || !allComponentsMatched)
505 {
506 if ((lookup & ScopeLookup::parent) != ScopeLookup::none)
507 {
508 ContainerScope* parentScope = ParentScope();
509 if (parentScope)
510 {
511 return parentScope->LookupQualified(components, lookup);
512 }
513 else
514 {
515 return nullptr;
516 }
517 }
518 }
519 return s;
520 }
521
522 std::std::vector<CCSymbolEntry>ContainerScope::LookupBeginWith(conststd::u32string&prefix) const
523 {
524 return LookupBeginWith(prefix, ScopeLookup::this_);
525 }
526
527 std::std::vector<CCSymbolEntry>ContainerScope::LookupBeginWith(conststd::u32string&prefix, ScopeLookuplookup) const
528 {
529 int numQualifiedNameComponents = CountCCComponents(prefix);
530 if (numQualifiedNameComponents > 1)
531 {
532 std::vector<CCComponent> components = ParseCCName(prefix);
533 return LookupQualifiedBeginWith(components, lookup);
534 }
535 else
536 {
537 std::vector<CCSymbolEntry> matches;
538 auto it = symbolMap.lower_bound(prefix);
539 while (it != symbolMap.cend() && StartsWith(it->first, prefix))
540 {
541 matches.push_back(CCSymbolEntry(it->second, prefix.length(), it->second->Name()));
542 ++it;
543 }
544 if ((lookup & ScopeLookup::base) != ScopeLookup::none)
545 {
546 ContainerScope* baseScope = BaseScope();
547 if (baseScope)
548 {
549 std::vector<CCSymbolEntry> m = baseScope->LookupBeginWith(prefix, lookup);
550 AddMatches(matches, m);
551 }
552 }
553 if ((lookup & ScopeLookup::parent) != ScopeLookup::none)
554 {
555 ContainerScope* parentScope = ParentScope();
556 if (parentScope)
557 {
558 std::vector<CCSymbolEntry> m = parentScope->LookupBeginWith(prefix, lookup);
559 AddMatches(matches, m);
560 }
561 }
562 return matches;
563 }
564 }
565
566 std::std::vector<CCSymbolEntry>ContainerScope::LookupQualifiedBeginWith(conststd::std::vector<CCComponent>&components, ScopeLookuplookup) const
567 {
568 std::vector<CCSymbolEntry> matches;
569 const ContainerScope* scope = this;
570 int n = int(components.size());
571 const Symbol* s = nullptr;
572 for (int i = 0; i < n - 1; ++i)
573 {
574 const CCComponent& component = components[i];
575 if (scope)
576 {
577 if (component.separator == CCComponentSeparator::arrow)
578 {
579 const ContainerSymbol* containerSymbol = scope->Container();
580 scope = containerSymbol->GetArrowScope();
581 }
582 if (component.str == U"this")
583 {
584 const ContainerSymbol* containerSymbol = Container();
585 const FunctionSymbol* f = containerSymbol->FunctionNoThrow();
586 if (f && f->GetSymbolType() == SymbolType::memberFunctionSymbol)
587 {
588 s = f->Parameters()[0];
589 }
590 else
591 {
592 s = nullptr;
593 }
594 }
595 else
596 {
597 s = scope->Lookup(component.str, ScopeLookup::this_);
598 }
599 if (s)
600 {
601 scope = s->GetTypeScope();
602 }
603 }
604 else
605 {
606 s = nullptr;
607 }
608 }
609 if (s && scope)
610 {
611 bool validAccess = true;
612 if (components[n - 1].separator == CCComponentSeparator::dot)
613 {
614 switch (s->GetSymbolType())
615 {
616 case SymbolType::localVariableSymbol:
617 case SymbolType::memberVariableSymbol:
618 case SymbolType::parameterSymbol:
619 {
620 const VariableSymbol* variableSymbol = static_cast<const VariableSymbol*>(s);
621 const TypeSymbol* type = variableSymbol->GetType();
622 if (type && type->IsPointerType())
623 {
624 validAccess = false;
625 }
626 }
627 }
628 }
629 else if (components[n - 1].separator == CCComponentSeparator::arrow)
630 {
631 const ContainerSymbol* containerSymbol = scope->Container();
632 scope = containerSymbol->GetArrowScope();
633 }
634 if (validAccess)
635 {
636 std::vector<CCSymbolEntry> m = MakeCCMatches(components, scope->LookupBeginWith(components[n - 1].str));
637 AddMatches(matches, m);
638 lookup = lookup & ~ScopeLookup::parent;
639 }
640 }
641 if ((lookup & ScopeLookup::base) != ScopeLookup::none)
642 {
643 ContainerScope* baseScope = BaseScope();
644 if (baseScope)
645 {
646 std::vector<CCSymbolEntry> m = baseScope->LookupQualifiedBeginWith(components, ScopeLookup::this_and_base);
647 AddMatches(matches, m);
648 }
649 }
650 if ((lookup & ScopeLookup::parent) != ScopeLookup::none)
651 {
652 ContainerScope* parentScope = ParentScope();
653 if (parentScope)
654 {
655 std::vector<CCSymbolEntry> m = parentScope->LookupQualifiedBeginWith(components, ScopeLookup::this_and_base_and_parent);
656 AddMatches(matches, m);
657 }
658 }
659 return matches;
660 }
661
662 const NamespaceSymbol* ContainerScope::Ns() const
663 {
664 return container->Ns();
665 }
666
667 NamespaceSymbol* ContainerScope::Ns()
668 {
669 return container->Ns();
670 }
671
672 void ContainerScope::Clear()
673 {
674 symbolMap.clear();
675 }
676
677 NamespaceSymbol* ContainerScope::CreateNamespace(const std::u32string& qualifiedNsName, const Span& span, const boost::uuids::uuid& sourceModuleId)
678 {
679 ContainerScope* scope = this;
680 NamespaceSymbol* parentNs = scope->Ns();
681 std::vector<std::u32string> components = Split(qualifiedNsName, '.');
682 for (const std::u32string& component : components)
683 {
684 Symbol* s = scope->Lookup(component);
685 if (s)
686 {
687 if (s->GetSymbolType() == SymbolType::namespaceSymbol)
688 {
689 scope = s->GetContainerScope();
690 parentNs = scope->Ns();
691 }
692 else
693 {
694 throw Exception("symbol '" + ToUtf8(s->Name()) + "' does not denote a namespace", s->GetSpan(), s->SourceModuleId());
695 }
696 }
697 else
698 {
699 NamespaceSymbol* newNs = new NamespaceSymbol(span, sourceModuleId, component);
700 newNs->SetModule(container->GetModule());
701 scope = newNs->GetContainerScope();
702 parentNs->AddMember(newNs);
703 parentNs = newNs;
704 }
705 }
706 return parentNs;
707 }
708
709 void ContainerScope::CollectViableFunctions(int arity, const std::u32string& groupName, std::std::unordered_set<ContainerScope*>&scopesLookedUp, ScopeLookupscopeLookup,
710 ViableFunctionSet& viableFunctions, Module* module)
711 {
712 if ((scopeLookup & ScopeLookup::this_) != ScopeLookup::none)
713 {
714 if (scopesLookedUp.find(this) == scopesLookedUp.end())
715 {
716 scopesLookedUp.insert(this);
717 Symbol* symbol = Lookup(groupName);
718 if (symbol)
719 {
720 if (symbol->GetSymbolType() == SymbolType::functionGroupSymbol)
721 {
722 FunctionGroupSymbol* functionGroupSymbol = static_cast<FunctionGroupSymbol*>(symbol);
723 functionGroupSymbol->CollectViableFunctions(arity, viableFunctions, module);
724 }
725 }
726 }
727 }
728 if ((scopeLookup & ScopeLookup::base) != ScopeLookup::none)
729 {
730 ContainerScope* baseScope = BaseScope();
731 if (baseScope)
732 {
733 baseScope->CollectViableFunctions(arity, groupName, scopesLookedUp, scopeLookup, viableFunctions, module);
734 }
735 }
736 if ((scopeLookup & ScopeLookup::parent) != ScopeLookup::none)
737 {
738 ContainerScope* parentScope = ParentScope();
739 if (parentScope)
740 {
741 parentScope->CollectViableFunctions(arity, groupName, scopesLookedUp, scopeLookup, viableFunctions, module);
742 }
743 }
744 }
745
746 FileScope::FileScope()
747 {
748 }
749
750 void FileScope::InstallAlias(ContainerScope* containerScope, AliasNode* aliasNode)
751 {
752 Assert(containerScope, "container scope is null");
753 std::u32string qualifiedName = aliasNode->Qid()->Str();
754 Symbol* symbol = containerScope->Lookup(qualifiedName, ScopeLookup::this_and_parent);
755 if (symbol)
756 {
757 std::u32string aliasName = aliasNode->Id()->Str();
758 aliasSymbolMap[aliasName] = symbol;
759 }
760 else
761 {
762 throw Exception("referred symbol '" + ToUtf8(aliasNode->Qid()->Str()) + "' not found", aliasNode->Qid()->GetSpan(), aliasNode->Qid()->ModuleId());
763 }
764 }
765
766 void FileScope::AddContainerScope(ContainerScope* containerScope)
767 {
768 if (std::find(containerScopes.begin(), containerScopes.end(), containerScope) == containerScopes.end())
769 {
770 containerScopes.push_back(containerScope);
771 }
772 }
773
774 void FileScope::InstallNamespaceImport(ContainerScope* containerScope, NamespaceImportNode* namespaceImportNode)
775 {
776 try
777 {
778 Assert(containerScope, "container scope is null");
779 std::u32string importedNamespaceName = namespaceImportNode->Ns()->Str();
780 Symbol* symbol = containerScope->Lookup(importedNamespaceName, ScopeLookup::this_and_parent);
781 if (symbol)
782 {
783 if (symbol->GetSymbolType() == SymbolType::namespaceSymbol)
784 {
785 ContainerScope* symbolContainerScope = symbol->GetContainerScope();
786 if (std::find(containerScopes.begin(), containerScopes.end(), symbolContainerScope) == containerScopes.end())
787 {
788 containerScopes.push_back(symbolContainerScope);
789 }
790 }
791 else
792 {
793 throw Exception("'" + ToUtf8(namespaceImportNode->Ns()->Str()) + "' does not denote a namespace", namespaceImportNode->Ns()->GetSpan(), namespaceImportNode->Ns()->ModuleId());
794 }
795 }
796 else
797 {
798 throw Exception("referred namespace symbol '" + ToUtf8(namespaceImportNode->Ns()->Str()) + "' not found", namespaceImportNode->Ns()->GetSpan(), namespaceImportNode->Ns()->ModuleId());
799 }
800 }
801 catch (const Exception&;)
802 {
803 throw ;
804 }
805 }
806
807 Symbol* FileScope::Lookup(const std::u32string& name) const
808 {
809 return Lookup(name, ScopeLookup::this_);
810 }
811
812 Symbol* FileScope::Lookup(const std::u32string& name, ScopeLookup lookup) const
813 {
814 if (lookup != ScopeLookup::this_)
815 {
816 throw std::runtime_error("file scope supports only this scope lookup");
817 }
818 std::unordered_set<Symbol*> foundSymbols;
819 auto it = aliasSymbolMap.find(name);
820 if (it != aliasSymbolMap.cend())
821 {
822 Symbol* symbol = it->second;
823 foundSymbols.insert(symbol);
824 }
825 else
826 {
827 for (ContainerScope* containerScope : containerScopes)
828 {
829 Symbol* symbol = containerScope->Lookup(name, ScopeLookup::this_);
830 if (symbol)
831 {
832 foundSymbols.insert(symbol);
833 }
834 }
835 }
836 if (foundSymbols.empty())
837 {
838 return nullptr;
839 }
840 else if (foundSymbols.size() > 1)
841 {
842 std::string message("reference to object '" + ToUtf8(name) + "' is ambiguous: ");
843 bool first = true;
844 Span span;
845 boost::uuids::uuid moduleId;
846 for (Symbol* symbol : foundSymbols)
847 {
848 if (first)
849 {
850 first = false;
851 span = symbol->GetSpan();
852 moduleId = symbol->SourceModuleId();
853 }
854 else
855 {
856 message.append(" or ");
857 }
858 message.append(ToUtf8(symbol->FullName()));
859 }
860 throw Exception(message, span, moduleId);
861 }
862 else
863 {
864 return *foundSymbols.begin();
865 }
866 }
867
868 std::std::vector<CCSymbolEntry>FileScope::LookupBeginWith(conststd::u32string&prefix) const
869 {
870 return LookupBeginWith(prefix, ScopeLookup::this_);
871 }
872
873 std::std::vector<CCSymbolEntry>FileScope::LookupBeginWith(conststd::u32string&prefix, ScopeLookuplookup) const
874 {
875 std::vector<CCSymbolEntry> matches;
876 auto it = aliasSymbolMap.lower_bound(prefix);
877 if (it != aliasSymbolMap.cend())
878 {
879 while (it != aliasSymbolMap.cend() && StartsWith(it->first, prefix))
880 {
881 matches.push_back(CCSymbolEntry(it->second, prefix.length(), it->second->Name()));
882 ++it;
883 }
884 }
885 for (ContainerScope* containerScope : containerScopes)
886 {
887 std::vector<CCSymbolEntry> m = containerScope->LookupBeginWith(prefix, ScopeLookup::this_);
888 AddMatches(matches, m);
889 }
890 return matches;
891 }
892
893 void FileScope::CollectViableFunctions(int arity, const std::u32string& groupName, std::std::unordered_set<ContainerScope*>&scopesLookedUp, ViableFunctionSet&viableFunctions,
894 Module* module)
895 {
896 for (ContainerScope* containerScope : containerScopes)
897 {
898 if (scopesLookedUp.find(containerScope) == scopesLookedUp.end())
899 {
900 containerScope->CollectViableFunctions(arity, groupName, scopesLookedUp, ScopeLookup::this_, viableFunctions, module);
901 scopesLookedUp.insert(containerScope);
902 }
903 }
904 }
905
906 } }