Browse Source

Fix IL Code mappings;

Unfold and scroll when hitting a BP.
Jump to the type that has a BP when the BP is hit.
pull/191/merge
Eusebiu Marcu 14 years ago
parent
commit
572c79f097
  1. 24
      Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs
  2. 7
      Debugger/ILSpy.Debugger/AvalonEdit/TextMarkerService.cs
  3. 7
      Debugger/ILSpy.Debugger/Bookmarks/BookmarkBase.cs
  4. 4
      Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs
  5. 3
      Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs
  6. 7
      Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs
  7. 3
      Debugger/ILSpy.Debugger/Bookmarks/MarkerBookmark.cs
  8. 19
      Debugger/ILSpy.Debugger/DebuggedType.cs
  9. 32
      Debugger/ILSpy.Debugger/Models/TreeModel/ExpressionNode.cs
  10. 11
      Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs
  11. 5
      Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs
  12. 62
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  13. 13
      Debugger/ILSpy.Debugger/UI/AttachToProcessWindow.xaml.cs
  14. 2
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  15. 12
      ICSharpCode.Decompiler/CodeMappings.cs
  16. 2
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  17. 6
      ILSpy.sln
  18. 96
      ILSpy/MainWindow.xaml.cs
  19. 36
      ILSpy/TextView/DecompilerTextView.cs
  20. 2
      ILSpy/TreeNodes/TypeTreeNode.cs

24
Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs

