Beispiel #1
0
        /// <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());
        }
Beispiel #2
0
        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);
        }