/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/MetadataMemberTests.cs
819 строк
35 KB
AlekseyTs
Adjust public API based on API review feedback (#71940)
05 фев 2024, 20:30
Не верифицирован
05 фев 2024, 20:30
1c5c7e2
Код
Авторство
О чём код?
// 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.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class MetadataMemberTests : CSharpTestBase { private const string VTableGapClassIL = @" .class public auto ansi beforefieldinit Class extends [mscorlib]System.Object { .method public hidebysig specialname rtspecialname instance void _VtblGap1_1() cil managed { ret } .method public hidebysig specialname instance int32 _VtblGap2_1() cil managed { ret } .method public hidebysig specialname instance void set_GetterIsGap(int32 'value') cil managed { ret } .method public hidebysig specialname instance int32 get_SetterIsGap() cil managed { ret } .method public hidebysig specialname instance void _VtblGap3_1(int32 'value') cil managed { ret } .method public hidebysig specialname instance int32 _VtblGap4_1() cil managed { ret } .method public hidebysig specialname instance void _VtblGap5_1(int32 'value') cil managed { ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .property instance int32 GetterIsGap() { .get instance int32 Class::_VtblGap2_1() .set instance void Class::set_GetterIsGap(int32) } // end of property Class::GetterIsGap .property instance int32 SetterIsGap() { .get instance int32 Class::get_SetterIsGap() .set instance void Class::_VtblGap3_1(int32) } // end of property Class::SetterIsGap .property instance int32 BothAccessorsAreGaps() { .get instance int32 Class::_VtblGap4_1() .set instance void Class::_VtblGap5_1(int32) } // end of property Class::BothAccessorsAreGaps } // end of class Class "; private const string VTableGapInterfaceIL = @" .class interface public abstract auto ansi Interface { .method public hidebysig newslot specialname rtspecialname abstract virtual instance void _VtblGap1_1() cil managed { } .method public hidebysig newslot specialname abstract virtual instance int32 _VtblGap2_1() cil managed { } .method public hidebysig newslot specialname abstract virtual instance void set_GetterIsGap(int32 'value') cil managed { } .method public hidebysig newslot specialname abstract virtual instance int32 get_SetterIsGap() cil managed { } .method public hidebysig newslot specialname abstract virtual instance void _VtblGap3_1(int32 'value') cil managed { } .method public hidebysig newslot specialname abstract virtual instance int32 _VtblGap4_1() cil managed { } .method public hidebysig newslot specialname abstract virtual instance void _VtblGap5_1(int32 'value') cil managed { } .property instance int32 GetterIsGap() { .get instance int32 Interface::_VtblGap2_1() .set instance void Interface::set_GetterIsGap(int32) } // end of property Interface::GetterIsGap .property instance int32 SetterIsGap() { .get instance int32 Interface::get_SetterIsGap() .set instance void Interface::_VtblGap3_1(int32) } // end of property Interface::SetterIsGap .property instance int32 BothAccessorsAreGaps() { .get instance int32 Interface::_VtblGap4_1() .set instance void Interface::_VtblGap5_1(int32) } // end of property Interface::BothAccessorsAreGaps } // end of class Interface "; [WorkItem(537346, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537346")] [Fact] public void MetadataMethodSymbolCtor01() { var text = "public class A {}"; var compilation = CreateCompilation(text); var mscorlib = compilation.ExternalReferences[0]; var mscorNS = compilation.GetReferencedAssemblySymbol(mscorlib); Assert.Equal(RuntimeCorLibName.Name, mscorNS.Name); Assert.Equal(SymbolKind.Assembly, mscorNS.Kind); var ns1 = mscorNS.GlobalNamespace.GetMembers("System").Single() as NamespaceSymbol; var type1 = ns1.GetTypeMembers("StringComparer").Single() as NamedTypeSymbol; var ctor = type1.InstanceConstructors.Single(); Assert.Equal(type1, ctor.ContainingSymbol); Assert.Equal(WellKnownMemberNames.InstanceConstructorName, ctor.Name); Assert.Equal(SymbolKind.Method, ctor.Kind); Assert.Equal(MethodKind.Constructor, ctor.MethodKind); Assert.Equal(Accessibility.Protected, ctor.DeclaredAccessibility); Assert.True(ctor.IsDefinition); Assert.False(ctor.IsStatic); Assert.False(ctor.IsSealed); Assert.False(ctor.IsOverride); Assert.False(ctor.IsExtensionMethod); Assert.True(ctor.ReturnsVoid); Assert.False(ctor.IsVararg); // Bug - 2067 Assert.Equal("System.StringComparer." + WellKnownMemberNames.InstanceConstructorName + "()", ctor.ToTestDisplayString()); Assert.Equal(0, ctor.TypeParameters.Length); Assert.Equal("Void", ctor.ReturnType.Name); Assert.Empty(compilation.GetDeclarationDiagnostics()); } [WorkItem(537345, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537345")] [Fact] public void MetadataMethodSymbol01() { 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("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; var members = class1.GetMembers("StrongNameSignatureGeneration"); // 4 overloads Assert.Equal(4, members.Length); var member1 = members.Last() as MethodSymbol; Assert.Equal(mscorNS, member1.ContainingAssembly); Assert.Equal(class1, member1.ContainingSymbol); Assert.Equal(SymbolKind.Method, member1.Kind); Assert.Equal(MethodKind.Ordinary, member1.MethodKind); Assert.Equal(Accessibility.Public, member1.DeclaredAccessibility); Assert.True(member1.IsDefinition); Assert.True(member1.IsStatic); Assert.False(member1.IsAbstract); Assert.False(member1.IsSealed); Assert.False(member1.IsVirtual); Assert.False(member1.IsOverride); // Bug - // Assert.True(member1.IsOverloads); Assert.False(member1.IsGenericMethod); // Not Impl // Assert.False(member1.IsExtensionMethod); Assert.False(member1.ReturnsVoid); Assert.False(member1.IsVararg); var fullName = "System.Boolean Microsoft.Runtime.Hosting.StrongNameHelpers.StrongNameSignatureGeneration(System.String pwzFilePath, System.String pwzKeyContainer, System.Byte[] bKeyBlob, System.Int32 cbKeyBlob, ref System.IntPtr ppbSignatureBlob, out System.Int32 pcbSignatureBlob)"; Assert.Equal(fullName, member1.ToTestDisplayString()); Assert.Equal(0, member1.TypeArgumentsWithAnnotations.Length); Assert.Equal(0, member1.TypeParameters.Length); Assert.Equal(6, member1.Parameters.Length); Assert.Equal("Boolean", member1.ReturnType.Name); Assert.Empty(compilation.GetDeclarationDiagnostics()); } [WorkItem(527150, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527150")] [WorkItem(527151, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527151")] [Fact] public void MetadataParameterSymbol01() { 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("Microsoft").Single() as NamespaceSymbol; var ns2 = (ns1.GetMembers("Runtime").Single() as NamespaceSymbol).GetMembers("Hosting").Single() as NamespaceSymbol; var class1 = ns2.GetTypeMembers("StrongNameHelpers").First() as NamedTypeSymbol; var members = class1.GetMembers("StrongNameSignatureGeneration"); var member1 = members.Last() as MethodSymbol; Assert.Equal(6, member1.Parameters.Length); var p1 = member1.Parameters[0] as ParameterSymbol; var p2 = member1.Parameters[1] as ParameterSymbol; var p3 = member1.Parameters[2] as ParameterSymbol; var p4 = member1.Parameters[3] as ParameterSymbol; var p5 = member1.Parameters[4] as ParameterSymbol; var p6 = member1.Parameters[5] as ParameterSymbol; Assert.Equal(mscorNS, p1.ContainingAssembly); Assert.Equal(class1, p1.ContainingType); Assert.Equal(member1, p1.ContainingSymbol); Assert.Equal(SymbolKind.Parameter, p1.Kind); Assert.Equal(Accessibility.NotApplicable, p1.DeclaredAccessibility); Assert.Equal("pwzFilePath", p1.Name); Assert.Equal("System.String pwzKeyContainer", p2.ToTestDisplayString()); Assert.Equal("String", p2.Type.Name); Assert.True(p2.IsDefinition); Assert.Equal("System.Byte[] bKeyBlob", p3.ToTestDisplayString()); Assert.Equal("System.Byte[]", p3.Type.ToTestDisplayString()); //array types do not have names - use ToTestDisplayString Assert.False(p1.IsStatic); Assert.False(p1.IsAbstract); Assert.False(p2.IsSealed); Assert.False(p2.IsVirtual); Assert.False(p3.IsOverride); Assert.False(p3.IsParams); Assert.False(p3.IsParamsArray); Assert.False(p3.IsParamsCollection); Assert.False(p4.IsOptional); Assert.False(p4.HasExplicitDefaultValue); // Not Impl - out of scope // Assert.Null(p4.DefaultValue); Assert.Equal("ppbSignatureBlob", p5.Name); Assert.Equal("IntPtr", p5.Type.Name); Assert.Equal(RefKind.Ref, p5.RefKind); Assert.Equal("out System.Int32 pcbSignatureBlob", p6.ToTestDisplayString()); Assert.Equal(RefKind.Out, p6.RefKind); Assert.Empty(compilation.GetDeclarationDiagnostics()); } [Fact] public void MetadataMethodSymbolGen02() { 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("IDictionary").First() as NamedTypeSymbol; var member1 = type1.GetMembers("Add").Single() as MethodSymbol; var member2 = type1.GetMembers("TryGetValue").Single() as MethodSymbol; Assert.Equal(mscorNS, member1.ContainingAssembly); Assert.Equal(type1, member1.ContainingSymbol); Assert.Equal(SymbolKind.Method, member1.Kind); // Not Impl //Assert.Equal(MethodKind.Ordinary, member2.MethodKind); Assert.Equal(Accessibility.Public, member2.DeclaredAccessibility); Assert.True(member2.IsDefinition); Assert.False(member1.IsStatic); Assert.True(member1.IsAbstract); Assert.False(member2.IsSealed); Assert.False(member2.IsVirtual); Assert.False(member2.IsOverride); //Assert.True(member1.IsOverloads); //Assert.True(member2.IsOverloads); Assert.False(member1.IsGenericMethod); // Not Impl //Assert.False(member1.IsExtensionMethod); Assert.True(member1.ReturnsVoid); Assert.False(member2.IsVararg); Assert.Equal(0, member1.TypeArgumentsWithAnnotations.Length); Assert.Equal(0, member2.TypeParameters.Length); Assert.Equal(2, member1.Parameters.Length); Assert.Equal("Boolean", member2.ReturnType.Name); Assert.Equal("System.Boolean System.Collections.Generic.IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)", member2.ToTestDisplayString()); Assert.Empty(compilation.GetDeclarationDiagnostics()); } [Fact] public void MetadataParameterSymbolGen02() { 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("IDictionary").First() as NamedTypeSymbol; var member1 = type1.GetMembers("TryGetValue").Single() as MethodSymbol; Assert.Equal(2, member1.Parameters.Length); var p1 = member1.Parameters[0] as ParameterSymbol; var p2 = member1.Parameters[1] as ParameterSymbol; Assert.Equal(mscorNS, p1.ContainingAssembly); Assert.Equal(type1, p2.ContainingType); Assert.Equal(member1, p1.ContainingSymbol); Assert.Equal(SymbolKind.Parameter, p2.Kind); Assert.Equal(Accessibility.NotApplicable, p1.DeclaredAccessibility); Assert.Equal("value", p2.Name); Assert.Equal("TKey key", p1.ToTestDisplayString()); // Empty // Assert.Equal("TValue", p2.Type.Name); Assert.True(p2.IsDefinition); Assert.False(p1.IsStatic); Assert.False(p1.IsAbstract); Assert.False(p2.IsSealed); Assert.False(p2.IsVirtual); Assert.False(p1.IsOverride); Assert.False(p1.IsExtern); Assert.False(p1.IsParams); Assert.False(p1.IsParamsArray); Assert.False(p1.IsParamsCollection); Assert.False(p2.IsOptional); Assert.False(p2.HasExplicitDefaultValue); // Not Impl - Not in M2 scope // Assert.Null(p2.DefaultValue); Assert.Empty(compilation.GetDeclarationDiagnostics()); } [WorkItem(537424, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537424")] [Fact] public void MetadataMethodStaticAndInstanceCtor() { var text = @" class C { C() { } static C() { } }"; var compilation = CreateCompilation(text); Assert.False(compilation.GetDiagnostics().Any()); var classC = compilation.SourceModule.GlobalNamespace.GetTypeMembers("C").Single(); // NamedTypeSymbol.Constructors only contains instance constructors Assert.Equal(1, classC.InstanceConstructors.Length); Assert.Equal(1, classC.GetMembers(WellKnownMemberNames.StaticConstructorName).Length); } [ClrOnlyFact] public void ImportDecimalConstantAttribute() { const string ilSource = @" .class public C extends [mscorlib]System.Object { .field public static initonly valuetype [mscorlib]System.Decimal MyDecimalTen .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8, uint8, uint32, uint32, uint32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 ) } // end of class C"; const string cSharpSource = @" class B { static void Main() { var x = C.MyDecimalTen; System.Console.Write(x); } } "; CompileWithCustomILSource(cSharpSource, ilSource, expectedOutput: "10"); } [Fact] public void TypeAndNamespaceWithSameNameButDifferentArities() { var il = @" .class interface public abstract auto ansi A.B.C { } .class interface public abstract auto ansi A.B`1<T> { } "; var csharp = @""; var compilation = CreateCompilationWithILAndMscorlib40(csharp, il); var namespaceA = compilation.GlobalNamespace.GetMember<NamespaceSymbol>("A"); var members = namespaceA.GetMembers("B"); Assert.Equal(2, members.Length); Assert.NotNull(members[0]); Assert.NotNull(members[1]); } [Fact] public void TypeAndNamespaceWithSameNameAndArity() { var il = @" .class interface public abstract auto ansi A.B.C { } .class interface public abstract auto ansi A.B { } "; var csharp = @""; var compilation = CreateCompilationWithILAndMscorlib40(csharp, il); var namespaceA = compilation.GlobalNamespace.GetMember<NamespaceSymbol>("A"); var members = namespaceA.GetMembers("B"); Assert.Equal(2, members.Length); Assert.NotNull(members[0]); Assert.NotNull(members[1]); } // TODO: Update this test if we decide to include gaps in the symbol table for NoPIA (DevDiv #17472). [WorkItem(546951, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546951")] [Fact] public void VTableGapsNotInSymbolTable() { var csharp = @""; var comp = CreateCompilationWithILAndMscorlib40(csharp, VTableGapClassIL); comp.VerifyDiagnostics(); var type = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Class"); AssertEx.None(type.GetMembersUnordered(), symbol => symbol.Name.StartsWith("_VtblGap", StringComparison.Ordinal)); // Dropped entirely. Assert.Equal(0, type.GetMembers("_VtblGap1_1").Length); // Dropped entirely, since both accessors are dropped. Assert.Equal(0, type.GetMembers("BothAccessorsAreGaps").Length); // Getter is silently dropped, property appears valid and write-only. var propWithoutGetter = type.GetMember<PropertySymbol>("GetterIsGap"); Assert.Null(propWithoutGetter.GetMethod); Assert.NotNull(propWithoutGetter.SetMethod); Assert.False(propWithoutGetter.MustCallMethodsDirectly); // Setter is silently dropped, property appears valid and read-only. var propWithoutSetter = type.GetMember<PropertySymbol>("SetterIsGap"); Assert.NotNull(propWithoutSetter.GetMethod); Assert.Null(propWithoutSetter.SetMethod); Assert.False(propWithoutSetter.MustCallMethodsDirectly); } [WorkItem(546951, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546951")] [Fact] public void CallVTableGap() { var csharp = @" class Test { static void Main() { Class c = new Class(); c._VtblGap1_1(); // CS1061 int x; x = c.BothAccessorsAreGaps; // CS1061 c.BothAccessorsAreGaps = x; // CS1061 x = c.GetterIsGap; // CS0154 c.GetterIsGap = x; x = c.SetterIsGap; c.SetterIsGap = x; // CS0200 } } "; var comp = CreateCompilationWithILAndMscorlib40(csharp, VTableGapClassIL); comp.VerifyDiagnostics( // (8,11): error CS1061: 'Class' does not contain a definition for '_VtblGap1_1' and no extension method '_VtblGap1_1' accepting a first argument of type 'Class' could be found (are you missing a using directive or an assembly reference?) // c._VtblGap1_1(); Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "_VtblGap1_1").WithArguments("Class", "_VtblGap1_1"), // (12,15): error CS1061: 'Class' does not contain a definition for 'BothAccessorsAreGaps' and no extension method 'BothAccessorsAreGaps' accepting a first argument of type 'Class' could be found (are you missing a using directive or an assembly reference?) // x = c.BothAccessorsAreGaps; Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "BothAccessorsAreGaps").WithArguments("Class", "BothAccessorsAreGaps"), // (13,11): error CS1061: 'Class' does not contain a definition for 'BothAccessorsAreGaps' and no extension method 'BothAccessorsAreGaps' accepting a first argument of type 'Class' could be found (are you missing a using directive or an assembly reference?) // c.BothAccessorsAreGaps = x; Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "BothAccessorsAreGaps").WithArguments("Class", "BothAccessorsAreGaps"), // (15,13): error CS0154: The property or indexer 'Class.GetterIsGap' cannot be used in this context because it lacks the get accessor // x = c.GetterIsGap; Diagnostic(ErrorCode.ERR_PropertyLacksGet, "c.GetterIsGap").WithArguments("Class.GetterIsGap"), // (19,9): error CS0200: Property or indexer 'Class.SetterIsGap' cannot be assigned to -- it is read only // c.SetterIsGap = x; Diagnostic(ErrorCode.ERR_AssgReadonlyProp, "c.SetterIsGap").WithArguments("Class.SetterIsGap")); } [WorkItem(546951, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546951")] [Fact] public void ImplementVTableGap() { var csharp = @" class Empty : Interface { } class Implicit : Interface { public void _VtblGap1_1() { } public int GetterIsGap { get; set; } public int SetterIsGap { get; set; } public int BothAccessorsAreGaps { get; set; } } class Explicit : Interface { void Interface._VtblGap1_1() { } int Interface.GetterIsGap { get; set; } int Interface.SetterIsGap { get; set; } int Interface.BothAccessorsAreGaps { get; set; } } "; var comp = CreateCompilationWithILAndMscorlib40(csharp, VTableGapInterfaceIL); comp.VerifyDiagnostics( // (2,7): error CS0535: 'Empty' does not implement interface member 'Interface.SetterIsGap' // class Empty : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Empty", "Interface.SetterIsGap"), // (2,7): error CS0535: 'Empty' does not implement interface member 'Interface.GetterIsGap' // class Empty : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Empty", "Interface.GetterIsGap"), // (17,33): error CS0550: 'Explicit.Interface.GetterIsGap.get' adds an accessor not found in interface member 'Interface.GetterIsGap' // int Interface.GetterIsGap { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("Explicit.Interface.GetterIsGap.get", "Interface.GetterIsGap"), // (18,38): error CS0550: 'Explicit.Interface.SetterIsGap.set' adds an accessor not found in interface member 'Interface.SetterIsGap' // int Interface.SetterIsGap { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("Explicit.Interface.SetterIsGap.set", "Interface.SetterIsGap"), // (19,19): error CS0539: 'Explicit.BothAccessorsAreGaps' in explicit interface declaration is not a member of interface // int Interface.BothAccessorsAreGaps { get; set; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "BothAccessorsAreGaps").WithArguments("Explicit.BothAccessorsAreGaps"), // (16,20): error CS0539: 'Explicit._VtblGap1_1()' in explicit interface declaration is not a member of interface // void Interface._VtblGap1_1() { } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "_VtblGap1_1").WithArguments("Explicit._VtblGap1_1()")); } [Fact, WorkItem(1094411, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1094411")] public void Bug1094411_01() { var source1 = @" class Test { public int F; public int P {get; set;} public event System.Action E { add { } remove { } } public void M() {} } "; var members = new[] { "F", "P", "E", "M" }; var comp1 = CreateCompilation(source1, options: TestOptions.ReleaseDll); var test1 = comp1.GetTypeByMetadataName("Test"); var memberNames1 = new HashSet<string>(test1.MemberNames); foreach (var m in members) { Assert.True(memberNames1.Contains(m), m); } var comp2 = CreateCompilation("", new[] { comp1.EmitToImageReference() }); var test2 = comp2.GetTypeByMetadataName("Test"); var memberNames2 = new HashSet<string>(test2.MemberNames); foreach (var m in members) { Assert.True(memberNames2.Contains(m), m); } } [Fact, WorkItem(1094411, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1094411")] public void Bug1094411_02() { var source1 = @" class Test { public int F; public int P {get; set;} public event System.Action E { add { } remove { } } public void M() {} } "; var members = new[] { "F", "P", "E", "M" }; var comp1 = CreateCompilation(source1, options: TestOptions.ReleaseDll); var test1 = comp1.GetTypeByMetadataName("Test"); test1.GetMembers(); var memberNames1 = new HashSet<string>(test1.MemberNames); foreach (var m in members) { Assert.True(memberNames1.Contains(m), m); } var comp2 = CreateCompilation("", new[] { comp1.EmitToImageReference() }); var test2 = comp2.GetTypeByMetadataName("Test"); test2.GetMembers(); var memberNames2 = new HashSet<string>(test2.MemberNames); foreach (var m in members) { Assert.True(memberNames2.Contains(m), m); } } [Fact] public void TestMetadataImportOptions_01() { var expectedDiagnostics = new[] { // error CS7088: Invalid 'MetadataImportOptions' value: '255'. Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MetadataImportOptions", "255").WithLocation(1, 1) }; var options = TestOptions.DebugDll; Assert.Equal(MetadataImportOptions.Public, options.MetadataImportOptions); options.VerifyErrors(); options = options.WithMetadataImportOptions(MetadataImportOptions.Internal); Assert.Equal(MetadataImportOptions.Internal, options.MetadataImportOptions); options.VerifyErrors(); options = options.WithMetadataImportOptions(MetadataImportOptions.All); Assert.Equal(MetadataImportOptions.All, options.MetadataImportOptions); options.VerifyErrors(); options = options.WithMetadataImportOptions(MetadataImportOptions.Public); Assert.Equal(MetadataImportOptions.Public, options.MetadataImportOptions); options.VerifyErrors(); options = options.WithMetadataImportOptions((MetadataImportOptions)byte.MaxValue); Assert.Equal((MetadataImportOptions)byte.MaxValue, options.MetadataImportOptions); options.VerifyErrors(expectedDiagnostics); var commonOptions = (CompilationOptions)options; commonOptions = commonOptions.WithMetadataImportOptions(MetadataImportOptions.Internal); Assert.Equal(MetadataImportOptions.Internal, ((CSharpCompilationOptions)commonOptions).MetadataImportOptions); ((CSharpCompilationOptions)commonOptions).VerifyErrors(); commonOptions = commonOptions.WithMetadataImportOptions(MetadataImportOptions.All); Assert.Equal(MetadataImportOptions.All, ((CSharpCompilationOptions)commonOptions).MetadataImportOptions); ((CSharpCompilationOptions)commonOptions).VerifyErrors(); commonOptions = commonOptions.WithMetadataImportOptions(MetadataImportOptions.Public); Assert.Equal(MetadataImportOptions.Public, ((CSharpCompilationOptions)commonOptions).MetadataImportOptions); ((CSharpCompilationOptions)commonOptions).VerifyErrors(); commonOptions = commonOptions.WithMetadataImportOptions((MetadataImportOptions)byte.MaxValue); Assert.Equal((MetadataImportOptions)byte.MaxValue, ((CSharpCompilationOptions)commonOptions).MetadataImportOptions); ((CSharpCompilationOptions)commonOptions).VerifyErrors(expectedDiagnostics); var source = @" public class C { public int P1 {get; set;} internal int P2 {get; set;} private int P3 {get; set;} } "; var compilation0 = CreateCompilation(source); options = TestOptions.DebugDll; var compilation = CreateCompilation("", options: options, references: new[] { compilation0.EmitToImageReference() }); var c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.Empty(c.GetMembers("P2")); Assert.Empty(c.GetMembers("P3")); CompileAndVerify(compilation); compilation = compilation.WithOptions(options.WithMetadataImportOptions(MetadataImportOptions.Internal)); c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.NotEmpty(c.GetMembers("P2")); Assert.Empty(c.GetMembers("P3")); CompileAndVerify(compilation); compilation = compilation.WithOptions(options.WithMetadataImportOptions(MetadataImportOptions.All)); c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.NotEmpty(c.GetMembers("P2")); Assert.NotEmpty(c.GetMembers("P3")); CompileAndVerify(compilation); compilation = compilation.WithOptions(options.WithMetadataImportOptions((MetadataImportOptions)byte.MaxValue)); c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.NotEmpty(c.GetMembers("P2")); Assert.Empty(c.GetMembers("P3")); compilation.VerifyEmitDiagnostics(expectedDiagnostics); compilation.VerifyDiagnostics(expectedDiagnostics); } [Fact] public void TestMetadataImportOptions_02() { var expectedDiagnostics = new[] { // error CS7088: Invalid 'MetadataImportOptions' value: '255'. Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MetadataImportOptions", "255").WithLocation(1, 1) }; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.Internal); Assert.Equal(MetadataImportOptions.Internal, options.MetadataImportOptions); options.VerifyErrors(); options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); Assert.Equal(MetadataImportOptions.All, options.MetadataImportOptions); options.VerifyErrors(); options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.Public); Assert.Equal(MetadataImportOptions.Public, options.MetadataImportOptions); options.VerifyErrors(); options = TestOptions.DebugDll.WithMetadataImportOptions((MetadataImportOptions)byte.MaxValue); Assert.Equal((MetadataImportOptions)byte.MaxValue, options.MetadataImportOptions); options.VerifyErrors(expectedDiagnostics); var source = @" public class C { public int P1 {get; set;} internal int P2 {get; set;} private int P3 {get; set;} } "; var compilation0 = CreateCompilation(source); var compilation = CreateCompilation("", options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.Internal), references: new[] { compilation0.EmitToImageReference() }); var c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.NotEmpty(c.GetMembers("P2")); Assert.Empty(c.GetMembers("P3")); CompileAndVerify(compilation); compilation = compilation.WithOptions(TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.NotEmpty(c.GetMembers("P2")); Assert.NotEmpty(c.GetMembers("P3")); CompileAndVerify(compilation); compilation = compilation.WithOptions(TestOptions.DebugDll.WithMetadataImportOptions((MetadataImportOptions)byte.MaxValue)); c = compilation.GetTypeByMetadataName("C"); Assert.NotEmpty(c.GetMembers("P1")); Assert.NotEmpty(c.GetMembers("P2")); Assert.Empty(c.GetMembers("P3")); compilation.VerifyEmitDiagnostics(expectedDiagnostics); compilation.VerifyDiagnostics(expectedDiagnostics); } } }