/// <summary> /// Method that is called from the CachingLookup to lookup the children of a given name. /// Looks in all the constituent namespaces. /// </summary> private ImmutableArray <Symbol> SlowGetChildrenOfName(string name) { ArrayBuilder <NamespaceSymbol> namespaceSymbols = null; var otherSymbols = ArrayBuilder <Symbol> .GetInstance(); // Accumulate all the child namespaces and types. foreach (NamespaceSymbol namespaceSymbol in namespacesToMerge) { foreach (Symbol childSymbol in namespaceSymbol.GetMembers(name)) { if (childSymbol.Kind == SymbolKind.Namespace) { namespaceSymbols = namespaceSymbols ?? ArrayBuilder <NamespaceSymbol> .GetInstance(); namespaceSymbols.Add((NamespaceSymbol)childSymbol); } else { otherSymbols.Add(childSymbol); } } } if (namespaceSymbols != null) { otherSymbols.Add(MergedNamespaceSymbol.Create(extent, this, namespaceSymbols.ToImmutableAndFree())); } return(otherSymbols.ToImmutableAndFree()); }
private Dictionary <string, ImmutableArray <NamespaceOrTypeSymbol> > MakeNameToMembersMap(DiagnosticBag diagnostics) { // NOTE: Even though the resulting map stores ImmutableArray<NamespaceOrTypeSymbol> as // NOTE: values if the name is mapped into an array of named types, which is frequently // NOTE: the case, we actually create an array of NamedTypeSymbol[] and wrap it in // NOTE: ImmutableArray<NamespaceOrTypeSymbol> // NOTE: // NOTE: This way we can save time and memory in GetNameToTypeMembersMap() -- when we see that // NOTE: a name maps into values collection containing types only instead of allocating another // NOTE: array of NamedTypeSymbol[] we downcast the array to ImmutableArray<NamedTypeSymbol> var builder = new NameToSymbolMapBuilder(_mergedDeclaration.Children.Length); foreach (var declaration in _mergedDeclaration.Children) { builder.Add(BuildSymbol(declaration, diagnostics)); } var result = builder.CreateMap(); var memberOfArity = new Symbol[10]; MergedNamespaceSymbol mergedAssemblyNamespace = null; if (this.ContainingAssembly.Modules.Length > 1) { mergedAssemblyNamespace = this.ContainingAssembly.GetAssemblyNamespace(this) as MergedNamespaceSymbol; } foreach (var name in result.Keys) { Array.Clear(memberOfArity, 0, memberOfArity.Length); foreach (var symbol in result[name]) { var nts = symbol as NamedTypeSymbol; var arity = ((object)nts != null) ? nts.Arity : 0; if (arity >= memberOfArity.Length) { Array.Resize(ref memberOfArity, arity + 1); } var other = memberOfArity[arity]; if ((object)other == null && (object)mergedAssemblyNamespace != null) { // Check for collision with declarations from added modules. foreach (NamespaceSymbol constituent in mergedAssemblyNamespace.ConstituentNamespaces) { if ((object)constituent != (object)this) { // For whatever reason native compiler only detects conflicts against types. // It doesn't complain when source declares a type with the same name as // a namespace in added module, but complains when source declares a namespace // with the same name as a type in added module. var types = constituent.GetTypeMembers(symbol.Name, arity); if (types.Length > 0) { other = types[0]; // Since the error doesn't specify what added module this type belongs to, we can stop searching // at the first match. break; } } } } if ((object)other != null) { if ((nts as SourceNamedTypeSymbol)?.IsPartial == true && (other as SourceNamedTypeSymbol)?.IsPartial == true) { diagnostics.Add(ErrorCode.ERR_PartialTypeKindConflict, symbol.Locations[0], symbol); } else { diagnostics.Add(ErrorCode.ERR_DuplicateNameInNS, symbol.Locations[0], name, this); } } memberOfArity[arity] = symbol; if ((object)nts != null) { //types declared at the namespace level may only have declared accessibility of public or internal (Section 3.5.1) Accessibility declaredAccessibility = nts.DeclaredAccessibility; if (declaredAccessibility != Accessibility.Public && declaredAccessibility != Accessibility.Internal) { diagnostics.Add(ErrorCode.ERR_NoNamespacePrivate, symbol.Locations[0]); } } } } return(result); }