public void DependencyVersionWildcardsCollisions() { string srcLib01 = @" [assembly: System.Reflection.AssemblyVersion(""1.0.0.1"")] public class D { } "; string srcLib02 = @" [assembly: System.Reflection.AssemblyVersion(""1.0.0.2"")] public class D { } "; string srcLib11 = @" [assembly: System.Reflection.AssemblyVersion(""1.0.1.1"")] public class D { } "; string srcLib12 = @" [assembly: System.Reflection.AssemblyVersion(""1.0.1.2"")] public class D { } "; string src0 = @" extern alias L0; extern alias L1; class C { public static int F(L0::D a, L1::D b) => 1; } "; string src1 = @" extern alias L0; extern alias L1; class C { public static int F(L0::D a, L1::D b) => 2; } "; var lib01 = CreateCompilation(srcLib01, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics(); var ref01 = lib01.ToMetadataReference(ImmutableArray.Create("L0")); var lib02 = CreateCompilation(srcLib02, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics(); var ref02 = lib02.ToMetadataReference(ImmutableArray.Create("L0")); var lib11 = CreateCompilation(srcLib11, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics(); var ref11 = lib11.ToMetadataReference(ImmutableArray.Create("L1")); var lib12 = CreateCompilation(srcLib12, assemblyName: "Lib", options: s_signedDll).VerifyDiagnostics(); var ref12 = lib12.ToMetadataReference(ImmutableArray.Create("L1")); var compilation0 = CreateEmptyCompilation(src0, new[] { MscorlibRef, ref01, ref11 }, assemblyName: "C", options: TestOptions.DebugDll); var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, ref02, ref12 }); var v0 = CompileAndVerify(compilation0); var f0 = compilation0.GetMember <MethodSymbol>("C.F"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, f0, f1))); diff1.EmitResult.Diagnostics.Verify( // error CS7038: Failed to emit module 'C': Changing the version of an assembly reference is not allowed during debugging: // 'Lib, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null' changed version to '1.0.0.2'. Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments("C", string.Format(CodeAnalysisResources.ChangingVersionOfAssemblyReferenceIsNotAllowedDuringDebugging, "Lib, Version=1.0.0.1, Culture=neutral, PublicKeyToken=ce65828c82a341f2", "1.0.0.2"))); }
public void CurrentCompilationVersionWildcards() { var source0 = MarkedSource(@" using System; [assembly: System.Reflection.AssemblyVersion(""1.0.0.*"")] class C { static void M() { new Action(<N:0>() => { Console.WriteLine(1); }</N:0>).Invoke(); } static void F() { } }"); var source1 = MarkedSource(@" using System; [assembly: System.Reflection.AssemblyVersion(""1.0.0.*"")] class C { static void M() { new Action(<N:0>() => { Console.WriteLine(1); }</N:0>).Invoke(); new Action(<N:1>() => { Console.WriteLine(2); }</N:1>).Invoke(); } static void F() { } }"); var source2 = MarkedSource(@" using System; [assembly: System.Reflection.AssemblyVersion(""1.0.0.*"")] class C { static void M() { new Action(<N:0>() => { Console.WriteLine(1); }</N:0>).Invoke(); new Action(<N:1>() => { Console.WriteLine(2); }</N:1>).Invoke(); } static void F() { Console.WriteLine(1); } }"); var source3 = MarkedSource(@" using System; [assembly: System.Reflection.AssemblyVersion(""1.0.0.*"")] class C { static void M() { new Action(<N:0>() => { Console.WriteLine(1); }</N:0>).Invoke(); new Action(<N:1>() => { Console.WriteLine(2); }</N:1>).Invoke(); new Action(<N:2>() => { Console.WriteLine(3); }</N:2>).Invoke(); new Action(<N:3>() => { Console.WriteLine(4); }</N:3>).Invoke(); } static void F() { Console.WriteLine(1); } }"); var options = ComSafeDebugDll.WithCryptoPublicKey(TestResources.TestKeys.PublicKey_ce65828c82a341f2); var compilation0 = CreateCompilation(source0.Tree, options: options.WithCurrentLocalTime(new DateTime(2016, 1, 1, 1, 0, 0))); var compilation1 = compilation0.WithSource(source1.Tree).WithOptions(options.WithCurrentLocalTime(new DateTime(2016, 1, 1, 1, 0, 10))); var compilation2 = compilation1.WithSource(source2.Tree).WithOptions(options.WithCurrentLocalTime(new DateTime(2016, 1, 1, 1, 0, 20))); var compilation3 = compilation2.WithSource(source3.Tree).WithOptions(options.WithCurrentLocalTime(new DateTime(2016, 1, 1, 1, 0, 30))); var v0 = CompileAndVerify(compilation0, verify: Verification.Passes); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var reader0 = md0.MetadataReader; var m0 = compilation0.GetMember <MethodSymbol>("C.M"); var m1 = compilation1.GetMember <MethodSymbol>("C.M"); var m2 = compilation2.GetMember <MethodSymbol>("C.M"); var m3 = compilation3.GetMember <MethodSymbol>("C.M"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var f2 = compilation2.GetMember <MethodSymbol>("C.F"); var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); // First update adds some new synthesized members (lambda related) var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, m0, m1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); diff1.VerifySynthesizedMembers( "C: {<>c}", "C.<>c: {<>9__0_0, <>9__0_1#1, <M>b__0_0, <M>b__0_1#1}"); // Second update is to a method that doesn't produce any synthesized members var diff2 = compilation2.EmitDifference( diff1.NextGeneration, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, f1, f2, GetSyntaxMapFromMarkers(source1, source2), preserveLocalVariables: true))); diff2.VerifySynthesizedMembers( "C: {<>c}", "C.<>c: {<>9__0_0, <>9__0_1#1, <M>b__0_0, <M>b__0_1#1}"); // Last update again adds some new synthesized members (lambdas). // Synthesized members added in the first update need to be mapped to the current compilation. // Their containing assembly version is different than the version of the previous assembly and // hence we need to account for wildcards when comparing the versions. var diff3 = compilation3.EmitDifference( diff2.NextGeneration, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, m2, m3, GetSyntaxMapFromMarkers(source2, source3), preserveLocalVariables: true))); diff3.VerifySynthesizedMembers( "C: {<>c}", "C.<>c: {<>9__0_0, <>9__0_1#1, <>9__0_2#3, <>9__0_3#3, <M>b__0_0, <M>b__0_1#1, <M>b__0_2#3, <M>b__0_3#3}"); }
public void CompilationReferences_Less() { // Add some references that are actually not used in the source. // The only actual reference stored in the metadata image would be: mscorlib (rowid 1). // If we incorrectly assume the references are the same we will map TypeRefs of // Mscorlib to System.Windows.Forms. var references = new[] { SystemWindowsFormsRef, MscorlibRef, SystemCoreRef }; string src1 = @" using System; using System.Threading.Tasks; class C { public Task<int> F() { Console.WriteLine(123); return null; } public static void Main() { Console.WriteLine(1); } } "; string src2 = @" using System; using System.Threading.Tasks; class C { public Task<int> F() { Console.WriteLine(123); return null; } public static void Main() { Console.WriteLine(2); } } "; var c1 = CreateEmptyCompilation(src1, references); var c2 = c1.WithSource(src2); var md1 = AssemblyMetadata.CreateFromStream(c1.EmitToStream()); var baseline = EmitBaseline.CreateInitialBaseline(md1.GetModules()[0], handle => default(EditAndContinueMethodDebugInformation)); var mdStream = new MemoryStream(); var ilStream = new MemoryStream(); var pdbStream = new MemoryStream(); var updatedMethods = new List <MethodDefinitionHandle>(); var edits = new[] { SemanticEdit.Create( SemanticEditKind.Update, c1.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main"), c2.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main")) }; c2.EmitDifference(baseline, edits, mdStream, ilStream, pdbStream, updatedMethods); var actualIL = ImmutableArray.Create(ilStream.ToArray()).GetMethodIL(); var expectedIL = @" { // Code size 7 (0x7) .maxstack 8 IL_0000: ldc.i4.2 IL_0001: call 0x0A000006 IL_0006: ret }"; // If the references are mismatched then the symbol matcher won't be able to find Task<T> // and will recompile the method body of F (even though the method hasn't changed). AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL); }
public void DependencyVersionWildcards_Metadata() { string srcLib = @" [assembly: System.Reflection.AssemblyVersion(""1.0.*"")] public class D { } "; string src0 = @" class C { public static int F(D a) { return 1; } } "; string src1 = @" class C { public static int F(D a) { return 2; } } "; string src2 = @" class C { public static int F(D a) { return 3; } public static int G(D a) { return 4; } } "; var lib0 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); ((SourceAssemblySymbol)lib0.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", new Version(1, 0, 2000, 1001)); lib0.VerifyDiagnostics(); var lib1 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); ((SourceAssemblySymbol)lib1.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", new Version(1, 0, 2000, 1002)); lib1.VerifyDiagnostics(); var lib2 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); ((SourceAssemblySymbol)lib2.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", new Version(1, 0, 2000, 1003)); lib2.VerifyDiagnostics(); var compilation0 = CreateEmptyCompilation(src0, new[] { MscorlibRef, lib0.EmitToImageReference() }, assemblyName: "C", options: TestOptions.DebugDll); var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, lib1.EmitToImageReference() }); var compilation2 = compilation1.WithSource(src2).WithReferences(new[] { MscorlibRef, lib2.EmitToImageReference() }); var v0 = CompileAndVerify(compilation0); var v1 = CompileAndVerify(compilation1); var v2 = CompileAndVerify(compilation2); var f0 = compilation0.GetMember <MethodSymbol>("C.F"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var f2 = compilation2.GetMember <MethodSymbol>("C.F"); var g2 = compilation2.GetMember <MethodSymbol>("C.G"); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, f0, f1))); diff1.EmitResult.Diagnostics.Verify( // error CS7038: Failed to emit module 'C': Changing the version of an assembly reference is not allowed during debugging: // 'Lib, Version=1.0.2000.1001, Culture=neutral, PublicKeyToken=null' changed version to '1.0.2000.1002'. Diagnostic(ErrorCode.ERR_ModuleEmitFailure).WithArguments("C", string.Format(CodeAnalysisResources.ChangingVersionOfAssemblyReferenceIsNotAllowedDuringDebugging, "Lib, Version=1.0.2000.1001, Culture=neutral, PublicKeyToken=null", "1.0.2000.1002"))); }
private void TestDependencyVersionWildcards(string sourceVersion, Version version0, Version version1, Version version2) { string srcLib = $@" [assembly: System.Reflection.AssemblyVersion(""{sourceVersion}"")] public class D {{ }} "; string src0 = @" class C { public static int F(D a) { return 1; } } "; string src1 = @" class C { public static int F(D a) { return 2; } } "; string src2 = @" class C { public static int F(D a) { return 3; } public static int G(D a) { return 4; } } "; var lib0 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); ((SourceAssemblySymbol)lib0.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", version0); lib0.VerifyDiagnostics(); var lib1 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); ((SourceAssemblySymbol)lib1.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", version1); lib1.VerifyDiagnostics(); var lib2 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); ((SourceAssemblySymbol)lib2.Assembly).lazyAssemblyIdentity = new AssemblyIdentity("Lib", version2); lib2.VerifyDiagnostics(); var compilation0 = CreateEmptyCompilation(src0, new[] { MscorlibRef, lib0.ToMetadataReference() }, assemblyName: "C", options: TestOptions.DebugDll); var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, lib1.ToMetadataReference() }); var compilation2 = compilation1.WithSource(src2).WithReferences(new[] { MscorlibRef, lib2.ToMetadataReference() }); var v0 = CompileAndVerify(compilation0); var v1 = CompileAndVerify(compilation1); var v2 = CompileAndVerify(compilation2); var f0 = compilation0.GetMember <MethodSymbol>("C.F"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var f2 = compilation2.GetMember <MethodSymbol>("C.F"); var g2 = compilation2.GetMember <MethodSymbol>("C.G"); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, f0, f1))); var diff2 = compilation2.EmitDifference( diff1.NextGeneration, ImmutableArray.Create( SemanticEdit.Create(SemanticEditKind.Update, f1, f2), SemanticEdit.Create(SemanticEditKind.Insert, null, g2))); var md1 = diff1.GetMetadata(); var md2 = diff2.GetMetadata(); var aggReader = new AggregatedMetadataReader(md0.MetadataReader, md1.Reader, md2.Reader); // all references to Lib should be to the baseline version: VerifyAssemblyReferences(aggReader, new[] { "mscorlib, 4.0.0.0", "Lib, " + lib0.Assembly.Identity.Version, "mscorlib, 4.0.0.0", "Lib, " + lib0.Assembly.Identity.Version, "mscorlib, 4.0.0.0", "Lib, " + lib0.Assembly.Identity.Version, }); }
public void ChangingCompilationDependencies() { string srcLib = @" public class D { } "; string src0 = @" class C { public static int F(D a) { return 1; } } "; string src1 = @" class C { public static int F(D a) { return 2; } } "; string src2 = @" class C { public static int F(D a) { return 3; } } "; var lib0 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); lib0.VerifyDiagnostics(); var lib1 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); lib1.VerifyDiagnostics(); var lib2 = CreateCompilation(srcLib, assemblyName: "Lib", options: TestOptions.DebugDll); lib2.VerifyDiagnostics(); var compilation0 = CreateEmptyCompilation(src0, new[] { MscorlibRef, lib0.ToMetadataReference() }, assemblyName: "C", options: TestOptions.DebugDll); var compilation1 = compilation0.WithSource(src1).WithReferences(new[] { MscorlibRef, lib1.ToMetadataReference() }); var compilation2 = compilation1.WithSource(src2).WithReferences(new[] { MscorlibRef, lib2.ToMetadataReference() }); var v0 = CompileAndVerify(compilation0); var v1 = CompileAndVerify(compilation1); var v2 = CompileAndVerify(compilation2); var f0 = compilation0.GetMember <MethodSymbol>("C.F"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var f2 = compilation2.GetMember <MethodSymbol>("C.F"); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, f0, f1))); diff1.EmitResult.Diagnostics.Verify(); var diff2 = compilation2.EmitDifference( diff1.NextGeneration, ImmutableArray.Create( SemanticEdit.Create(SemanticEditKind.Update, f1, f2))); diff2.EmitResult.Diagnostics.Verify(); }
public void CompilationReferences_More() { string src1 = @" using System; class C { public static int F(object a) { return 1; } public static void Main() { Console.WriteLine(F(null)); } } "; string src2 = @" using System; class C { public static int F(object a) { return 1; } public static void Main() { F(null); } } "; // Let's say an IL rewriter inserts a new overload of F that references // a type in a new AssemblyRef. string srcPE = @" using System; class C { public static int F(System.Diagnostics.Process a) { return 2; } public static int F(object a) { return 1; } public static void Main() { F(null); } } "; var md1 = AssemblyMetadata.CreateFromStream(CreateEmptyCompilation(srcPE, new[] { MscorlibRef, SystemRef }).EmitToStream()); var c1 = CreateEmptyCompilation(src1, new[] { MscorlibRef }); var c2 = c1.WithSource(src2); var baseline = EmitBaseline.CreateInitialBaseline(md1.GetModules()[0], handle => default(EditAndContinueMethodDebugInformation)); var mdStream = new MemoryStream(); var ilStream = new MemoryStream(); var pdbStream = new MemoryStream(); var updatedMethods = new List <MethodDefinitionHandle>(); var edits = new[] { SemanticEdit.Create( SemanticEditKind.Update, c1.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main"), c2.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember("Main")) }; c2.EmitDifference(baseline, edits, mdStream, ilStream, pdbStream, updatedMethods); var actualIL = ImmutableArray.Create(ilStream.ToArray()).GetMethodIL(); // Symbol matcher should ignore overloads with missing type symbols and match // F(object). var expectedIL = @" { // Code size 8 (0x8) .maxstack 8 IL_0000: ldnull IL_0001: call 0x06000002 IL_0006: pop IL_0007: ret }"; AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL); }
public void MethodExtents(DebugInformationFormat format) { var source0 = MarkedSource( WithWindowsLineBreaks( @"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""1111111111111111111111111111111111111111"" using System; public class C { int A() => 1; void F() { #line 10 ""C:\F\A.cs"" Console.WriteLine(); #line 20 ""C:\F\B.cs"" Console.WriteLine(); #line default } int E() => 1; void G() { Func<int> <N:4>H1</N:4> = <N:0>() => 1</N:0>; Action <N:5>H2</N:5> = <N:1>() => { Func<int> <N:6>H3</N:6> = <N:2>() => 3</N:2>; }</N:1>; } } " ), fileName: @"C:\Enc1.cs" ); var source1 = MarkedSource( WithWindowsLineBreaks( @"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""2222222222222222222222222222222222222222"" using System; public class C { int A() => 1; void F() { #line 10 ""C:\F\A.cs"" Console.WriteLine(); #line 10 ""C:\F\C.cs"" Console.WriteLine(); #line default } void G() { Func<int> <N:4>H1</N:4> = <N:0>() => 1</N:0>; Action <N:5>H2</N:5> = <N:1>() => { Func<int> <N:6>H3</N:6> = <N:2>() => 3</N:2>; Func<int> <N:7>H4</N:7> = <N:3>() => 4</N:3>; }</N:1>; } int E() => 1; } " ), fileName: @"C:\Enc1.cs" ); var source2 = MarkedSource( WithWindowsLineBreaks( @"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""3333333333333333333333333333333333333333"" using System; public class C { int A() => 3; void F() { #line 10 ""C:\F\B.cs"" Console.WriteLine(); #line 10 ""C:\F\E.cs"" Console.WriteLine(); #line default } void G() { Action <N:5>H2</N:5> = <N:1>() => { Func<int> <N:7>H4</N:7> = <N:3>() => 4</N:3>; }</N:1>; } int E() => 1; int B() => 4; } " ), fileName: @"C:\Enc1.cs" ); var compilation0 = CreateCompilation( source0.Tree, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All), assemblyName: "EncMethodExtents" ); var compilation1 = compilation0.WithSource(source1.Tree); var compilation2 = compilation1.WithSource(source2.Tree); compilation0.VerifyDiagnostics(); compilation1.VerifyDiagnostics(); compilation2.VerifyDiagnostics(); var v0 = CompileAndVerify( compilation0, emitOptions: EmitOptions.Default.WithDebugInformationFormat(format) ); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var f0 = compilation0.GetMember <MethodSymbol>("C.F"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var f2 = compilation2.GetMember <MethodSymbol>("C.F"); var g0 = compilation0.GetMember <MethodSymbol>("C.G"); var g1 = compilation1.GetMember <MethodSymbol>("C.G"); var g2 = compilation2.GetMember <MethodSymbol>("C.G"); var a1 = compilation1.GetMember <MethodSymbol>("C.A"); var a2 = compilation2.GetMember <MethodSymbol>("C.A"); var b2 = compilation2.GetMember <MethodSymbol>("C.B"); var generation0 = EmitBaseline.CreateInitialBaseline( md0, v0.CreateSymReader().GetEncMethodDebugInfo ); var syntaxMap1 = GetSyntaxMapFromMarkers(source0, source1); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create( SemanticEdit.Create( SemanticEditKind.Update, f0, f1, syntaxMap1, preserveLocalVariables: true ), SemanticEdit.Create( SemanticEditKind.Update, g0, g1, syntaxMap1, preserveLocalVariables: true ) ) ); diff1.VerifySynthesizedMembers( "C: {<>c}", "C.<>c: {<>9__3_0, <>9__3_2, <>9__3_3#1, <>9__3_1, <G>b__3_0, <G>b__3_1, <G>b__3_2, <G>b__3_3#1}" ); var reader1 = diff1.GetMetadata().Reader; CheckEncLogDefinitions( reader1, Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default), Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), Row(5, TableIndex.Field, EditAndContinueOperation.Default), Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default) ); if (format == DebugInformationFormat.PortablePdb) { using var pdbProvider = MetadataReaderProvider.FromPortablePdbImage(diff1.PdbDelta); CheckEncMap( pdbProvider.GetMetadataReader(), Handle(2, TableIndex.MethodDebugInformation), Handle(4, TableIndex.MethodDebugInformation), Handle(8, TableIndex.MethodDebugInformation), Handle(9, TableIndex.MethodDebugInformation), Handle(10, TableIndex.MethodDebugInformation), Handle(11, TableIndex.MethodDebugInformation) ); } diff1.VerifyPdb( Enumerable.Range(0x06000001, 20), @" <symbols> <files> <file id=""1"" name=""C:\Enc1.cs"" language=""C#"" checksumAlgorithm=""SHA1"" checksum=""0B-95-CB-78-00-AE-C7-34-45-D9-FB-31-E4-30-A4-0E-FC-EA-9E-95"" /> <file id=""2"" name=""C:\F\A.cs"" language=""C#"" /> <file id=""3"" name=""C:\F\C.cs"" language=""C#"" /> </files> <methods> <method token=""0x6000002""> <customDebugInfo> <using> <namespace usingCount=""1"" /> </using> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""9"" startColumn=""5"" endLine=""9"" endColumn=""6"" document=""1"" /> <entry offset=""0x1"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""2"" /> <entry offset=""0x7"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""3"" /> <entry offset=""0xd"" startLine=""15"" startColumn=""5"" endLine=""15"" endColumn=""6"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0xe""> <namespace name=""System"" /> </scope> </method> <method token=""0x6000004""> <customDebugInfo> <forward token=""0x6000002"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""18"" startColumn=""5"" endLine=""18"" endColumn=""6"" document=""1"" /> <entry offset=""0x1"" startLine=""19"" startColumn=""9"" endLine=""19"" endColumn=""54"" document=""1"" /> <entry offset=""0x21"" startLine=""21"" startColumn=""9"" endLine=""25"" endColumn=""17"" document=""1"" /> <entry offset=""0x41"" startLine=""26"" startColumn=""5"" endLine=""26"" endColumn=""6"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0x42""> <local name=""H1"" il_index=""0"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" /> <local name=""H2"" il_index=""1"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" /> </scope> </method> <method token=""0x6000008""> <customDebugInfo> <forward token=""0x6000002"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""19"" startColumn=""46"" endLine=""19"" endColumn=""47"" document=""1"" /> </sequencePoints> </method> <method token=""0x6000009""> <customDebugInfo> <forward token=""0x6000002"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""22"" startColumn=""9"" endLine=""22"" endColumn=""10"" document=""1"" /> <entry offset=""0x1"" startLine=""23"" startColumn=""13"" endLine=""23"" endColumn=""58"" document=""1"" /> <entry offset=""0x21"" startLine=""24"" startColumn=""13"" endLine=""24"" endColumn=""58"" document=""1"" /> <entry offset=""0x41"" startLine=""25"" startColumn=""9"" endLine=""25"" endColumn=""10"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0x42""> <local name=""H3"" il_index=""0"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" /> <local name=""H4"" il_index=""1"" il_start=""0x0"" il_end=""0x42"" attributes=""0"" /> </scope> </method> <method token=""0x600000a""> <customDebugInfo> <forward token=""0x6000002"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""23"" startColumn=""50"" endLine=""23"" endColumn=""51"" document=""1"" /> </sequencePoints> </method> <method token=""0x600000b""> <customDebugInfo> <forward token=""0x6000002"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""24"" startColumn=""50"" endLine=""24"" endColumn=""51"" document=""1"" /> </sequencePoints> </method> </methods> </symbols> " ); var syntaxMap2 = GetSyntaxMapFromMarkers(source1, source2); var diff2 = compilation2.EmitDifference( diff1.NextGeneration, ImmutableArray.Create( SemanticEdit.Create( SemanticEditKind.Update, f1, f2, syntaxMap2, preserveLocalVariables: true ), SemanticEdit.Create( SemanticEditKind.Update, g1, g2, syntaxMap2, preserveLocalVariables: true ), SemanticEdit.Create( SemanticEditKind.Update, a1, a2, syntaxMap2, preserveLocalVariables: true ), SemanticEdit.Create(SemanticEditKind.Insert, null, b2) ) ); diff2.VerifySynthesizedMembers( "C: {<>c}", "C.<>c: {<>9__3_3#1, <>9__3_1, <G>b__3_1, <G>b__3_3#1, <>9__3_0, <>9__3_2, <G>b__3_0, <G>b__3_2}" ); var reader2 = diff2.GetMetadata().Reader; CheckEncLogDefinitions( reader2, Row(5, TableIndex.StandAloneSig, EditAndContinueOperation.Default), Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default), Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default), Row(2, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default) ); if (format == DebugInformationFormat.PortablePdb) { using var pdbProvider = MetadataReaderProvider.FromPortablePdbImage(diff2.PdbDelta); CheckEncMap( pdbProvider.GetMetadataReader(), Handle(1, TableIndex.MethodDebugInformation), Handle(2, TableIndex.MethodDebugInformation), Handle(4, TableIndex.MethodDebugInformation), Handle(9, TableIndex.MethodDebugInformation), Handle(11, TableIndex.MethodDebugInformation), Handle(12, TableIndex.MethodDebugInformation) ); } diff2.VerifyPdb( Enumerable.Range(0x06000001, 20), @" <symbols> <files> <file id=""1"" name=""C:\Enc1.cs"" language=""C#"" checksumAlgorithm=""SHA1"" checksum=""9C-B9-FF-18-0E-9F-A4-22-93-85-A8-5A-06-11-43-1E-64-3E-88-06"" /> <file id=""2"" name=""C:\F\B.cs"" language=""C#"" /> <file id=""3"" name=""C:\F\E.cs"" language=""C#"" /> </files> <methods> <method token=""0x6000001""> <customDebugInfo> <using> <namespace usingCount=""1"" /> </using> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""6"" startColumn=""16"" endLine=""6"" endColumn=""17"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0x2""> <namespace name=""System"" /> </scope> </method> <method token=""0x6000002""> <customDebugInfo> <forward token=""0x6000001"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""9"" startColumn=""5"" endLine=""9"" endColumn=""6"" document=""1"" /> <entry offset=""0x1"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""2"" /> <entry offset=""0x7"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""29"" document=""3"" /> <entry offset=""0xd"" startLine=""15"" startColumn=""5"" endLine=""15"" endColumn=""6"" document=""1"" /> </sequencePoints> </method> <method token=""0x6000004""> <customDebugInfo> <forward token=""0x6000001"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""18"" startColumn=""5"" endLine=""18"" endColumn=""6"" document=""1"" /> <entry offset=""0x1"" startLine=""21"" startColumn=""9"" endLine=""25"" endColumn=""17"" document=""1"" /> <entry offset=""0x21"" startLine=""26"" startColumn=""5"" endLine=""26"" endColumn=""6"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0x22""> <local name=""H2"" il_index=""1"" il_start=""0x0"" il_end=""0x22"" attributes=""0"" /> </scope> </method> <method token=""0x6000009""> <customDebugInfo> <forward token=""0x6000001"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""22"" startColumn=""9"" endLine=""22"" endColumn=""10"" document=""1"" /> <entry offset=""0x1"" startLine=""24"" startColumn=""13"" endLine=""24"" endColumn=""58"" document=""1"" /> <entry offset=""0x21"" startLine=""25"" startColumn=""9"" endLine=""25"" endColumn=""10"" document=""1"" /> </sequencePoints> <scope startOffset=""0x0"" endOffset=""0x22""> <local name=""H4"" il_index=""1"" il_start=""0x0"" il_end=""0x22"" attributes=""0"" /> </scope> </method> <method token=""0x600000b""> <customDebugInfo> <forward token=""0x6000001"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""24"" startColumn=""50"" endLine=""24"" endColumn=""51"" document=""1"" /> </sequencePoints> </method> <method token=""0x600000c""> <customDebugInfo> <forward token=""0x6000001"" /> </customDebugInfo> <sequencePoints> <entry offset=""0x0"" startLine=""30"" startColumn=""16"" endLine=""30"" endColumn=""17"" document=""1"" /> </sequencePoints> </method> </methods> </symbols> " ); }
public void TargetChanged1() { var source0 = @" class C<T> { static int Target0<G>() => 0; static int Target1<G>() => 1; System.Func<int> F() => Target0<T>; } "; var source1 = @" class C<T> { static int Target0<G>() => 0; static int Target1<G>() => 1; System.Func<int> F() => Target1<T>; } "; var compilation0 = CreateCompilation(source0); var compilation1 = compilation0.WithSource(source1); Assert.Equal(compilation0.LanguageVersion, compilation1.LanguageVersion); var f0 = compilation0.GetMember <MethodSymbol>("C.F"); var f1 = compilation1.GetMember <MethodSymbol>("C.F"); var v0 = CompileAndVerify(compilation0); using var moduleData0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var methodData0 = v0.TestData.GetMethodData("C<T>.F"); var generation0 = EmitBaseline.CreateInitialBaseline(moduleData0, methodData0.EncDebugInfoProvider()); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create( SemanticEdit.Create(SemanticEditKind.Update, f0, f1, preserveLocalVariables: true))); diff1.EmitResult.Diagnostics.Verify(); diff1.VerifyIL("C<T>.F", @" { // Code size 28 (0x1c) .maxstack 2 IL_0000: ldsfld ""System.Func<int> C<T>.<>O#1.<0>__Target1"" IL_0005: dup IL_0006: brtrue.s IL_001b IL_0008: pop IL_0009: ldnull IL_000a: ldftn ""int C<T>.Target1<T>()"" IL_0010: newobj ""System.Func<int>..ctor(object, System.IntPtr)"" IL_0015: dup IL_0016: stsfld ""System.Func<int> C<T>.<>O#1.<0>__Target1"" IL_001b: ret } "); var reader0 = moduleData0.MetadataReader; var reader1 = diff1.GetMetadata().Reader; CheckNames(reader0, reader0.GetTypeDefNames(), "<Module>", "C`1", "<>O"); CheckNames(new[] { reader0, reader1 }, reader1.GetTypeDefNames(), "<>O#1"); }