Browse Source

Remove the dictionary storage; Code mappings are found in CodeMappings property in AstBuilder or ReflectionDisassembler.

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
617236b31d
  1. 2
      Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs
  2. 12
      Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs
  3. 10
      Debugger/ILSpy.Debugger/DebuggedData.cs
  4. 28
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  5. 26
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  6. 27
      ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs
  7. 70
      ICSharpCode.Decompiler/CodeMappings.cs
  8. 25
      ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs
  9. 5
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  10. 21
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  11. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  12. 8
      ILSpy.sln
  13. 4
      ILSpy/CSharpLanguage.cs
  14. 6
      ILSpy/ILLanguage.cs

2
Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs

@ -231,7 +231,7 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
if (DebugData.CurrentMemberReference != null) { if (DebugData.CurrentMemberReference != null) {
// check if the codemappings exists for this line // check if the codemappings exists for this line
var storage = CodeMappings.GetStorage(DebugData.Language); var storage = DebugData.CodeMappings;
uint token; uint token;
var instruction = storage.GetInstructionByTypeAndLine(DebugData.CurrentMemberReference.FullName, line, out token); var instruction = storage.GetInstructionByTypeAndLine(DebugData.CurrentMemberReference.FullName, line, out token);

12
Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs

@ -142,10 +142,10 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
if (CurrentLineBookmark.Instance == null) if (CurrentLineBookmark.Instance == null)
return; return;
var oldMappings = CodeMappings.GetStorage(oldLanguage); var oldMappings = DebugData.OldCodeMappings;
var newMappings = CodeMappings.GetStorage(newLanguage); var newMappings = DebugData.CodeMappings;
if (oldMappings == null || oldMappings.Count == 0 || newMappings == null || newMappings.Count == 0) if (oldMappings == null || newMappings == null)
return; return;
// 1. Save it's data // 1. Save it's data
@ -177,10 +177,10 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
static void SyncBreakpointBookmarks(DecompiledLanguages oldLanguage, DecompiledLanguages newLanguage) static void SyncBreakpointBookmarks(DecompiledLanguages oldLanguage, DecompiledLanguages newLanguage)
{ {
// checks // checks
var oldMappings = CodeMappings.GetStorage(oldLanguage); var oldMappings = DebugData.OldCodeMappings;
var newMappings = CodeMappings.GetStorage(newLanguage); var newMappings = DebugData.CodeMappings;
if (oldMappings == null || oldMappings.Count == 0 || newMappings == null || newMappings.Count == 0) if (oldMappings == null || newMappings == null)
return; return;
// 1. map the breakpoint lines // 1. map the breakpoint lines

10
Debugger/ILSpy.Debugger/DebuggedData.cs

@ -48,6 +48,16 @@ namespace ICSharpCode.ILSpy.Debugger
} }
} }
/// <summary>
/// Gets or sets the current code mappings.
/// </summary>
public static Tuple<string, List<MemberMapping>> CodeMappings { get; set; }
/// <summary>
/// Gets or sets the old code mappings.
/// </summary>
public static Tuple<string, List<MemberMapping>> OldCodeMappings { get; set; }
/// <summary> /// <summary>
/// Occures when the language is changed. /// Occures when the language is changed.
/// </summary> /// </summary>