@ -57,10 +57,10 @@ namespace ILSpy.Debugger.AvalonEdit @@ -57,10 +57,10 @@ namespace ILSpy.Debugger.AvalonEdit
// create a dictionary line number => first bookmark
Dictionary<int, BookmarkBase> bookmarkDict = new Dictionary<int, BookmarkBase>();
foreach (var bm in BookmarkManager.Bookmarks) {
if (DebuggedType.CurrentType == null || bm.TypeName != DebuggedType.CurrentType.FullName)
if (DebuggedData.CurrentType == null || bm.Type.FullName != DebuggedData.CurrentType.FullName)
continue;
if (bm is BreakpointBookmark &&
((BreakpointBookmark)bm).Language != DebuggerService.CurrentDebugger.Language)
((BreakpointBookmark)bm).Language != DebuggedData.Language)
continue;
int line = bm.LineNumber;
@ -119,8 +119,8 @@ namespace ILSpy.Debugger.AvalonEdit @@ -119,8 +119,8 @@ namespace ILSpy.Debugger.AvalonEdit
BookmarkBase result = null;
foreach (BookmarkBase bm in BookmarkManager.Bookmarks) {
if (bm.LineNumber == line &&
DebuggedType.CurrentType != null &&
bm.TypeName == DebuggedType.CurrentType.FullName) {
DebuggedData.CurrentType != null &&
bm.Type.FullName == DebuggedData.CurrentType.FullName) {
if (result == null || bm.ZOrder > result.ZOrder)
result = bm;
}
@ -189,11 +189,11 @@ namespace ILSpy.Debugger.AvalonEdit @@ -189,11 +189,11 @@ namespace ILSpy.Debugger.AvalonEdit
InvalidateVisual();
}
if (DebuggedType.CurrentType == null)
if (DebuggedData.CurrentType == null)
return;
BreakpointBookmark bm = BookmarkManager.Bookmarks.Find(
b => b.TypeName == DebuggedType.CurrentType.FullName &&
b => b.Type.FullName == DebuggedData.CurrentType.FullName &&
b.LineNumber == GetLineFromMousePosition(e)
&& b is BreakpointBookmark) as BreakpointBookmark;
@ -226,24 +226,24 @@ namespace ILSpy.Debugger.AvalonEdit @@ -226,24 +226,24 @@ namespace ILSpy.Debugger.AvalonEdit
return;
}
if (e.ChangedButton == MouseButton.Left) {
if (DebuggedType.CurrentType != null) {
if (DebuggedData.CurrentType != null) {
// check if the codemappings exists for this line
var storage = CodeMappings.GetStorage(DebuggerService.CurrentDebugger.Language);
var storage = CodeMappings.GetStorage(DebuggedData.Language);
uint token;
var instruction = storage.GetInstructionByTypeAndLine(DebuggedType.CurrentType.FullName, line, out token);
var instruction = storage.GetInstructionByTypeAndLine(DebuggedData.CurrentType.FullName, line, out token);
if (instruction == null || instruction.ILInstructionOffset.From == 0) {
MessageBox.Show(string.Format("Missing code mappings for {0} at line {1}", DebuggedType.CurrentType.FullName, line),
MessageBox.Show(string.Format("Missing code mappings for {0} at line {1}", DebuggedData.CurrentType.FullName, line),
"Code mappings", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// no bookmark on the line: create a new breakpoint
DebuggerService.ToggleBreakpointAt(
DebuggedType.CurrentType.FullName,
DebuggedData.CurrentType,
line,
DebuggerService.CurrentDebugger.Language);
DebuggedData.Language);
}
}
InvalidateVisual();

7
Debugger/ILSpy.Debugger/AvalonEdit/TextMarkerService.cs

@ -45,8 +45,11 @@ namespace ILSpy.Debugger.AvalonEdit @@ -45,8 +45,11 @@ namespace ILSpy.Debugger.AvalonEdit
{
if (e.Bookmark is MarkerBookmark) {
var bm = (MarkerBookmark)e.Bookmark;
DocumentLine line = codeEditor.Document.GetLineByNumber(bm.LineNumber);
bm.Marker = bm.CreateMarker(this, line.Offset, line.Length);
if (DebuggedData.CurrentType != null && DebuggedData.CurrentType.FullName.Equals(bm.Type.FullName, StringComparison.OrdinalIgnoreCase)) {
// add bookmark for the current type
DocumentLine line = codeEditor.Document.GetLineByNumber(bm.LineNumber);
bm.Marker = bm.CreateMarker(this, line.Offset, line.Length);
}
}
}

7
Debugger/ILSpy.Debugger/Bookmarks/BookmarkBase.cs

@ -6,6 +6,7 @@ using System.Windows.Input; @@ -6,6 +6,7 @@ using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace ILSpy.Debugger.Bookmarks
{
@ -40,7 +41,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -40,7 +41,7 @@ namespace ILSpy.Debugger.Bookmarks
}
public string TypeName { get; set; }
public TypeDefinition Type { get; set; }
public int LineNumber {
get { return location.Line; }
@ -63,9 +64,9 @@ namespace ILSpy.Debugger.Bookmarks @@ -63,9 +64,9 @@ namespace ILSpy.Debugger.Bookmarks
}
}
public BookmarkBase(string typeName, AstLocation location)
public BookmarkBase(TypeDefinition type, AstLocation location)
{
this.TypeName = typeName;
this.Type = type;
this.Location = location;
}

4
Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs

@ -29,7 +29,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -29,7 +29,7 @@ namespace ILSpy.Debugger.Bookmarks
List<BookmarkBase> marks = new List<BookmarkBase>();
foreach (BookmarkBase mark in bookmarks) {
if (typeName == mark.TypeName) {
if (typeName == mark.Type.FullName) {
marks.Add(mark);
}
}
@ -54,7 +54,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -54,7 +54,7 @@ namespace ILSpy.Debugger.Bookmarks
return false;
if (a.GetType() != b.GetType())
return false;
if (a.TypeName != b.TypeName)
if (a.Type.FullName != b.Type.FullName)
return false;
return a.LineNumber == b.LineNumber;
}

3
Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs

@ -8,6 +8,7 @@ using ICSharpCode.Decompiler; @@ -8,6 +8,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
using ILSpy.Debugger.AvalonEdit;
using ILSpy.Debugger.Services;
using Mono.Cecil;
namespace ILSpy.Debugger.Bookmarks
{
@ -72,7 +73,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -72,7 +73,7 @@ namespace ILSpy.Debugger.Bookmarks
set { tooltip = value; }
}
public BreakpointBookmark(string typeName, AstLocation location, BreakpointAction action, DecompiledLanguages language) : base(typeName, location)
public BreakpointBookmark(TypeDefinition type, AstLocation location, BreakpointAction action, DecompiledLanguages language) : base(type, location)
{
this.action = action;
this.tooltip = language.ToString();

7
Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs

@ -6,6 +6,7 @@ using System.Windows.Media; @@ -6,6 +6,7 @@ using System.Windows.Media;
using ICSharpCode.NRefactory.CSharp;
using ILSpy.Debugger.AvalonEdit;
using ILSpy.Debugger.Services;
using Mono.Cecil;
using Mono.CSharp;
namespace ILSpy.Debugger.Bookmarks
@ -23,7 +24,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -23,7 +24,7 @@ namespace ILSpy.Debugger.Bookmarks
static int endLine;
static int endColumn;
public static void SetPosition(string typeName, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn)
public static void SetPosition(TypeDefinition type, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn)
{
Remove();
@ -32,7 +33,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -32,7 +33,7 @@ namespace ILSpy.Debugger.Bookmarks
endLine = makerEndLine;
endColumn = makerEndColumn;
instance = new CurrentLineBookmark(typeName, new AstLocation(startLine, startColumn));
instance = new CurrentLineBookmark(type, new AstLocation(startLine, startColumn));
BookmarkManager.AddMark(instance);
}
@ -52,7 +53,7 @@ namespace ILSpy.Debugger.Bookmarks @@ -52,7 +53,7 @@ namespace ILSpy.Debugger.Bookmarks
get { return 100; }
}
public CurrentLineBookmark(string typeName, AstLocation location) : base(typeName, location)
public CurrentLineBookmark(TypeDefinition type, AstLocation location) : base(type, location)
{
}

3
Debugger/ILSpy.Debugger/Bookmarks/MarkerBookmark.cs

@ -4,12 +4,13 @@ @@ -4,12 +4,13 @@
using System;
using ICSharpCode.NRefactory.CSharp;
using ILSpy.Debugger.AvalonEdit;
using Mono.Cecil;
namespace ILSpy.Debugger.Bookmarks
{
public abstract class MarkerBookmark : BookmarkBase
{
public MarkerBookmark(string typeName, AstLocation location) : base(typeName, location)
public MarkerBookmark(TypeDefinition type, AstLocation location) : base(type, location)
{
}

19
Debugger/ILSpy.Debugger/DebuggedType.cs

@ -17,17 +17,24 @@ @@ -17,17 +17,24 @@
// DEALINGS IN THE SOFTWARE.
using System;
using ICSharpCode.Decompiler;
using Mono.Cecil;
namespace ILSpy.Debugger
{
public static class DebuggedType
/// <summary>
/// Contains the data important for debugger from the main application.
/// </summary>
public static class DebuggedData
{
static TypeDefinition currentTypeName;
/// <summary>
/// Gets or sets the current debugged type
/// </summary>
public static TypeDefinition CurrentType { get; set; }
public static TypeDefinition CurrentType {
get { return currentTypeName; }
set { currentTypeName = value; }
}
/// <summary>
/// Gets or sets the decompiled language.
/// </summary>
public static DecompiledLanguages Language { get; set; }
}
}

32
Debugger/ILSpy.Debugger/Models/TreeModel/ExpressionNode.cs

@ -257,22 +257,22 @@ namespace ILSpy.Debugger.Models.TreeModel @@ -257,22 +257,22 @@ namespace ILSpy.Debugger.Models.TreeModel
if (true)
return i.ToString();
string hex = null;
for(int len = 1;; len *= 2) {
hex = string.Format("{0:X" + len + "}", i);
if (hex.Length == len)
break;
}
if (true) {
return "0x" + hex;
} else {
if (ShowAsHex(i)) {
return String.Format("{0} (0x{1})", i, hex);
} else {
return i.ToString();
}
}
// string hex = null;
// for(int len = 1;; len *= 2) {
// hex = string.Format("{0:X" + len + "}", i);
// if (hex.Length == len)
// break;
// }
//
// if (true) {
// return "0x" + hex;
// } else {
// if (ShowAsHex(i)) {
// return String.Format("{0} (0x{1})", i, hex);
// } else {
// return i.ToString();
// }
// }
}
bool ShowAsHex(object i)

11
Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs

@ -8,6 +8,7 @@ using ICSharpCode.Decompiler; @@ -8,6 +8,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ILSpy.Debugger.Bookmarks;
using ILSpy.Debugger.ToolTips;
using Mono.Cecil;
namespace ILSpy.Debugger.Services
{
@ -162,12 +163,12 @@ namespace ILSpy.Debugger.Services @@ -162,12 +163,12 @@ namespace ILSpy.Debugger.Services
}
}
public static void ToggleBreakpointAt(string typeName, int lineNumber, DecompiledLanguages language)
public static void ToggleBreakpointAt(TypeDefinition type, int lineNumber, DecompiledLanguages language)
{
BookmarkManager.ToggleBookmark(
typeName, lineNumber,
type.FullName, lineNumber,
b => b.CanToggle && b is BreakpointBookmark,
location => new BreakpointBookmark(typeName, location, BreakpointAction.Break, language));
location => new BreakpointBookmark(type, location, BreakpointAction.Break, language));
}
/* TODO: reimplement this stuff
@ -183,9 +184,9 @@ namespace ILSpy.Debugger.Services @@ -183,9 +184,9 @@ namespace ILSpy.Debugger.Services
CurrentLineBookmark.Remove();
}
public static void JumpToCurrentLine(string typeName, int startLine, int startColumn, int endLine, int endColumn)
public static void JumpToCurrentLine(TypeDefinition type, int startLine, int startColumn, int endLine, int endColumn)
{
CurrentLineBookmark.SetPosition(typeName, startLine, startColumn, endLine, endColumn);
CurrentLineBookmark.SetPosition(type, startLine, startColumn, endLine, endColumn);
}
#region Tool tips

5
Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs

@ -10,11 +10,6 @@ namespace ILSpy.Debugger.Services @@ -10,11 +10,6 @@ namespace ILSpy.Debugger.Services
{
public interface IDebugger : IDisposable
{
/// <summary>
/// Gets or sets the decompiled language.
/// </summary>
DecompiledLanguages Language { get; set; }
/// <summary>
/// Gets whether the debugger can evaluate the expression.
/// </summary>

62
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -20,6 +20,7 @@ using ILSpy.Debugger.Bookmarks; @@ -20,6 +20,7 @@ using ILSpy.Debugger.Bookmarks;
using ILSpy.Debugger.Models.TreeModel;
using ILSpy.Debugger.Services.Debugger;
using ILSpy.Debugger.Tooltips;
using Mono.Cecil;
using CorDbg = Debugger;
using Process = Debugger.Process;
using StackFrame = Debugger.StackFrame;
@ -48,7 +49,7 @@ namespace ILSpy.Debugger.Services @@ -48,7 +49,7 @@ namespace ILSpy.Debugger.Services
private ConcurrentDictionary<string, List<MethodMapping>> CodeMappingsStorage {
get {
return CodeMappings.GetStorage(Language);
return CodeMappings.GetStorage(DebuggedData.Language);
}
}
@ -109,8 +110,6 @@ namespace ILSpy.Debugger.Services @@ -109,8 +110,6 @@ namespace ILSpy.Debugger.Services
string errorProcessPaused = "Error.ProcessPaused";
string errorCannotStepNoActiveFunction = "Threads.CannotStepNoActiveFunction";
public DecompiledLanguages Language { get; set; }
public bool IsDebugging {
get {
return ServiceInitialized && debuggedProcess != null;
@ -289,10 +288,10 @@ namespace ILSpy.Debugger.Services @@ -289,10 +288,10 @@ namespace ILSpy.Debugger.Services
// get the mapped instruction from the current line marker or the next one
uint token;
var instruction = CodeMappingsStorage.GetInstructionByTypeAndLine(
CurrentLineBookmark.Instance.TypeName,
CurrentLineBookmark.Instance.Type.FullName,
CurrentLineBookmark.Instance.LineNumber, out token);
var val = CodeMappingsStorage[CurrentLineBookmark.Instance.TypeName];
var val = CodeMappingsStorage[CurrentLineBookmark.Instance.Type.FullName];
var mapping = val.Find(m => m.MetadataToken == token);
@ -560,21 +559,19 @@ namespace ILSpy.Debugger.Services @@ -560,21 +559,19 @@ namespace ILSpy.Debugger.Services
{
Breakpoint breakpoint = null;
if (Language == bookmark.Language) {
uint token;
SourceCodeMapping map =
CodeMappingsStorage.GetInstructionByTypeAndLine(
bookmark.TypeName, bookmark.LineNumber, out token);
if (map != null) {
breakpoint = new ILBreakpoint(
debugger,
bookmark.TypeName,
bookmark.LineNumber,
token,
map.ILInstructionOffset.From,
bookmark.IsEnabled);
}
uint token;
SourceCodeMapping map = CodeMappings
.GetStorage(bookmark.Language)
.GetInstructionByTypeAndLine(bookmark.Type.FullName, bookmark.LineNumber, out token);
if (map != null) {
breakpoint = new ILBreakpoint(
debugger,
bookmark.Type.FullName,
bookmark.LineNumber,
token,
map.ILInstructionOffset.From,
bookmark.IsEnabled);
}
if (breakpoint == null)
@ -748,7 +745,7 @@ namespace ILSpy.Debugger.Services @@ -748,7 +745,7 @@ namespace ILSpy.Debugger.Services
foreach (var bookmark in DebuggerService.Breakpoints) {
var breakpoint =
debugger.Breakpoints.FirstOrDefault(
b => b.Line == bookmark.LineNumber && b.TypeName == bookmark.TypeName);
b => b.Line == bookmark.LineNumber && b.TypeName == bookmark.Type.FullName);
if (breakpoint == null)
continue;
@ -758,22 +755,8 @@ namespace ILSpy.Debugger.Services @@ -758,22 +755,8 @@ namespace ILSpy.Debugger.Services
void debuggedProcess_DebuggingPaused(object sender, ProcessEventArgs e)
{
OnIsProcessRunningChanged(EventArgs.Empty);
//using(new PrintTimes("Jump to current line")) {
JumpToCurrentLine();
//}
// TODO update tooltip
/*if (currentTooltipRow != null && currentTooltipRow.IsShown) {
using(new PrintTimes("Update tooltip")) {
try {
Utils.DoEvents(debuggedProcess);
AbstractNode updatedNode = ValueNode.Create(currentTooltipExpression);
currentTooltipRow.SetContentRecursive(updatedNode);
} catch (AbortedBecauseDebuggeeResumedException) {
}
}
}*/
OnIsProcessRunningChanged(EventArgs.Empty);
}
void debuggedProcess_DebuggingResumed(object sender, CorDbg.ProcessEventArgs e)
@ -832,9 +815,10 @@ namespace ILSpy.Debugger.Services @@ -832,9 +815,10 @@ namespace ILSpy.Debugger.Services
uint token = (uint)frame.MethodInfo.MetadataToken;
int ilOffset = frame.IP;
int line;
string typeName;
if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out typeName, out line))
DebuggerService.JumpToCurrentLine(typeName, line, 0, line, 0);
TypeDefinition type;
if (CodeMappingsStorage.GetSourceCodeFromMetadataTokenAndOffset(token, ilOffset, out type, out line)) {
DebuggerService.JumpToCurrentLine(type, line, 0, line, 0);
}
}
}

