public unsafe void ShouldTryAgain_Mixed() { var comp1 = CreateCompilationWithMscorlib("public class C { }", assemblyName: GetUniqueName()); var comp2 = CreateCompilationWithMscorlib("public class D { }", assemblyName: GetUniqueName()); using (PinnedMetadata pinned1 = new PinnedMetadata(GetMetadataBytes(comp1)), pinned2 = new PinnedMetadata(GetMetadataBytes(comp2))) { var assemblyIdentity1 = comp1.Assembly.Identity; var assemblyIdentity2 = comp2.Assembly.Identity; Assert.NotEqual(assemblyIdentity1, assemblyIdentity2); DkmUtilities.GetMetadataBytesPtrFunction gmdbpf = (AssemblyIdentity assemblyIdentity, out uint uSize) => { if (assemblyIdentity == assemblyIdentity1) { uSize = (uint)pinned1.Size; return pinned1.Pointer; } else if (assemblyIdentity == assemblyIdentity2) { uSize = (uint)pinned2.Size; return pinned2.Pointer; } else { Marshal.ThrowExceptionForHR(unchecked((int)MetadataUtilities.CORDBG_E_MISSING_METADATA)); throw ExceptionUtilities.Unreachable; } }; var references = ImmutableArray.Create(default(MetadataBlock)); var unknownAssemblyIdentity = new AssemblyIdentity(GetUniqueName()); var missingAssemblyIdentities = ImmutableArray.Create(assemblyIdentity1, unknownAssemblyIdentity, assemblyIdentity2); Assert.True(ExpressionCompiler.ShouldTryAgainWithMoreMetadataBlocks(gmdbpf, missingAssemblyIdentities, ref references)); Assert.Equal(3, references.Length); Assert.Equal(default(MetadataBlock), references[0]); Assert.Equal(pinned1.Pointer, references[1].Pointer); Assert.Equal(pinned1.Size, references[1].Size); Assert.Equal(pinned2.Pointer, references[2].Pointer); Assert.Equal(pinned2.Size, references[2].Size); } }
public void ImportScopeEquality() { var sources = new[] { @" extern alias A; using System; using C = System; namespace N.M { using System.Collections; class C1 { void F() {} } } namespace N.M { using System.Collections; class C2 { void F() {} } } ", @" extern alias A; using System; using C = System; namespace N.M { using System.Collections; class C3 { void F() {} } } namespace N.M { using System.Collections.Generic; class C4 { void F() {} } } ", @" extern alias A; using System; using D = System; namespace N.M { using System.Collections; class C5 { void F() {} } } ", @" extern alias A; using System; class C6 { void F() {} } " }; var c = CreateCompilationWithMscorlib(sources, new[] { SystemCoreRef.WithAliases(ImmutableArray.Create("A")) }); var pdbStream = new MemoryStream(); c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream); var pdbImage = pdbStream.ToImmutable(); using (var metadata = new PinnedMetadata(pdbImage)) { var mdReader = metadata.Reader; var writer = new StringWriter(); var mdVisualizer = new MetadataVisualizer(mdReader, writer); mdVisualizer.WriteImportScope(); AssertEx.AssertEqualToleratingWhitespaceDifferences(@" ImportScope (index: 0x35, size: 36): ============================================================================================= Parent Imports ============================================================================================= 1: nil (ImportScope) 'A' (#1) = 0x23000002 (AssemblyRef) 2: 0x35000001 (ImportScope) Extern Alias 'A' (#1), 'System' (#7) 3: 0x35000001 (ImportScope) Extern Alias 'A' (#1), 'System' (#7), 'C' (#1d) = 'System' (#7) 4: 0x35000003 (ImportScope) nil 5: 0x35000004 (ImportScope) 'System.Collections' (#27) 6: 0x35000004 (ImportScope) 'System.Collections.Generic' (#4b) 7: 0x35000001 (ImportScope) Extern Alias 'A' (#1), 'System' (#7), 'D' (#69) = 'System' (#7) 8: 0x35000007 (ImportScope) nil 9: 0x35000008 (ImportScope) 'System.Collections' (#27) ", writer.ToString()); } }
public unsafe void ShouldTryAgain_Success() { var comp = CreateCompilationWithMscorlib("public class C { }"); using (var pinned = new PinnedMetadata(GetMetadataBytes(comp))) { DkmUtilities.GetMetadataBytesPtrFunction gmdbpf = (AssemblyIdentity assemblyIdentity, out uint uSize) => { uSize = (uint)pinned.Size; return pinned.Pointer; }; var references = ImmutableArray<MetadataBlock>.Empty; var missingAssemblyIdentity = new AssemblyIdentity("A"); var missingAssemblyIdentities = ImmutableArray.Create(missingAssemblyIdentity); Assert.True(ExpressionCompiler.ShouldTryAgainWithMoreMetadataBlocks(gmdbpf, missingAssemblyIdentities, ref references)); var newReference = references.Single(); Assert.Equal(pinned.Pointer, newReference.Pointer); Assert.Equal(pinned.Size, newReference.Size); } }
public void SequencePointBlob() { string source = @" class C { public static void Main() { if (F()) { System.Console.WriteLine(1); } } public static bool F() => false; } "; var c = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var pdbStream = new MemoryStream(); var peBlob = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream); using (var peReader = new PEReader(peBlob)) using (var pdbMetadata = new PinnedMetadata(pdbStream.ToImmutable())) { var mdReader = peReader.GetMetadataReader(); var pdbReader = pdbMetadata.Reader; foreach (var methodHandle in mdReader.MethodDefinitions) { var method = mdReader.GetMethodDefinition(methodHandle); var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodHandle); var name = mdReader.GetString(method.Name); TextWriter writer = new StringWriter(); foreach (var sp in methodDebugInfo.GetSequencePoints()) { if (sp.IsHidden) { writer.WriteLine($"{sp.Offset}: <hidden>"); } else { writer.WriteLine($"{sp.Offset}: ({sp.StartLine},{sp.StartColumn})-({sp.EndLine},{sp.EndColumn})"); } } var spString = writer.ToString(); var spBlob = pdbReader.GetBlobBytes(methodDebugInfo.SequencePointsBlob); switch (name) { case "Main": AssertEx.AssertEqualToleratingWhitespaceDifferences(@" 0: (5,5)-(5,6) 1: (6,9)-(6,17) 7: <hidden> 10: (7,9)-(7,10) 11: (8,13)-(8,41) 18: (9,9)-(9,10) 19: (10,5)-(10,6) ", spString); AssertEx.Equal(new byte[] { 0x01, // local signature 0x00, // IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x05, // Start Line 0x05, // Start Column 0x01, // delta IL offset 0x00, // Delta Lines 0x08, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x08, // delta Start Column (signed compressed) 0x06, // delta IL offset 0x00, // hidden 0x00, // hidden 0x03, // delta IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x00, // delta Start Column (signed compressed) 0x01, // delta IL offset 0x00, // Delta Lines 0x1C, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x08, // delta Start Column (signed compressed) 0x07, // delta IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x79, // delta Start Column (signed compressed) 0x01, // delta IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x79, // delta Start Column (signed compressed) }, spBlob); break; case "F": AssertEx.AssertEqualToleratingWhitespaceDifferences("0: (12,31)-(12,36)", spString); AssertEx.Equal(new byte[] { 0x00, // local signature 0x00, // delta IL offset 0x00, // Delta Lines 0x05, // Delta Columns 0x0C, // Start Line 0x1F // Start Column }, spBlob); break; } } } }