Browse Source

sync bookmarks : types/members and C#/IL(not working 100%).

pull/191/merge
Eusebiu Marcu 14 years ago
parent
commit
a0bff8626e
  1. 65
      Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs
  2. 10
      Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs
  3. 3
      Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs
  4. 3
      Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs
  5. 5
      Debugger/ILSpy.Debugger/DebuggedData.cs
  6. 18
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  7. 51
      Debugger/ILSpy.Debugger/Services/ExtensionMethods.cs
  8. 6
      ICSharpCode.Decompiler/CodeMappings.cs
  9. 6
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  10. 3
      ILSpy/Options/DebuggerSettingsPanel.xaml
  11. 6
      ILSpy/Options/DebuggerSettingsPanel.xaml.cs
  12. 5
      ILSpy/TextView/DecompilerTextView.cs

65
Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs

@ -8,12 +8,14 @@ using System.Linq; @@ -8,12 +8,14 @@ using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Editing;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Debugger.Bookmarks;
using ICSharpCode.ILSpy.Debugger.Services;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
@ -62,9 +64,6 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit @@ -62,9 +64,6 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
if (DebugData.DecompiledMemberReferences == null || DebugData.DecompiledMemberReferences.Count == 0 ||
!DebugData.DecompiledMemberReferences.ContainsKey(bm.MemberReference.FullName))
continue;
if (bm is BreakpointBookmark &&
((BreakpointBookmark)bm).Language != DebugData.Language)
continue;
int line = bm.LineNumber;
BookmarkBase existingBookmark;
@ -232,7 +231,7 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit @@ -232,7 +231,7 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
uint token = 0;
foreach (var member in DebugData.DecompiledMemberReferences.Values) {
string memberName = member.FullName;
var instruction = storage[memberName].GetInstructionByTypeAndLine(memberName, line, out token);
var instruction = storage[memberName].GetInstructionByLineNumber(line, out token);
if (instruction == null) {
continue;
@ -257,5 +256,63 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit @@ -257,5 +256,63 @@ namespace ICSharpCode.ILSpy.Debugger.AvalonEdit
InvalidateVisual();
}
}
public void SyncBookmarks()
{
if (DebugData.CodeMappings == null || DebugData.CodeMappings.Count == 0)
return;
//remove existing bookmarks and create new ones
List<BreakpointBookmark> newBookmarks = new List<BreakpointBookmark>();
for (int i = BookmarkManager.Bookmarks.Count - 1; i >= 0; --i) {
var breakpoint = BookmarkManager.Bookmarks[i] as BreakpointBookmark;
if (breakpoint == null)
continue;
foreach (var key in DebugData.CodeMappings.Keys) {
var member = DebugData.DecompiledMemberReferences[key];
uint token;
if (member is TypeDefinition) {
var m = member as TypeDefinition;
if (breakpoint.MemberReference is TypeDefinition) {
if (member != breakpoint.MemberReference)
continue;
token = (uint)member.MetadataToken.ToInt32();
} else {
if (!m.ContainsMember(breakpoint.MemberReference))
continue;
token = (uint)breakpoint.MemberReference.MetadataToken.ToInt32();
}
} else {
if (breakpoint.MemberReference is TypeDefinition) {
if (!(breakpoint.MemberReference as TypeDefinition).ContainsMember(member))
continue;
token = (uint)member.MetadataToken.ToInt32();
} else {
if (breakpoint.MemberReference != member)
continue;
token = (uint)breakpoint.MemberReference.MetadataToken.ToInt32();
}
}
bool isMatch;
SourceCodeMapping map = DebugData.CodeMappings[key]
.GetInstructionByTokenAndOffset(token, breakpoint.ILRange.From, out isMatch);
if (map != null) {
newBookmarks.Add(new BreakpointBookmark(
DebugData.DecompiledMemberReferences[key],
new AstLocation(map.SourceCodeLine, 0),
map.ILInstructionOffset, BreakpointAction.Break, DebugData.Language));
BookmarkManager.RemoveMark(breakpoint);
break;
}
}
}
newBookmarks.ForEach(m => BookmarkManager.AddMark(m));
}
}
}

10
Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs

