public void TestGenericNameFormatting() { MetadataType testClass = _testModule.GetType("ILDisassembler", "TestGenericClass`1"); EcmaMethod testMethod = (EcmaMethod)testClass.GetMethod("TestMethod", null); EcmaMethodIL methodIL = EcmaMethodIL.Create(testMethod); Dictionary <int, string> interestingLines = new Dictionary <int, string> { { 4, "IL_0003: ldstr \"Hello \\\"World\\\"!\\n\"" }, { 9, "IL_000D: call instance void class ILDisassembler.TestGenericClass`1<!TClassParam>::VoidGenericMethod<string, valuetype ILDisassembler.TestStruct>(!!0, int32, native int, class ILDisassembler.TestClass&)" }, { 14, "IL_0017: initobj !TClassParam" }, { 16, "IL_001E: call !!0 class ILDisassembler.TestGenericClass`1<!TClassParam>::MethodParamGenericMethod<class ILDisassembler.TestClass>(class ILDisassembler.TestGenericClass`1<!!0>, class ILDisassembler.TestGenericClass`1/Nested<!0>, valuetype ILDisassembler.TestStruct*[], !0)" }, { 24, "IL_0030: call !!0 class ILDisassembler.TestGenericClass`1<!TClassParam>::MethodParamGenericMethod<!0>(class ILDisassembler.TestGenericClass`1<!!0>, class ILDisassembler.TestGenericClass`1/Nested<!0>, valuetype ILDisassembler.TestStruct*[], !0)" }, { 26, "IL_0036: ldtoken !TClassParam" }, { 28, "IL_003C: ldtoken valuetype [CoreTestAssembly]System.Nullable`1<int32>" }, { 31, "IL_0043: ldc.r8 3.14" }, { 32, "IL_004C: ldc.r4 1.68" }, { 34, "IL_0053: call instance valuetype ILDisassembler.TestStruct class ILDisassembler.TestGenericClass`1<!TClassParam>::NonGenericMethod(float64, float32, int16)" }, { 37, "IL_005A: ldflda !0 class ILDisassembler.TestGenericClass`1<!TClassParam>::somefield" }, { 41, "IL_0067: stfld class ILDisassembler.TestClass class ILDisassembler.TestGenericClass`1<!TClassParam>::otherfield" }, { 44, "IL_006E: stfld class ILDisassembler.TestGenericClass`1<class ILDisassembler.TestGenericClass`1<class ILDisassembler.TestClass>> class ILDisassembler.TestGenericClass`1<!TClassParam>::genericfield" }, { 47, "IL_0075: stfld !0[] class ILDisassembler.TestGenericClass`1<!TClassParam>::arrayfield" }, { 48, "IL_007A: call void ILDisassembler.TestClass::NonGenericMethod()" }, { 49, "IL_007F: ldsflda valuetype ILDisassembler.TestStruct ILDisassembler.TestClass::somefield" }, { 50, "IL_0084: initobj ILDisassembler.TestStruct" } }; ILDisassember disasm = new ILDisassember(methodIL); int numLines = 1; while (disasm.HasNextInstruction) { string line = disasm.GetNextInstruction(); string expectedLine; if (interestingLines.TryGetValue(numLines, out expectedLine)) { Assert.Equal(expectedLine, line); } numLines++; } Assert.Equal(52, numLines); }
private MethodDebugInformation GetDebugInformation(MethodIL methodIL) { MethodDesc owningMethod = methodIL.OwningMethod; var disasm = new ILDisassember(methodIL); var fmt = new ILDisassember.ILTypeNameFormatter(null); ArrayBuilder <ILSequencePoint> sequencePoints = new ArrayBuilder <ILSequencePoint>(); _tw.Write(".method "); // TODO: accessibility, specialname, calling conventions etc. if (!owningMethod.Signature.IsStatic) { _tw.Write("instance "); } _tw.Write(fmt.FormatName(owningMethod.Signature.ReturnType)); _tw.Write(" "); _tw.Write(owningMethod.Name); if (owningMethod.HasInstantiation) { _tw.Write("<"); for (int i = 0; i < owningMethod.Instantiation.Length; i++) { if (i != 0) { _tw.Write(", "); } _tw.Write(fmt.FormatName(owningMethod.Instantiation[i])); } _tw.Write(">"); } _tw.Write("("); for (int i = 0; i < owningMethod.Signature.Length; i++) { if (i != 0) { _tw.Write(", "); } _tw.Write(fmt.FormatName(owningMethod.Signature[i])); } _tw.WriteLine(") cil managed"); _currentLine++; _tw.WriteLine("{"); _currentLine++; _tw.Write(" // Code size: "); _tw.Write(disasm.CodeSize); _tw.WriteLine(); _currentLine++; _tw.Write(" .maxstack "); _tw.Write(methodIL.MaxStack); _tw.WriteLine(); _currentLine++; LocalVariableDefinition[] locals = methodIL.GetLocals(); if (locals != null && locals.Length > 0) { _tw.Write(" .locals "); if (methodIL.IsInitLocals) { _tw.Write("init "); } _tw.Write("("); for (int i = 0; i < locals.Length; i++) { if (i != 0) { _tw.WriteLine(","); _currentLine++; _tw.Write(" "); } _tw.Write(fmt.FormatName(locals[i].Type)); _tw.Write(" "); if (locals[i].IsPinned) { _tw.Write("pinned "); } _tw.Write("V_"); _tw.Write(i); } _tw.WriteLine(")"); _currentLine++; } _tw.WriteLine(); _currentLine++; while (disasm.HasNextInstruction) { _currentLine++; int offset = disasm.Offset; _tw.WriteLine(disasm.GetNextInstruction()); sequencePoints.Add(new ILSequencePoint(offset, _fileName, _currentLine)); } _tw.WriteLine("}"); _currentLine++; _tw.WriteLine(); _currentLine++; return(new SyntheticMethodDebugInformation(sequencePoints.ToArray())); }