|
|
@ -13,55 +13,8 @@ namespace ILSpy.Debugger.Bookmarks |
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Static class that maintains the list of bookmarks and breakpoints.
|
|
|
|
/// Static class that maintains the list of bookmarks and breakpoints.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public static class BookmarkManager |
|
|
|
public static partial class BookmarkManager |
|
|
|
{ |
|
|
|
{ |
|
|
|
static BookmarkManager() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
DebugData.LanguageChanged += OnLanguageChanged; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void OnLanguageChanged(object sender, LanguageEventArgs e) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var oldLanguage = e.OldLanguage; |
|
|
|
|
|
|
|
var newLanguage = e.NewLanguage; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// synchronize the IL<->C# breakpoints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. map the breakpoint lines
|
|
|
|
|
|
|
|
var oldbps = bookmarks.FindAll(b => b is BreakpointBookmark && ((BreakpointBookmark)b).Language == oldLanguage); |
|
|
|
|
|
|
|
if (oldbps == null || oldbps.Count == 0) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var oldMappings = CodeMappings.GetStorage(oldLanguage); |
|
|
|
|
|
|
|
var newMappings = CodeMappings.GetStorage(newLanguage); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (oldMappings == null || oldMappings.Count == 0 || |
|
|
|
|
|
|
|
newMappings == null || newMappings.Count == 0) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var bp in oldbps) { |
|
|
|
|
|
|
|
uint token; |
|
|
|
|
|
|
|
var instruction = oldMappings.GetInstructionByTypeAndLine(DebugData.CurrentType.FullName, bp.LineNumber, out token); |
|
|
|
|
|
|
|
if (instruction == null) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TypeDefinition type; |
|
|
|
|
|
|
|
int line; |
|
|
|
|
|
|
|
if (newMappings.GetSourceCodeFromMetadataTokenAndOffset(token, instruction.ILInstructionOffset.From, out type, out line)) { |
|
|
|
|
|
|
|
// 2. create breakpoint for new languages
|
|
|
|
|
|
|
|
var bookmark = new BreakpointBookmark(type, new AstLocation(line, 0), BreakpointAction.Break, newLanguage); |
|
|
|
|
|
|
|
AddMark(bookmark); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. remove all breakpoints for the old language
|
|
|
|
|
|
|
|
for (int i = bookmarks.Count - 1; i >= 0; --i) { |
|
|
|
|
|
|
|
var bm = bookmarks[i]; |
|
|
|
|
|
|
|
if (bm is BreakpointBookmark && ((BreakpointBookmark)bm).Language == oldLanguage) |
|
|
|
|
|
|
|
RemoveMark(bm); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static List<BookmarkBase> bookmarks = new List<BookmarkBase>(); |
|
|
|
static List<BookmarkBase> bookmarks = new List<BookmarkBase>(); |
|
|
|
|
|
|
|
|
|
|
|
public static List<BookmarkBase> Bookmarks { |
|
|
|
public static List<BookmarkBase> Bookmarks { |
|
|
@ -160,4 +113,103 @@ namespace ILSpy.Debugger.Bookmarks |
|
|
|
public static event BookmarkEventHandler Removed; |
|
|
|
public static event BookmarkEventHandler Removed; |
|
|
|
public static event BookmarkEventHandler Added; |
|
|
|
public static event BookmarkEventHandler Added; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is for the synchronize bookmarks logic
|
|
|
|
|
|
|
|
public static partial class BookmarkManager |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static BookmarkManager() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
DebugData.LanguageChanged += OnLanguageChanged; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void OnLanguageChanged(object sender, LanguageEventArgs e) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var oldLanguage = e.OldLanguage; |
|
|
|
|
|
|
|
var newLanguage = e.NewLanguage; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SyncCurrentLineBookmark(oldLanguage, newLanguage); |
|
|
|
|
|
|
|
SyncBreakpointBookmarks(oldLanguage, newLanguage); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Synchronize the IL<->C# current line marker.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <param name="oldLanguage">Old language.</param>
|
|
|
|
|
|
|
|
/// <param name="newLanguage">New language.</param>
|
|
|
|
|
|
|
|
static void SyncCurrentLineBookmark(DecompiledLanguages oldLanguage, DecompiledLanguages newLanguage) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// checks
|
|
|
|
|
|
|
|
if (CurrentLineBookmark.Instance == null) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var oldMappings = CodeMappings.GetStorage(oldLanguage); |
|
|
|
|
|
|
|
var newMappings = CodeMappings.GetStorage(newLanguage); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (oldMappings == null || oldMappings.Count == 0 || newMappings == null || newMappings.Count == 0) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. Save it's data
|
|
|
|
|
|
|
|
int line = CurrentLineBookmark.Instance.LineNumber; |
|
|
|
|
|
|
|
var markerType = CurrentLineBookmark.Instance.Type; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Remove it
|
|
|
|
|
|
|
|
CurrentLineBookmark.Remove(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. map the marker line
|
|
|
|
|
|
|
|
uint token; |
|
|
|
|
|
|
|
var instruction = oldMappings.GetInstructionByTypeAndLine(markerType.FullName, line, out token); |
|
|
|
|
|
|
|
if (instruction == null) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TypeDefinition type; |
|
|
|
|
|
|
|
int newline; |
|
|
|
|
|
|
|
if (newMappings.GetSourceCodeFromMetadataTokenAndOffset(token, instruction.ILInstructionOffset.From, out type, out newline)) { |
|
|
|
|
|
|
|
// 4. create breakpoint for new languages
|
|
|
|
|
|
|
|
CurrentLineBookmark.SetPosition(type, newline, 0, newline, 0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Synchronize the IL<->C# breakpoints bookmarks.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
/// <param name="oldLanguage">Old language.</param>
|
|
|
|
|
|
|
|
/// <param name="newLanguage">New language.</param>
|
|
|
|
|
|
|
|
static void SyncBreakpointBookmarks(DecompiledLanguages oldLanguage, DecompiledLanguages newLanguage) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// checks
|
|
|
|
|
|
|
|
var oldMappings = CodeMappings.GetStorage(oldLanguage); |
|
|
|
|
|
|
|
var newMappings = CodeMappings.GetStorage(newLanguage); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (oldMappings == null || oldMappings.Count == 0 || newMappings == null || newMappings.Count == 0) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. map the breakpoint lines
|
|
|
|
|
|
|
|
var oldbps = bookmarks.FindAll(b => b is BreakpointBookmark && |
|
|
|
|
|
|
|
((BreakpointBookmark)b).Language == oldLanguage); |
|
|
|
|
|
|
|
if (oldbps == null || oldbps.Count == 0) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var bp in oldbps) { |
|
|
|
|
|
|
|
uint token; |
|
|
|
|
|
|
|
var instruction = oldMappings.GetInstructionByTypeAndLine(bp.Type.FullName, bp.LineNumber, out token); |
|
|
|
|
|
|
|
if (instruction == null) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TypeDefinition type; |
|
|
|
|
|
|
|
int line; |
|
|
|
|
|
|
|
if (newMappings.GetSourceCodeFromMetadataTokenAndOffset(token, instruction.ILInstructionOffset.From, out type, out line)) { |
|
|
|
|
|
|
|
// 2. create breakpoint for new languages
|
|
|
|
|
|
|
|
var bookmark = new BreakpointBookmark(type, new AstLocation(line, 0), BreakpointAction.Break, newLanguage); |
|
|
|
|
|
|
|
AddMark(bookmark); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. remove all breakpoints for the old language
|
|
|
|
|
|
|
|
for (int i = bookmarks.Count - 1; i >= 0; --i) { |
|
|
|
|
|
|
|
var bm = bookmarks[i]; |
|
|
|
|
|
|
|
if (bm is BreakpointBookmark && ((BreakpointBookmark)bm).Language == oldLanguage) |
|
|
|
|
|
|
|
RemoveMark(bm); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|