28
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -51,12 +51,6 @@ namespace ICSharpCode.ILSpy.Debugger.Services
//DynamicTreeDebuggerRow currentTooltipRow; //DynamicTreeDebuggerRow currentTooltipRow;
//Expression currentTooltipExpression; //Expression currentTooltipExpression;
private ConcurrentDictionary<string, List<MemberMapping>> CodeMappingsStorage {
get {
return CodeMappings.GetStorage(DebugData.Language);
}
}
public event EventHandler<ProcessEventArgs> ProcessSelected; public event EventHandler<ProcessEventArgs> ProcessSelected;
public NDebugger DebuggerCore { public NDebugger DebuggerCore {
@ -296,7 +290,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
frame = debuggedProcess.SelectedThread.MostRecentStackFrame; frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
// get the mapped instruction from the current line marker or the next one // get the mapped instruction from the current line marker or the next one
return CodeMappingsStorage.GetInstructionByTypeTokenAndOffset( return DebugData.CodeMappings.GetInstructionByTypeTokenAndOffset(
((DebugType)frame.MethodInfo.DeclaringType).FullNameWithoutGenericArguments, ((DebugType)frame.MethodInfo.DeclaringType).FullNameWithoutGenericArguments,
(uint)frame.MethodInfo.MetadataToken, (uint)frame.MethodInfo.MetadataToken,
frame.IP, out isMatch); frame.IP, out isMatch);
@ -566,8 +560,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
Breakpoint breakpoint = null; Breakpoint breakpoint = null;
uint token; uint token;
SourceCodeMapping map = CodeMappings SourceCodeMapping map = DebugData.CodeMappings
.GetStorage(bookmark.Language)
.GetInstructionByTypeAndLine(bookmark.Member.FullName, bookmark.LineNumber, out token); .GetInstructionByTypeAndLine(bookmark.Member.FullName, bookmark.LineNumber, out token);
if (map != null) { if (map != null) {
@ -821,11 +814,12 @@ namespace ICSharpCode.ILSpy.Debugger.Services
return; return;
uint token = (uint)frame.MethodInfo.MetadataToken; uint token = (uint)frame.MethodInfo.MetadataToken;
var debugType = (DebugType)frame.MethodInfo.DeclaringType;
int ilOffset = frame.IP; int ilOffset = frame.IP;
int line; int line;
MemberReference memberReference; MemberReference memberReference;
if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset(frame.MethodInfo.DeclaringType.FullName, token, ilOffset, out memberReference, out line) if (DebugData.CodeMappings.GetSourceCodeFromMetadataTokenAndOffset(debugType.FullNameWithoutGenericArguments, token, ilOffset, out memberReference, out line)
&& memberReference.DeclaringType == null) { && memberReference.DeclaringType == null) {
DebuggerService.RemoveCurrentLineMarker(); DebuggerService.RemoveCurrentLineMarker();
DebuggerService.JumpToCurrentLine(memberReference, line, 0, line, 0); DebuggerService.JumpToCurrentLine(memberReference, line, 0, line, 0);
@ -873,22 +867,26 @@ namespace ICSharpCode.ILSpy.Debugger.Services
} }
if (typeDef != null) { if (typeDef != null) {
// decompile on demand // decompile on demand
if (!CodeMappingsStorage.ContainsKey(typeDef.FullName)) { Tuple<string, List<MemberMapping>> codeMappings = null;
if (DebugData.CodeMappings.Item1 != (nestedTypeDef ?? typeDef).FullName) {
if (DebugData.Language == DecompiledLanguages.IL) { if (DebugData.Language == DecompiledLanguages.IL) {
var dis = new ReflectionDisassembler(new PlainTextOutput(), true, CancellationToken.None); var dis = new ReflectionDisassembler(new PlainTextOutput(), true, CancellationToken.None);
dis.DisassembleType(typeDef); dis.DisassembleType(nestedTypeDef ?? typeDef);
codeMappings = dis.CodeMappings;
} else { } else {
AstBuilder builder = new AstBuilder(new DecompilerContext(typeDef.Module)); AstBuilder builder = new AstBuilder(new DecompilerContext(typeDef.Module));
builder.AddType(typeDef); builder.AddType(nestedTypeDef ?? typeDef);
builder.GenerateCode(new PlainTextOutput()); builder.GenerateCode(new PlainTextOutput());
codeMappings = builder.CodeMappings;
} }
} }
// try jump // try jump
int line; int line;
MemberReference memberReference; MemberReference memberReference;
if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset((nestedTypeDef ?? typeDef).FullName, token, ilOffset, out memberReference, out line)) { codeMappings = codeMappings ?? DebugData.CodeMappings;
if (codeMappings.GetSourceCodeFromMetadataTokenAndOffset((nestedTypeDef ?? typeDef).FullName, token, ilOffset, out memberReference, out line)) {
DebuggerService.RemoveCurrentLineMarker(); DebuggerService.RemoveCurrentLineMarker();
DebuggerService.JumpToCurrentLine(typeDef, line, 0, line, 0); DebuggerService.JumpToCurrentLine(nestedTypeDef ?? typeDef, line, 0, line, 0);
} else { } else {
StepOut(); StepOut();
} }

26
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.Ast
IncludeTypeParameterDefinitions = 2 IncludeTypeParameterDefinitions = 2
} }
public class AstBuilder public class AstBuilder : ICodeMappings
{ {
DecompilerContext context; DecompilerContext context;
CompilationUnit astCompileUnit = new CompilationUnit(); CompilationUnit astCompileUnit = new CompilationUnit();
@ -193,11 +193,8 @@ namespace ICSharpCode.Decompiler.Ast
public AttributedNode CreateType(TypeDefinition typeDef) public AttributedNode CreateType(TypeDefinition typeDef)
{ {
// create CSharp code mappings - used for debugger // create CSharp code mappings - used for debugger
if (!CSharpCodeMapping.SourceCodeMappings.ContainsKey(typeDef.FullName)) { if (this.CodeMappings == null)
CSharpCodeMapping.SourceCodeMappings.TryAdd(typeDef.FullName, new List<MemberMapping>()); this.CodeMappings = new Tuple<string, List<MemberMapping>>(typeDef.FullName, new List<MemberMapping>());
} else {
CSharpCodeMapping.SourceCodeMappings[typeDef.FullName].Clear();
}
// create type // create type
TypeDefinition oldCurrentType = context.CurrentType; TypeDefinition oldCurrentType = context.CurrentType;
@ -623,7 +620,7 @@ namespace ICSharpCode.Decompiler.Ast
AttributedNode CreateMethod(MethodDefinition methodDef) AttributedNode CreateMethod(MethodDefinition methodDef)
{ {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings);
MethodDeclaration astMethod = new MethodDeclaration(); MethodDeclaration astMethod = new MethodDeclaration();
astMethod.AddAnnotation(methodDef); astMethod.AddAnnotation(methodDef);
@ -712,7 +709,7 @@ namespace ICSharpCode.Decompiler.Ast
ConstructorDeclaration CreateConstructor(MethodDefinition methodDef) ConstructorDeclaration CreateConstructor(MethodDefinition methodDef)
{ {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings);
ConstructorDeclaration astMethod = new ConstructorDeclaration(); ConstructorDeclaration astMethod = new ConstructorDeclaration();
astMethod.AddAnnotation(methodDef); astMethod.AddAnnotation(methodDef);
@ -772,7 +769,7 @@ namespace ICSharpCode.Decompiler.Ast
astProp.ReturnType = ConvertType(propDef.PropertyType, propDef); astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
if (propDef.GetMethod != null) { if (propDef.GetMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = propDef.GetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = propDef.GetMethod.CreateCodeMapping(this.CodeMappings);
astProp.Getter = new Accessor(); astProp.Getter = new Accessor();
astProp.Getter.Body = CreateMethodBody(propDef.GetMethod); astProp.Getter.Body = CreateMethodBody(propDef.GetMethod);
@ -786,7 +783,7 @@ namespace ICSharpCode.Decompiler.Ast
} }
if (propDef.SetMethod != null) { if (propDef.SetMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = propDef.SetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = propDef.SetMethod.CreateCodeMapping(this.CodeMappings);
astProp.Setter = new Accessor(); astProp.Setter = new Accessor();
astProp.Setter.Body = CreateMethodBody(propDef.SetMethod); astProp.Setter.Body = CreateMethodBody(propDef.SetMethod);
@ -846,7 +843,7 @@ namespace ICSharpCode.Decompiler.Ast
astEvent.PrivateImplementationType = ConvertType(eventDef.AddMethod.Overrides.First().DeclaringType); astEvent.PrivateImplementationType = ConvertType(eventDef.AddMethod.Overrides.First().DeclaringType);
if (eventDef.AddMethod != null) { if (eventDef.AddMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(this.CodeMappings);
astEvent.AddAccessor = new Accessor { astEvent.AddAccessor = new Accessor {
Body = CreateMethodBody(eventDef.AddMethod) Body = CreateMethodBody(eventDef.AddMethod)
@ -857,7 +854,7 @@ namespace ICSharpCode.Decompiler.Ast
} }
if (eventDef.RemoveMethod != null) { if (eventDef.RemoveMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MemberMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(this.CodeMappings);
astEvent.RemoveAccessor = new Accessor { astEvent.RemoveAccessor = new Accessor {
Body = CreateMethodBody(eventDef.RemoveMethod) Body = CreateMethodBody(eventDef.RemoveMethod)
@ -1342,5 +1339,10 @@ namespace ICSharpCode.Decompiler.Ast
return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute"); return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute");
} }
public Tuple<string, List<MemberMapping>> CodeMappings {
get;
private set;
}
} }
} }

27
ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs

@ -1,27 +0,0 @@
// 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.Concurrent;
using System.Collections.Generic;
using ICSharpCode.Decompiler;
namespace ICSharpCode.Decompiler.Ast
{
/// <summary>
/// Stores the C# code mappings.
/// </summary>
static class CSharpCodeMapping
{
static ConcurrentDictionary<string, List<MemberMapping>> codeMappings = new ConcurrentDictionary<string, List<MemberMapping>>();
/// <summary>
/// Stores the source codes mappings: CSharp &lt;-&gt; editor lines
/// </summary>
public static ConcurrentDictionary<string, List<MemberMapping>> SourceCodeMappings {
get { return codeMappings; }
set { codeMappings = value; }
}
}
}

70
ICSharpCode.Decompiler/CodeMappings.cs

@ -19,6 +19,17 @@ namespace ICSharpCode.Decompiler
CSharp CSharp
} }
/// <summary>
/// Interface for decompliler classes : AstBuilder & ReflectionDisassembler.
/// </summary>
public interface ICodeMappings
{
/// <summary>
/// Gets the code mappings.
/// </summary>
Tuple<string, List<MemberMapping>> CodeMappings { get; }
}
/// <summary> /// <summary>
/// Maps the source code to IL. /// Maps the source code to IL.
/// </summary> /// </summary>
@ -123,29 +134,6 @@ namespace ICSharpCode.Decompiler
/// </summary> /// </summary>
public static class CodeMappings public static class CodeMappings
{ {
/// <summary>
/// Gets the storage of code mappings for a language.
/// </summary>
/// <param name="language">A language.</param>
/// <returns>The storage of code mappings.</returns>
public static ConcurrentDictionary<string, List<MemberMapping>> GetStorage(DecompiledLanguages language)
{
ConcurrentDictionary<string, List<MemberMapping>> 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> /// <summary>
/// Create code mapping for a method. /// Create code mapping for a method.
/// </summary> /// </summary>
@ -153,18 +141,18 @@ namespace ICSharpCode.Decompiler
/// <param name="sourceCodeMappings">Source code mapping storage.</param> /// <param name="sourceCodeMappings">Source code mapping storage.</param>
internal static MemberMapping CreateCodeMapping( internal static MemberMapping CreateCodeMapping(
this MethodDefinition member, this MethodDefinition member,
ConcurrentDictionary<string, List<MemberMapping>> codeMappings) Tuple<string, List<MemberMapping>> codeMappings)
{ {
if (member == null || !member.HasBody) if (member == null || !member.HasBody)
return null; return null;
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); return null;
// create IL/CSharp code mappings - used in debugger // create IL/CSharp code mappings - used in debugger
MemberMapping currentMemberMapping = null; MemberMapping currentMemberMapping = null;
if (codeMappings.ContainsKey(member.DeclaringType.FullName)) { if (codeMappings.Item1 == member.DeclaringType.FullName) {
var mapping = codeMappings[member.DeclaringType.FullName]; var mapping = codeMappings.Item2;
if (mapping.Find(map => (int)map.MetadataToken == member.MetadataToken.ToInt32()) == null) { if (mapping.Find(map => (int)map.MetadataToken == member.MetadataToken.ToInt32()) == null) {
currentMemberMapping = new MemberMapping() { currentMemberMapping = new MemberMapping() {
MetadataToken = (uint)member.MetadataToken.ToInt32(), MetadataToken = (uint)member.MetadataToken.ToInt32(),
@ -188,15 +176,15 @@ namespace ICSharpCode.Decompiler
/// <param name="metadataToken">Metadata token.</param> /// <param name="metadataToken">Metadata token.</param>
/// <returns></returns> /// <returns></returns>
public static SourceCodeMapping GetInstructionByTypeAndLine( public static SourceCodeMapping GetInstructionByTypeAndLine(
this ConcurrentDictionary<string, List<MemberMapping>> codeMappings, this Tuple<string, List<MemberMapping>> codeMappings,
string typeName, string memberReferenceName,
int lineNumber, int lineNumber,
out uint metadataToken) out uint metadataToken)
{ {
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); throw new ArgumentNullException("CodeMappings storage must be valid!");
if (!codeMappings.ContainsKey(typeName)) { if (codeMappings.Item1 != memberReferenceName) {
metadataToken = 0; metadataToken = 0;
return null; return null;
} }
@ -206,7 +194,7 @@ namespace ICSharpCode.Decompiler
return null; return null;
} }
var methodMappings = codeMappings[typeName]; var methodMappings = codeMappings.Item2;
foreach (var maping in methodMappings) { foreach (var maping in methodMappings) {
var map = maping.MemberCodeMappings.Find(m => m.SourceCodeLine == lineNumber); var map = maping.MemberCodeMappings.Find(m => m.SourceCodeLine == lineNumber);
if (map != null) { if (map != null) {
@ -229,22 +217,22 @@ namespace ICSharpCode.Decompiler
/// <param name="isMatch">True, if perfect match.</param> /// <param name="isMatch">True, if perfect match.</param>
/// <returns>A code mapping.</returns> /// <returns>A code mapping.</returns>
public static SourceCodeMapping GetInstructionByTypeTokenAndOffset( public static SourceCodeMapping GetInstructionByTypeTokenAndOffset(
this ConcurrentDictionary<string, List<MemberMapping>> codeMappings, this Tuple<string, List<MemberMapping>> codeMappings,
string typeName, string memberReferenceName,
uint token, uint token,
int ilOffset, out bool isMatch) int ilOffset, out bool isMatch)
{ {
isMatch = false; isMatch = false;
typeName = typeName.Replace("+", "/"); memberReferenceName = memberReferenceName.Replace("+", "/");
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); throw new ArgumentNullException("CodeMappings storage must be valid!");
if (!codeMappings.ContainsKey(typeName)) { if (codeMappings.Item1 != memberReferenceName) {
return null; return null;
} }
var methodMappings = codeMappings[typeName]; var methodMappings = codeMappings.Item2;
var maping = methodMappings.Find(m => m.MetadataToken == token); var maping = methodMappings.Find(m => m.MetadataToken == token);
if (maping == null) { if (maping == null) {
@ -279,8 +267,8 @@ namespace ICSharpCode.Decompiler
/// <param name="line">Line number.</param> /// <param name="line">Line number.</param>
/// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks> /// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks>
public static bool GetSourceCodeFromMetadataTokenAndOffset( public static bool GetSourceCodeFromMetadataTokenAndOffset(
this ConcurrentDictionary<string, List<MemberMapping>> codeMappings, this Tuple<string, List<MemberMapping>> codeMappings,
string typeName, string memberReferenceName,
uint token, uint token,
int ilOffset, int ilOffset,
out MemberReference type, out MemberReference type,
@ -292,11 +280,11 @@ namespace ICSharpCode.Decompiler
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); throw new ArgumentNullException("CodeMappings storage must be valid!");
typeName = typeName.Replace("+", "/"); memberReferenceName = memberReferenceName.Replace("+", "/");
if (!codeMappings.ContainsKey(typeName)) if (codeMappings.Item1 != memberReferenceName)
return false; return false;
var mapping = codeMappings[typeName].Find(m => m.MetadataToken == token); var mapping = codeMappings.Item2.Find(m => m.MetadataToken == token);
if (mapping == null) if (mapping == null)
return false; return false;

25
ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs

@ -1,25 +0,0 @@
// 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.Concurrent;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Disassembler
{
/// <summary>
/// Stores the IL code mappings.
/// </summary>
static class ILCodeMapping
{
static ConcurrentDictionary<string, List<MemberMapping>> codeMappings = new ConcurrentDictionary<string, List<MemberMapping>>();
/// <summary>
/// Stores the source codes mappings: IL &lt;-&gt; editor lines
/// </summary>
public static ConcurrentDictionary<string, List<MemberMapping>> SourceCodeMappings {
get { return codeMappings; }
set { codeMappings = value; }
}
}
}

5
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -47,11 +47,8 @@ namespace ICSharpCode.Decompiler.Disassembler
this.cancellationToken = cancellationToken; this.cancellationToken = cancellationToken;
} }
public void Disassemble(MethodBody body) public void Disassemble(MethodBody body, MemberMapping methodMapping)
{ {
// create IL code mappings - used in debugger
MemberMapping methodMapping = body.Method.CreateCodeMapping(ILCodeMapping.SourceCodeMappings);
// start writing IL code // start writing IL code
MethodDefinition method = body.Method; MethodDefinition method = body.Method;
output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA); output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);

21
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// <summary> /// <summary>
/// Disassembles type and member definitions. /// Disassembles type and member definitions.
/// </summary> /// </summary>
public sealed class ReflectionDisassembler public sealed class ReflectionDisassembler : ICodeMappings
{ {
ITextOutput output; ITextOutput output;
CancellationToken cancellationToken; CancellationToken cancellationToken;
@ -146,8 +146,11 @@ namespace ICSharpCode.Decompiler.Disassembler
OpenBlock(defaultCollapsed: isInType); OpenBlock(defaultCollapsed: isInType);
WriteAttributes(method.CustomAttributes); WriteAttributes(method.CustomAttributes);
if (method.HasBody) if (method.HasBody) {
methodBodyDisassembler.Disassemble(method.Body); // create IL code mappings - used in debugger
MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings);
methodBodyDisassembler.Disassemble(method.Body, methodMapping);
}
CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name); CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name);
} else { } else {
@ -313,11 +316,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleType(TypeDefinition type) public void DisassembleType(TypeDefinition type)
{ {
// create IL code mappings - used for debugger // create IL code mappings - used for debugger
if (!ILCodeMapping.SourceCodeMappings.ContainsKey(type.FullName)) { this.CodeMappings = new Tuple<string, List<MemberMapping>>(type.FullName, new List<MemberMapping>());
ILCodeMapping.SourceCodeMappings.TryAdd(type.FullName, new List<MemberMapping>());
} else {
ILCodeMapping.SourceCodeMappings[type.FullName].Clear();
}
// start writing IL // start writing IL
output.WriteDefinition(".class ", type); output.WriteDefinition(".class ", type);
@ -566,5 +565,11 @@ namespace ICSharpCode.Decompiler.Disassembler
WriteAttributes(asm.CustomAttributes); WriteAttributes(asm.CustomAttributes);
CloseBlock(); CloseBlock();
} }
/// <inheritdoc/>
public Tuple<string, List<MemberMapping>> CodeMappings {
get;
private set;
}
} }
} }

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -53,7 +53,6 @@
<Compile Include="Ast\AstMethodBodyBuilder.cs" /> <Compile Include="Ast\AstMethodBodyBuilder.cs" />
<Compile Include="Ast\CecilTypeResolveContext.cs" /> <Compile Include="Ast\CecilTypeResolveContext.cs" />
<Compile Include="Ast\CommentStatement.cs" /> <Compile Include="Ast\CommentStatement.cs" />
<Compile Include="Ast\CSharpCodeMapping.cs" />
<Compile Include="Ast\DecompilerContext.cs" /> <Compile Include="Ast\DecompilerContext.cs" />
<Compile Include="Ast\NameVariables.cs" /> <Compile Include="Ast\NameVariables.cs" />
<Compile Include="Ast\NRefactoryExtensions.cs" /> <Compile Include="Ast\NRefactoryExtensions.cs" />
@ -78,7 +77,6 @@
<Compile Include="DecompilerException.cs" /> <Compile Include="DecompilerException.cs" />
<Compile Include="DecompilerSettings.cs" /> <Compile Include="DecompilerSettings.cs" />
<Compile Include="Disassembler\DisassemblerHelpers.cs" /> <Compile Include="Disassembler\DisassemblerHelpers.cs" />
<Compile Include="Disassembler\ILCodeMapping.cs" />
<Compile Include="Disassembler\ILStructure.cs" /> <Compile Include="Disassembler\ILStructure.cs" />
<Compile Include="Disassembler\MethodBodyDisassembler.cs" /> <Compile Include="Disassembler\MethodBodyDisassembler.cs" />
<Compile Include="Disassembler\ReflectionDisassembler.cs" /> <Compile Include="Disassembler\ReflectionDisassembler.cs" />

8
ILSpy.sln

@ -1,15 +1,15 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
# SharpDevelop 4.1.0.7371-alpha # SharpDevelop 4.1.0.7383-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}"
ProjectSection(SolutionItems) = postProject ProjectSection(SolutionItems) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "Debugger\Debugger.Core\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.Debugger", "Debugger\ILSpy.Debugger\ILSpy.Debugger.csproj", "{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.Debugger", "Debugger\ILSpy.Debugger\ILSpy.Debugger.csproj", "{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "Debugger\Debugger.Core\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy", "ILSpy\ILSpy.csproj", "{1E85EFF9-E370-4683-83E4-8A3D063FF791}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy", "ILSpy\ILSpy.csproj", "{1E85EFF9-E370-4683-83E4-8A3D063FF791}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TreeView", "SharpTreeView\ICSharpCode.TreeView.csproj", "{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TreeView", "SharpTreeView\ICSharpCode.TreeView.csproj", "{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}"
@ -119,7 +119,7 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B} {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

4
ILSpy/CSharpLanguage.cs

@ -28,9 +28,11 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xaml; using System.Xaml;
using System.Xml; using System.Xml;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast; using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.Ast.Transforms; using ICSharpCode.Decompiler.Ast.Transforms;
using ICSharpCode.ILSpy.Debugger;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil; using Mono.Cecil;
@ -121,10 +123,12 @@ namespace ICSharpCode.ILSpy
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
{ {
DebugData.OldCodeMappings = DebugData.CodeMappings;
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type);
codeDomBuilder.AddType(type); codeDomBuilder.AddType(type);
codeDomBuilder.RunTransformations(transformAbortCondition); codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output); codeDomBuilder.GenerateCode(output);
DebugData.CodeMappings = codeDomBuilder.CodeMappings;
} }
public override void DecompileAssembly(AssemblyDefinition assembly, string fileName, ITextOutput output, DecompilationOptions options) public override void DecompileAssembly(AssemblyDefinition assembly, string fileName, ITextOutput output, DecompilationOptions options)

6
ILSpy/ILLanguage.cs

@ -22,6 +22,7 @@ using System.IO;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.ILSpy.Debugger;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
@ -72,7 +73,10 @@ namespace ICSharpCode.ILSpy
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
{ {
new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleType(type); DebugData.OldCodeMappings = DebugData.CodeMappings;
var dis = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken);
dis.DisassembleType(type);
DebugData.CodeMappings = dis.CodeMappings;
} }
public override void DecompileNamespace(string nameSpace, IEnumerable<TypeDefinition> types, ITextOutput output, DecompilationOptions options) public override void DecompileNamespace(string nameSpace, IEnumerable<TypeDefinition> types, ITextOutput output, DecompilationOptions options)

Loading…
Cancel
Save