Browse Source

CSharp Code mappings and stepping

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
a5d912969c
  1. 5
      Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs
  2. 6
      Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs
  3. 9
      Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs
  4. 63
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  5. 32
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  6. 25
      ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs
  7. 19
      ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  8. 157
      ICSharpCode.Decompiler/CodeMappings.cs
  9. 124
      ICSharpCode.Decompiler/Disassembler/CodeMappings.cs
  10. 24
      ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs
  11. 40
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  12. 11
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  13. 4
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

5
Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
using ILSpy.Debugger.Services;
@ -35,9 +36,10 @@ namespace ILSpy.Debugger.Bookmarks @@ -35,9 +36,10 @@ namespace ILSpy.Debugger.Bookmarks
bool isHealthy = true;
bool isEnabled = true;
string tooltip;
BreakpointAction action = BreakpointAction.Break;
public DecompiledLanguages Laguage { get; private set; }
public BreakpointAction Action {
get {
return action;
@ -87,6 +89,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -87,6 +89,7 @@ namespace ILSpy.Debugger.Bookmarks
{
this.action = action;
this.tooltip = language.ToString();
this.Laguage = language;
}
public override ImageSource Image {

6
Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs

@ -3,12 +3,8 @@ @@ -3,12 +3,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ILSpy.Debugger.Bookmarks;
using ILSpy.Debugger.ToolTips;

9
Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs

@ -3,18 +3,11 @@ @@ -3,18 +3,11 @@
using System;
using System.Diagnostics;
using ICSharpCode.NRefactory;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
using Mono.CSharp;
namespace ILSpy.Debugger.Services
{
public enum DecompiledLanguages
{
IL,
CSharp
}
public interface IDebugger : IDisposable
{
/// <summary>

63
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
@ -9,6 +10,8 @@ using System.Windows.Media; @@ -9,6 +10,8 @@ using System.Windows.Media;
using Debugger;
using Debugger.Interop.CorPublish;
using Decompiler;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
@ -494,22 +497,24 @@ namespace ILSpy.Debugger.Services @@ -494,22 +497,24 @@ namespace ILSpy.Debugger.Services
{
Breakpoint breakpoint = null;
switch (Language) {
case DecompiledLanguages.IL:
uint token;
ILCodeMapping map = ILCodeMappings.GetInstructionByTypeAndLine(bookmark.TypeName, bookmark.LineNumber, out token);
if (map != null) {
breakpoint = new ILBreakpoint(debugger, bookmark.LineNumber, token, map.ILInstruction.Offset , bookmark.IsEnabled);
debugger.Breakpoints.Add(breakpoint);
}
break;
case DecompiledLanguages.CSharp:
break;
var storage = CodeMappings.GetStorage(Language);
if (Language == bookmark.Laguage) {
uint token;
SourceCodeMapping map =
storage.GetInstructionByTypeAndLine(
bookmark.TypeName, bookmark.LineNumber, out token);
if (map != null) {
breakpoint = new ILBreakpoint(
debugger,
bookmark.LineNumber,
token,
map.ILInstructionOffset.From,
bookmark.IsEnabled);
default:
throw new NotImplementedException("Not implemented!");
debugger.Breakpoints.Add(breakpoint);
}
}
if (breakpoint == null)
@ -741,25 +746,15 @@ namespace ILSpy.Debugger.Services @@ -741,25 +746,15 @@ namespace ILSpy.Debugger.Services
DebuggerService.RemoveCurrentLineMarker();
if (debuggedProcess != null && debuggedProcess.SelectedStackFrame != null) {
switch (Language) {
case DecompiledLanguages.IL:
// IL mapping
uint token = (uint)debuggedProcess.SelectedStackFrame.MethodInfo.MetadataToken;
int ilOffset = debuggedProcess.SelectedStackFrame.IP;
int line;
string typeName;
ILCodeMappings.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out typeName, out line);
if (typeName != null)
DebuggerService.JumpToCurrentLine(typeName, line, 0, line, 0);
break;
case DecompiledLanguages.CSharp:
// FIXME CSharp mappings
break;
default:
throw new NotImplementedException("The language is not supported!");
}
var storage = CodeMappings.GetStorage(Language);
uint token = (uint)debuggedProcess.SelectedStackFrame.MethodInfo.MetadataToken;
int ilOffset = debuggedProcess.SelectedStackFrame.IP;
int line;
string typeName;
storage.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out typeName, out line);
if (typeName != null)
DebuggerService.JumpToCurrentLine(typeName, line, 0, line, 0);
}
}

32
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -111,6 +111,14 @@ namespace Decompiler @@ -111,6 +111,14 @@ namespace Decompiler
public TypeDeclaration CreateType(TypeDefinition typeDef)
{
// create IL code mappings - used for debugger
if (!CSharpCodeMapping.SourceCodeMappings.ContainsKey(typeDef.FullName)) {
CSharpCodeMapping.SourceCodeMappings.Add(typeDef.FullName, new List<MethodMapping>());
} else {
CSharpCodeMapping.SourceCodeMappings[typeDef.FullName].Clear();
}
// create type
TypeDeclaration astType = new TypeDeclaration();
astType.AddAnnotation(typeDef);
astType.Modifiers = ConvertModifiers(typeDef);
@ -423,8 +431,12 @@ namespace Decompiler @@ -423,8 +431,12 @@ namespace Decompiler
MethodDeclaration CreateMethod(MethodDefinition methodDef)
{
// Create mapping - used in debugger
MethodMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
MethodDeclaration astMethod = new MethodDeclaration();
astMethod.AddAnnotation(methodDef);
astMethod.AddAnnotation(methodMapping);
astMethod.Name = methodDef.Name;
astMethod.ReturnType = ConvertType(methodDef.ReturnType, methodDef.MethodReturnType);
astMethod.Parameters.AddRange(MakeParameters(methodDef.Parameters));
@ -437,8 +449,12 @@ namespace Decompiler @@ -437,8 +449,12 @@ namespace Decompiler
ConstructorDeclaration CreateConstructor(MethodDefinition methodDef)
{
// Create mapping - used in debugger
MethodMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
ConstructorDeclaration astMethod = new ConstructorDeclaration();
astMethod.AddAnnotation(methodDef);
astMethod.AddAnnotation(methodMapping);
astMethod.Modifiers = ConvertModifiers(methodDef);
if (methodDef.IsStatic) {
// don't show visibility for static ctors
@ -457,14 +473,22 @@ namespace Decompiler @@ -457,14 +473,22 @@ namespace Decompiler
astProp.Name = propDef.Name;
astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
if (propDef.GetMethod != null) {
// Create mapping - used in debugger
MethodMapping methodMapping = propDef.GetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
astProp.Getter = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(propDef.GetMethod, context)
}.WithAnnotation(propDef.GetMethod);
astProp.Getter.AddAnnotation(methodMapping);
}
if (propDef.SetMethod != null) {
// Create mapping - used in debugger
MethodMapping methodMapping = propDef.SetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
astProp.Setter = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(propDef.SetMethod, context)
}.WithAnnotation(propDef.SetMethod);
astProp.Setter.AddAnnotation(methodMapping);
}
return astProp;
}
@ -477,14 +501,22 @@ namespace Decompiler @@ -477,14 +501,22 @@ namespace Decompiler
astEvent.ReturnType = ConvertType(eventDef.EventType, eventDef);
astEvent.Modifiers = ConvertModifiers(eventDef.AddMethod);
if (eventDef.AddMethod != null) {
// Create mapping - used in debugger
MethodMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
astEvent.AddAccessor = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(eventDef.AddMethod, context)
}.WithAnnotation(eventDef.AddMethod);
astEvent.AddAccessor.AddAnnotation(methodMapping);
}
if (eventDef.RemoveMethod != null) {
// Create mapping - used in debugger
MethodMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings);
astEvent.RemoveAccessor = new Accessor {
Body = AstMethodBodyBuilder.CreateMethodBody(eventDef.RemoveMethod, context)
}.WithAnnotation(eventDef.RemoveMethod);
astEvent.RemoveAccessor.AddAnnotation(methodMapping);
}
return astEvent;
}

25
ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.Decompiler;
namespace Decompiler
{
/// <summary>
/// Stores the C# code mappings.
/// </summary>
public static class CSharpCodeMapping
{
static Dictionary<string, List<MethodMapping>> codeMappings = new Dictionary<string, List<MethodMapping>>();
/// <summary>
/// Stores the source codes mappings: CSharp &lt;-&gt; editor lines
/// </summary>
public static Dictionary<string, List<MethodMapping>> SourceCodeMappings {
get { return codeMappings; }
set { codeMappings = value; }
}
}
}

19
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -121,6 +121,25 @@ namespace Decompiler @@ -121,6 +121,25 @@ namespace Decompiler
public void StartNode(AstNode node)
{
var ranges = node.Annotation<List<ILRange>>();
if (ranges != null)
{
// find the ancestor that has method mapping as annotation
if (node.Ancestors != null && node.Ancestors.Count() > 0)
{
var n = node.Ancestors.FirstOrDefault(a => a.Annotation<MethodMapping>() != null);
if (n != default(AstType)) {
MethodMapping mapping = n.Annotation<MethodMapping>();
foreach (var range in ranges) {
mapping.MethodCodeMappings.Add(new SourceCodeMapping {
ILInstructionOffset = range,
SourceCodeLine = output.CurrentLine
});
}
}
}
}
nodeStack.Push(node);
}

157
ICSharpCode.Decompiler/CodeMappings.cs

@ -0,0 +1,157 @@ @@ -0,0 +1,157 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
public enum DecompiledLanguages
{
IL,
CSharp
}
/// <summary>
/// Maps the source code to IL.
/// </summary>
public class SourceCodeMapping
{
public int SourceCodeLine { get; set; }
public ILRange ILInstructionOffset { get; set; }
}
/// <summary>
/// Stores the method information and its source code mappings.
/// </summary>
public sealed class MethodMapping
{
public string TypeName { get; set; }
public uint MetadataToken { get; set; }
public List<SourceCodeMapping> MethodCodeMappings { get; set; }
}
public static class CodeMappings
{
public static Dictionary<string, List<MethodMapping>> GetStorage(DecompiledLanguages language)
{
Dictionary<string, List<MethodMapping>> storage = null;
switch (language) {
case DecompiledLanguages.IL:
storage = ILCodeMapping.SourceCodeMappings;
break;
case DecompiledLanguages.CSharp:
storage = CSharpCodeMapping.SourceCodeMappings;
break;
default:
throw new System.Exception("Invalid value for DecompiledLanguages");
}
return storage;
}
/// <summary>
/// Create code mapping for a method.
/// </summary>
/// <param name="method">Method to create the mapping for.</param>
/// <param name="sourceCodeMappings">Source code mapping storage.</param>
public static MethodMapping CreateCodeMapping(
this MethodDefinition method,
Dictionary<string, List<MethodMapping>> sourceCodeMappings)
{
// create IL code mappings - used in debugger
MethodMapping currentMethodMapping = null;
if (sourceCodeMappings.ContainsKey(method.DeclaringType.FullName)) {
var mapping = sourceCodeMappings[method.DeclaringType.FullName];
if (mapping.Find(map => (int)map.MetadataToken == method.MetadataToken.ToInt32()) == null) {
currentMethodMapping = new MethodMapping() {
MetadataToken = (uint)method.MetadataToken.ToInt32(),
TypeName = method.DeclaringType.FullName,
MethodCodeMappings = new List<SourceCodeMapping>()
};
mapping.Add(currentMethodMapping);
}
}
return currentMethodMapping;
}
/// <summary>
/// Gets source code mapping and metadata token based on type name and line number.
/// </summary>
/// <param name="codeMappings">Code mappings storage.</param>
/// <param name="typeName">Type name.</param>
/// <param name="lineNumber">Line number.</param>
/// <param name="metadataToken">Metadata token.</param>
/// <returns></returns>
public static SourceCodeMapping GetInstructionByTypeAndLine(
this Dictionary<string, List<MethodMapping>> codeMappings,
string typeName,
int lineNumber,
out uint metadataToken)
{
if (!codeMappings.ContainsKey(typeName)) {
metadataToken = 0;
return null;
}
if (lineNumber <= 0) {
metadataToken = 0;
return null;
}
var methodMappings = codeMappings[typeName];
foreach (var maping in methodMappings) {
var map = maping.MethodCodeMappings.Find(m => m.SourceCodeLine == lineNumber);
if (map != null) {
metadataToken = maping.MetadataToken;
return map;
}
}
metadataToken = 0;
return null;
}
/// <summary>
/// Gets the source code and type name from metadata token and offset.
/// </summary>
/// <param name="codeMappings">Code mappings storage.</param>
/// <param name="token">Metadata token.</param>
/// <param name="ilOffset">IL offset.</param>
/// <param name="typeName">Type name.</param>
/// <param name="line">Line number.</param>
public static void GetSourceCodeFromMetadataTokenAndOffset(
this Dictionary<string, List<MethodMapping>> codeMappings,
uint token,
int ilOffset,
out string typeName,
out int line)
{
typeName = null;
line = 0;
foreach (var typename in codeMappings.Keys) {
var mapping = codeMappings[typename].Find(m => m.MetadataToken == token);
if (mapping == null)
continue;
var codeMapping = mapping.MethodCodeMappings.Find(
cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To);
if (codeMapping == null)
continue;
typeName = typename;
line = codeMapping.SourceCodeLine;
break;
}
}
}
}

124
ICSharpCode.Decompiler/Disassembler/CodeMappings.cs

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using Mono.Cecil.Cil;
namespace ICSharpCode.Decompiler.Disassembler
{
public class ILCodeMapping
{
public int SourceCodeLine { get; set; }
public Instruction ILInstruction { get; set; }
}
public class MethodMapping
{
public string TypeName { get; set; }
public uint MetadataToken { get; set; }
public List<ILCodeMapping> MethodCodeMappings { get; set; }
/// <summary>
/// Finds the IL instruction given a source code line number.
/// </summary>
/// <param name="sourceCodeLine">Source code line number.</param>
/// <returns>IL Instruction or null, if the instruction was not found.</returns>
public Instruction FindByLine(int sourceCodeLine)
{
if (sourceCodeLine <= 0)
throw new ArgumentException("The source line must be greater thatn 0.");
if (MethodCodeMappings == null || MethodCodeMappings.Count == 0)
return null;
foreach (var codeMapping in MethodCodeMappings) {
if (codeMapping.SourceCodeLine == sourceCodeLine)
return codeMapping.ILInstruction;
}
return null;
}
/// <summary>
/// Finds the source code line given an IL instruction offset.
/// </summary>
/// <param name="instruction">IL Instruction offset.</param>
/// <returns>Source code line, if it is found, -1 otherwise.</returns>
public int FindByInstruction(int instructionOffset)
{
if (instructionOffset <= 0)
throw new ArgumentNullException("The instruction offset cannot be lower than 0.");
if (MethodCodeMappings == null || MethodCodeMappings.Count == 0)
return -1;
foreach (var codeMapping in MethodCodeMappings) {
if (codeMapping.ILInstruction.Offset == instructionOffset)
return codeMapping.SourceCodeLine;
}
return -1;
}
}
public static class ILCodeMappings
{
static Dictionary<string, List<MethodMapping>> ilCodeMappings = new Dictionary<string, List<MethodMapping>>();
/// <summary>
/// Stores the source codes mappings: IL &lt;-&gt; editor lines
/// </summary>
public static Dictionary<string, List<MethodMapping>> ILSourceCodeMappings {
get { return ilCodeMappings; }
set { ilCodeMappings = value; }
}
public static ILCodeMapping GetInstructionByTypeAndLine(string typeName, int lineNumber, out uint metadataToken)
{
if (!ilCodeMappings.ContainsKey(typeName)) {
metadataToken = 0;
return null;
}
if (lineNumber <= 0) {
metadataToken = 0;
return null;
}
var methodMappings = ilCodeMappings[typeName];
foreach (var maping in methodMappings) {
var ilMap = maping.MethodCodeMappings.Find(m => m.SourceCodeLine == lineNumber);
if (ilMap != null) {
metadataToken = maping.MetadataToken;
return ilMap;
}
}
metadataToken = 0;
return null;
}
public static void GetSourceCodeFromMetadataTokenAndOffset(uint token, int ilOffset, out string typeName, out int line)
{
typeName = null;
line = 0;
foreach (var typename in ilCodeMappings.Keys) {
var mapping = ilCodeMappings[typename].Find(m => m.MetadataToken == token);
if (mapping == null)
continue;
var ilCodeMapping = mapping.MethodCodeMappings.Find(cm => cm.ILInstruction.Offset == ilOffset);
if (ilCodeMapping == null)
continue;
typeName = typename;
line = ilCodeMapping.SourceCodeLine;
break;
}
}
}
}

24
ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Disassembler
{
/// <summary>
/// Stores the IL code mappings.
/// </summary>
public static class ILCodeMapping
{
static Dictionary<string, List<MethodMapping>> codeMappings = new Dictionary<string, List<MethodMapping>>();
/// <summary>
/// Stores the source codes mappings: IL &lt;-&gt; editor lines
/// </summary>
public static Dictionary<string, List<MethodMapping>> SourceCodeMappings {
get { return codeMappings; }
set { codeMappings = value; }
}
}
}

40
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -20,6 +20,8 @@ using System; @@ -20,6 +20,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Decompiler;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.FlowAnalysis;
using Mono.Cecil;
@ -47,20 +49,10 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -47,20 +49,10 @@ namespace ICSharpCode.Decompiler.Disassembler
public void Disassemble(MethodBody body)
{
// create mappings
MethodMapping currentMethodMapping = null;
if (ILCodeMappings.ILSourceCodeMappings.ContainsKey(body.Method.DeclaringType.FullName)) {
var mapping = ILCodeMappings.ILSourceCodeMappings[body.Method.DeclaringType.FullName];
if (mapping.Find(map => (int)map.MetadataToken == body.Method.MetadataToken.ToInt32()) == null) {
currentMethodMapping = new MethodMapping() {
MetadataToken = (uint)body.Method.MetadataToken.ToInt32(),
TypeName = body.Method.DeclaringType.FullName,
MethodCodeMappings = new List<ILCodeMapping>()
};
mapping.Add(currentMethodMapping);
}
}
// create IL code mappings - used in debugger
MethodMapping methodMapping = body.Method.CreateCodeMapping(ILCodeMapping.SourceCodeMappings);
// start writing IL code
MethodDefinition method = body.Method;
output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
@ -88,14 +80,15 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -88,14 +80,15 @@ namespace ICSharpCode.Decompiler.Disassembler
if (detectControlStructure && body.Instructions.Count > 0) {
Instruction inst = body.Instructions[0];
WriteStructureBody(new ILStructure(body), ref inst, currentMethodMapping);
WriteStructureBody(new ILStructure(body), ref inst, methodMapping);
} else {
foreach (var inst in method.Body.Instructions) {
// add IL code mappings
currentMethodMapping.MethodCodeMappings.Add(new ILCodeMapping() {
SourceCodeLine = output.CurrentLine,
ILInstruction = inst
});
methodMapping.MethodCodeMappings.Add(
new SourceCodeMapping() {
SourceCodeLine = output.CurrentLine,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Offset }
});
inst.WriteTo(output);
output.WriteLine();
@ -157,12 +150,13 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -157,12 +150,13 @@ namespace ICSharpCode.Decompiler.Disassembler
{
int childIndex = 0;
while (inst != null && inst.Offset < s.EndOffset) {
// add IL code mappings
// add IL code mappings - used in debugger
if (currentMethodMapping != null) {
currentMethodMapping.MethodCodeMappings.Add(new ILCodeMapping() {
SourceCodeLine = output.CurrentLine,
ILInstruction = inst
});
currentMethodMapping.MethodCodeMappings.Add(
new SourceCodeMapping() {
SourceCodeLine = output.CurrentLine,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Offset }
});
}
int offset = inst.Offset;

11
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -101,11 +101,6 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -101,11 +101,6 @@ namespace ICSharpCode.Decompiler.Disassembler
void DisassembleMethodInternal(MethodDefinition method)
{
// create mappings for types that were not disassebled
if (!ILCodeMappings.ILSourceCodeMappings.ContainsKey(method.DeclaringType.FullName)) {
ILCodeMappings.ILSourceCodeMappings.Add(method.DeclaringType.FullName, new List<MethodMapping>());
}
// .method public hidebysig specialname
// instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed
//
@ -317,6 +312,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -317,6 +312,12 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleType(TypeDefinition type)
{
// create IL code mappings - used for debugger
if (!ILCodeMapping.SourceCodeMappings.ContainsKey(type.FullName)) {
ILCodeMapping.SourceCodeMappings.Add(type.FullName, new List<MethodMapping>());
}
// start writing IL
output.WriteDefinition(".class ", type);
if ((type.Attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface)

4
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -51,6 +51,7 @@ @@ -51,6 +51,7 @@
<ItemGroup>
<Compile Include="Ast\AstBuilder.cs" />
<Compile Include="Ast\AstMethodBodyBuilder.cs" />
<Compile Include="Ast\CSharpCodeMapping.cs" />
<Compile Include="Ast\CommentStatement.cs" />
<Compile Include="Ast\DecompilerContext.cs" />
<Compile Include="Ast\NameVariables.cs" />
@ -67,8 +68,9 @@ @@ -67,8 +68,9 @@
<Compile Include="Ast\Transforms\RestoreLoop.cs" />
<Compile Include="Ast\Transforms\TransformationPipeline.cs" />
<Compile Include="CecilExtensions.cs" />
<Compile Include="CodeMappings.cs" />
<Compile Include="DecompilerException.cs" />
<Compile Include="Disassembler\CodeMappings.cs" />
<Compile Include="Disassembler\ILCodeMapping.cs" />
<Compile Include="Disassembler\DisassemblerHelpers.cs" />
<Compile Include="Disassembler\ILStructure.cs" />
<Compile Include="Disassembler\MethodBodyDisassembler.cs" />

Loading…
Cancel
Save