| File: Symbols\Metadata\PE\PENestedNamespaceSymbol.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata; using System.Threading; using Roslyn.Utilities; using System.Diagnostics; namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE { /// <summary> /// The class to represent all, but Global, namespaces imported from a PE/module. /// Namespaces that differ only by casing in name are not merged. /// </summary> /// <remarks></remarks> internal sealed class PENestedNamespaceSymbol : PENamespaceSymbol { /// <summary> /// The parent namespace. There is always one, Global namespace contains all /// top level namespaces. /// </summary> /// <remarks></remarks> private readonly PENamespaceSymbol _containingNamespaceSymbol; /// <summary> /// The name of the namespace. /// </summary> /// <remarks></remarks> private readonly string _name; /// <summary> /// The sequence of groups of TypeDef row ids for types contained within the namespace, /// recursively including those from nested namespaces. The row ids are grouped by the /// fully-qualified namespace name case-sensitively. There could be multiple groups /// for each fully-qualified namespace name. The groups are sorted by their /// key in case-sensitive manner. Empty string is used as namespace name for types /// immediately contained within Global namespace. Therefore, all types in this namespace, if any, /// will be in several first IGroupings. /// /// This member is initialized by constructor and is cleared in EnsureAllMembersLoaded /// as soon as symbols for children are created. /// </summary> /// <remarks></remarks> private IEnumerable<IGrouping<string, TypeDefinitionHandle>> _typesByNS; /// <summary> /// Constructor. /// </summary> /// <param name="name"> /// Name of the namespace, must be not empty. /// </param> /// <param name="containingNamespace"> /// Containing namespace. /// </param> /// <param name="typesByNS"> /// The sequence of groups of TypeDef row ids for types contained within the namespace, /// recursively including those from nested namespaces. The row ids are grouped by the /// fully-qualified namespace name case-sensitively. There could be multiple groups /// for each fully-qualified namespace name. The groups are sorted by their /// key in case-sensitive manner. Empty string is used as namespace name for types /// immediately contained within Global namespace. Therefore, all types in this namespace, if any, /// will be in several first IGroupings. /// </param> internal PENestedNamespaceSymbol( string name, PENamespaceSymbol containingNamespace, IEnumerable<IGrouping<string, TypeDefinitionHandle>> typesByNS) { Debug.Assert(name != null); Debug.Assert((object)containingNamespace != null); Debug.Assert(typesByNS != null); _containingNamespaceSymbol = containingNamespace; _name = name; _typesByNS = typesByNS; } public override Symbol ContainingSymbol { get { return _containingNamespaceSymbol; } } internal override PEModuleSymbol ContainingPEModule { get { return _containingNamespaceSymbol.ContainingPEModule; } } public override string Name { get { return _name; } } public override bool IsGlobalNamespace { get { return false; } } public override AssemblySymbol ContainingAssembly { get { return ContainingPEModule.ContainingAssembly; } } internal override ModuleSymbol ContainingModule { get { return _containingNamespaceSymbol.ContainingPEModule; } } protected override void EnsureAllMembersLoaded() { var typesByNS = Volatile.Read(ref _typesByNS); if (typesByNS == null) { Debug.Assert(lazyNamespaces != null && lazyTypes != null); } else { LoadAllMembers(typesByNS); Interlocked.Exchange(ref _typesByNS, null); } } internal sealed override CSharpCompilation DeclaringCompilation // perf, not correctness { get { return null; } } } }