diff --git a/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj b/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj
index 742048f58..cfaa007cc 100644
--- a/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj
+++ b/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj
@@ -78,7 +78,6 @@
-
diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs b/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs
index 35f85fb58..75906b6ce 100644
--- a/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs
+++ b/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs
@@ -22,7 +22,7 @@ namespace ILSpy.Debugger.Services
static IDebugger GetCompatibleDebugger()
{
- return new DefaultDebugger();
+ return new WindowsDebugger();
}
///
diff --git a/ICSharpCode.Decompiler/Disassembler/CodeMappings.cs b/ICSharpCode.Decompiler/Disassembler/CodeMappings.cs
new file mode 100644
index 000000000..ff4e710b2
--- /dev/null
+++ b/ICSharpCode.Decompiler/Disassembler/CodeMappings.cs
@@ -0,0 +1,66 @@
+// 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 int MetadataToken { get; set; }
+
+ public List MethodCodeMappings { get; set; }
+
+ ///
+ /// Finds the IL instruction given a source code line number.
+ ///
+ /// Source code line number.
+ /// IL Instruction or null, if the instruction was not found.
+ 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;
+ }
+
+ ///
+ /// Finds the source code line given an IL instruction offset.
+ ///
+ /// IL Instruction offset.
+ /// Source code line, if it is found, -1 otherwise.
+ 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;
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
index 55ff87df0..fc36bcf41 100644
--- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
+++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
@@ -47,6 +47,20 @@ namespace ICSharpCode.Decompiler.Disassembler
public void Disassemble(MethodBody body)
{
+ // create mappings
+ MethodMapping currentMethodMapping = null;
+ if (ReflectionDisassembler.ILSourceCodeMappings.ContainsKey(body.Method.DeclaringType.FullName)) {
+ var mapping = ReflectionDisassembler.ILSourceCodeMappings[body.Method.DeclaringType.FullName];
+ if (mapping.Find(map => map.MetadataToken == body.Method.MetadataToken.ToInt32()) == null) {
+ currentMethodMapping = new MethodMapping() {
+ MetadataToken = body.Method.MetadataToken.ToInt32(),
+ TypeName = body.Method.DeclaringType.FullName,
+ MethodCodeMappings = new List()
+ };
+ mapping.Add(currentMethodMapping);
+ }
+ }
+
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);
@@ -74,9 +88,15 @@ namespace ICSharpCode.Decompiler.Disassembler
if (detectControlStructure && body.Instructions.Count > 0) {
Instruction inst = body.Instructions[0];
- WriteStructureBody(new ILStructure(body), ref inst);
+ WriteStructureBody(new ILStructure(body), ref inst, currentMethodMapping);
} else {
foreach (var inst in method.Body.Instructions) {
+ // add IL code mappings
+ currentMethodMapping.MethodCodeMappings.Add(new ILCodeMapping() {
+ SourceCodeLine = output.CurrentLine,
+ ILInstruction = inst
+ });
+
inst.WriteTo(output);
output.WriteLine();
}
@@ -133,15 +153,23 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Indent();
}
- void WriteStructureBody(ILStructure s, ref Instruction inst)
+ void WriteStructureBody(ILStructure s, ref Instruction inst, MethodMapping currentMethodMapping)
{
int childIndex = 0;
while (inst != null && inst.Offset < s.EndOffset) {
+ // add IL code mappings
+ if (currentMethodMapping != null) {
+ currentMethodMapping.MethodCodeMappings.Add(new ILCodeMapping() {
+ SourceCodeLine = output.CurrentLine,
+ ILInstruction = inst
+ });
+ }
+
int offset = inst.Offset;
if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
ILStructure child = s.Children[childIndex++];
WriteStructureHeader(child);
- WriteStructureBody(child, ref inst);
+ WriteStructureBody(child, ref inst, currentMethodMapping);
WriteStructureFooter(child);
} else {
inst.WriteTo(output);
diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
index fb0d9d1e2..60e88fda8 100644
--- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
+++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
@@ -36,6 +36,16 @@ namespace ICSharpCode.Decompiler.Disassembler
bool isInType; // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings)
MethodBodyDisassembler methodBodyDisassembler;
+ static Dictionary> ilCodeMappings = new Dictionary>();
+
+ ///
+ /// Stores the source codes mappings: IL <-> editor lines
+ ///
+ public static Dictionary> ILSourceCodeMappings {
+ get { return ilCodeMappings; }
+ set { ilCodeMappings = value; }
+ }
+
public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken)
{
if (output == null)
@@ -101,6 +111,11 @@ namespace ICSharpCode.Decompiler.Disassembler
void DisassembleMethodInternal(MethodDefinition method)
{
+ // create mappings for types that were not disassebled
+ if (!ilCodeMappings.ContainsKey(method.DeclaringType.FullName)) {
+ ilCodeMappings.Add(method.DeclaringType.FullName, new List());
+ }
+
// .method public hidebysig specialname
// instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed
//
diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
index af57a944b..320db9c11 100644
--- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
+++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
@@ -60,6 +60,7 @@
+
diff --git a/ICSharpCode.Decompiler/ITextOutput.cs b/ICSharpCode.Decompiler/ITextOutput.cs
index f862d5f0a..fdee0a682 100644
--- a/ICSharpCode.Decompiler/ITextOutput.cs
+++ b/ICSharpCode.Decompiler/ITextOutput.cs
@@ -22,6 +22,8 @@ namespace ICSharpCode.Decompiler
{
public interface ITextOutput
{
+ int CurrentLine { get; set; }
+
void Indent();
void Unindent();
void Write(char ch);
diff --git a/ICSharpCode.Decompiler/PlainTextOutput.cs b/ICSharpCode.Decompiler/PlainTextOutput.cs
index 76721e666..8464c22d5 100644
--- a/ICSharpCode.Decompiler/PlainTextOutput.cs
+++ b/ICSharpCode.Decompiler/PlainTextOutput.cs
@@ -32,6 +32,7 @@ namespace ICSharpCode.Decompiler
if (writer == null)
throw new ArgumentNullException("writer");
this.writer = writer;
+ CurrentLine = 1;
}
public PlainTextOutput()
@@ -39,6 +40,8 @@ namespace ICSharpCode.Decompiler
this.writer = new StringWriter();
}
+ public int CurrentLine { get; set; }
+
public override string ToString()
{
return writer.ToString();
@@ -80,6 +83,7 @@ namespace ICSharpCode.Decompiler
{
writer.WriteLine();
needsIndent = true;
+ ++CurrentLine;
}
public void WriteDefinition(string text, object definition)
diff --git a/ILSpy.sln b/ILSpy.sln
index 40407ff69..279b1b8c8 100644
--- a/ILSpy.sln
+++ b/ILSpy.sln
@@ -6,25 +6,25 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{BF
ProjectSection(SolutionItems) = postProject
EndProjectSection
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}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "Debugger\Debugger.Core\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{4E076A9B-159A-45C4-9E34-AE1D20D83E42}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "Mono.Cecil\Mono.Cecil.csproj", "{D68133BD-1E63-496E-9EDE-4FBDBF77B486}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.AvalonEdit", "AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj", "{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Decompiler\lib\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Libraries\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj", "{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TreeView", "SharpTreeView\ICSharpCode.TreeView.csproj", "{DDE2A481-8271-4EAC-A330-8FA6A38D13D1}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj", "{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Libraries\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Decompiler\lib\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.AvalonEdit", "AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj", "{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "Mono.Cecil\Mono.Cecil.csproj", "{D68133BD-1E63-496E-9EDE-4FBDBF77B486}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy", "ILSpy\ILSpy.csproj", "{1E85EFF9-E370-4683-83E4-8A3D063FF791}"
EndProject
@@ -117,13 +117,13 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {BF79A230-0918-47DF-8A36-776779A331DE}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {BF79A230-0918-47DF-8A36-776779A331DE}
- {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
- {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
- {DDE2A481-8271-4EAC-A330-8FA6A38D13D1} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
- {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
- {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
+ {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {BF79A230-0918-47DF-8A36-776779A331DE}
{D68133BD-1E63-496E-9EDE-4FBDBF77B486} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
+ {DDE2A481-8271-4EAC-A330-8FA6A38D13D1} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {4E076A9B-159A-45C4-9E34-AE1D20D83E42}
EndGlobalSection
EndGlobal
diff --git a/ILSpy/TextView/AvalonEditTextOutput.cs b/ILSpy/TextView/AvalonEditTextOutput.cs
index e3934a886..500501a06 100644
--- a/ILSpy/TextView/AvalonEditTextOutput.cs
+++ b/ILSpy/TextView/AvalonEditTextOutput.cs
@@ -86,6 +86,11 @@ namespace ICSharpCode.ILSpy.TextView
/// Embedded UIElements, see .
public readonly List>> UIElements = new List>>();
+ public AvalonEditTextOutput()
+ {
+ CurrentLine = 1;
+ }
+
///
/// Gets the list of references (hyperlinks).
///
@@ -104,6 +109,8 @@ namespace ICSharpCode.ILSpy.TextView
get { return b.Length; }
}
+ public int CurrentLine { get; set; }
+
#region Text Document
TextDocument textDocument;
@@ -173,6 +180,7 @@ namespace ICSharpCode.ILSpy.TextView
{
Debug.Assert(textDocument == null);
b.AppendLine();
+ ++CurrentLine;
needsIndent = true;
if (this.TextLength > LengthLimit) {
throw new OutputLengthExceededException();