mirror of https://github.com/icsharpcode/ILSpy.git
32 changed files with 243 additions and 2529 deletions
@ -1,14 +0,0 @@ |
|||||||
// 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.Windows; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.AvalonEdit |
|
||||||
{ |
|
||||||
public interface ITextEditorListener : IWeakEventListener |
|
||||||
{ |
|
||||||
new bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e); |
|
||||||
void ClosePopup(); |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,35 +0,0 @@ |
|||||||
// 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.Windows; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.AvalonEdit |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Content of text editor tooltip (used as <see cref="ToolTipRequestEventArgs.ContentToShow"/>),
|
|
||||||
/// specifying whether it should be displayed in a WPF Popup.
|
|
||||||
/// </summary>
|
|
||||||
public interface ITooltip |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// If true, this ITooltip will be displayed in a WPF Popup.
|
|
||||||
/// Otherwise it will be displayed in a WPF Tooltip.
|
|
||||||
/// WPF Popups are (unlike WPF Tooltips) focusable.
|
|
||||||
/// </summary>
|
|
||||||
bool ShowAsPopup { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Closes this tooltip.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="mouseClick">True if close request is raised
|
|
||||||
/// because of mouse click on some SharpDevelop GUI element.</param>
|
|
||||||
/// <returns>True if Close succeeded (that is, can close). False otherwise.</returns>
|
|
||||||
bool Close(bool mouseClick); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when this tooltip decides to close.
|
|
||||||
/// </summary>
|
|
||||||
event RoutedEventHandler Closed; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,47 +0,0 @@ |
|||||||
// 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 System.Collections.ObjectModel; |
|
||||||
using System.Collections.Specialized; |
|
||||||
using System.Linq; |
|
||||||
|
|
||||||
using ICSharpCode.ILSpy.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.Debugger; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.AvalonEdit |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Stores the entries in the icon bar margin. Multiple icon bar margins
|
|
||||||
/// can use the same manager if split view is used.
|
|
||||||
/// </summary>
|
|
||||||
public class IconBarManager : IBookmarkMargin |
|
||||||
{ |
|
||||||
ObservableCollection<IBookmark> bookmarks = new ObservableCollection<IBookmark>(); |
|
||||||
|
|
||||||
public IconBarManager() |
|
||||||
{ |
|
||||||
bookmarks.CollectionChanged += bookmarks_CollectionChanged; |
|
||||||
} |
|
||||||
|
|
||||||
public IList<IBookmark> Bookmarks { |
|
||||||
get { return bookmarks; } |
|
||||||
} |
|
||||||
|
|
||||||
void bookmarks_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
|
||||||
{ |
|
||||||
Redraw(); |
|
||||||
} |
|
||||||
|
|
||||||
public void Redraw() |
|
||||||
{ |
|
||||||
if (RedrawRequested != null) |
|
||||||
RedrawRequested(this, EventArgs.Empty); |
|
||||||
} |
|
||||||
|
|
||||||
public event EventHandler RedrawRequested; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,353 +0,0 @@ |
|||||||
// 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 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.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.Debugger; |
|
||||||
using ICSharpCode.ILSpy.Debugger.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.Debugger.Services; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.AvalonEdit |
|
||||||
{ |
|
||||||
public class IconBarMargin : AbstractMargin, IDisposable |
|
||||||
{ |
|
||||||
readonly IconBarManager manager; |
|
||||||
|
|
||||||
public IconBarMargin(IconBarManager manager) |
|
||||||
{ |
|
||||||
BookmarkManager.Added += new BookmarkEventHandler(OnBookmarkAdded); |
|
||||||
BookmarkManager.Removed += new BookmarkEventHandler(OnBookmarkRemoved); |
|
||||||
|
|
||||||
this.manager = manager; |
|
||||||
} |
|
||||||
|
|
||||||
public IconBarManager Manager { |
|
||||||
get { return manager; } |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void Dispose() |
|
||||||
{ |
|
||||||
this.TextView = null; // detach from TextView (will also detach from manager)
|
|
||||||
} |
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) |
|
||||||
{ |
|
||||||
// accept clicks even when clicking on the background
|
|
||||||
return new PointHitTestResult(this, hitTestParameters.HitPoint); |
|
||||||
} |
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
protected override Size MeasureOverride(Size availableSize) |
|
||||||
{ |
|
||||||
// 16px wide icon + 1px each side padding + 1px right-side border
|
|
||||||
return new Size(19, 0); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnRender(DrawingContext drawingContext) |
|
||||||
{ |
|
||||||
Size renderSize = this.RenderSize; |
|
||||||
drawingContext.DrawRectangle(SystemColors.ControlBrush, null, |
|
||||||
new Rect(0, 0, renderSize.Width, renderSize.Height)); |
|
||||||
drawingContext.DrawLine(new Pen(SystemColors.ControlDarkBrush, 1), |
|
||||||
new Point(renderSize.Width - 0.5, 0), |
|
||||||
new Point(renderSize.Width - 0.5, renderSize.Height)); |
|
||||||
|
|
||||||
ICSharpCode.AvalonEdit.Rendering.TextView textView = this.TextView; |
|
||||||
if (textView != null && textView.VisualLinesValid) { |
|
||||||
// create a dictionary line number => first bookmark
|
|
||||||
Dictionary<int, IBookmark> bookmarkDict = new Dictionary<int, IBookmark>(); |
|
||||||
foreach (var bm in BookmarkManager.Bookmarks) { |
|
||||||
if (bm is BreakpointBookmark) { |
|
||||||
if (DebugInformation.CodeMappings == null || DebugInformation.CodeMappings.Count == 0 || |
|
||||||
!DebugInformation.CodeMappings.ContainsKey(((BreakpointBookmark)bm).FunctionToken)) |
|
||||||
continue; |
|
||||||
} |
|
||||||
int line = bm.LineNumber; |
|
||||||
IBookmark existingBookmark; |
|
||||||
if (!bookmarkDict.TryGetValue(line, out existingBookmark) || bm.ZOrder > existingBookmark.ZOrder) |
|
||||||
bookmarkDict[line] = bm; |
|
||||||
} |
|
||||||
|
|
||||||
foreach (var bm in manager.Bookmarks) { |
|
||||||
int line = bm.LineNumber; |
|
||||||
IBookmark existingBookmark; |
|
||||||
if (!bookmarkDict.TryGetValue(line, out existingBookmark) || bm.ZOrder > existingBookmark.ZOrder) |
|
||||||
bookmarkDict[line] = bm; |
|
||||||
} |
|
||||||
|
|
||||||
const double imagePadding = 1.0; |
|
||||||
Size pixelSize = PixelSnapHelpers.GetPixelSize(this); |
|
||||||
foreach (VisualLine line in textView.VisualLines) { |
|
||||||
int lineNumber = line.FirstDocumentLine.LineNumber; |
|
||||||
IBookmark bm; |
|
||||||
if (bookmarkDict.TryGetValue(lineNumber, out bm)) { |
|
||||||
Rect rect = new Rect(imagePadding, PixelSnapHelpers.Round(line.VisualTop - textView.VerticalOffset, pixelSize.Height), 16, 16); |
|
||||||
if (dragDropBookmark == bm && dragStarted) |
|
||||||
drawingContext.PushOpacity(0.5); |
|
||||||
drawingContext.DrawImage(bm.Image, rect); |
|
||||||
if (dragDropBookmark == bm && dragStarted) |
|
||||||
drawingContext.Pop(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (dragDropBookmark != null && dragStarted) { |
|
||||||
Rect rect = new Rect(imagePadding, PixelSnapHelpers.Round(dragDropCurrentPoint - 8, pixelSize.Height), 16, 16); |
|
||||||
drawingContext.DrawImage(dragDropBookmark.Image, rect); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IBookmark dragDropBookmark; // bookmark being dragged (!=null if drag'n'drop is active)
|
|
||||||
double dragDropStartPoint; |
|
||||||
double dragDropCurrentPoint; |
|
||||||
bool dragStarted; // whether drag'n'drop operation has started (mouse was moved minimum distance)
|
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseDown(e); |
|
||||||
int line = GetLineFromMousePosition(e); |
|
||||||
if (!e.Handled && line > 0) { |
|
||||||
IBookmark bm = GetBookmarkFromLine(line); |
|
||||||
if (bm != null) { |
|
||||||
bm.MouseDown(e); |
|
||||||
if (!e.Handled) { |
|
||||||
if (e.ChangedButton == MouseButton.Left && bm.CanDragDrop && CaptureMouse()) { |
|
||||||
StartDragDrop(bm, e); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// don't allow selecting text through the IconBarMargin
|
|
||||||
if (e.ChangedButton == MouseButton.Left) |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
|
|
||||||
IBookmark GetBookmarkFromLine(int line) |
|
||||||
{ |
|
||||||
BookmarkBase result = null; |
|
||||||
foreach (BookmarkBase bm in BookmarkManager.Bookmarks) { |
|
||||||
if (bm.LineNumber != line) |
|
||||||
continue; |
|
||||||
if (bm is BreakpointBookmark) { |
|
||||||
if (DebugInformation.CodeMappings == null || DebugInformation.CodeMappings.Count == 0 || |
|
||||||
!DebugInformation.CodeMappings.ContainsKey(((BreakpointBookmark)bm).FunctionToken)) |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (result == null || bm.ZOrder > result.ZOrder) |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
return manager.Bookmarks.FirstOrDefault(b => b.LineNumber == line); |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnLostMouseCapture(MouseEventArgs e) |
|
||||||
{ |
|
||||||
CancelDragDrop(); |
|
||||||
base.OnLostMouseCapture(e); |
|
||||||
} |
|
||||||
|
|
||||||
void StartDragDrop(IBookmark bm, MouseEventArgs e) |
|
||||||
{ |
|
||||||
dragDropBookmark = bm; |
|
||||||
dragDropStartPoint = dragDropCurrentPoint = e.GetPosition(this).Y; |
|
||||||
if (TextView != null) { |
|
||||||
TextArea area = TextView.Services.GetService(typeof(TextArea)) as TextArea; |
|
||||||
if (area != null) |
|
||||||
area.PreviewKeyDown += TextArea_PreviewKeyDown; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void CancelDragDrop() |
|
||||||
{ |
|
||||||
if (dragDropBookmark != null) { |
|
||||||
dragDropBookmark = null; |
|
||||||
dragStarted = false; |
|
||||||
if (TextView != null) { |
|
||||||
TextArea area = TextView.Services.GetService(typeof(TextArea)) as TextArea; |
|
||||||
if (area != null) |
|
||||||
area.PreviewKeyDown -= TextArea_PreviewKeyDown; |
|
||||||
} |
|
||||||
ReleaseMouseCapture(); |
|
||||||
InvalidateVisual(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void TextArea_PreviewKeyDown(object sender, KeyEventArgs e) |
|
||||||
{ |
|
||||||
// any key press cancels drag'n'drop
|
|
||||||
CancelDragDrop(); |
|
||||||
if (e.Key == Key.Escape) |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
|
|
||||||
public int GetLineFromMousePosition(MouseEventArgs e) |
|
||||||
{ |
|
||||||
ICSharpCode.AvalonEdit.Rendering.TextView textView = this.TextView; |
|
||||||
if (textView == null) |
|
||||||
return 0; |
|
||||||
VisualLine vl = textView.GetVisualLineFromVisualTop(e.GetPosition(textView).Y + textView.ScrollOffset.Y); |
|
||||||
if (vl == null) |
|
||||||
return 0; |
|
||||||
return vl.FirstDocumentLine.LineNumber; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseMove(e); |
|
||||||
if (dragDropBookmark != null) { |
|
||||||
dragDropCurrentPoint = e.GetPosition(this).Y; |
|
||||||
if (Math.Abs(dragDropCurrentPoint - dragDropStartPoint) > SystemParameters.MinimumVerticalDragDistance) |
|
||||||
dragStarted = true; |
|
||||||
InvalidateVisual(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected override void OnMouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
base.OnMouseUp(e); |
|
||||||
int line = GetLineFromMousePosition(e); |
|
||||||
if (!e.Handled && dragDropBookmark != null) { |
|
||||||
if (dragStarted) { |
|
||||||
if (line != 0) |
|
||||||
dragDropBookmark.Drop(line); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
CancelDragDrop(); |
|
||||||
} |
|
||||||
if (!e.Handled && line != 0) { |
|
||||||
var bm = GetBookmarkFromLine(line); |
|
||||||
if (bm != null) { |
|
||||||
bm.MouseUp(e); |
|
||||||
|
|
||||||
if (bm is BookmarkBase) { |
|
||||||
if ((bm as BookmarkBase).CanToggle) { |
|
||||||
BookmarkManager.RemoveMark(bm as BookmarkBase); |
|
||||||
InvalidateVisual(); |
|
||||||
} |
|
||||||
} |
|
||||||
if (e.Handled) |
|
||||||
return; |
|
||||||
} |
|
||||||
if (e.ChangedButton == MouseButton.Left) { |
|
||||||
// see IBookmarkActionEntry interface
|
|
||||||
} |
|
||||||
InvalidateVisual(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void OnBookmarkAdded(object sender, BookmarkEventArgs args) |
|
||||||
{ |
|
||||||
var breakpoint = args.Bookmark as BreakpointBookmark; |
|
||||||
if (null == breakpoint) |
|
||||||
return; |
|
||||||
var storage = DebugInformation.CodeMappings; |
|
||||||
if (storage == null || storage.Count == 0) |
|
||||||
return; |
|
||||||
var key = breakpoint.MemberReference.MetadataToken.ToInt32(); |
|
||||||
if (storage.ContainsKey(key)) |
|
||||||
{ |
|
||||||
// register to show enabled/disabled state
|
|
||||||
breakpoint.ImageChanged += delegate { InvalidateVisual(); }; |
|
||||||
InvalidateVisual(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void OnBookmarkRemoved(object sender, BookmarkEventArgs args) |
|
||||||
{ |
|
||||||
var breakpoint = args.Bookmark as BreakpointBookmark; |
|
||||||
if (null == breakpoint) |
|
||||||
return; |
|
||||||
var storage = DebugInformation.CodeMappings; |
|
||||||
if (storage == null || storage.Count == 0) |
|
||||||
return; |
|
||||||
var key = breakpoint.MemberReference.MetadataToken.ToInt32(); |
|
||||||
if (storage.ContainsKey(key)) |
|
||||||
{ |
|
||||||
breakpoint.ImageChanged -= delegate { InvalidateVisual(); }; |
|
||||||
InvalidateVisual(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void SyncBookmarks() |
|
||||||
{ |
|
||||||
var storage = DebugInformation.CodeMappings; |
|
||||||
if (storage == null || storage.Count == 0) |
|
||||||
return; |
|
||||||
|
|
||||||
// TODO: handle other types of bookmarks
|
|
||||||
// remove existing bookmarks and create new ones
|
|
||||||
// update of existing bookmarks for new position does not update TextMarker
|
|
||||||
// this is only done in TextMarkerService handlers for BookmarkManager.Added/Removed
|
|
||||||
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; |
|
||||||
|
|
||||||
var key = breakpoint.FunctionToken; |
|
||||||
if (!storage.ContainsKey(key)) |
|
||||||
continue; |
|
||||||
|
|
||||||
bool isMatch; |
|
||||||
SourceCodeMapping map = storage[key].GetInstructionByTokenAndOffset(breakpoint.ILRange.From, out isMatch); |
|
||||||
|
|
||||||
if (map != null) { |
|
||||||
BreakpointBookmark newBookmark = new BreakpointBookmark(breakpoint.MemberReference, |
|
||||||
new TextLocation(map.StartLocation.Line, 0), |
|
||||||
breakpoint.FunctionToken, |
|
||||||
map.ILInstructionOffset, |
|
||||||
BreakpointAction.Break); |
|
||||||
newBookmark.IsEnabled = breakpoint.IsEnabled; |
|
||||||
|
|
||||||
newBookmarks.Add(newBookmark); |
|
||||||
|
|
||||||
BookmarkManager.RemoveMark(breakpoint); |
|
||||||
} |
|
||||||
} |
|
||||||
newBookmarks.ForEach(m => BookmarkManager.AddMark(m)); |
|
||||||
SyncCurrentLineBookmark(); |
|
||||||
} |
|
||||||
|
|
||||||
void SyncCurrentLineBookmark() |
|
||||||
{ |
|
||||||
// checks
|
|
||||||
if (CurrentLineBookmark.Instance == null) |
|
||||||
return; |
|
||||||
|
|
||||||
var codeMappings = DebugInformation.CodeMappings; |
|
||||||
if (codeMappings == null) |
|
||||||
return; |
|
||||||
|
|
||||||
// 1. Save it's data
|
|
||||||
int line = CurrentLineBookmark.Instance.LineNumber; |
|
||||||
var markerType = CurrentLineBookmark.Instance.MemberReference; |
|
||||||
int token = markerType.MetadataToken.ToInt32(); |
|
||||||
int offset = CurrentLineBookmark.Instance.ILOffset; |
|
||||||
|
|
||||||
if (!codeMappings.ContainsKey(token)) |
|
||||||
return; |
|
||||||
|
|
||||||
// 2. map the marker line
|
|
||||||
MemberReference memberReference; |
|
||||||
int newline; |
|
||||||
if (codeMappings[token].GetInstructionByTokenAndOffset(offset, out memberReference, out newline)) { |
|
||||||
// 3. create breakpoint for new languages
|
|
||||||
DebuggerService.JumpToCurrentLine(memberReference, newline, 0, newline, 0, offset); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,52 +0,0 @@ |
|||||||
// 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.Windows; |
|
||||||
using ICSharpCode.AvalonEdit; |
|
||||||
using ICSharpCode.AvalonEdit.Utils; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.AvalonEdit |
|
||||||
{ |
|
||||||
public static class TextEditorWeakEventManager |
|
||||||
{ |
|
||||||
public sealed class MouseHover : WeakEventManagerBase<MouseHover, TextEditor> |
|
||||||
{ |
|
||||||
protected override void StopListening(TextEditor source) |
|
||||||
{ |
|
||||||
source.MouseHover -= DeliverEvent; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void StartListening(TextEditor source) |
|
||||||
{ |
|
||||||
source.MouseHover += DeliverEvent; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public sealed class MouseHoverStopped : WeakEventManagerBase<MouseHoverStopped, TextEditor> |
|
||||||
{ |
|
||||||
protected override void StopListening(TextEditor source) |
|
||||||
{ |
|
||||||
source.MouseHoverStopped -= DeliverEvent; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void StartListening(TextEditor source) |
|
||||||
{ |
|
||||||
source.MouseHoverStopped += DeliverEvent; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public sealed class MouseDown : WeakEventManagerBase<MouseDown, TextEditor> |
|
||||||
{ |
|
||||||
protected override void StopListening(TextEditor source) |
|
||||||
{ |
|
||||||
source.MouseDown -= DeliverEvent; |
|
||||||
} |
|
||||||
|
|
||||||
protected override void StartListening(TextEditor source) |
|
||||||
{ |
|
||||||
source.MouseDown += DeliverEvent; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,97 +0,0 @@ |
|||||||
// 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.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Bookmarks |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// A bookmark that can be attached to an AvalonEdit TextDocument.
|
|
||||||
/// </summary>
|
|
||||||
public class BookmarkBase : IBookmark |
|
||||||
{ |
|
||||||
TextLocation location; |
|
||||||
|
|
||||||
protected virtual void RemoveMark() |
|
||||||
{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
public TextLocation Location { |
|
||||||
get { return location; } |
|
||||||
set { location = value; } |
|
||||||
} |
|
||||||
|
|
||||||
public event EventHandler DocumentChanged; |
|
||||||
|
|
||||||
protected virtual void OnDocumentChanged(EventArgs e) |
|
||||||
{ |
|
||||||
if (DocumentChanged != null) { |
|
||||||
DocumentChanged(this, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected virtual void Redraw() |
|
||||||
{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
public MemberReference MemberReference { get; set; } |
|
||||||
|
|
||||||
public int LineNumber { |
|
||||||
get { return location.Line; } |
|
||||||
} |
|
||||||
|
|
||||||
public int ColumnNumber { |
|
||||||
get { return location.Column; } |
|
||||||
} |
|
||||||
|
|
||||||
public virtual int ZOrder { |
|
||||||
get { return 0; } |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the bookmark can be toggled off using the 'set/unset bookmark' command.
|
|
||||||
/// </summary>
|
|
||||||
public virtual bool CanToggle { |
|
||||||
get { |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public BookmarkBase(MemberReference member, TextLocation location) |
|
||||||
{ |
|
||||||
this.MemberReference = member; |
|
||||||
this.Location = location; |
|
||||||
} |
|
||||||
|
|
||||||
public virtual ImageSource Image { |
|
||||||
get { return null; } |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void MouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void MouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
if (e.ChangedButton == MouseButton.Left && CanToggle) { |
|
||||||
RemoveMark(); |
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual bool CanDragDrop { |
|
||||||
get { return false; } |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void Drop(int lineNumber) |
|
||||||
{ |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,28 +0,0 @@ |
|||||||
// 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; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Bookmarks |
|
||||||
{ |
|
||||||
public delegate void BookmarkEventHandler(object sender, BookmarkEventArgs e); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Description of BookmarkEventHandler.
|
|
||||||
/// </summary>
|
|
||||||
public class BookmarkEventArgs : EventArgs |
|
||||||
{ |
|
||||||
BookmarkBase bookmark; |
|
||||||
|
|
||||||
public BookmarkBase Bookmark { |
|
||||||
get { |
|
||||||
return bookmark; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public BookmarkEventArgs(BookmarkBase bookmark) |
|
||||||
{ |
|
||||||
this.bookmark = bookmark; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,117 +0,0 @@ |
|||||||
// 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 ICSharpCode.Decompiler; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
using Mono.Cecil; |
|
||||||
using Mono.CSharp; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Bookmarks |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Static class that maintains the list of bookmarks and breakpoints.
|
|
||||||
/// </summary>
|
|
||||||
public static partial class BookmarkManager |
|
||||||
{ |
|
||||||
static List<BookmarkBase> bookmarks = new List<BookmarkBase>(); |
|
||||||
|
|
||||||
public static List<BookmarkBase> Bookmarks { |
|
||||||
get { |
|
||||||
return bookmarks; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static List<BookmarkBase> GetBookmarks(string typeName) |
|
||||||
{ |
|
||||||
if (typeName == null) |
|
||||||
throw new ArgumentNullException("typeName"); |
|
||||||
|
|
||||||
List<BookmarkBase> marks = new List<BookmarkBase>(); |
|
||||||
|
|
||||||
foreach (BookmarkBase mark in bookmarks) { |
|
||||||
if (typeName == mark.MemberReference.FullName) { |
|
||||||
marks.Add(mark); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return marks; |
|
||||||
} |
|
||||||
|
|
||||||
public static void AddMark(BookmarkBase bookmark) |
|
||||||
{ |
|
||||||
if (bookmark == null) return; |
|
||||||
if (bookmarks.Contains(bookmark)) return; |
|
||||||
if (bookmarks.Exists(b => IsEqualBookmark(b, bookmark))) return; |
|
||||||
bookmarks.Add(bookmark); |
|
||||||
OnAdded(new BookmarkEventArgs(bookmark)); |
|
||||||
} |
|
||||||
|
|
||||||
static bool IsEqualBookmark(BookmarkBase a, BookmarkBase b) |
|
||||||
{ |
|
||||||
if (a == b) |
|
||||||
return true; |
|
||||||
if (a == null || b == null) |
|
||||||
return false; |
|
||||||
if (a.GetType() != b.GetType()) |
|
||||||
return false; |
|
||||||
if (a.MemberReference.FullName != b.MemberReference.FullName) |
|
||||||
return false; |
|
||||||
return a.LineNumber == b.LineNumber; |
|
||||||
} |
|
||||||
|
|
||||||
public static void RemoveMark(BookmarkBase bookmark) |
|
||||||
{ |
|
||||||
bookmarks.Remove(bookmark); |
|
||||||
OnRemoved(new BookmarkEventArgs(bookmark)); |
|
||||||
} |
|
||||||
|
|
||||||
public static void Clear() |
|
||||||
{ |
|
||||||
while (bookmarks.Count > 0) { |
|
||||||
var b = bookmarks[bookmarks.Count - 1]; |
|
||||||
bookmarks.RemoveAt(bookmarks.Count - 1); |
|
||||||
OnRemoved(new BookmarkEventArgs(b)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal static void Initialize() |
|
||||||
{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
static void OnRemoved(BookmarkEventArgs e) |
|
||||||
{ |
|
||||||
if (Removed != null) { |
|
||||||
Removed(null, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void OnAdded(BookmarkEventArgs e) |
|
||||||
{ |
|
||||||
if (Added != null) { |
|
||||||
Added(null, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void ToggleBookmark(string typeName, int line, |
|
||||||
Predicate<BookmarkBase> canToggle, |
|
||||||
Func<TextLocation, BookmarkBase> bookmarkFactory) |
|
||||||
{ |
|
||||||
foreach (BookmarkBase bookmark in GetBookmarks(typeName)) { |
|
||||||
if (canToggle(bookmark) && bookmark.LineNumber == line) { |
|
||||||
BookmarkManager.RemoveMark(bookmark); |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// no bookmark at that line: create a new bookmark
|
|
||||||
BookmarkManager.AddMark(bookmarkFactory(new TextLocation(line, 0))); |
|
||||||
} |
|
||||||
|
|
||||||
public static event BookmarkEventHandler Removed; |
|
||||||
public static event BookmarkEventHandler Added; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,115 +0,0 @@ |
|||||||
// 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.Windows.Media; |
|
||||||
using ICSharpCode.Decompiler; |
|
||||||
using ICSharpCode.Decompiler.ILAst; |
|
||||||
using ICSharpCode.ILSpy.AvalonEdit; |
|
||||||
using ICSharpCode.ILSpy.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.SharpDevelop; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Bookmarks |
|
||||||
{ |
|
||||||
public enum BreakpointAction |
|
||||||
{ |
|
||||||
Break, |
|
||||||
Trace, |
|
||||||
Condition |
|
||||||
} |
|
||||||
|
|
||||||
public class BreakpointBookmark : MarkerBookmark |
|
||||||
{ |
|
||||||
bool isHealthy = true; |
|
||||||
bool isEnabled = true; |
|
||||||
BreakpointAction action = BreakpointAction.Break; |
|
||||||
|
|
||||||
public BreakpointAction Action { |
|
||||||
get { |
|
||||||
return action; |
|
||||||
} |
|
||||||
set { |
|
||||||
if (action != value) { |
|
||||||
action = value; |
|
||||||
Redraw(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the function/method where the breakpoint is set.
|
|
||||||
/// <remarks>
|
|
||||||
/// In case of methods, it is the same as the MemberReference metadata token.<br/>
|
|
||||||
/// In case of properties and events, it's the GetMethod/SetMethod|AddMethod/RemoveMethod token.
|
|
||||||
/// </remarks>
|
|
||||||
/// </summary>
|
|
||||||
public int FunctionToken { get; private set; } |
|
||||||
|
|
||||||
public ILRange ILRange { get; private set; } |
|
||||||
|
|
||||||
public virtual bool IsHealthy { |
|
||||||
get { |
|
||||||
return isHealthy; |
|
||||||
} |
|
||||||
set { |
|
||||||
if (isHealthy != value) { |
|
||||||
isHealthy = value; |
|
||||||
Redraw(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public virtual bool IsEnabled { |
|
||||||
get { |
|
||||||
return isEnabled; |
|
||||||
} |
|
||||||
set { |
|
||||||
if (isEnabled != value) { |
|
||||||
isEnabled = value; |
|
||||||
if (IsEnabledChanged != null) |
|
||||||
IsEnabledChanged(this, EventArgs.Empty); |
|
||||||
if (ImageChanged != null) |
|
||||||
ImageChanged(this, EventArgs.Empty); // Image property reflects IsEnabled property
|
|
||||||
Redraw(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public event EventHandler IsEnabledChanged; |
|
||||||
|
|
||||||
public string Tooltip { get; private set; } |
|
||||||
|
|
||||||
public BreakpointBookmark(MemberReference member, TextLocation location, int functionToken, ILRange range, BreakpointAction action) |
|
||||||
: base(member, location) |
|
||||||
{ |
|
||||||
this.action = action; |
|
||||||
this.FunctionToken = functionToken; |
|
||||||
this.ILRange = range; |
|
||||||
this.Tooltip = string.Format("Line:{0}, IL range:{1}-{2}", location.Line, range.From, range.To); |
|
||||||
} |
|
||||||
|
|
||||||
public override ImageSource Image { |
|
||||||
get { |
|
||||||
return IsEnabled ? Images.Breakpoint : Images.DisabledBreakpoint; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public event EventHandler ImageChanged; |
|
||||||
|
|
||||||
public override ITextMarker CreateMarker(ITextMarkerService markerService, int offset, int length) |
|
||||||
{ |
|
||||||
ITextMarker marker = markerService.Create(offset, length); |
|
||||||
marker.BackgroundColor = Color.FromRgb(180, 38, 38); |
|
||||||
marker.ForegroundColor = Colors.White; |
|
||||||
marker.IsVisible = b => b is BreakpointBookmark && DebugInformation.CodeMappings != null && |
|
||||||
DebugInformation.CodeMappings.ContainsKey(((BreakpointBookmark)b).FunctionToken); |
|
||||||
marker.Bookmark = this; |
|
||||||
this.Marker = marker; |
|
||||||
|
|
||||||
return marker; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,23 +0,0 @@ |
|||||||
// 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; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Bookmarks |
|
||||||
{ |
|
||||||
public class BreakpointBookmarkEventArgs : EventArgs |
|
||||||
{ |
|
||||||
BreakpointBookmark breakpointBookmark; |
|
||||||
|
|
||||||
public BreakpointBookmark BreakpointBookmark { |
|
||||||
get { |
|
||||||
return breakpointBookmark; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public BreakpointBookmarkEventArgs(BreakpointBookmark breakpointBookmark) |
|
||||||
{ |
|
||||||
this.breakpointBookmark = breakpointBookmark; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,94 +0,0 @@ |
|||||||
// 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.Windows.Media; |
|
||||||
using ICSharpCode.ILSpy.AvalonEdit; |
|
||||||
using ICSharpCode.ILSpy.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.SharpDevelop; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Bookmarks |
|
||||||
{ |
|
||||||
public class CurrentLineBookmark : MarkerBookmark |
|
||||||
{ |
|
||||||
static CurrentLineBookmark instance; |
|
||||||
|
|
||||||
public static CurrentLineBookmark Instance { |
|
||||||
get { return instance; } |
|
||||||
} |
|
||||||
|
|
||||||
static int startLine; |
|
||||||
static int startColumn; |
|
||||||
static int endLine; |
|
||||||
static int endColumn; |
|
||||||
|
|
||||||
public static void SetPosition(MemberReference memberReference, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn, int ilOffset) |
|
||||||
{ |
|
||||||
Remove(); |
|
||||||
|
|
||||||
startLine = makerStartLine; |
|
||||||
startColumn = makerStartColumn; |
|
||||||
endLine = makerEndLine; |
|
||||||
endColumn = makerEndColumn; |
|
||||||
|
|
||||||
instance = new CurrentLineBookmark(memberReference, new TextLocation(startLine, startColumn), ilOffset); |
|
||||||
BookmarkManager.AddMark(instance); |
|
||||||
} |
|
||||||
|
|
||||||
public static void Remove() |
|
||||||
{ |
|
||||||
if (instance != null) { |
|
||||||
BookmarkManager.RemoveMark(instance); |
|
||||||
instance = null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override bool CanToggle { |
|
||||||
get { return false; } |
|
||||||
} |
|
||||||
|
|
||||||
public override int ZOrder { |
|
||||||
get { return 100; } |
|
||||||
} |
|
||||||
|
|
||||||
private CurrentLineBookmark(MemberReference member, TextLocation location, int ilOffset) : base(member, location) |
|
||||||
{ |
|
||||||
this.ILOffset = ilOffset; |
|
||||||
} |
|
||||||
|
|
||||||
public int ILOffset { get; private set; } |
|
||||||
|
|
||||||
public override ImageSource Image { |
|
||||||
get { return Images.CurrentLine; } |
|
||||||
} |
|
||||||
|
|
||||||
public override bool CanDragDrop { |
|
||||||
get { return false; } |
|
||||||
} |
|
||||||
|
|
||||||
public override void Drop(int lineNumber) |
|
||||||
{ |
|
||||||
// call async because the Debugger seems to use Application.DoEvents(), but we don't want to process events
|
|
||||||
// because Drag'N'Drop operation has finished
|
|
||||||
// WorkbenchSingleton.SafeThreadAsyncCall(
|
|
||||||
// delegate {
|
|
||||||
// DebuggerService.CurrentDebugger.SetInstructionPointer(this.FileName, lineNumber, 1);
|
|
||||||
// });
|
|
||||||
} |
|
||||||
|
|
||||||
public override ITextMarker CreateMarker(ITextMarkerService markerService, int offset, int length) |
|
||||||
{ |
|
||||||
ITextMarker marker = markerService.Create(offset + startColumn - 1, length + 1); |
|
||||||
marker.BackgroundColor = Colors.Yellow; |
|
||||||
marker.ForegroundColor = Colors.Blue; |
|
||||||
marker.IsVisible = b => b is MarkerBookmark && DebugInformation.CodeMappings != null && |
|
||||||
DebugInformation.CodeMappings.ContainsKey(((MarkerBookmark)b).MemberReference.MetadataToken.ToInt32()); |
|
||||||
marker.Bookmark = this; |
|
||||||
this.Marker = marker; |
|
||||||
return marker; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,69 +0,0 @@ |
|||||||
// 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 System.Collections.ObjectModel; |
|
||||||
using System.Collections.Specialized; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Bookmarks |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// The bookmark margin.
|
|
||||||
/// </summary>
|
|
||||||
public interface IBookmarkMargin |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Gets the list of bookmarks.
|
|
||||||
/// </summary>
|
|
||||||
IList<IBookmark> Bookmarks { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Redraws the bookmark margin. Bookmarks need to call this method when the Image changes.
|
|
||||||
/// </summary>
|
|
||||||
void Redraw(); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a bookmark in the bookmark margin.
|
|
||||||
/// </summary>
|
|
||||||
public interface IBookmark |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Gets the line number of the bookmark.
|
|
||||||
/// </summary>
|
|
||||||
int LineNumber { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the image.
|
|
||||||
/// </summary>
|
|
||||||
ImageSource Image { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Z-Order of the bookmark icon.
|
|
||||||
/// </summary>
|
|
||||||
int ZOrder { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles the mouse down event.
|
|
||||||
/// </summary>
|
|
||||||
void MouseDown(MouseButtonEventArgs e); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles the mouse up event.
|
|
||||||
/// </summary>
|
|
||||||
void MouseUp(MouseButtonEventArgs e); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets whether this bookmark can be dragged around.
|
|
||||||
/// </summary>
|
|
||||||
bool CanDragDrop { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Notifies the bookmark that it was dropped on the specified line.
|
|
||||||
/// </summary>
|
|
||||||
void Drop(int lineNumber); |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,22 +0,0 @@ |
|||||||
// 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 ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
using ICSharpCode.ILSpy.AvalonEdit; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Bookmarks |
|
||||||
{ |
|
||||||
public abstract class MarkerBookmark : BookmarkBase |
|
||||||
{ |
|
||||||
public MarkerBookmark(MemberReference member, TextLocation location) : base(member, location) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public ITextMarker Marker { get; set; } |
|
||||||
|
|
||||||
public abstract ITextMarker CreateMarker(ITextMarkerService markerService, int offset, int length); |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,39 +0,0 @@ |
|||||||
// 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.Concurrent; |
|
||||||
using System.Collections.Generic; |
|
||||||
|
|
||||||
using ICSharpCode.Decompiler; |
|
||||||
using ICSharpCode.Decompiler.ILAst; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Contains the data important for debugger from the main application.
|
|
||||||
/// </summary>
|
|
||||||
public static class DebugInformation |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// List of loaded assemblies.
|
|
||||||
/// </summary>
|
|
||||||
public static IEnumerable<AssemblyDefinition> LoadedAssemblies { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the current code mappings.
|
|
||||||
/// </summary>
|
|
||||||
public static Dictionary<int, MemberMapping> CodeMappings { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the current token, IL offset and member reference. Used for step in/out.
|
|
||||||
/// </summary>
|
|
||||||
public static Tuple<int, int, MemberReference> DebugStepInformation { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets whether the debugger is loaded.
|
|
||||||
/// </summary>
|
|
||||||
public static bool IsDebuggerLoaded { get; set; } |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,118 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> |
|
||||||
<PropertyGroup> |
|
||||||
<ProjectGuid>{704F66F1-5C7F-4326-A7AA-C604A3896D4E}</ProjectGuid> |
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
||||||
<OutputType>Library</OutputType> |
|
||||||
<RootNamespace>ICSharpCode.ILSpy.SharpDevelop</RootNamespace> |
|
||||||
<AssemblyName>ILSpy.SharpDevelop.LGPL</AssemblyName> |
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> |
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|
||||||
<BaseAddress>6881280</BaseAddress> |
|
||||||
<SignAssembly>True</SignAssembly> |
|
||||||
<DelaySign>False</DelaySign> |
|
||||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> |
|
||||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> |
|
||||||
<NoStdLib>False</NoStdLib> |
|
||||||
<WarningLevel>4</WarningLevel> |
|
||||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> |
|
||||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile> |
|
||||||
<AssemblyOriginatorKeyFile>..\NRefactory\ICSharpCode.NRefactory.snk</AssemblyOriginatorKeyFile> |
|
||||||
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> |
|
||||||
<OutputPath>bin\Debug\</OutputPath> |
|
||||||
<DebugSymbols>true</DebugSymbols> |
|
||||||
<DebugType>Full</DebugType> |
|
||||||
<Optimize>False</Optimize> |
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
|
||||||
<OutputPath>bin\Release\</OutputPath> |
|
||||||
<DebugSymbols>true</DebugSymbols> |
|
||||||
<DebugType>PdbOnly</DebugType> |
|
||||||
<Optimize>True</Optimize> |
|
||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> |
|
||||||
<DefineConstants>TRACE</DefineConstants> |
|
||||||
</PropertyGroup> |
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> |
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget> |
|
||||||
</PropertyGroup> |
|
||||||
<ItemGroup> |
|
||||||
<Reference Include="PresentationCore"> |
|
||||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="PresentationFramework"> |
|
||||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="System" /> |
|
||||||
<Reference Include="System.Core"> |
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="System.Xaml"> |
|
||||||
<RequiredTargetFramework>4.0</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="System.Xml" /> |
|
||||||
<Reference Include="System.Xml.Linq"> |
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
<Reference Include="WindowsBase"> |
|
||||||
<RequiredTargetFramework>3.0</RequiredTargetFramework> |
|
||||||
</Reference> |
|
||||||
</ItemGroup> |
|
||||||
<ItemGroup> |
|
||||||
<Compile Include="AvalonEdit\IconBarManager.cs" /> |
|
||||||
<Compile Include="AvalonEdit\IconBarMargin.cs" /> |
|
||||||
<Compile Include="AvalonEdit\ITextEditorListener.cs" /> |
|
||||||
<Compile Include="AvalonEdit\ITextMarker.cs" /> |
|
||||||
<Compile Include="AvalonEdit\IToolTip.cs" /> |
|
||||||
<Compile Include="AvalonEdit\TextEditorWeakEventManager.cs" /> |
|
||||||
<Compile Include="AvalonEdit\TextMarkerService.cs" /> |
|
||||||
<Compile Include="Bookmarks\BookmarkBase.cs" /> |
|
||||||
<Compile Include="Bookmarks\BookmarkEventHandler.cs" /> |
|
||||||
<Compile Include="Bookmarks\BookmarkManager.cs" /> |
|
||||||
<Compile Include="Bookmarks\BreakpointBookmark.cs" /> |
|
||||||
<Compile Include="Bookmarks\BreakpointBookmarkEventArgs.cs" /> |
|
||||||
<Compile Include="Bookmarks\CurrentLineBookmark.cs" /> |
|
||||||
<Compile Include="Bookmarks\IBookmark.cs" /> |
|
||||||
<Compile Include="Bookmarks\MarkerBookmark.cs" /> |
|
||||||
<Compile Include="DebugInformation.cs" /> |
|
||||||
<Compile Include="Images.cs" /> |
|
||||||
<Compile Include="Models\ToolTipRequestEventArgs.cs" /> |
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|
||||||
<Compile Include="Services\DebuggerService.cs" /> |
|
||||||
<Compile Include="Services\IDebugger.cs" /> |
|
||||||
<Compile Include="Services\ParserService.cs" /> |
|
||||||
</ItemGroup> |
|
||||||
<ItemGroup> |
|
||||||
<Folder Include="AvalonEdit" /> |
|
||||||
<Folder Include="Bookmarks" /> |
|
||||||
<Folder Include="Models" /> |
|
||||||
<Folder Include="Services" /> |
|
||||||
</ItemGroup> |
|
||||||
<ItemGroup> |
|
||||||
<ProjectReference Include="..\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj"> |
|
||||||
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project> |
|
||||||
<Name>ICSharpCode.AvalonEdit</Name> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj"> |
|
||||||
<Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project> |
|
||||||
<Name>ICSharpCode.Decompiler</Name> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\Mono.Cecil\Mono.Cecil.csproj"> |
|
||||||
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project> |
|
||||||
<Name>Mono.Cecil</Name> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\NRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj"> |
|
||||||
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project> |
|
||||||
<Name>ICSharpCode.NRefactory.CSharp</Name> |
|
||||||
</ProjectReference> |
|
||||||
<ProjectReference Include="..\NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj"> |
|
||||||
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project> |
|
||||||
<Name>ICSharpCode.NRefactory</Name> |
|
||||||
</ProjectReference> |
|
||||||
</ItemGroup> |
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> |
|
||||||
</Project> |
|
||||||
@ -1,36 +0,0 @@ |
|||||||
// 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.Windows.Media; |
|
||||||
using System.Windows.Media.Imaging; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.SharpDevelop |
|
||||||
{ |
|
||||||
static class Images |
|
||||||
{ |
|
||||||
static BitmapImage LoadBitmap(string name) |
|
||||||
{ |
|
||||||
try { |
|
||||||
BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/ILSpy;component/Images/" + name + ".png")); |
|
||||||
if (image == null) |
|
||||||
return null; |
|
||||||
image.Freeze(); |
|
||||||
return image; |
|
||||||
} |
|
||||||
catch { |
|
||||||
// resource not found
|
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static readonly BitmapImage Breakpoint = LoadBitmap("Breakpoint"); |
|
||||||
public static readonly BitmapImage DisabledBreakpoint = LoadBitmap("DisabledBreakpoint"); |
|
||||||
public static readonly BitmapImage CurrentLine = LoadBitmap("CurrentLine"); |
|
||||||
|
|
||||||
public static ImageSource GetImage(string imageName) |
|
||||||
{ |
|
||||||
return LoadBitmap(imageName); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,57 +0,0 @@ |
|||||||
// 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 ICSharpCode.AvalonEdit; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Tooltips |
|
||||||
{ |
|
||||||
public class ToolTipRequestEventArgs : EventArgs |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Gets whether the tool tip request was handled.
|
|
||||||
/// </summary>
|
|
||||||
public bool Handled { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the editor causing the request.
|
|
||||||
/// </summary>
|
|
||||||
public TextEditor Editor { get; private set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets whether the mouse was inside the document bounds.
|
|
||||||
/// </summary>
|
|
||||||
public bool InDocument { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The mouse position, in document coordinates.
|
|
||||||
/// </summary>
|
|
||||||
public TextLocation LogicalPosition { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets/Sets the content to show as a tooltip.
|
|
||||||
/// </summary>
|
|
||||||
public object ContentToShow { get; set; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the tooltip to be shown.
|
|
||||||
/// </summary>
|
|
||||||
public void SetToolTip(object content) |
|
||||||
{ |
|
||||||
if (content == null) |
|
||||||
throw new ArgumentNullException("content"); |
|
||||||
this.Handled = true; |
|
||||||
this.ContentToShow = content; |
|
||||||
} |
|
||||||
|
|
||||||
public ToolTipRequestEventArgs(TextEditor editor) |
|
||||||
{ |
|
||||||
if (editor == null) |
|
||||||
throw new ArgumentNullException("editor"); |
|
||||||
this.Editor = editor; |
|
||||||
this.InDocument = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,31 +0,0 @@ |
|||||||
#region Using directives
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Reflection; |
|
||||||
using System.Runtime.InteropServices; |
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("ILSpy.SharpDevelop.LGPL")] |
|
||||||
[assembly: AssemblyDescription("")] |
|
||||||
[assembly: AssemblyConfiguration("")] |
|
||||||
[assembly: AssemblyCompany("")] |
|
||||||
[assembly: AssemblyProduct("ILSpy.SharpDevelop.LGPL")] |
|
||||||
[assembly: AssemblyCopyright("Copyright 2011")] |
|
||||||
[assembly: AssemblyTrademark("")] |
|
||||||
[assembly: AssemblyCulture("")] |
|
||||||
|
|
||||||
// This sets the default COM visibility of types in the assembly to invisible.
|
|
||||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
|
||||||
[assembly: ComVisible(false)] |
|
||||||
|
|
||||||
// The assembly version has following format :
|
|
||||||
//
|
|
||||||
// Major.Minor.Build.Revision
|
|
||||||
//
|
|
||||||
// You can specify all the values or you can use the default the Revision and
|
|
||||||
// Build Numbers by using the '*' as shown below:
|
|
||||||
[assembly: AssemblyVersion("2.0.0.0")] |
|
||||||
@ -1,409 +0,0 @@ |
|||||||
// 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 ICSharpCode.AvalonEdit.Document; |
|
||||||
using ICSharpCode.Decompiler; |
|
||||||
using ICSharpCode.Decompiler.ILAst; |
|
||||||
using ICSharpCode.ILSpy; |
|
||||||
using ICSharpCode.ILSpy.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.Debugger.Bookmarks; |
|
||||||
using ICSharpCode.ILSpy.Debugger.Tooltips; |
|
||||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
|
||||||
using ICSharpCode.NRefactory.Semantics; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Services |
|
||||||
{ |
|
||||||
public static class DebuggerService |
|
||||||
{ |
|
||||||
static IDebugger currentDebugger; |
|
||||||
|
|
||||||
static DebuggerService() |
|
||||||
{ |
|
||||||
BookmarkManager.Added += BookmarkAdded; |
|
||||||
BookmarkManager.Removed += BookmarkRemoved; |
|
||||||
} |
|
||||||
|
|
||||||
static IDebugger GetCompatibleDebugger() |
|
||||||
{ |
|
||||||
return currentDebugger; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current debugger. The debugger addin is loaded on demand; so if you
|
|
||||||
/// just want to check a property like IsDebugging, check <see cref="IsDebuggerLoaded"/>
|
|
||||||
/// before using this property.
|
|
||||||
/// </summary>
|
|
||||||
public static IDebugger CurrentDebugger { |
|
||||||
get { |
|
||||||
if (currentDebugger == null) { |
|
||||||
currentDebugger = GetCompatibleDebugger(); |
|
||||||
if (currentDebugger == null) |
|
||||||
return null; |
|
||||||
currentDebugger.DebugStarting += new EventHandler(OnDebugStarting); |
|
||||||
currentDebugger.DebugStarted += new EventHandler(OnDebugStarted); |
|
||||||
currentDebugger.DebugStopped += new EventHandler(OnDebugStopped); |
|
||||||
} |
|
||||||
return currentDebugger; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if debugger is already loaded.
|
|
||||||
/// </summary>
|
|
||||||
public static bool IsDebuggerLoaded { |
|
||||||
get { |
|
||||||
return currentDebugger != null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static bool debuggerStarted; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets whether the debugger is currently active.
|
|
||||||
/// </summary>
|
|
||||||
public static bool IsDebuggerStarted { |
|
||||||
get { return debuggerStarted; } |
|
||||||
} |
|
||||||
|
|
||||||
public static event EventHandler DebugStarting; |
|
||||||
public static event EventHandler DebugStarted; |
|
||||||
public static event EventHandler DebugStopped; |
|
||||||
|
|
||||||
static void OnDebugStarting(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
ClearDebugMessages(); |
|
||||||
|
|
||||||
if (DebugStarting != null) |
|
||||||
DebugStarting(null, e); |
|
||||||
} |
|
||||||
|
|
||||||
static void OnDebugStarted(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
debuggerStarted = true; |
|
||||||
if (DebugStarted != null) |
|
||||||
DebugStarted(null, e); |
|
||||||
} |
|
||||||
|
|
||||||
static void OnDebugStopped(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
debuggerStarted = false; |
|
||||||
|
|
||||||
RemoveCurrentLineMarker(); |
|
||||||
|
|
||||||
if (DebugStopped != null) |
|
||||||
DebugStopped(null, e); |
|
||||||
} |
|
||||||
|
|
||||||
public static void ClearDebugMessages() |
|
||||||
{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
public static void PrintDebugMessage(string msg) |
|
||||||
{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
public static event EventHandler<BreakpointBookmarkEventArgs> BreakPointChanged; |
|
||||||
public static event EventHandler<BreakpointBookmarkEventArgs> BreakPointAdded; |
|
||||||
public static event EventHandler<BreakpointBookmarkEventArgs> BreakPointRemoved; |
|
||||||
|
|
||||||
static void OnBreakPointChanged(BreakpointBookmarkEventArgs e) |
|
||||||
{ |
|
||||||
if (BreakPointChanged != null) { |
|
||||||
BreakPointChanged(null, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void OnBreakPointAdded(BreakpointBookmarkEventArgs e) |
|
||||||
{ |
|
||||||
if (BreakPointAdded != null) { |
|
||||||
BreakPointAdded(null, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void OnBreakPointRemoved(BreakpointBookmarkEventArgs e) |
|
||||||
{ |
|
||||||
if (BreakPointRemoved != null) { |
|
||||||
BreakPointRemoved(null, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static IList<BreakpointBookmark> Breakpoints { |
|
||||||
get { |
|
||||||
List<BreakpointBookmark> breakpoints = new List<BreakpointBookmark>(); |
|
||||||
foreach (var bookmark in BookmarkManager.Bookmarks) { |
|
||||||
BreakpointBookmark breakpoint = bookmark as BreakpointBookmark; |
|
||||||
if (breakpoint != null) { |
|
||||||
breakpoints.Add(breakpoint); |
|
||||||
} |
|
||||||
} |
|
||||||
return breakpoints.AsReadOnly(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void BookmarkAdded(object sender, BookmarkEventArgs e) |
|
||||||
{ |
|
||||||
BreakpointBookmark bb = e.Bookmark as BreakpointBookmark; |
|
||||||
if (bb != null) { |
|
||||||
OnBreakPointAdded(new BreakpointBookmarkEventArgs(bb)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void BookmarkRemoved(object sender, BookmarkEventArgs e) |
|
||||||
{ |
|
||||||
BreakpointBookmark bb = e.Bookmark as BreakpointBookmark; |
|
||||||
if (bb != null) { |
|
||||||
OnBreakPointRemoved(new BreakpointBookmarkEventArgs(bb)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void BookmarkChanged(object sender, EventArgs e) |
|
||||||
{ |
|
||||||
BreakpointBookmark bb = sender as BreakpointBookmark; |
|
||||||
if (bb != null) { |
|
||||||
OnBreakPointChanged(new BreakpointBookmarkEventArgs(bb)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public static void ToggleBreakpointAt(MemberReference member, int lineNumber, int functionToken, ILRange range) |
|
||||||
{ |
|
||||||
BookmarkManager.ToggleBookmark( |
|
||||||
member.FullName, lineNumber, |
|
||||||
b => b.CanToggle && b is BreakpointBookmark, |
|
||||||
location => new BreakpointBookmark(member, location, functionToken, range, BreakpointAction.Break)); |
|
||||||
} |
|
||||||
|
|
||||||
/* TODO: reimplement this stuff |
|
||||||
static void ViewContentOpened(object sender, ViewContentEventArgs e) |
|
||||||
{ |
|
||||||
textArea.IconBarMargin.MouseDown += IconBarMouseDown; |
|
||||||
textArea.ToolTipRequest += TextAreaToolTipRequest; |
|
||||||
textArea.MouseLeave += TextAreaMouseLeave; |
|
||||||
}*/ |
|
||||||
|
|
||||||
public static void RemoveCurrentLineMarker() |
|
||||||
{ |
|
||||||
CurrentLineBookmark.Remove(); |
|
||||||
} |
|
||||||
|
|
||||||
public static void JumpToCurrentLine(MemberReference memberReference, int startLine, int startColumn, int endLine, int endColumn, int ilOffset) |
|
||||||
{ |
|
||||||
CurrentLineBookmark.SetPosition(memberReference, startLine, startColumn, endLine, endColumn, ilOffset); |
|
||||||
} |
|
||||||
|
|
||||||
#region Tool tips
|
|
||||||
/// <summary>
|
|
||||||
/// Gets debugger tooltip information for the specified position.
|
|
||||||
/// A descriptive string for the element or a DebuggerTooltipControl
|
|
||||||
/// showing its current value (when in debugging mode) can be returned
|
|
||||||
/// through the ToolTipRequestEventArgs.SetTooltip() method.
|
|
||||||
/// </summary>
|
|
||||||
public static void HandleToolTipRequest(ToolTipRequestEventArgs e) |
|
||||||
{ |
|
||||||
if (!e.InDocument) |
|
||||||
return; |
|
||||||
|
|
||||||
var logicPos = e.LogicalPosition; |
|
||||||
var doc = (TextDocument)e.Editor.Document; |
|
||||||
var line = doc.GetLineByNumber(logicPos.Line); |
|
||||||
|
|
||||||
if (line.Offset + logicPos.Column >= doc.TextLength) |
|
||||||
return; |
|
||||||
|
|
||||||
var c = doc.GetText(line.Offset + logicPos.Column, 1); |
|
||||||
if (string.IsNullOrEmpty(c) || c == "\n" || c == "\t") |
|
||||||
return; |
|
||||||
|
|
||||||
string variable = |
|
||||||
ParserService.SimpleParseAt(doc.Text, doc.GetOffset(new TextLocation(logicPos.Line, logicPos.Column))); |
|
||||||
|
|
||||||
if (currentDebugger == null || !currentDebugger.IsDebugging || !currentDebugger.CanEvaluate) { |
|
||||||
e.ContentToShow = null; |
|
||||||
} |
|
||||||
else { |
|
||||||
try { |
|
||||||
e.ContentToShow = currentDebugger.GetTooltipControl(e.LogicalPosition, variable); |
|
||||||
} catch { |
|
||||||
return; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// FIXME Do proper parsing
|
|
||||||
//
|
|
||||||
// using (var sr = new StringReader(doc.Text))
|
|
||||||
// {
|
|
||||||
// var parser = new CSharpParser();
|
|
||||||
// parser.Parse(sr);
|
|
||||||
//
|
|
||||||
// IExpressionFinder expressionFinder = ParserService.GetExpressionFinder();
|
|
||||||
// if (expressionFinder == null)
|
|
||||||
// return;
|
|
||||||
// var currentLine = doc.GetLine(logicPos.Y);
|
|
||||||
// if (logicPos.X > currentLine.Length)
|
|
||||||
// return;
|
|
||||||
// string textContent = doc.Text;
|
|
||||||
// ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, doc.GetOffset(new TextLocation(logicPos.Line, logicPos.Column)));
|
|
||||||
// string expression = (expressionResult.Expression ?? "").Trim();
|
|
||||||
// if (expression.Length > 0) {
|
|
||||||
// // Look if it is variable
|
|
||||||
// ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y, logicPos.X, e.Editor.FileName, textContent);
|
|
||||||
// bool debuggerCanShowValue;
|
|
||||||
// string toolTipText = GetText(result, expression, out debuggerCanShowValue);
|
|
||||||
// if (Control.ModifierKeys == Keys.Control) {
|
|
||||||
// toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText;
|
|
||||||
// debuggerCanShowValue = false;
|
|
||||||
// }
|
|
||||||
// if (toolTipText != null) {
|
|
||||||
// if (debuggerCanShowValue && currentDebugger != null) {
|
|
||||||
// object toolTip = currentDebugger.GetTooltipControl(e.LogicalPosition, expressionResult.Expression);
|
|
||||||
// if (toolTip != null)
|
|
||||||
// e.SetToolTip(toolTip);
|
|
||||||
// else
|
|
||||||
// e.SetToolTip(toolTipText);
|
|
||||||
// } else {
|
|
||||||
// e.SetToolTip(toolTipText);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// #if DEBUG
|
|
||||||
// if (Control.ModifierKeys == Keys.Control) {
|
|
||||||
// e.SetToolTip("no expr: " + expressionResult.ToString());
|
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} |
|
||||||
|
|
||||||
static string GetText(ResolveResult result, string expression, out bool debuggerCanShowValue) |
|
||||||
{ |
|
||||||
debuggerCanShowValue = false; |
|
||||||
return "FIXME"; |
|
||||||
|
|
||||||
// FIXME
|
|
||||||
// debuggerCanShowValue = false;
|
|
||||||
// if (result == null) {
|
|
||||||
// // when pressing control, show the expression even when it could not be resolved
|
|
||||||
// return (Control.ModifierKeys == Keys.Control) ? "" : null;
|
|
||||||
// }
|
|
||||||
// if (result is MixedResolveResult)
|
|
||||||
// return GetText(((MixedResolveResult)result).PrimaryResult, expression, out debuggerCanShowValue);
|
|
||||||
// else if (result is DelegateCallResolveResult)
|
|
||||||
// return GetText(((DelegateCallResolveResult)result).Target, expression, out debuggerCanShowValue);
|
|
||||||
//
|
|
||||||
// IAmbience ambience = AmbienceService.GetCurrentAmbience();
|
|
||||||
// ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.UseFullyQualifiedMemberNames;
|
|
||||||
// if (result is MemberResolveResult) {
|
|
||||||
// return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember, expression, out debuggerCanShowValue);
|
|
||||||
// } else if (result is LocalResolveResult) {
|
|
||||||
// LocalResolveResult rr = (LocalResolveResult)result;
|
|
||||||
// ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames
|
|
||||||
// | ConversionFlags.ShowReturnType | ConversionFlags.ShowDefinitionKeyWord;
|
|
||||||
// StringBuilder b = new StringBuilder();
|
|
||||||
// if (rr.IsParameter)
|
|
||||||
// b.Append("parameter ");
|
|
||||||
// else
|
|
||||||
// b.Append("local variable ");
|
|
||||||
// b.Append(ambience.Convert(rr.Field));
|
|
||||||
// if (currentDebugger != null) {
|
|
||||||
// string currentValue = currentDebugger.GetValueAsString(rr.VariableName);
|
|
||||||
// if (currentValue != null) {
|
|
||||||
// debuggerCanShowValue = true;
|
|
||||||
// b.Append(" = ");
|
|
||||||
// if (currentValue.Length > 256)
|
|
||||||
// currentValue = currentValue.Substring(0, 256) + "...";
|
|
||||||
// b.Append(currentValue);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return b.ToString();
|
|
||||||
// } else if (result is NamespaceResolveResult) {
|
|
||||||
// return "namespace " + ((NamespaceResolveResult)result).Name;
|
|
||||||
// } else if (result is TypeResolveResult) {
|
|
||||||
// IClass c = ((TypeResolveResult)result).ResolvedClass;
|
|
||||||
// if (c != null)
|
|
||||||
// return GetMemberText(ambience, c, expression, out debuggerCanShowValue);
|
|
||||||
// else
|
|
||||||
// return ambience.Convert(result.ResolvedType);
|
|
||||||
// } else if (result is MethodGroupResolveResult) {
|
|
||||||
// MethodGroupResolveResult mrr = result as MethodGroupResolveResult;
|
|
||||||
// IMethod m = mrr.GetMethodIfSingleOverload();
|
|
||||||
// IMethod m2 = mrr.GetMethodWithEmptyParameterList();
|
|
||||||
// if (m != null)
|
|
||||||
// return GetMemberText(ambience, m, expression, out debuggerCanShowValue);
|
|
||||||
// else if (ambience is VBNetAmbience && m2 != null)
|
|
||||||
// return GetMemberText(ambience, m2, expression, out debuggerCanShowValue);
|
|
||||||
// else
|
|
||||||
// return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name;
|
|
||||||
// } else {
|
|
||||||
// if (Control.ModifierKeys == Keys.Control) {
|
|
||||||
// if (result.ResolvedType != null)
|
|
||||||
// return "expression of type " + ambience.Convert(result.ResolvedType);
|
|
||||||
// else
|
|
||||||
// return "ResolveResult without ResolvedType";
|
|
||||||
// } else {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} |
|
||||||
|
|
||||||
// static string GetMemberText(IAmbience ambience, IEntity member, string expression, out bool debuggerCanShowValue)
|
|
||||||
// {
|
|
||||||
// bool tryDisplayValue = false;
|
|
||||||
// debuggerCanShowValue = false;
|
|
||||||
// StringBuilder text = new StringBuilder();
|
|
||||||
// if (member is IField) {
|
|
||||||
// text.Append(ambience.Convert(member as IField));
|
|
||||||
// tryDisplayValue = true;
|
|
||||||
// } else if (member is IProperty) {
|
|
||||||
// text.Append(ambience.Convert(member as IProperty));
|
|
||||||
// tryDisplayValue = true;
|
|
||||||
// } else if (member is IEvent) {
|
|
||||||
// text.Append(ambience.Convert(member as IEvent));
|
|
||||||
// } else if (member is IMethod) {
|
|
||||||
// text.Append(ambience.Convert(member as IMethod));
|
|
||||||
// } else if (member is IClass) {
|
|
||||||
// text.Append(ambience.Convert(member as IClass));
|
|
||||||
// } else {
|
|
||||||
// text.Append("unknown member ");
|
|
||||||
// text.Append(member.ToString());
|
|
||||||
// }
|
|
||||||
// if (tryDisplayValue && currentDebugger != null) {
|
|
||||||
// LoggingService.Info("asking debugger for value of '" + expression + "'");
|
|
||||||
// string currentValue = currentDebugger.GetValueAsString(expression);
|
|
||||||
// if (currentValue != null) {
|
|
||||||
// debuggerCanShowValue = true;
|
|
||||||
// text.Append(" = ");
|
|
||||||
// text.Append(currentValue);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// string documentation = member.Documentation;
|
|
||||||
// if (documentation != null && documentation.Length > 0) {
|
|
||||||
// text.Append('\n');
|
|
||||||
// text.Append(ICSharpCode.SharpDevelop.Editor.CodeCompletion.CodeCompletionItem.ConvertDocumentation(documentation));
|
|
||||||
// }
|
|
||||||
// return text.ToString();
|
|
||||||
// }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public static void SetDebugger(Lazy<IDebugger> debugger) |
|
||||||
{ |
|
||||||
if (currentDebugger != null) |
|
||||||
{ |
|
||||||
currentDebugger.DebugStarting -= new EventHandler(OnDebugStarting); |
|
||||||
currentDebugger.DebugStarted -= new EventHandler(OnDebugStarted); |
|
||||||
currentDebugger.DebugStopped -= new EventHandler(OnDebugStopped); |
|
||||||
} |
|
||||||
currentDebugger = debugger.Value; |
|
||||||
if (currentDebugger != null) |
|
||||||
{ |
|
||||||
currentDebugger.DebugStarting += new EventHandler(OnDebugStarting); |
|
||||||
currentDebugger.DebugStarted += new EventHandler(OnDebugStarted); |
|
||||||
currentDebugger.DebugStopped += new EventHandler(OnDebugStopped); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,122 +0,0 @@ |
|||||||
// 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.Diagnostics; |
|
||||||
using ICSharpCode.Decompiler; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.CSharp; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Services |
|
||||||
{ |
|
||||||
public interface IDebugger : IDisposable |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Gets whether the debugger can evaluate the expression.
|
|
||||||
/// </summary>
|
|
||||||
bool CanEvaluate { get; } |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if debuger is attached to a process
|
|
||||||
/// </summary>
|
|
||||||
bool IsDebugging { |
|
||||||
get; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if process is running
|
|
||||||
/// Returns false if breakpoint is hit, program is breaked, program is stepped, etc...
|
|
||||||
/// </summary>
|
|
||||||
bool IsProcessRunning { |
|
||||||
get; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets whether the debugger should break at the first line of execution.
|
|
||||||
/// </summary>
|
|
||||||
bool BreakAtBeginning { |
|
||||||
get; set; |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts process and attaches debugger
|
|
||||||
/// </summary>
|
|
||||||
void Start(ProcessStartInfo processStartInfo); |
|
||||||
|
|
||||||
void StartWithoutDebugging(ProcessStartInfo processStartInfo); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stops/terminates attached process
|
|
||||||
/// </summary>
|
|
||||||
void Stop(); |
|
||||||
|
|
||||||
// ExecutionControl:
|
|
||||||
|
|
||||||
void Break(); |
|
||||||
|
|
||||||
void Continue(); |
|
||||||
|
|
||||||
// Stepping:
|
|
||||||
|
|
||||||
void StepInto(); |
|
||||||
|
|
||||||
void StepOver(); |
|
||||||
|
|
||||||
void StepOut(); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows a dialog so the user can attach to a process.
|
|
||||||
/// </summary>
|
|
||||||
void ShowAttachDialog(); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used to attach to an existing process.
|
|
||||||
/// </summary>
|
|
||||||
void Attach(Process process); |
|
||||||
|
|
||||||
void Detach(); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current value of the variable as string that can be displayed in tooltips.
|
|
||||||
/// </summary>
|
|
||||||
string GetValueAsString(string variable); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the tooltip control that shows the value of given variable.
|
|
||||||
/// Return null if no tooltip is available.
|
|
||||||
/// </summary>
|
|
||||||
object GetTooltipControl(TextLocation logicalPosition, string variable); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queries the debugger whether it is possible to set the instruction pointer to a given position.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if possible. False otherwise</returns>
|
|
||||||
bool CanSetInstructionPointer(string filename, int line, int column); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the instruction pointer to a given position.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if successful. False otherwise</returns>
|
|
||||||
bool SetInstructionPointer(string filename, int line, int column); |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ocurrs when the debugger is starting.
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler DebugStarting; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ocurrs after the debugger has started.
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler DebugStarted; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ocurrs when the value of IsProcessRunning changes.
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler IsProcessRunningChanged; |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ocurrs after the debugging of program is finished.
|
|
||||||
/// </summary>
|
|
||||||
event EventHandler DebugStopped; |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,87 +0,0 @@ |
|||||||
// 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; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Debugger.Services |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Very naive parser.
|
|
||||||
/// </summary>
|
|
||||||
static class ParserService |
|
||||||
{ |
|
||||||
static HashSet<string> mySet = new HashSet<string>(); |
|
||||||
|
|
||||||
static ParserService() |
|
||||||
{ |
|
||||||
mySet.AddRange((new string [] { |
|
||||||
".", |
|
||||||
"{", |
|
||||||
"}", |
|
||||||
"(", |
|
||||||
")", |
|
||||||
"[", |
|
||||||
"]", |
|
||||||
" ", |
|
||||||
"=", |
|
||||||
"+", |
|
||||||
"-", |
|
||||||
"/", |
|
||||||
"%", |
|
||||||
"*", |
|
||||||
"&", |
|
||||||
Environment.NewLine, |
|
||||||
";", |
|
||||||
",", |
|
||||||
"~", |
|
||||||
"!", |
|
||||||
"?", |
|
||||||
@"\n", |
|
||||||
@"\t", |
|
||||||
@"\r", |
|
||||||
"|" |
|
||||||
})); |
|
||||||
} |
|
||||||
|
|
||||||
static void AddRange<T>(this ICollection<T> list, IEnumerable<T> items) |
|
||||||
{ |
|
||||||
foreach (T item in items) |
|
||||||
if (!list.Contains(item)) |
|
||||||
list.Add(item); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the variable name
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fullText"></param>
|
|
||||||
/// <param name="offset"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string SimpleParseAt(string fullText, int offset) |
|
||||||
{ |
|
||||||
if (string.IsNullOrEmpty(fullText)) |
|
||||||
return string.Empty; |
|
||||||
|
|
||||||
if (offset <= 0 || offset >= fullText.Length) |
|
||||||
return string.Empty; |
|
||||||
|
|
||||||
string currentValue = fullText[offset].ToString(); |
|
||||||
|
|
||||||
if (mySet.Contains(currentValue)) |
|
||||||
return string.Empty; |
|
||||||
|
|
||||||
int left = offset, right = offset; |
|
||||||
|
|
||||||
//search left
|
|
||||||
while((!mySet.Contains(currentValue) || currentValue == ".") && left > 0) |
|
||||||
currentValue = fullText[--left].ToString(); |
|
||||||
|
|
||||||
currentValue = fullText[offset].ToString(); |
|
||||||
// searh right
|
|
||||||
while(!mySet.Contains(currentValue) && right < fullText.Length - 2) |
|
||||||
currentValue = fullText[++right].ToString(); |
|
||||||
|
|
||||||
return fullText.Substring(left + 1, right - 1 - left).Trim(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,190 +0,0 @@ |
|||||||
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
||||||
// software and associated documentation files (the "Software"), to deal in the Software
|
|
||||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
||||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
||||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or
|
|
||||||
// substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
||||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
||||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
||||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.ComponentModel.Composition; |
|
||||||
using System.Linq; |
|
||||||
using System.Windows.Controls; |
|
||||||
using System.Windows.Input; |
|
||||||
using ICSharpCode.ILSpy.Bookmarks; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.AvalonEdit |
|
||||||
{ |
|
||||||
#region Context menu extensibility
|
|
||||||
public interface IBookmarkContextMenuEntry |
|
||||||
{ |
|
||||||
bool IsVisible(IBookmark bookmarks); |
|
||||||
bool IsEnabled(IBookmark bookmarks); |
|
||||||
void Execute(IBookmark bookmarks); |
|
||||||
} |
|
||||||
|
|
||||||
public interface IBookmarkContextMenuEntryMetadata |
|
||||||
{ |
|
||||||
string Icon { get; } |
|
||||||
string Header { get; } |
|
||||||
string Category { get; } |
|
||||||
|
|
||||||
double Order { get; } |
|
||||||
} |
|
||||||
|
|
||||||
[MetadataAttribute] |
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] |
|
||||||
public class ExportBookmarkContextMenuEntryAttribute : ExportAttribute, IBookmarkContextMenuEntryMetadata |
|
||||||
{ |
|
||||||
public ExportBookmarkContextMenuEntryAttribute() |
|
||||||
: base(typeof(IBookmarkContextMenuEntry)) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public string Icon { get; set; } |
|
||||||
public string Header { get; set; } |
|
||||||
public string Category { get; set; } |
|
||||||
public double Order { get; set; } |
|
||||||
} |
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Actions (simple clicks) - this will be used for creating bookmarks (e.g. Breakpoint bookmarks)
|
|
||||||
|
|
||||||
public interface IBookmarkActionEntry |
|
||||||
{ |
|
||||||
bool IsEnabled(); |
|
||||||
void Execute(int line); |
|
||||||
} |
|
||||||
|
|
||||||
public interface IBookmarkActionMetadata |
|
||||||
{ |
|
||||||
string Category { get; } |
|
||||||
|
|
||||||
double Order { get; } |
|
||||||
} |
|
||||||
|
|
||||||
[MetadataAttribute] |
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] |
|
||||||
public class ExportBookmarkActionEntryAttribute : ExportAttribute, IBookmarkActionMetadata |
|
||||||
{ |
|
||||||
public ExportBookmarkActionEntryAttribute() |
|
||||||
: base(typeof(IBookmarkActionEntry)) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public string Icon { get; set; } |
|
||||||
public string Header { get; set; } |
|
||||||
public string Category { get; set; } |
|
||||||
public double Order { get; set; } |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
internal class IconMarginActionsProvider |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Enables extensible context menu support for the specified icon margin.
|
|
||||||
/// </summary>
|
|
||||||
public static void Add(IconBarMargin margin) |
|
||||||
{ |
|
||||||
var provider = new IconMarginActionsProvider(margin); |
|
||||||
margin.MouseUp += provider.HandleMouseEvent; |
|
||||||
margin.ContextMenu = new ContextMenu(); |
|
||||||
} |
|
||||||
|
|
||||||
readonly IconBarMargin margin; |
|
||||||
|
|
||||||
[ImportMany(typeof(IBookmarkContextMenuEntry))] |
|
||||||
Lazy<IBookmarkContextMenuEntry, IBookmarkContextMenuEntryMetadata>[] contextEntries = null; |
|
||||||
|
|
||||||
[ImportMany(typeof(IBookmarkActionEntry))] |
|
||||||
Lazy<IBookmarkActionEntry, IBookmarkActionMetadata>[] actionEntries = null; |
|
||||||
|
|
||||||
private IconMarginActionsProvider(IconBarMargin margin) |
|
||||||
{ |
|
||||||
this.margin = margin; |
|
||||||
App.CompositionContainer.ComposeParts(this); |
|
||||||
} |
|
||||||
|
|
||||||
void HandleMouseEvent(object sender, MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
int line = margin.GetLineFromMousePosition(e); |
|
||||||
|
|
||||||
if (e.ChangedButton == MouseButton.Left) { |
|
||||||
foreach (var category in actionEntries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.Category)) { |
|
||||||
foreach (var entryPair in category) { |
|
||||||
IBookmarkActionEntry entry = entryPair.Value; |
|
||||||
|
|
||||||
if (entryPair.Value.IsEnabled()) { |
|
||||||
entry.Execute(line); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// context menu entries
|
|
||||||
var bookmarks = margin.Manager.Bookmarks.ToArray(); |
|
||||||
if (bookmarks.Length == 0) { |
|
||||||
// don't show the menu
|
|
||||||
e.Handled = true; |
|
||||||
this.margin.ContextMenu = null; |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (e.ChangedButton == MouseButton.Right) { |
|
||||||
// check if we are on a Member
|
|
||||||
var bookmark = bookmarks.FirstOrDefault(b => b.LineNumber == line); |
|
||||||
if (bookmark == null) { |
|
||||||
// don't show the menu
|
|
||||||
e.Handled = true; |
|
||||||
this.margin.ContextMenu = null; |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
ContextMenu menu = new ContextMenu(); |
|
||||||
foreach (var category in contextEntries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.Category)) { |
|
||||||
bool needSeparatorForCategory = true; |
|
||||||
foreach (var entryPair in category) { |
|
||||||
IBookmarkContextMenuEntry entry = entryPair.Value; |
|
||||||
if (entry.IsVisible(bookmark)) { |
|
||||||
if (needSeparatorForCategory && menu.Items.Count > 0) { |
|
||||||
menu.Items.Add(new Separator()); |
|
||||||
needSeparatorForCategory = false; |
|
||||||
} |
|
||||||
|
|
||||||
MenuItem menuItem = new MenuItem(); |
|
||||||
menuItem.Header = entryPair.Metadata.Header; |
|
||||||
if (!string.IsNullOrEmpty(entryPair.Metadata.Icon)) { |
|
||||||
menuItem.Icon = new Image { |
|
||||||
Width = 16, |
|
||||||
Height = 16, |
|
||||||
Source = Images.LoadImage(entry, entryPair.Metadata.Icon) |
|
||||||
}; |
|
||||||
} |
|
||||||
if (entryPair.Value.IsEnabled(bookmark)) { |
|
||||||
menuItem.Click += delegate { entry.Execute(bookmark); }; |
|
||||||
} else |
|
||||||
menuItem.IsEnabled = false; |
|
||||||
menu.Items.Add(menuItem); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
if (menu.Items.Count > 0) |
|
||||||
margin.ContextMenu = menu; |
|
||||||
else |
|
||||||
// hide the context menu.
|
|
||||||
e.Handled = true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,93 +0,0 @@ |
|||||||
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
||||||
// software and associated documentation files (the "Software"), to deal in the Software
|
|
||||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
||||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
||||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all copies or
|
|
||||||
// substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
||||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
||||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
||||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
using System; |
|
||||||
using System.Windows.Input; |
|
||||||
using System.Windows.Media; |
|
||||||
using Mono.Cecil; |
|
||||||
|
|
||||||
namespace ICSharpCode.ILSpy.Bookmarks |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Bookmark used to give additional operations for class members.
|
|
||||||
/// Does not derive from SDBookmark because it is not stored in the central BookmarkManager,
|
|
||||||
/// but only in the document's BookmarkManager.
|
|
||||||
/// </summary>
|
|
||||||
public class MemberBookmark : IBookmark |
|
||||||
{ |
|
||||||
MemberReference member; |
|
||||||
|
|
||||||
public MemberReference Member { |
|
||||||
get { |
|
||||||
return member; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public MemberBookmark(MemberReference member, int line) |
|
||||||
{ |
|
||||||
this.member = member; |
|
||||||
LineNumber = line; |
|
||||||
} |
|
||||||
|
|
||||||
public virtual ImageSource Image { |
|
||||||
get { |
|
||||||
if (member is FieldDefinition) |
|
||||||
return TreeNodes.FieldTreeNode.GetIcon((FieldDefinition)member); |
|
||||||
|
|
||||||
if (member is PropertyDefinition) |
|
||||||
return TreeNodes.PropertyTreeNode.GetIcon((PropertyDefinition)member); |
|
||||||
|
|
||||||
if (member is EventDefinition) |
|
||||||
return TreeNodes.EventTreeNode.GetIcon((EventDefinition)member); |
|
||||||
|
|
||||||
if (member is MethodDefinition) |
|
||||||
return TreeNodes.MethodTreeNode.GetIcon((MethodDefinition)member); |
|
||||||
|
|
||||||
if (member is TypeDefinition) |
|
||||||
return TreeNodes.TypeTreeNode.GetIcon((TypeDefinition)member); |
|
||||||
|
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public int LineNumber { |
|
||||||
get; private set; |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void MouseDown(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
public virtual void MouseUp(MouseButtonEventArgs e) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
int IBookmark.ZOrder { |
|
||||||
get { return -10; } |
|
||||||
} |
|
||||||
|
|
||||||
bool IBookmark.CanDragDrop { |
|
||||||
get { return false; } |
|
||||||
} |
|
||||||
|
|
||||||
void IBookmark.Drop(int lineNumber) |
|
||||||
{ |
|
||||||
throw new NotSupportedException(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Loading…
Reference in new issue