Skip to content
Browse files

Remove dynamic code. Simplify debugging decompiled code.

  • Loading branch information...
1 parent 0b5295f commit 5d5d266a9d8a1c9dceaa2bebf8e2f89c275c4c4d @eusebiu eusebiu committed with dgrunwald Aug 17, 2011
View
30 src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs
@@ -1,8 +1,10 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
+using System;
using System.Windows;
using System.Windows.Controls;
+
using Debugger;
using Debugger.AddIn.Pads.Controls;
using ICSharpCode.Core;
@@ -26,7 +28,7 @@ public BreakPointsPad()
CreateColumns();
}
-
+
void InitializeComponents()
{
debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
@@ -52,7 +54,7 @@ protected override ToolBar CreateToolBar()
return toolbar;
}
- protected override void CreateColumns()
+ protected override void CreateColumns()
{
string conditionHeader = StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.ConditionalColumnHeader}");
@@ -66,5 +68,29 @@ protected override bool ShowBookmarkInThisPad(SDBookmark mark)
{
return mark.IsVisibleInBookmarkPad && mark is BreakpointBookmark;
}
+
+ protected override void OnItemActivated(object sender, EventArgs e)
+ {
+ var node = CurrentItem;
+ if (node == null)
+ return;
+ SDBookmark mark = node.Mark as SDBookmark;
+ if (mark == null)
+ return;
+
+ string fileName = mark.FileName;
+ if (mark is DecompiledBreakpointBookmark) {
+ // get information from breakpoint and navigate to the decompiled type
+ string assemblyFile, typeName;
+ if (DecompiledBreakpointBookmark.GetAssemblyAndType(fileName, out assemblyFile, out typeName)) {
+ NavigationService.NavigateTo(assemblyFile, typeName, string.Empty, mark.LineNumber, false);
+ }
+ } else {
+ // jump to normal breakpoint
+ FileService.JumpToFilePosition(fileName, mark.LineNumber, 1);
+
+ // TODO: if other types of breakpoint bookmarks are available, one should do jumping/navigation here
+ }
+ }
}
}
View
147 src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
@@ -2,7 +2,6 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
@@ -583,7 +582,7 @@ public Value GetValueFromName(string variableName)
var stackFrame = !debuggedProcess.IsInExternalCode ? debuggedProcess.SelectedStackFrame : debuggedProcess.SelectedThread.MostRecentStackFrame;
try {
- object data = debuggerDecompilerService.GetLocalVariableIndex(stackFrame.MethodInfo.DeclaringType.MetadataToken,
+ object data = debuggerDecompilerService.GetLocalVariableIndex(stackFrame.MethodInfo.DeclaringType.MetadataToken,
stackFrame.MethodInfo.MetadataToken,
variableName);
// evaluate expression
@@ -723,7 +722,7 @@ public void InitializeService()
// init NDebugger
debugger = new NDebugger();
- debugger.Options = DebuggingOptions.Instance;
+ debugger.Options = DebuggingOptions.Instance;
debugger.DebuggerTraceMessage += debugger_TraceMessage;
debugger.Processes.Added += debugger_ProcessStarted;
debugger.Processes.Removed += debugger_ProcessExited;
@@ -755,29 +754,42 @@ void AddBreakpoint(BreakpointBookmark bookmark)
Breakpoint breakpoint = null;
if (bookmark is DecompiledBreakpointBookmark) {
- var dbb = (DecompiledBreakpointBookmark)bookmark;
- var memberReference = dbb.MemberReference;
- int token = memberReference.MetadataToken.ToInt32();
-
- if (!debuggerDecompilerService.CheckMappings(token))
- debuggerDecompilerService.DecompileOnDemand(memberReference as TypeDefinition);
-
- int[] ilRanges;
- int methodToken;
- if (debuggerDecompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) {
- dbb.ILFrom = ilRanges[0];
- dbb.ILTo = ilRanges[1];
- // create BP
- breakpoint = new ILBreakpoint(
- debugger,
- dbb.MemberReference.FullName,
- dbb.LineNumber,
- memberReference.MetadataToken.ToInt32(),
- methodToken,
- dbb.ILFrom,
- dbb.IsEnabled);
+ try {
+ if (debuggerDecompilerService == null) {
+ LoggingService.Warn("No IDebuggerDecompilerService found!");
+ return;
+ }
+ var dbb = (DecompiledBreakpointBookmark)bookmark;
+ MemberReference memberReference = null;
- debugger.Breakpoints.Add(breakpoint);
+ string assemblyFile, typeName;
+ if (DecompiledBreakpointBookmark.GetAssemblyAndType(dbb.FileName, out assemblyFile, out typeName)) {
+ memberReference = dbb.GetMemberReference(debuggerDecompilerService.GetAssemblyResolver(assemblyFile));
+ }
+
+ int token = memberReference.MetadataToken.ToInt32();
+ if (!debuggerDecompilerService.CheckMappings(token))
+ debuggerDecompilerService.DecompileOnDemand(memberReference as TypeDefinition);
+
+ int[] ilRanges;
+ int methodToken;
+ if (debuggerDecompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) {
+ dbb.ILFrom = ilRanges[0];
+ dbb.ILTo = ilRanges[1];
+ // create BP
+ breakpoint = new ILBreakpoint(
+ debugger,
+ memberReference.FullName,
+ dbb.LineNumber,
+ memberReference.MetadataToken.ToInt32(),
+ methodToken,
+ dbb.ILFrom,
+ dbb.IsEnabled);
+
+ debugger.Breakpoints.Add(breakpoint);
+ }
+ } catch (System.Exception ex) {
+ LoggingService.Error("Error on DecompiledBreakpointBookmark: " + ex.Message);
}
} else {
breakpoint = debugger.Breakpoints.Add(bookmark.FileName, null, bookmark.LineNumber, 0, bookmark.IsEnabled);
@@ -1038,56 +1050,49 @@ public void JumpToCurrentLine()
DebuggerService.JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
}
} else {
- if (debuggerDecompilerService == null) {
- LoggingService.Warn("No IDebuggerDecompilerService found!");
- return;
- }
- // use most recent stack frame because we don't have the symbols
- var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
- if (frame == null)
- return;
- int typeToken = frame.MethodInfo.DeclaringType.MetadataToken;
-
- // get external data
- int methodToken = frame.MethodInfo.MetadataToken;
- int ilOffset = frame.IP;
-
- int[] ilRanges = null;
- int line = -1;
- bool isMatch = false;
- if (debuggerDecompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) {
- debuggerDecompilerService.DebugStepInformation = null; // we do not need to step into/out
-
- // update marker
- var debugType = (DebugType)frame.MethodInfo.DeclaringType;
-
- foreach (dynamic vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<AbstractViewContentWithoutFile>()) {
- if (vc == null || vc.MemberReference == null)
- continue;
-
- if (vc.MemberReference.MetadataToken.ToInt32() == debugType.MetadataToken) {
- CurrentLineBookmark.SetPosition(vc, line, 0, line, 0);
- var wbw = vc.WorkbenchWindow as IWorkbenchWindow;
- if (wbw != null)
- wbw.SelectWindow();
- return;
- }
- }
- // the decompiled content was closed so we have to recreate it
- StepIntoUnknownFrame(frame, methodToken, ilOffset);
- } else {
- StepIntoUnknownFrame(frame, methodToken, ilOffset);
- }
-
+ JumpToDecompiledCode();
}
}
-
- void StepIntoUnknownFrame(Debugger.StackFrame frame, int token, int ilOffset)
+
+ void JumpToDecompiledCode()
{
+ if (debuggerDecompilerService == null) {
+ LoggingService.Warn("No IDebuggerDecompilerService found!");
+ return;
+ }
+
+ // check for options - if these options are enabled, debugging decompiled code should not continue
+ if (debuggedProcess.Options.EnableJustMyCode || debuggedProcess.Options.StepOverNoSymbols) {
+ LoggingService.Info("Decompiled code debugging is disabled!");
+ return;
+ }
+
+ // use most recent stack frame because we don't have the symbols
+ var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
+ Debug.Assert(frame != null);
+
+ // get external data
+ int typeToken = frame.MethodInfo.DeclaringType.MetadataToken;
+ int methodToken = frame.MethodInfo.MetadataToken;
+ int ilOffset = frame.IP;
+ int[] ilRanges = null;
+ int line = -1;
+ bool isMatch = false;
var debugType = (DebugType)frame.MethodInfo.DeclaringType;
- string fullName = debugType.FullNameWithoutGenericArguments;
- debuggerDecompilerService.DebugStepInformation = Tuple.Create(token, ilOffset);
- NavigationService.NavigateTo(debugType.DebugModule.FullPath, debugType.FullNameWithoutGenericArguments, string.Empty);
+ debuggerDecompilerService.DebugStepInformation = Tuple.Create(methodToken, ilOffset);
+
+ if (debuggerDecompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) {
+ // update marker & navigate to line
+ NavigationService.NavigateTo(debugType.DebugModule.FullPath,
+ debugType.FullNameWithoutGenericArguments,
+ string.Empty,
+ line);
+ } else {
+ // no line => do decompilation
+ NavigationService.NavigateTo(debugType.DebugModule.FullPath,
+ debugType.FullNameWithoutGenericArguments,
+ string.Empty);
+ }
}
StopAttachedProcessDialogResult ShowStopAttachedProcessDialog()
View
3 src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs
@@ -105,8 +105,7 @@ protected void OnClosed()
if (provider != null) {
editor = provider.TextEditor;
} else {
- dynamic codeView = viewContent.Control;
- editor = codeView.TextEditor as ITextEditor;
+ editor = viewContent.GetService(typeof(ITextEditor)) as ITextEditor;
}
if (editor != null) {
View
18 src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/IconBarMargin.cs
@@ -238,14 +238,16 @@ protected override void OnMouseUp(MouseButtonEventArgs e)
DebuggerService.ToggleBreakpointAt(textEditor, line);
return;
}
- // create breakpoint for the decompiled content
- dynamic viewContent = WorkbenchSingleton.Workbench.ActiveContent;
- if (viewContent is AbstractViewContentWithoutFile) {
- dynamic codeView = ((AbstractViewContentWithoutFile)viewContent).Control;
- var editor = codeView.TextEditor as ITextEditor;
- var memberReference = viewContent.MemberReference as MemberReference;
- if (editor != null && !string.IsNullOrEmpty(editor.FileName))
- DebuggerService.ToggleBreakpointAt(memberReference, editor, line);
+
+ // create breakpoint for the other posible active contents
+ var viewContent = WorkbenchSingleton.Workbench.ActiveContent as AbstractViewContentWithoutFile;
+ if (viewContent != null && viewContent.Tag is MemberReference) {
+ var memberReference = (MemberReference)viewContent.Tag;
+ textEditor = viewContent.Services.GetService(typeof(ITextEditor)) as ITextEditor;
+ if (textEditor != null) {
+ DebuggerService.ToggleBreakpointAt(memberReference, textEditor, line);
+ return;
+ }
}
}
}
View
19 src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs
@@ -3,10 +3,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.ILAst;
+using ICSharpCode.ILSpyAddIn.LaunchILSpy;
using ICSharpCode.SharpDevelop.Debugging;
using Mono.Cecil;
@@ -17,6 +19,8 @@ namespace ICSharpCode.ILSpyAddIn
/// </summary>
public class DebuggerDecompilerService : IDebuggerDecompilerService
{
+ ILSpyAssemblyResolver resolver;
+
static DebuggerDecompilerService()
{
DebugInformation = new ConcurrentDictionary<int, DecompileInformation>();
@@ -166,5 +170,20 @@ public object GetLocalVariableIndex(int typeToken, int memberToken, string name)
return null;
}
+
+ public IAssemblyResolver GetAssemblyResolver(string assemblyFile)
+ {
+ if (string.IsNullOrEmpty(assemblyFile))
+ throw new ArgumentException("assemblyFile is null or empty");
+
+ string folderPath = Path.GetDirectoryName(assemblyFile);
+ if (resolver == null)
+ return (resolver = new ILSpyAssemblyResolver(folderPath));
+
+ if (string.Compare(folderPath, resolver.FolderPath, StringComparison.OrdinalIgnoreCase) != 0)
+ return (resolver = new ILSpyAssemblyResolver(folderPath));
+
+ return resolver;
+ }
}
}
View
5 src/AddIns/DisplayBindings/ILSpyAddIn/LaunchILSpy/ILSpyAssemblyResolver.cs
@@ -22,10 +22,15 @@ public ILSpyAssemblyResolver(string decompiledAssemblyFolder)
if (string.IsNullOrEmpty(decompiledAssemblyFolder))
throw new ArgumentException("Invalid working folder");
+ FolderPath = decompiledAssemblyFolder;
this.directoryInfo = new DirectoryInfo(decompiledAssemblyFolder);
this.cache = new Dictionary<string, AssemblyDefinition> ();
}
+ public string FolderPath {
+ get; private set;
+ }
+
public AssemblyDefinition Resolve(AssemblyNameReference name)
{
return this.Resolve(name, new ReaderParameters());
View
42 src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs
@@ -48,29 +48,45 @@ public static void NavigateTo(string assemblyFile, string typeName, string entit
if (string.IsNullOrEmpty(typeName))
throw new ArgumentException("typeName is null or empty");
- foreach (var vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
- if (string.Equals(vc.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == vc.FullTypeName) {
- vc.WorkbenchWindow.SelectWindow();
- vc.JumpToEntity(entityTag);
+ foreach (var viewContent in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
+ if (string.Equals(viewContent.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == viewContent.FullTypeName) {
+ viewContent.WorkbenchWindow.SelectWindow();
+ viewContent.JumpToEntity(entityTag);
return;
}
}
WorkbenchSingleton.Workbench.ShowView(new DecompiledViewContent(assemblyFile, typeName, entityTag));
}
- public bool NavigateToMember(string assemblyFile, string typeName, string entityTag, int lineNumber)
+ public bool NavigateToMember(string assemblyFile, string typeName, string entityTag, int lineNumber, bool updateMarker)
{
- //close the window if exists - this is a workaround
- foreach (var vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
- if (string.Equals(vc.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == vc.FullTypeName) {
- vc.WorkbenchWindow.CloseWindow(true);
- break;
+ if (string.IsNullOrEmpty(assemblyFile))
+ throw new ArgumentException("assemblyFile is null or empty");
+
+ if (string.IsNullOrEmpty(typeName))
+ throw new ArgumentException("typeName is null or empty");
+
+ // jump to line number if the decompiled view content exits - no need for a new decompilation
+ foreach (var viewContent in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
+ if (string.Equals(viewContent.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == viewContent.FullTypeName) {
+ if (updateMarker) {
+ viewContent.UpdateDebuggingUI();
+ }
+ viewContent.JumpToLineNumber(lineNumber);
+ viewContent.WorkbenchWindow.SelectWindow();
+ return true;
}
}
- var view = new DecompiledViewContent(assemblyFile, typeName, entityTag);
- view.DecompilationFinished += delegate { view.JumpTo(lineNumber); };
- WorkbenchSingleton.Workbench.ShowView(view);
+ // create a new decompiled view
+ var decompiledView = new DecompiledViewContent(assemblyFile, typeName, entityTag);
+ decompiledView.DecompilationFinished += delegate {
+ if (updateMarker) {
+ decompiledView.UpdateDebuggingUI();
+ }
+ decompiledView.JumpToLineNumber(lineNumber);
+ };
+ WorkbenchSingleton.Workbench.ShowView(decompiledView);
return true;
}
}
View
27 src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs
@@ -25,17 +25,17 @@ class DecompiledTextEditorAdapter : AvalonEditTextEditorAdapter
public DecompiledTextEditorAdapter(TextEditor textEditor) : base(textEditor)
{}
- public string DecompiledFullTypeName { get; set; }
+ public string DecompiledFileName { get; set; }
public override ICSharpCode.Core.FileName FileName {
- get { return ICSharpCode.Core.FileName.Create(DecompiledFullTypeName); }
+ get { return ICSharpCode.Core.FileName.Create(DecompiledFileName); }
}
}
/// <summary>
/// Equivalent to AE.AddIn CodeEditor, but without editing capabilities.
/// </summary>
- public class CodeView : Grid, IDisposable, ICodeEditor
+ class CodeView : Grid, IDisposable, ICodeEditor
{
public event EventHandler DocumentChanged;
@@ -44,11 +44,10 @@ public class CodeView : Grid, IDisposable, ICodeEditor
readonly IconBarMargin iconMargin;
readonly TextMarkerService textMarkerService;
- public CodeView(string decompiledFullTypeName)
+ public CodeView(string decompiledFileName)
{
- DecompiledFullTypeName = decompiledFullTypeName;
this.adapter = new DecompiledTextEditorAdapter(new SharpDevelopTextEditor { IsReadOnly = true }) {
- DecompiledFullTypeName = decompiledFullTypeName
+ DecompiledFileName = decompiledFileName
};
this.Children.Add(adapter.TextEditor);
adapter.TextEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#");
@@ -64,6 +63,7 @@ public CodeView(string decompiledFullTypeName)
this.adapter.TextEditor.TextArea.TextView.LineTransformers.Add(textMarkerService);
this.adapter.TextEditor.TextArea.TextView.Services.AddService(typeof(ITextMarkerService), textMarkerService);
this.adapter.TextEditor.TextArea.TextView.Services.AddService(typeof(IBookmarkMargin), iconBarManager);
+ // DON'T add the editor in textview ervices - will mess the setting of breakpoints
// add events
this.adapter.TextEditor.MouseHover += TextEditorMouseHover;
@@ -230,16 +230,6 @@ void TextEditorMouseLeave(object sender, MouseEventArgs e)
get { return iconBarManager; }
}
- public AvalonEditTextEditorAdapter Adapter {
- get {
- return adapter;
- }
- }
-
- public string DecompiledFullTypeName {
- get; private set;
- }
-
public void Dispose()
{
}
@@ -249,9 +239,9 @@ public void UnfoldAndScroll(int lineNumber)
if (lineNumber <= 0 || lineNumber > adapter.Document.TotalNumberOfLines)
return;
- //var line = adapter.TextEditor.Document.GetLineByNumber(lineNumber);
+// var line = adapter.TextEditor.Document.GetLineByNumber(lineNumber);
- // unfold
+// // unfold
// var foldings = foldingManager.GetFoldingsContaining(line.Offset);
// if (foldings != null) {
// foreach (var folding in foldings) {
@@ -260,6 +250,7 @@ public void UnfoldAndScroll(int lineNumber)
// }
// }
// }
+
// scroll to
adapter.TextEditor.ScrollTo(lineNumber, 0);
}
View
77 src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs
@@ -16,6 +16,7 @@
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Bookmarks;
using ICSharpCode.SharpDevelop.Debugging;
+using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
using Mono.Cecil;
@@ -24,7 +25,7 @@ namespace ICSharpCode.ILSpyAddIn
/// <summary>
/// Hosts a decompiled type.
/// </summary>
- public class DecompiledViewContent : AbstractViewContentWithoutFile
+ class DecompiledViewContent : AbstractViewContentWithoutFile
{
readonly string assemblyFile;
readonly string fullTypeName;
@@ -43,14 +44,17 @@ public class DecompiledViewContent : AbstractViewContentWithoutFile
#region Constructor
public DecompiledViewContent(string assemblyFile, string fullTypeName, string entityTag)
{
- codeView = new CodeView(string.Format("{0},{1}", assemblyFile, fullTypeName));
+ // TODO: create options for decompiling in a specific language
+ this.tempFileName = string.Format("{0}{1}{2}.cs", assemblyFile, DecompiledBreakpointBookmark.SEPARATOR, fullTypeName);
+ this.codeView = new CodeView(tempFileName);
+
this.assemblyFile = assemblyFile;
this.fullTypeName = fullTypeName;
this.jumpToEntityTagWhenDecompilationFinished = entityTag;
string shortTypeName = fullTypeName.Substring(fullTypeName.LastIndexOf('.') + 1);
this.TitleName = "[" + shortTypeName + "]";
- tempFileName = string.Format("decompiled/{0}.cs", fullTypeName);
+
this.InfoTip = tempFileName;
Thread thread = new Thread(DecompilationThread);
@@ -59,6 +63,9 @@ public DecompiledViewContent(string assemblyFile, string fullTypeName, string en
BookmarkManager.Removed += BookmarkManager_Removed;
BookmarkManager.Added += BookmarkManager_Added;
+
+ // add services
+ this.Services.AddService(typeof(ITextEditor), this.codeView.TextEditor);
}
#endregion
@@ -83,6 +90,10 @@ public DecompiledViewContent(string assemblyFile, string fullTypeName, string en
get; private set;
}
+ public override object Tag {
+ get { return MemberReference; }
+ }
+
#endregion
#region Dispose
@@ -194,9 +205,8 @@ void OnDecompilationFinished(StringWriter output)
// update UI
UpdateIconMargin(output.ToString());
- UpdateDebuggingUI();
- // fire event
+ // fire events
OnDecompilationFinished(EventArgs.Empty);
}
#endregion
@@ -207,56 +217,73 @@ void UpdateIconMargin(string text)
codeView.IconBarManager.UpdateClassMemberBookmarks(ParserService.ParseFile(tempFileName, new StringTextBuffer(text)));
// load bookmarks
- foreach (SDBookmark bookmark in BookmarkManager.GetBookmarks(codeView.Adapter.FileName)) {
- bookmark.Document = codeView.Adapter.Document;
+ foreach (SDBookmark bookmark in BookmarkManager.GetBookmarks(this.codeView.TextEditor.FileName)) {
+ bookmark.Document = this.codeView.TextEditor.Document;
codeView.IconBarManager.Bookmarks.Add(bookmark);
}
}
- void UpdateDebuggingUI()
+ public void UpdateDebuggingUI()
{
if (!DebuggerService.IsDebuggerStarted)
return;
if (MemberReference == null || MemberReference.MetadataToken == null)
return;
- int typeToken = MemberReference.MetadataToken.ToInt32();
+ int typeToken = MemberReference.MetadataToken.ToInt32();
if (!DebuggerDecompilerService.DebugInformation.ContainsKey(typeToken))
return;
- if (DebuggerDecompilerService.Instance == null || DebuggerDecompilerService.Instance.DebugStepInformation == null)
+ var decompilerService = DebuggerDecompilerService.Instance;
+ if (decompilerService == null || decompilerService.DebugStepInformation == null)
return;
// get debugging information
DecompileInformation debugInformation = (DecompileInformation)DebuggerDecompilerService.DebugInformation[typeToken];
- int token = DebuggerDecompilerService.Instance.DebugStepInformation.Item1;
- int ilOffset = DebuggerDecompilerService.Instance.DebugStepInformation.Item2;
+ int methodToken = decompilerService.DebugStepInformation.Item1;
+ int ilOffset = decompilerService.DebugStepInformation.Item2;
int line;
MemberReference member;
- if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(token))
+ if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(methodToken))
return;
- debugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out member, out line);
+ debugInformation.CodeMappings[methodToken].GetInstructionByTokenAndOffset(methodToken, ilOffset, out member, out line);
- // HACK : if the codemappings are not built
+ // if the codemappings are not built
if (line <= 0) {
DebuggerService.CurrentDebugger.StepOver();
return;
}
- // update bookmark & marker
- codeView.UnfoldAndScroll(line);
- CurrentLineBookmark.SetPosition(this, line, 0, line, 0);
+
+ // jump to line - scoll and unfold
+ this.UpdateCurrentLineBookmark(line);
+ this.JumpToLineNumber(line);
}
- public void JumpTo(int lineNumber)
- {
- if (codeView == null)
+ public void JumpToLineNumber(int lineNumber)
+ {
+ if (codeView == null || codeView.Document == null)
return;
if (lineNumber <= 0 || lineNumber > codeView.Document.LineCount)
return;
-
+
codeView.UnfoldAndScroll(lineNumber);
}
+
+ void UpdateCurrentLineBookmark(int lineNumber)
+ {
+ if (lineNumber <= 0)
+ return;
+
+ CurrentLineBookmark.SetPosition(codeView.TextEditor.FileName, codeView.TextEditor.Document, lineNumber, 0, lineNumber, 0);
+ var currentLineBookmark = BookmarkManager.Bookmarks.OfType<CurrentLineBookmark>().FirstOrDefault();
+ if (currentLineBookmark != null) {
+ // update bookmark & marker
+ codeView.IconBarManager.Bookmarks.Add(currentLineBookmark);
+ currentLineBookmark.Document = this.codeView.TextEditor.Document;
+ }
+ }
+
#endregion
#region Bookmarks
@@ -272,14 +299,15 @@ void BookmarkManager_Removed(object sender, BookmarkEventArgs e)
void BookmarkManager_Added(object sender, BookmarkEventArgs e)
{
var mark = e.Bookmark;
- if (mark != null && mark is BreakpointBookmark && mark.FileName == codeView.DecompiledFullTypeName) {
+ if (mark != null && mark is BreakpointBookmark && mark.FileName == this.codeView.TextEditor.FileName) {
codeView.IconBarManager.Bookmarks.Add(mark);
- mark.Document = codeView.Adapter.Document;
+ mark.Document = this.codeView.TextEditor.Document;
}
}
#endregion
#region Events
+
public event EventHandler DecompilationFinished;
protected virtual void OnDecompilationFinished(EventArgs e)
@@ -288,6 +316,7 @@ protected virtual void OnDecompilationFinished(EventArgs e)
DecompilationFinished(this, e);
}
}
+
#endregion
}
}
View
34 src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPad.cs
@@ -72,14 +72,14 @@ protected BookmarkPadBase()
listView.SetValue(Grid.RowProperty, 1);
myPanel.Children.Add(listView);
- BookmarkManager.Added += new BookmarkEventHandler(BookmarkManagerAdded);
- BookmarkManager.Removed += new BookmarkEventHandler(BookmarkManagerRemoved);
+ BookmarkManager.Added += BookmarkManagerAdded;
+ BookmarkManager.Removed += BookmarkManagerRemoved;
foreach (SDBookmark mark in BookmarkManager.Bookmarks) {
AddMark(mark);
}
- listView.ItemActivated += new EventHandler(listView_ItemActivated);
+ listView.ItemActivated += new EventHandler(OnItemActivated);
}
public IEnumerable<ListViewPadItemModel> AllItems {
@@ -120,6 +120,12 @@ public void SelectItem(ListViewPadItemModel model)
listView.CurrentItem = model;
}
+ public override void Dispose()
+ {
+ BookmarkManager.Added -= BookmarkManagerAdded;
+ BookmarkManager.Removed -= BookmarkManagerRemoved;
+ }
+
void AddMark(SDBookmark mark)
{
if (!ShowBookmarkInThisPad(mark))
@@ -133,6 +139,17 @@ protected virtual bool ShowBookmarkInThisPad(SDBookmark mark)
return mark.IsVisibleInBookmarkPad && !(mark is BreakpointBookmark);
}
+ protected virtual void OnItemActivated(object sender, EventArgs e)
+ {
+ var node = CurrentItem;
+ if (node != null) {
+ SDBookmark mark = node.Mark as SDBookmark;
+ if (mark != null) {
+ FileService.JumpToFilePosition(mark.FileName, mark.LineNumber, 1);
+ }
+ }
+ }
+
void BookmarkManagerAdded(object sender, BookmarkEventArgs e)
{
AddMark((SDBookmark)e.Bookmark);
@@ -143,16 +160,5 @@ void BookmarkManagerRemoved(object sender, BookmarkEventArgs e)
if (ShowBookmarkInThisPad(e.Bookmark))
listView.Remove(new ListViewPadItemModel(e.Bookmark));
}
-
- void listView_ItemActivated(object sender, EventArgs e)
- {
- var node = CurrentItem;
- if (node != null) {
- SDBookmark mark = node.Mark as SDBookmark;
- if (mark != null) {
- FileService.JumpToFilePosition(mark.FileName, mark.LineNumber, 1);
- }
- }
- }
}
}
View
7 src/Main/Base/Project/Src/Gui/AbstractViewContentWithoutFile.cs
@@ -16,6 +16,13 @@ namespace ICSharpCode.SharpDevelop.Gui
/// </summary>
public abstract class AbstractViewContentWithoutFile : AbstractViewContent, ICustomizedCommands
{
+ /// <summary>
+ /// Gets specific information (from implementations) regarding this view content.
+ /// </summary>
+ public virtual object Tag {
+ get { return null; }
+ }
+
public override bool IsViewOnly {
get { return false; }
}
View
15 src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs
@@ -22,24 +22,11 @@ public class CurrentLineBookmark : SDMarkerBookmark
static int endLine;
static int endColumn;
- public static void SetPosition(IViewContent viewContent, int markerStartLine, int markerStartColumn, int markerEndLine, int markerEndColumn)
+ public static void SetPosition(IViewContent viewContent, int markerStartLine, int markerStartColumn, int markerEndLine, int markerEndColumn)
{
ITextEditorProvider tecp = viewContent as ITextEditorProvider;
if (tecp != null) {
SetPosition(tecp.TextEditor.FileName, tecp.TextEditor.Document, markerStartLine, markerStartColumn, markerEndLine, markerEndColumn);
- } else {
- lock (syncObject) {
- // get the decompiled view if exists
- if (viewContent != null && viewContent.Control != null) {
- dynamic codeView = viewContent.Control;
- var document = codeView.TextEditor.Document as IDocument;
- SetPosition(codeView.Adapter.FileName, document, markerStartLine, markerStartColumn, markerEndLine, markerEndColumn);
- codeView.IconBarManager.Bookmarks.Add(CurrentLineBookmark.instance);
- codeView.UnfoldAndScroll(markerStartLine);
- if (document != null)
- CurrentLineBookmark.instance.Document = document;
- }
- }
}
}
View
7 src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
@@ -479,5 +479,12 @@ public interface IDebuggerDecompilerService
/// Gets the local variable index.
/// </summary>
object GetLocalVariableIndex(int typeToken, int memberToken, string name);
+
+ /// <summary>
+ /// Gets an implementation of an assembly resolver.
+ /// </summary>
+ /// <param name="assemblyFile">Assembly file path.</param>
+ /// <returns>An <see cref="IAssemblyResolver"/>.</returns>
+ IAssemblyResolver GetAssemblyResolver(string assemblyFile);
}
}
View
67 src/Main/Base/Project/Src/Services/Debugger/DecompiledBreakpointBookmark.cs
@@ -10,9 +10,14 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
{
public class DecompiledBreakpointBookmark : BreakpointBookmark
{
+ public const string SEPARATOR = ","; // don't use '.'
+
+ MemberReference memberReference;
+ string assemblyFile;
+
public DecompiledBreakpointBookmark(MemberReference member, int ilFrom, int ilTo, FileName fileName, Location location, BreakpointAction action, string scriptLanguage, string script) : base(fileName, location, action, scriptLanguage, script)
{
- this.MemberReference = member;
+ this.memberReference = member;
this.ILFrom = ilFrom;
this.ILTo = ILTo;
}
@@ -25,32 +30,52 @@ public DecompiledBreakpointBookmark(MemberReference member, int ilFrom, int ilTo
get; set;
}
- MemberReference memberReference;
-
public MemberReference MemberReference {
- get {
- if (memberReference != null)
- return memberReference;
-
- // reload from filename
- ReaderParameters readerParameters = new ReaderParameters();
- // Use new assembly resolver instance so that the AssemblyDefinitions can be garbage-collected
- // once the code is decompiled.
- readerParameters.AssemblyResolver = new DefaultAssemblyResolver();
-
- string fileName = FileName.ToString();
- int index = fileName.IndexOf(",");
- string assemblyFile = fileName.Substring(0, index);
- string fullTypeName = fileName.Substring(index + 1, fileName.Length - index - 1);
-
+ get { return memberReference; }
+ }
+
+ public MemberReference GetMemberReference(IAssemblyResolver resolver)
+ {
+ if (resolver == null)
+ throw new ArgumentNullException("resolver");
+
+ if (memberReference != null)
+ return memberReference;
+
+ // reload from filename
+ ReaderParameters readerParameters = new ReaderParameters();
+ // Use new assembly resolver instance so that the AssemblyDefinitions can be garbage-collected
+ // once the code is decompiled.
+ readerParameters.AssemblyResolver = resolver;
+
+ string typeName;
+ if (GetAssemblyAndType(FileName.ToString(), out assemblyFile, out typeName)) {
ModuleDefinition module = ModuleDefinition.ReadModule(assemblyFile, readerParameters);
- TypeDefinition typeDefinition = module.GetType(fullTypeName);
+ TypeDefinition typeDefinition = module.GetType(typeName);
if (typeDefinition == null)
throw new InvalidOperationException("Could not find type");
memberReference = typeDefinition;
- return memberReference;
}
- private set { memberReference = value; }
+
+ return memberReference;
+ }
+
+ /// <summary>
+ /// Gets the assembly file and the type from the file name.
+ /// </summary>
+ /// <returns><c>true</c>, if the operation succeded; <c>false</c>, otherwise.</returns>
+ public static bool GetAssemblyAndType(string fileName, out string assemblyFile, out string typeName)
+ {
+ if (string.IsNullOrEmpty(fileName) || !fileName.Contains(",")) {
+ assemblyFile = null;
+ typeName = null;
+ return false;
+ }
+
+ int index = fileName.IndexOf(SEPARATOR);
+ assemblyFile = fileName.Substring(0, index);
+ typeName = fileName.Substring(index + 1, fileName.Length - index - 4);
+ return true;
}
}
}
View
9 src/Main/Base/Project/Src/Services/File/FileService.cs
@@ -533,15 +533,6 @@ public static IViewContent JumpToFilePosition(string fileName, int line, int col
bool loggingResumed = false;
try {
- // jump to decompiled type from filename
- if (fileName.Contains(",")) {
- int index = fileName.IndexOf(",");
- string assemblyName = fileName.Substring(0, index);
- string typeName = fileName.Substring(index + 1, fileName.Length - index - 1);
- NavigationService.NavigateTo(assemblyName, typeName, string.Empty, line);
- return null;
- }
-
IViewContent content = OpenFile(fileName);
if (content is IPositionable) {
// TODO: enable jumping to a particular view
View
7 src/Main/Base/Project/Src/Services/NavigationService/NavigationService.cs
@@ -6,7 +6,6 @@
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
-using Mono.Cecil;
namespace ICSharpCode.SharpDevelop
{
@@ -475,7 +474,7 @@ public static bool NavigateTo(Dom.IEntity entity)
#region Navigate to Member
- public static bool NavigateTo(string assemblyFile, string typeName, string entityTag, int lineNumber = 0)
+ public static bool NavigateTo(string assemblyFile, string typeName, string entityTag, int lineNumber = 0, bool updateMarker = true)
{
if (string.IsNullOrEmpty(assemblyFile))
throw new ArgumentException("assemblyFile is null or empty");
@@ -484,7 +483,7 @@ public static bool NavigateTo(string assemblyFile, string typeName, string entit
throw new ArgumentException("typeName is null or empty");
foreach (var item in AddInTree.BuildItems<INavigateToMemberService>("/SharpDevelop/Services/NavigateToEntityService", null, false)) {
- if (item.NavigateToMember(assemblyFile, typeName, entityTag, lineNumber))
+ if (item.NavigateToMember(assemblyFile, typeName, entityTag, lineNumber, updateMarker))
return true;
}
return false;
@@ -512,6 +511,6 @@ public interface INavigateToEntityService
/// </remarks>
public interface INavigateToMemberService
{
- bool NavigateToMember(string assemblyFile, string typeName, string entityTag, int lineNumber);
+ bool NavigateToMember(string assemblyFile, string typeName, string entityTag, int lineNumber, bool updateMarker);
}
}

0 comments on commit 5d5d266

Please sign in to comment.
Something went wrong with that request. Please try again.