public void HoistedAnonymousTypes_Complex() { var source0 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Y = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Y); } } "; var source1 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Z = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Z); } }"; var compilation0 = CreateCompilationWithMscorlib(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateCompilationWithMscorlib("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("X", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType2", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("Y", isKey: false, ignoreCase: false)))].Name); Assert.Equal(3, anonymousTypeMap0.Count); var compilation1 = CreateCompilationWithMscorlib(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember <NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass0_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag()); var fields = displayClass.GetFields(emitContext).ToArray(); var x1 = fields[0]; var x2 = fields[1]; Assert.Equal("x1", x1.Name); Assert.Equal("x2", x2.Name); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedX1 = (Cci.IFieldDefinition)matcher.MapDefinition(x1); var mappedX2 = (Cci.IFieldDefinition)matcher.MapDefinition(x2); Assert.Equal("x1", mappedX1.Name); Assert.Null(mappedX2); }
public void AnonymousTypesWithNullables() { var source0 = @" using System; class C { static T id<T>(T t) => t; static T F<T>(Func<T> f) => f(); static void M(string? x) { var y1 = new { A = id(x) }; var y2 = F(() => new { B = id(x) }); var z = new Func<string>(() => y1.A + y2.B); } }"; var source1 = @" using System; class C { static T id<T>(T t) => t; static T F<T>(Func<T> f) => f(); static void M(string? x) { if (x is null) throw new Exception(); var y1 = new { A = id(x) }; var y2 = F(() => new { B = id(x) }); var z = new Func<string>(() => y1.A + y2.B); } }"; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateCompilation("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("B", isKey: false, ignoreCase: false)))].Name); Assert.Equal(2, anonymousTypeMap0.Count); var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember <NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass2_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true); var fields = displayClass.GetFields(emitContext).ToArray(); AssertEx.SetEqual(fields.Select(f => f.Name), new[] { "x", "y1", "y2" }); var y1 = fields.Where(f => f.Name == "y1").Single(); var y2 = fields.Where(f => f.Name == "y2").Single(); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedY1 = (Cci.IFieldDefinition)matcher.MapDefinition(y1); var mappedY2 = (Cci.IFieldDefinition)matcher.MapDefinition(y2); Assert.Equal("y1", mappedY1.Name); Assert.Equal("y2", mappedY2.Name); }