@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -128,7 +128,7 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
var newLanguage = e.NewLanguage;
SyncCurrentLineBookmark(oldLanguage, newLanguage);
SyncBreakpointBookmarks(oldLanguage, newLanguage);
//SyncBreakpointBookmarks(oldLanguage, newLanguage);
}
/// <summary>
@ -152,7 +152,7 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -152,7 +152,7 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
int line = CurrentLineBookmark.Instance.LineNumber;
var markerType = CurrentLineBookmark.Instance.MemberReference;
if (!oldMappings.ContainsKey(markerType.FullName) || !oldMappings.ContainsKey(markerType.FullName))
if (!oldMappings.ContainsKey(markerType.FullName) || !newMappings.ContainsKey(markerType.FullName))
return;
// 2. Remove it
@ -160,7 +160,7 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -160,7 +160,7 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
// 3. map the marker line
uint token;
var instruction = oldMappings[markerType.FullName].GetInstructionByTypeAndLine(markerType.FullName, line, out token);
var instruction = oldMappings[markerType.FullName].GetInstructionByLineNumber(line, out token);
if (instruction == null)
return;
@ -195,10 +195,10 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -195,10 +195,10 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
foreach (var bp in oldbps) {
uint token;
string name = bp.MemberReference.FullName;
if (!oldMappings.ContainsKey(name) || !oldMappings.ContainsKey(name))
if (!oldMappings.ContainsKey(name) || !newMappings.ContainsKey(name))
continue;
var instruction = oldMappings[name].GetInstructionByTypeAndLine(bp.MemberReference.FullName, bp.LineNumber, out token);
var instruction = oldMappings[name].GetInstructionByLineNumber(bp.LineNumber, out token);
if (instruction == null)
continue;

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

@ -91,7 +91,8 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -91,7 +91,8 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
ITextMarker marker = markerService.Create(offset, length);
marker.BackgroundColor = Color.FromRgb(180, 38, 38);
marker.ForegroundColor = Colors.White;
marker.IsVisible = b => b is MarkerBookmark && DebugData.DecompiledMemberReferences.ContainsKey(((MarkerBookmark)b).MemberReference.FullName);
marker.IsVisible = b => b is MarkerBookmark && DebugData.DecompiledMemberReferences != null &&
DebugData.DecompiledMemberReferences.ContainsKey(((MarkerBookmark)b).MemberReference.FullName);
marker.Bookmark = this;
this.Marker = marker;

3
Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs

@ -81,7 +81,8 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks @@ -81,7 +81,8 @@ namespace ICSharpCode.ILSpy.Debugger.Bookmarks
ITextMarker marker = markerService.Create(offset + startColumn - 1, length + 1);
marker.BackgroundColor = Colors.Yellow;
marker.ForegroundColor = Colors.Blue;
marker.IsVisible = b => b is MarkerBookmark && DebugData.DecompiledMemberReferences.ContainsKey(((MarkerBookmark)b).MemberReference.FullName);
marker.IsVisible = b => b is MarkerBookmark && DebugData.DecompiledMemberReferences != null &&
DebugData.DecompiledMemberReferences.ContainsKey(((MarkerBookmark)b).MemberReference.FullName);
marker.Bookmark = this;
this.Marker = marker;
return marker;

5
Debugger/ILSpy.Debugger/DebuggedData.cs

@ -57,11 +57,6 @@ namespace ICSharpCode.ILSpy.Debugger @@ -57,11 +57,6 @@ namespace ICSharpCode.ILSpy.Debugger
/// </summary>
public static Dictionary<string, MemberReference> DecompiledMemberReferences { get; set; }
/// <summary>
/// Gets or sets the debug type.
/// </summary>
public static bool DebugWholeTypesOnly { get; set; }
/// <summary>
/// Occures when the language is changed.
/// </summary>

18
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -289,10 +289,10 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -289,10 +289,10 @@ namespace ICSharpCode.ILSpy.Debugger.Services
isMatch = false;
frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
var debugType = (DebugType)frame.MethodInfo.DeclaringType;
string nameKey = DebugData.DebugWholeTypesOnly ? debugType.FullNameWithoutGenericArguments : frame.MethodInfo.FullNameWithoutParameterNames;
string nameKey = debugType.FullNameWithoutGenericArguments;
// get the mapped instruction from the current line marker or the next one
return DebugData.CodeMappings[nameKey].GetInstructionByTypeTokenAndOffset(
return DebugData.CodeMappings[nameKey].GetInstructionByTokenAndOffset(
(uint)frame.MethodInfo.MetadataToken,
frame.IP, out isMatch);
}
@ -562,7 +562,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -562,7 +562,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
uint token;
SourceCodeMapping map = DebugData.CodeMappings[bookmark.MemberReference.FullName]
.GetInstructionByTypeAndLine(bookmark.MemberReference.FullName, bookmark.LineNumber, out token);
.GetInstructionByLineNumber(bookmark.LineNumber, out token);
if (map != null) {
var declaringType = bookmark.MemberReference.DeclaringType;
@ -822,7 +822,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -822,7 +822,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
int ilOffset = frame.IP;
int line;
MemberReference memberReference;
string nameKey = DebugData.DebugWholeTypesOnly ? debugType.FullNameWithoutGenericArguments : frame.MethodInfo.FullNameWithoutParameterNames;
string nameKey = debugType.FullNameWithoutGenericArguments;
foreach (var key in DebugData.CodeMappings.Keys) {
if (key.CreateKey() == nameKey.CreateKey()) {
@ -883,15 +883,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -883,15 +883,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
if (!DebugData.CodeMappings.ContainsKey(member.FullName)) {
if (DebugData.Language == DecompiledLanguages.IL) {
var dis = new ReflectionDisassembler(new PlainTextOutput(), true, CancellationToken.None);
dis.DisassembleType(nestedTypeDef ?? typeDef);
// else if (ICSharpCode.Decompiler.CodeMappings.DecompiledMember is MethodDefinition)
// dis.DisassembleMethod(ICSharpCode.Decompiler.CodeMappings.DecompiledMember as MethodDefinition);
// else if (ICSharpCode.Decompiler.CodeMappings.DecompiledMember is PropertyDefinition)
// dis.DisassembleProperty(ICSharpCode.Decompiler.CodeMappings.DecompiledMember as PropertyDefinition);
// else if (ICSharpCode.Decompiler.CodeMappings.DecompiledMember is EventDefinition)
// dis.DisassembleEvent(ICSharpCode.Decompiler.CodeMappings.DecompiledMember as EventDefinition);
dis.DisassembleType(nestedTypeDef ?? typeDef);
codeMappings = dis.CodeMappings;
} else {
AstBuilder builder = new AstBuilder(new DecompilerContext(typeDef.Module));

51
Debugger/ILSpy.Debugger/Services/ExtensionMethods.cs

@ -14,6 +14,8 @@ using System.Windows.Media; @@ -14,6 +14,8 @@ using System.Windows.Media;
using System.Xml;
using System.Xml.Linq;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.Debugger.Services
{
/// <summary>
@ -344,7 +346,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -344,7 +346,7 @@ namespace ICSharpCode.ILSpy.Debugger.Services
int bytes;
while ((bytes = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
targetStream.Write(buffer, 0, bytes);
}
}
}
/// <summary>
@ -358,8 +360,8 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -358,8 +360,8 @@ namespace ICSharpCode.ILSpy.Debugger.Services
public static ScrollViewer GetScrollViewer(this DependencyObject o)
{
var scrollViewer = o as ScrollViewer;
if (scrollViewer != null) {
return scrollViewer;
if (scrollViewer != null) {
return scrollViewer;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
@ -398,5 +400,48 @@ namespace ICSharpCode.ILSpy.Debugger.Services @@ -398,5 +400,48 @@ namespace ICSharpCode.ILSpy.Debugger.Services
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset);
}
/// <summary>
/// Verifies if the type contains the member.
/// </summary>
/// <param name="type"></param>
/// <param name="member"></param>
/// <returns></returns>
public static bool ContainsMember(this TypeDefinition type, MemberReference member)
{
// check fields
if (member is FieldDefinition) {
foreach (var field in type.Fields) {
if (field == member)
return true;
}
}
// check properties
if (member is PropertyDefinition) {
foreach (var field in type.Properties) {
if (field.Resolve() == member)
return true;
}
}
// check methods
if (member is MethodDefinition) {
foreach (var field in type.Methods) {
if (field == member)
return true;
}
}
// check events
if (member is EventDefinition) {
foreach (var field in type.Events) {
if (field == member)
return true;
}
}
return false;
}
}
}

6
ICSharpCode.Decompiler/CodeMappings.cs

@ -201,9 +201,8 @@ namespace ICSharpCode.Decompiler @@ -201,9 +201,8 @@ namespace ICSharpCode.Decompiler
/// <param name="lineNumber">Line number.</param>
/// <param name="metadataToken">Metadata token.</param>
/// <returns></returns>
public static SourceCodeMapping GetInstructionByTypeAndLine(
public static SourceCodeMapping GetInstructionByLineNumber(
this List<MemberMapping> codeMappings,
string memberReferenceName,
int lineNumber,
out uint metadataToken)
{
@ -226,12 +225,11 @@ namespace ICSharpCode.Decompiler @@ -226,12 +225,11 @@ namespace ICSharpCode.Decompiler
/// Gets a mapping given a type, a token and an IL offset.
/// </summary>
/// <param name="codeMappings">Code mappings storage.</param>
/// <param name="memberReferenceName">Member reference name.</param>
/// <param name="token">Token.</param>
/// <param name="ilOffset">IL offset.</param>
/// <param name="isMatch">True, if perfect match.</param>
/// <returns>A code mapping.</returns>
public static SourceCodeMapping GetInstructionByTypeTokenAndOffset(
public static SourceCodeMapping GetInstructionByTokenAndOffset(
this List<MemberMapping> codeMappings,
uint token,
int ilOffset,

6
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -347,10 +347,8 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -347,10 +347,8 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleType(TypeDefinition type)
{
// create IL code mappings - used for debugger
if (this.CodeMappings == null) {
this.CodeMappings.Add(type.FullName, new List<MemberMapping>());
this.DecompiledMemberReferences.Add(type.FullName, type);
}
this.CodeMappings.Add(type.FullName, new List<MemberMapping>());
this.DecompiledMemberReferences.Add(type.FullName, type);
// start writing IL
output.WriteDefinition(".class ", type);

3
ILSpy/Options/DebuggerSettingsPanel.xaml

@ -5,9 +5,6 @@ @@ -5,9 +5,6 @@
<Grid>
<StackPanel Margin="10">
<CheckBox IsChecked="{Binding ShowWarnings}">Show warning messages</CheckBox>
<CheckBox
ToolTip="If checked, debug only whole types; otherwise debug only methods or properties."
IsChecked="{Binding DebugWholeTypesOnly}">Debug whole types only</CheckBox>
</StackPanel>
</Grid>
</UserControl>

6
ILSpy/Options/DebuggerSettingsPanel.xaml.cs

@ -21,8 +21,7 @@ namespace ICSharpCode.ILSpy.Options @@ -21,8 +21,7 @@ namespace ICSharpCode.ILSpy.Options
{
private const string DEBUGGER_SETTINGS = "DebuggerSettings";
private const string SHOW_WARNINGS = "showWarnings";
private const string DEBUG_WHOLE_TYPES_ONLY = "debugWholeTypesOnly";
public DebuggerSettingsPanel()
{
InitializeComponent();
@ -46,7 +45,7 @@ namespace ICSharpCode.ILSpy.Options @@ -46,7 +45,7 @@ namespace ICSharpCode.ILSpy.Options
XElement e = settings[DEBUGGER_SETTINGS];
DebuggerSettings s = new DebuggerSettings();
s.ShowWarnings = (bool?)e.Attribute(SHOW_WARNINGS) ?? s.ShowWarnings;
s.DebugWholeTypesOnly = (bool?)e.Attribute(DEBUG_WHOLE_TYPES_ONLY) ?? s.DebugWholeTypesOnly;
return s;
}
@ -55,7 +54,6 @@ namespace ICSharpCode.ILSpy.Options @@ -55,7 +54,6 @@ namespace ICSharpCode.ILSpy.Options
var s = (DebuggerSettings)this.DataContext;
XElement section = new XElement(DEBUGGER_SETTINGS);
section.SetAttributeValue(SHOW_WARNINGS, s.ShowWarnings);
section.SetAttributeValue(DEBUG_WHOLE_TYPES_ONLY, s.DebugWholeTypesOnly);
XElement existingElement = root.Element(DEBUGGER_SETTINGS);
if (existingElement != null)

5
ILSpy/TextView/DecompilerTextView.cs

@ -380,11 +380,10 @@ namespace ICSharpCode.ILSpy.TextView @@ -380,11 +380,10 @@ namespace ICSharpCode.ILSpy.TextView
isDecompilationOk = false;
}
finally {
// sync bookmarks
iconMargin.SyncBookmarks();
// set the language
DebugData.Language = MainWindow.Instance.sessionSettings.FilterSettings.Language.Name.StartsWith("IL") ? DecompiledLanguages.IL : DecompiledLanguages.CSharp;
bool debugOnlyTypes = DebuggerSettingsPanel.CurrentDebuggerSettings.DebugWholeTypesOnly;
DebugData.DebugWholeTypesOnly = debugOnlyTypes;
if (isDecompilationOk) {
if (DebugData.DecompiledMemberReferences != null && DebugData.DecompiledMemberReferences.Count > 0) {

Loading…
Cancel
Save