13
Debugger/ILSpy.Debugger/UI/AttachToProcessWindow.xaml.cs

@ -10,7 +10,6 @@ using System.Linq; @@ -10,7 +10,6 @@ using System.Linq;
using System.Windows;
using ILSpy.Debugger.Models;
using ILSpy.Debugger.Services;
namespace ILSpy.Debugger.UI
{
@ -26,6 +25,15 @@ namespace ILSpy.Debugger.UI @@ -26,6 +25,15 @@ namespace ILSpy.Debugger.UI
Loaded += OnLoaded;
}
public Process SelectedProcess {
get {
if (this.RunningProcesses.SelectedItem != null)
return ((RunningProcess)this.RunningProcesses.SelectedItem).Process;
return null;
}
}
void RefreshProcessList()
{
ObservableCollection<RunningProcess> list = new ObservableCollection<RunningProcess>();
@ -68,9 +76,6 @@ namespace ILSpy.Debugger.UI @@ -68,9 +76,6 @@ namespace ILSpy.Debugger.UI
if (this.RunningProcesses.SelectedItem == null)
return;
// start attaching
var process = ((RunningProcess)this.RunningProcesses.SelectedItem).Process;
DebuggerService.CurrentDebugger.Attach(process);
this.DialogResult = true;
}

2
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -137,7 +137,7 @@ namespace Decompiler @@ -137,7 +137,7 @@ namespace Decompiler
public TypeDeclaration CreateType(TypeDefinition typeDef)
{
// create IL code mappings - used for debugger
// create CSharp code mappings - used for debugger
if (!CSharpCodeMapping.SourceCodeMappings.ContainsKey(typeDef.FullName)) {
CSharpCodeMapping.SourceCodeMappings.TryAdd(typeDef.FullName, new List<MethodMapping>());
} else {

12
ICSharpCode.Decompiler/CodeMappings.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler @@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler
/// </summary>
public sealed class MethodMapping
{
public string TypeName { get; set; }
public TypeDefinition Type { get; set; }
public uint MetadataToken { get; set; }
@ -100,7 +100,7 @@ namespace ICSharpCode.Decompiler @@ -100,7 +100,7 @@ namespace ICSharpCode.Decompiler
if (mapping.Find(map => (int)map.MetadataToken == method.MetadataToken.ToInt32()) == null) {
currentMethodMapping = new MethodMapping() {
MetadataToken = (uint)method.MetadataToken.ToInt32(),
TypeName = method.DeclaringType.FullName,
Type = method.DeclaringType,
MethodCodeMappings = new List<SourceCodeMapping>()
};
mapping.Add(currentMethodMapping);
@ -153,16 +153,16 @@ namespace ICSharpCode.Decompiler @@ -153,16 +153,16 @@ namespace ICSharpCode.Decompiler
/// <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="typeName">Type definition.</param>
/// <param name="line">Line number.</param>
public static bool GetSourceCodeFromMetadataTokenAndOffset(
this ConcurrentDictionary<string, List<MethodMapping>> codeMappings,
uint token,
int ilOffset,
out string typeName,
out TypeDefinition type,
out int line)
{
typeName = null;
type = null;
line = 0;
foreach (var typename in codeMappings.Keys) {
@ -182,7 +182,7 @@ namespace ICSharpCode.Decompiler @@ -182,7 +182,7 @@ namespace ICSharpCode.Decompiler
}
typeName = typename;
type = mapping.Type;
line = codeMapping.SourceCodeLine;
return true;
}

2
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -316,7 +316,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -316,7 +316,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (!ILCodeMapping.SourceCodeMappings.ContainsKey(type.FullName)) {
ILCodeMapping.SourceCodeMappings.TryAdd(type.FullName, new List<MethodMapping>());
} else {
ILCodeMapping.SourceCodeMappings.Clear();
ILCodeMapping.SourceCodeMappings[type.FullName].Clear();
}
// start writing IL

6
ILSpy.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.1.0.7302-alpha
# SharpDevelop 4.1.0.7322-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -108,4 +108,8 @@ Global @@ -108,4 +108,8 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}
EndGlobalSection
EndGlobal

96
ILSpy/MainWindow.xaml.cs

@ -26,12 +26,15 @@ using System.Threading.Tasks; @@ -26,12 +26,15 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.TreeNodes.Analyzer;
using ICSharpCode.TreeView;
using ILSpy.Debugger;
using ILSpy.Debugger.AvalonEdit;
using ILSpy.Debugger.Bookmarks;
using ILSpy.Debugger.Services;
@ -304,22 +307,25 @@ namespace ICSharpCode.ILSpy @@ -304,22 +307,25 @@ namespace ICSharpCode.ILSpy
}
}
void OpenFiles(string[] fileNames)
void OpenFiles(string[] fileNames, bool focusNode = true)
{
treeView.UnselectAll();
SharpTreeNode lastNode = null;
foreach (string file in fileNames) {
var asm = assemblyList.OpenAssembly(file);
if (asm != null) {
var node = assemblyListTreeNode.FindAssemblyNode(asm);
if (node != null) {
treeView.SelectedItems.Add(node);
lastNode = node;
if (focusNode) {
treeView.UnselectAll();
SharpTreeNode lastNode = null;
foreach (string file in fileNames) {
var asm = assemblyList.OpenAssembly(file);
if (asm != null) {
var node = assemblyListTreeNode.FindAssemblyNode(asm);
if (node != null) {
treeView.SelectedItems.Add(node);
lastNode = node;
}
}
}
if (lastNode != null)
treeView.FocusNode(lastNode);
}
if (lastNode != null)
treeView.FocusNode(lastNode);
}
void OpenFromGac_Click(object sender, RoutedEventArgs e)
@ -345,12 +351,60 @@ namespace ICSharpCode.ILSpy @@ -345,12 +351,60 @@ namespace ICSharpCode.ILSpy
#region Debugger commands
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool SetWindowPos(
IntPtr hWnd,
IntPtr hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
uint uFlags);
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
static readonly IntPtr HWND_TOP = new IntPtr(0);
static void SendWpfWindowPos(Window window, IntPtr place)
{
var hWnd = new WindowInteropHelper(window).Handle;
SetWindowPos(hWnd, place, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
}
IDebugger CurrentDebugger {
get {
return DebuggerService.CurrentDebugger;
}
}
void StartDebugging(Process process)
{
CurrentDebugger.Attach(process);
EnableDebuggerUI(false);
CurrentDebugger.DebugStopped += OnDebugStopped;
CurrentDebugger.IsProcessRunningChanged += CurrentDebugger_IsProcessRunningChanged;
}
void CurrentDebugger_IsProcessRunningChanged(object sender, EventArgs e)
{
if (CurrentDebugger.IsProcessRunning) {
//SendWpfWindowPos(this, HWND_BOTTOM);
return;
}
// breakpoint was hit => bring to front the main window
SendWpfWindowPos(this, HWND_TOP);
this.Activate();
// jump to type & expand folding
if (CurrentLineBookmark.Instance != null) {
JumpToReference(CurrentLineBookmark.Instance.Type);
decompilerTextView.UnfoldAndScroll(CurrentLineBookmark.Instance.LineNumber);
}
}
void DebugExecutableExecuted(object sender, ExecutedRoutedEventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog() {
@ -359,18 +413,15 @@ namespace ICSharpCode.ILSpy @@ -359,18 +413,15 @@ namespace ICSharpCode.ILSpy
DefaultExt = "exe"
};
var result = dialog.ShowDialog();
if (result.HasValue && result.Value) {
if (dialog.ShowDialog() == true) {
string fileName = dialog.FileName;
// add it to references
OpenFiles(new [] { fileName });
OpenFiles(new [] { fileName }, false);
if (!CurrentDebugger.IsDebugging) {
// execute the process
CurrentDebugger.Attach(Process.Start(fileName));
EnableDebuggerUI(false);
CurrentDebugger.DebugStopped += OnDebugStopped;
this.StartDebugging(Process.Start(fileName));
}
}
}
@ -383,8 +434,7 @@ namespace ICSharpCode.ILSpy @@ -383,8 +434,7 @@ namespace ICSharpCode.ILSpy
if (window.ShowDialog() == true)
{
if (CurrentDebugger.IsDebugging) {
EnableDebuggerUI(false);
CurrentDebugger.DebugStopped += OnDebugStopped;
this.StartDebugging(window.SelectedProcess);
}
}
}
@ -393,7 +443,8 @@ namespace ICSharpCode.ILSpy @@ -393,7 +443,8 @@ namespace ICSharpCode.ILSpy
void OnDebugStopped(object sender, EventArgs e)
{
EnableDebuggerUI(true);
DebuggerService.CurrentDebugger.DebugStopped -= OnDebugStopped;
CurrentDebugger.DebugStopped -= OnDebugStopped;
CurrentDebugger.IsProcessRunningChanged -= CurrentDebugger_IsProcessRunningChanged;
}
void DetachFromProcessExecuted(object sender, ExecutedRoutedEventArgs e)
@ -599,8 +650,7 @@ namespace ICSharpCode.ILSpy @@ -599,8 +650,7 @@ namespace ICSharpCode.ILSpy
void LanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DebuggerService.CurrentDebugger.Language =
sessionSettings.FilterSettings.Language.Name.StartsWith("IL") ? DecompiledLanguages.IL : DecompiledLanguages.CSharp;
DebuggedData.Language = sessionSettings.FilterSettings.Language.Name.StartsWith("IL") ? DecompiledLanguages.IL : DecompiledLanguages.CSharp;
}
}
}

36
ILSpy/TextView/DecompilerTextView.cs

@ -34,6 +34,7 @@ using System.Windows.Threading; @@ -34,6 +34,7 @@ using System.Windows.Threading;
using System.Xml;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
@ -42,6 +43,7 @@ using ICSharpCode.ILSpy.TreeNodes; @@ -42,6 +43,7 @@ using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.NRefactory.Documentation;
using ILSpy.Debugger;
using ILSpy.Debugger.AvalonEdit;
using ILSpy.Debugger.Bookmarks;
using ILSpy.Debugger.ToolTips;
using Microsoft.Win32;
using TextEditorWeakEventManager = ILSpy.Debugger.AvalonEdit.TextEditorWeakEventManager;
@ -329,7 +331,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -329,7 +331,7 @@ namespace ICSharpCode.ILSpy.TextView
/// </summary>
public void Decompile(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, DecompilationOptions options)
{
DebuggedType.CurrentType = null;
DebuggedData.CurrentType = null;
// Some actions like loading an assembly list cause several selection changes in the tree view,
// and each of those will start a decompilation action.
bool isDecompilationScheduled = this.nextDecompilationRun != null;
@ -390,6 +392,16 @@ namespace ICSharpCode.ILSpy.TextView @@ -390,6 +392,16 @@ namespace ICSharpCode.ILSpy.TextView
finally {
// repaint bookmarks
iconMargin.InvalidateVisual();
// show the currentline marker
var bm = CurrentLineBookmark.Instance;
if (bm != null && DebuggedData.CurrentType != null) {
if (DebuggedData.CurrentType.FullName.Equals(bm.Type.FullName, StringComparison.OrdinalIgnoreCase)) {
DocumentLine line = textEditor.Document.GetLineByNumber(bm.LineNumber);
bm.Marker = bm.CreateMarker(textMarkerService, line.Offset, line.Length);
UnfoldAndScroll(bm.LineNumber);
}
}
}
});
}
@ -623,5 +635,27 @@ namespace ICSharpCode.ILSpy.TextView @@ -623,5 +635,27 @@ namespace ICSharpCode.ILSpy.TextView
return text;
}
#endregion
#region Unfold
public void UnfoldAndScroll(int lineNumber)
{
if (lineNumber <= 0 || lineNumber > textEditor.Document.LineCount)
return;
var line = textEditor.Document.GetLineByNumber(lineNumber);
// unfold
var foldings = foldingManager.GetFoldingsContaining(line.Offset);
if (foldings != null) {
foreach (var folding in foldings) {
if (folding.IsFolded) {
folding.IsFolded = false;
}
}
}
// scroll to
textEditor.ScrollTo(lineNumber, 0);
}
#endregion
}
}

2
ILSpy/TreeNodes/TypeTreeNode.cs

@ -129,7 +129,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -129,7 +129,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
DebuggedType.CurrentType = type;
DebuggedData.CurrentType = type;
language.DecompileType(type, output, options);
}

Loading…
Cancel
Save