File: Symbols\Metadata\MetadataTypeTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests)
// 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;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
using Basic.Reference.Assemblies;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    public class MetadataTypeTests : CSharpTestBase
    {
        [Fact]
        public void MetadataNamespaceSymbol01()
        {
            var text = "public class A {}";
            var compilation = CreateEmptyCompilation(text, new[] { MscorlibRef });
 
            var mscorlib = compilation.ExternalReferences[0];
            var mscorNS = compilation.GetReferencedAssemblySymbol(mscorlib);
            Assert.Equal("mscorlib", mscorNS.Name);
            Assert.Equal(SymbolKind.Assembly, mscorNS.Kind);
            var ns1 = mscorNS.GlobalNamespace.GetMembers("System").Single() as NamespaceSymbol;
            var ns2 = ns1.GetMembers("Runtime").Single() as NamespaceSymbol;
            var ns = ns2.GetMembers("Serialization").Single() as NamespaceSymbol;
 
            Assert.Equal(mscorNS, ns.ContainingAssembly);
            Assert.Equal(ns2, ns.ContainingSymbol);
            Assert.Equal(ns2, ns.ContainingNamespace);
            Assert.True(ns.IsDefinition); // ?
            Assert.True(ns.IsNamespace);
            Assert.False(ns.IsType);
 
            Assert.Equal(SymbolKind.Namespace, ns.Kind);
            // bug 1995
            Assert.Equal(Accessibility.Public, ns.DeclaredAccessibility);
            Assert.True(ns.IsStatic);
            Assert.False(ns.IsAbstract);
            Assert.False(ns.IsSealed);
            Assert.False(ns.IsVirtual);
            Assert.False(ns.IsOverride);
 
            // 47 types, 1 namespace (Formatters);
            Assert.Equal(48, ns.GetMembers().Length);
            Assert.Equal(47, ns.GetTypeMembers().Length);
 
            var fullName = "System.Runtime.Serialization";
            Assert.Equal(fullName, ns.ToTestDisplayString());
 
            Assert.Empty(compilation.GetDeclarationDiagnostics());
        }
 
        [Fact]
        public void MetadataTypeSymbolClass01()
        {
            var text = "public class A {}";
            var compilation = CreateEmptyCompilation(text, new[] { MscorlibRef });
 
            var mscorlib = compilation.ExternalReferences[0];
            var mscorNS = compilation.GetReferencedAssemblySymbol(mscorlib);
            Assert.Equal("mscorlib", mscorNS.Name);
            var ns1 = mscorNS.GlobalNamespace.GetMembers("Microsoft").Single() as NamespaceSymbol;
            var ns2 = ns1.GetMembers("Runtime").Single() as NamespaceSymbol;
            var ns3 = ns2.GetMembers("Hosting").Single() as NamespaceSymbol;
 
            var class1 = ns3.GetTypeMembers("StrongNameHelpers").First() as NamedTypeSymbol;
            // internal static class
            Assert.Equal(0, class1.Arity);
            Assert.Equal(mscorNS, class1.ContainingAssembly);
            Assert.Equal(ns3, class1.ContainingSymbol);
            Assert.Equal(ns3, class1.ContainingNamespace);
            Assert.True(class1.IsDefinition);
            Assert.False(class1.IsNamespace);
            Assert.True(class1.IsType);
            Assert.True(class1.IsReferenceType);
            Assert.False(class1.IsValueType);
 
            Assert.Equal(SymbolKind.NamedType, class1.Kind);
            Assert.Equal(TypeKind.Class, class1.TypeKind);
            Assert.Equal(Accessibility.Internal, class1.DeclaredAccessibility);
            Assert.True(class1.IsStatic);
            Assert.False(class1.IsAbstract);
            Assert.False(class1.IsAbstract);
            Assert.False(class1.IsExtern);
            Assert.False(class1.IsSealed);
            Assert.False(class1.IsVirtual);
            Assert.False(class1.IsOverride);
 
            // 18 members
            Assert.Equal(18, class1.GetMembers().Length);
            Assert.Equal(0, class1.GetTypeMembers().Length);
            Assert.Equal(0, class1.Interfaces().Length);
 
            var fullName = "Microsoft.Runtime.Hosting.StrongNameHelpers";
            // Internal: Assert.Equal(fullName, class1.GetFullNameWithoutGenericArgs());
            Assert.Equal(fullName, class1.ToTestDisplayString());
            Assert.Equal(0, class1.TypeArguments().Length);
            Assert.Equal(0, class1.TypeParameters.Length);
 
            Assert.Empty(compilation.GetDeclarationDiagnostics());
        }
 
        [Fact]
        public void MetadataTypeSymbolGenClass02()
        {
            var text = "public class A {}";
            var compilation = CreateEmptyCompilation(text, new[] { MscorlibRef }, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
 
            var mscorlib = compilation.ExternalReferences[0];
            var mscorNS = compilation.GetReferencedAssemblySymbol(mscorlib);
            Assert.Equal("mscorlib", mscorNS.Name);
            Assert.Equal(SymbolKind.Assembly, mscorNS.Kind);
            var ns1 = (mscorNS.GlobalNamespace.GetMembers("System").Single() as NamespaceSymbol).GetMembers("Collections").Single() as NamespaceSymbol;
            var ns2 = ns1.GetMembers("Generic").Single() as NamespaceSymbol;
 
            var type1 = ns2.GetTypeMembers("Dictionary").First() as NamedTypeSymbol;
            // public generic class
            Assert.Equal(2, type1.Arity);
            Assert.Equal(mscorNS, type1.ContainingAssembly);
            Assert.Equal(ns2, type1.ContainingSymbol);
            Assert.Equal(ns2, type1.ContainingNamespace);
            Assert.True(type1.IsDefinition);
            Assert.False(type1.IsNamespace);
            Assert.True(type1.IsType);
            Assert.True(type1.IsReferenceType);
            Assert.False(type1.IsValueType);
 
            Assert.Equal(SymbolKind.NamedType, type1.Kind);
            Assert.Equal(TypeKind.Class, type1.TypeKind);
            Assert.Equal(Accessibility.Public, type1.DeclaredAccessibility);
            Assert.False(type1.IsStatic);
            Assert.False(type1.IsAbstract);
            Assert.False(type1.IsSealed);
            Assert.False(type1.IsVirtual);
            Assert.False(type1.IsOverride);
 
            // 4 nested types, 67 members overall
            Assert.Equal(67, type1.GetMembers().Length);
            Assert.Equal(3, type1.GetTypeMembers().Length);
            // IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
            // IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback
            Assert.Equal(10, type1.Interfaces().Length);
 
            var fullName = "System.Collections.Generic.Dictionary<TKey, TValue>";
            // Internal Assert.Equal(fullName, class1.GetFullNameWithoutGenericArgs());
            Assert.Equal(fullName, type1.ToTestDisplayString());
            Assert.Equal(2, type1.TypeArguments().Length);
            Assert.Equal(2, type1.TypeParameters.Length);
 
            Assert.Empty(compilation.GetDeclarationDiagnostics());
        }
 
        [Fact]
        public void MetadataTypeSymbolGenInterface01()
        {
            var text = "public class A {}";
            var compilation = CreateCompilation(text);
 
            var mscorlib = compilation.ExternalReferences[0];
            var mscorNS = compilation.GetReferencedAssemblySymbol(mscorlib);
            var ns1 = (mscorNS.GlobalNamespace.GetMembers("System").Single() as NamespaceSymbol).GetMembers("Collections").Single() as NamespaceSymbol;
            var ns2 = ns1.GetMembers("Generic").Single() as NamespaceSymbol;
 
            var type1 = ns2.GetTypeMembers("IList").First() as NamedTypeSymbol;
            // public generic interface
            Assert.Equal(1, type1.Arity);
            Assert.Equal(mscorNS, type1.ContainingAssembly);
            Assert.Equal(ns2, type1.ContainingSymbol);
            Assert.Equal(ns2, type1.ContainingNamespace);
            Assert.True(type1.IsDefinition);
            Assert.False(type1.IsNamespace);
            Assert.True(type1.IsType);
            Assert.True(type1.IsReferenceType);
            Assert.False(type1.IsValueType);
 
            Assert.Equal(SymbolKind.NamedType, type1.Kind);
            Assert.Equal(TypeKind.Interface, type1.TypeKind);
            Assert.Equal(Accessibility.Public, type1.DeclaredAccessibility);
            Assert.False(type1.IsStatic);
            Assert.True(type1.IsAbstract);
            Assert.False(type1.IsSealed);
            Assert.False(type1.IsVirtual);
            Assert.False(type1.IsOverride);
            Assert.False(type1.IsExtern);
 
            // 3 method, 2 get|set_<Prop> method, 1 Properties
            Assert.Equal(6, type1.GetMembers().Length);
            Assert.Equal(0, type1.GetTypeMembers().Length);
            // ICollection<T>, IEnumerable<T>, IEnumerable
            Assert.Equal(3, type1.Interfaces().Length);
 
            var fullName = "System.Collections.Generic.IList<T>";
            // Internal Assert.Equal(fullName, class1.GetFullNameWithoutGenericArgs());
            Assert.Equal(fullName, type1.ToTestDisplayString());
            Assert.Equal(1, type1.TypeArguments().Length);
            Assert.Equal(1, type1.TypeParameters.Length);
 
            Assert.Empty(compilation.GetDeclarationDiagnostics());
        }
 
        [Fact]
        public void MetadataTypeSymbolStruct01()
        {
            var text = "public class A {}";
            var compilation = CreateEmptyCompilation(text,
                new[] { MscorlibRef },
                options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
 
            var mscorlib = compilation.ExternalReferences[0];
            var mscorNS = compilation.GetReferencedAssemblySymbol(mscorlib);
            Assert.Equal("mscorlib", mscorNS.Name);
            var ns1 = mscorNS.GlobalNamespace.GetMembers("System").Single() as NamespaceSymbol;
            var ns2 = ns1.GetMembers("Runtime").Single() as NamespaceSymbol;
            var ns3 = ns2.GetMembers("Serialization").Single() as NamespaceSymbol;
            var type1 = ns3.GetTypeMembers("StreamingContext").First() as NamedTypeSymbol;
 
            Assert.Equal(mscorNS, type1.ContainingAssembly);
            Assert.Equal(ns3, type1.ContainingSymbol);
            Assert.Equal(ns3, type1.ContainingNamespace);
            Assert.True(type1.IsDefinition);
            Assert.False(type1.IsNamespace);
            Assert.True(type1.IsType);
            Assert.False(type1.IsReferenceType);
            Assert.True(type1.IsValueType);
 
            Assert.Equal(SymbolKind.NamedType, type1.Kind);
            Assert.Equal(TypeKind.Struct, type1.TypeKind);
            Assert.Equal(Accessibility.Public, type1.DeclaredAccessibility);
            Assert.False(type1.IsStatic);
            Assert.False(type1.IsAbstract);
            Assert.True(type1.IsSealed);
            Assert.False(type1.IsVirtual);
            Assert.False(type1.IsOverride);
 
            // 4 method + 1 synthesized ctor, 2 get_<Prop> method, 2 Properties, 2 fields
            Assert.Equal(11, type1.GetMembers().Length);
            Assert.Equal(0, type1.GetTypeMembers().Length);
            Assert.Equal(0, type1.Interfaces().Length);
 
            var fullName = "System.Runtime.Serialization.StreamingContext";
            // Internal Assert.Equal(fullName, class1.GetFullNameWithoutGenericArgs());
            Assert.Equal(fullName, type1.ToTestDisplayString());
            Assert.Equal(0, type1.TypeArguments().Length);
            Assert.Equal(0, type1.TypeParameters.Length);
 
            Assert.Empty(compilation.GetDeclarationDiagnostics());
        }
 
        [Fact]
        public void MetadataArrayTypeSymbol01()
        {
            // This is a copy of the EventProviderBase type which existed in a beta of .NET framework
            // 4.5. Replicating the structure of the type to maintain the test validation.
            var source1 = @"
namespace System.Diagnostics.Eventing
{
    internal class EventProviderBase
    {
 
        internal struct EventData { }
 
        internal EventData[] m_eventData = null;
 
        protected void WriteTransferEventHelper(int eventId, Guid relatedActivityId, params object[] args) { }
    }
}
";
 
            var compilation1 = CreateEmptyCompilation(source1, new[] { Net40.References.mscorlib, Net40.References.SystemCore });
            compilation1.VerifyDiagnostics();
 
            var source2 = "public class A {}";
            var compilation2 = CreateEmptyCompilation(source2, new MetadataReference[] { Net40.References.mscorlib, Net40.References.SystemCore, compilation1.EmitToImageReference() },
                options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
 
            var compilation1Lib = compilation2.ExternalReferences[2];
            var systemCoreNS = compilation2.GetReferencedAssemblySymbol(compilation1Lib);
            var ns1 = systemCoreNS.GlobalNamespace.GetMembers("System").Single() as NamespaceSymbol;
            var ns2 = ns1.GetMembers("Diagnostics").Single() as NamespaceSymbol;
            var ns3 = ns2.GetMembers("Eventing").Single() as NamespaceSymbol;
 
            var type1 = ns3.GetTypeMembers("EventProviderBase").Single() as NamedTypeSymbol;
            // EventData[]
            var type2 = (type1.GetMembers("m_eventData").Single() as FieldSymbol).Type as ArrayTypeSymbol;
            var member2 = type1.GetMembers("WriteTransferEventHelper").Single() as MethodSymbol;
            Assert.Equal(3, member2.Parameters.Length);
            // params object[]
            var type3 = (member2.Parameters[2] as ParameterSymbol).Type as ArrayTypeSymbol;
 
            Assert.Equal(SymbolKind.ArrayType, type2.Kind);
            Assert.Equal(SymbolKind.ArrayType, type3.Kind);
            Assert.Equal(Accessibility.NotApplicable, type2.DeclaredAccessibility);
            Assert.Equal(Accessibility.NotApplicable, type3.DeclaredAccessibility);
 
            Assert.True(type2.IsSZArray);
            Assert.True(type3.IsSZArray);
            Assert.Equal(TypeKind.Array, type2.TypeKind);
            Assert.Equal(TypeKind.Array, type3.TypeKind);
 
            Assert.Equal("EventData", type2.ElementType.Name);
            Assert.Equal("Array", type2.BaseType().Name);
            Assert.Equal("Object", type3.ElementType.Name);
            Assert.Equal("System.Diagnostics.Eventing.EventProviderBase.EventData[]", type2.ToTestDisplayString());
            Assert.Equal("System.Object[]", type3.ToTestDisplayString());
 
            Assert.Equal(1, type2.Interfaces().Length);
            Assert.Equal(1, type3.Interfaces().Length);
            // bug
            // Assert.False(type2.IsDefinition);
            Assert.False(type2.IsNamespace);
            Assert.True(type3.IsType);
 
            Assert.True(type2.IsReferenceType);
            Assert.True(type2.ElementType.IsValueType);
            Assert.True(type3.IsReferenceType);
            Assert.False(type3.IsValueType);
 
            Assert.False(type2.IsStatic);
            Assert.False(type2.IsAbstract);
            Assert.False(type2.IsSealed);
            Assert.False(type3.IsVirtual);
            Assert.False(type3.IsOverride);
 
            Assert.Equal(0, type2.GetMembers().Length);
            Assert.Equal(0, type3.GetMembers(String.Empty).Length);
 
            Assert.Equal(0, type3.GetTypeMembers().Length);
            Assert.Equal(0, type2.GetTypeMembers(String.Empty).Length);
            Assert.Equal(0, type3.GetTypeMembers(String.Empty, 0).Length);
 
            Assert.Empty(compilation2.GetDeclarationDiagnostics());
        }
 
        [Fact, WorkItem(531619, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531619"), WorkItem(531619, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531619")]
        public void InheritFromNetModuleMetadata01()
        {
            var modRef = TestReferences.MetadataTests.NetModule01.ModuleCS00;
 
            var text1 = @"
class Test : StaticModClass
{";
            var text2 = @"
    public static int Main()
    {
        r";
 
            var tree = SyntaxFactory.ParseSyntaxTree(String.Empty);
            var comp = CreateCompilation(source: tree, references: new[] { modRef });
 
            var currComp = comp;
 
            var oldTree = comp.SyntaxTrees.First();
            var oldIText = oldTree.GetText();
            var span = new TextSpan(oldIText.Length, 0);
            var change = new TextChange(span, text1);
 
            var newIText = oldIText.WithChanges(change);
            var newTree = oldTree.WithChangedText(newIText);
            currComp = currComp.ReplaceSyntaxTree(oldTree, newTree);
 
            var model = currComp.GetSemanticModel(newTree);
            var id = newTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(s => s.ToString() == "StaticModClass").First();
            // NRE is thrown later but this one has to be called first
            var symInfo = model.GetSymbolInfo(id);
            Assert.NotNull(symInfo.Symbol);
 
            oldTree = newTree;
            oldIText = oldTree.GetText();
            span = new TextSpan(oldIText.Length, 0);
            change = new TextChange(span, text2);
 
            newIText = oldIText.WithChanges(change);
            newTree = oldTree.WithChangedText(newIText);
            currComp = currComp.ReplaceSyntaxTree(oldTree, newTree);
 
            model = currComp.GetSemanticModel(newTree);
            id = newTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(s => s.ToString() == "StaticModClass").First();
            symInfo = model.GetSymbolInfo(id);
            Assert.NotNull(symInfo.Symbol);
        }
 
        [WorkItem(1066489, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1066489")]
        [Fact]
        public void InstanceIterator_ExplicitInterfaceImplementation_OldName()
        {
            var ilSource = @"
.class interface public abstract auto ansi I`1<T>
{
  .method public hidebysig newslot abstract virtual 
          instance class [mscorlib]System.Collections.IEnumerable 
          F() cil managed
  {
  } // end of method I`1::F
 
} // end of class I`1
 
.class public auto ansi beforefieldinit C
       extends [mscorlib]System.Object
       implements class I`1<int32>
{
  .class auto ansi sealed nested private beforefieldinit '<I<System.Int32>'.'F>d__0'
         extends [mscorlib]System.Object
         implements class [mscorlib]System.Collections.Generic.IEnumerable`1<object>,
                    [mscorlib]System.Collections.IEnumerable,
                    class [mscorlib]System.Collections.Generic.IEnumerator`1<object>,
                    [mscorlib]System.Collections.IEnumerator,
                    [mscorlib]System.IDisposable
  {
    .field private object '<>2__current'
    .field private int32 '<>1__state'
    .field private int32 '<>l__initialThreadId'
    .field public class C '<>4__this'
 
    .method private hidebysig newslot virtual final 
            instance class [mscorlib]System.Collections.Generic.IEnumerator`1<object> 
            'System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator'() cil managed
    {
      ldnull
      throw
    }
 
    .method private hidebysig newslot virtual final 
            instance class [mscorlib]System.Collections.IEnumerator 
            System.Collections.IEnumerable.GetEnumerator() cil managed
    {
      ldnull
      throw
    }
 
    .method private hidebysig newslot virtual final 
            instance bool  MoveNext() cil managed
    {
      ldnull
      throw
    }
 
    .method private hidebysig newslot specialname virtual final 
            instance object  'System.Collections.Generic.IEnumerator<System.Object>.get_Current'() cil managed
    {
      ldnull
      throw
    }
 
    .method private hidebysig newslot virtual final 
            instance void  System.Collections.IEnumerator.Reset() cil managed
    {
      ldnull
      throw
    }
 
    .method private hidebysig newslot virtual final 
            instance void  System.IDisposable.Dispose() cil managed
    {
      ldnull
      throw
    }
 
    .method private hidebysig newslot specialname virtual final 
            instance object  System.Collections.IEnumerator.get_Current() cil managed
    {
      ldnull
      throw
    }
 
    .method public hidebysig specialname rtspecialname 
            instance void  .ctor(int32 '<>1__state') cil managed
    {
      ldarg.0
      call       instance void [mscorlib]System.Object::.ctor()
      ret
    }
 
    .property instance object 'System.Collections.Generic.IEnumerator<System.Object>.Current'()
    {
      .get instance object C/'<I<System.Int32>'.'F>d__0'::'System.Collections.Generic.IEnumerator<System.Object>.get_Current'()
    }
    .property instance object System.Collections.IEnumerator.Current()
    {
      .get instance object C/'<I<System.Int32>'.'F>d__0'::System.Collections.IEnumerator.get_Current()
    }
  } // end of class '<I<System.Int32>'.'F>d__0'
 
  .method private hidebysig newslot virtual final 
          instance class [mscorlib]System.Collections.IEnumerable 
          'I<System.Int32>.F'() cil managed
  {
    ldnull
    throw
  }
 
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    ldarg.0
    call       instance void [mscorlib]System.Object::.ctor()
    ret
  }
 
} // end of class C
";
 
            var comp = CreateCompilationWithILAndMscorlib40("", ilSource);
 
            var stateMachineClass = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMembers().OfType<NamedTypeSymbol>().Single();
            Assert.Equal("<I<System.Int32>.F>d__0", stateMachineClass.Name); // The name has been reconstructed correctly.
            Assert.Equal("C.<I<System.Int32>.F>d__0", stateMachineClass.ToTestDisplayString()); // SymbolDisplay works.
            Assert.Equal(stateMachineClass, comp.GetTypeByMetadataName("C+<I<System.Int32>.F>d__0")); // GetTypeByMetadataName works.
        }
 
        [ConditionalFact(typeof(ClrOnly))]
        [WorkItem(23761, "https://github.com/dotnet/roslyn/issues/23761")] // reason for skipping mono
        public void EmptyNamespaceNames()
        {
            var ilSource =
@".class public A
{
  .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
}
.namespace '.N'
{
  .class public B
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}
.namespace '.'
{
  .class public C
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}
.namespace '..'
{
  .class public D
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}
.namespace '..N'
{
  .class public E
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}
.namespace N.M
{
  .class public F
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}
.namespace 'N.M.'
{
  .class public G
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}
.namespace 'N.M..'
{
  .class public H
  {
    .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  }
}";
            var comp = CreateCompilationWithILAndMscorlib40("", ilSource);
            comp.VerifyDiagnostics();
            var builder = ArrayBuilder<string>.GetInstance();
            var module = comp.GetMember<NamedTypeSymbol>("A").ContainingModule;
            GetAllNamespaceNames(builder, module.GlobalNamespace);
            Assert.Equal(new[] { "<global namespace>", "", ".", "..N", ".N", "N", "N.M", "N.M." }, builder);
            builder.Free();
        }
 
        private static void GetAllNamespaceNames(ArrayBuilder<string> builder, NamespaceSymbol @namespace)
        {
            builder.Add(@namespace.ToTestDisplayString());
            foreach (var member in @namespace.GetMembers())
            {
                if (member.Kind != SymbolKind.Namespace)
                {
                    continue;
                }
                GetAllNamespaceNames(builder, (NamespaceSymbol)member);
            }
        }
    }
}