diff --git a/SharpDevelop.Tests.sln b/SharpDevelop.Tests.sln
index a4c13fad46..308757e312 100644
--- a/SharpDevelop.Tests.sln
+++ b/SharpDevelop.Tests.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-# SharpDevelop 4.3.0.8807-alpha
+# SharpDevelop 4.2.0.8717-Beta 2
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
diff --git a/src/AddIns/Analysis/UnitTesting/Test/Utils/MockDebugger.cs b/src/AddIns/Analysis/UnitTesting/Test/Utils/MockDebugger.cs
index 3caf49a6c6..dd99f8d047 100644
--- a/src/AddIns/Analysis/UnitTesting/Test/Utils/MockDebugger.cs
+++ b/src/AddIns/Analysis/UnitTesting/Test/Utils/MockDebugger.cs
@@ -154,12 +154,7 @@ namespace UnitTesting.Tests.Utils
throw new NotImplementedException();
}
- public bool CanSetInstructionPointer(string filename, int line, int column)
- {
- throw new NotImplementedException();
- }
-
- public bool SetInstructionPointer(string filename, int line, int column)
+ public bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
{
throw new NotImplementedException();
}
diff --git a/src/AddIns/BackendBindings/Scripting/Test/Utils/MockDebugger.cs b/src/AddIns/BackendBindings/Scripting/Test/Utils/MockDebugger.cs
index 43bcfcacd6..fd6a91f501 100644
--- a/src/AddIns/BackendBindings/Scripting/Test/Utils/MockDebugger.cs
+++ b/src/AddIns/BackendBindings/Scripting/Test/Utils/MockDebugger.cs
@@ -128,12 +128,7 @@ namespace ICSharpCode.Scripting.Tests.Utils
throw new NotImplementedException();
}
- public bool CanSetInstructionPointer(string filename, int line, int column)
- {
- throw new NotImplementedException();
- }
-
- public bool SetInstructionPointer(string filename, int line, int column)
+ public bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
{
throw new NotImplementedException();
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
index 79c009707e..b79f5d4de9 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
+++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin
@@ -15,13 +15,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -198,44 +168,6 @@
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
index bd536316c0..14bc2e885c 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
+++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
@@ -97,30 +97,19 @@
+
+
DebuggingOptionsPanel.xaml
Code
-
- CallStackPad.xaml
+
Code
-
-
-
- ConditionCell.xaml
-
-
-
- WatchList.xaml
-
-
- WatchListAutoCompleteCell.xaml
-
-
+
DrawSurface.xaml
Code
@@ -133,10 +122,6 @@
ThreadStack.xaml
Code
-
- WatchInputBox.xaml
- Code
-
@@ -150,18 +135,16 @@
DebuggingSymbolsPanel.cs
-
UserControl
-
+
Component
-
Form
@@ -175,28 +158,13 @@
EditBreakpointScriptWindow.xaml
Code
-
DebuggerTooltipControl.xaml
-
-
- PinCloseControl.xaml
-
-
- PinDebuggerControl.xaml
-
-
-
-
VisualizerPicker.xaml
-
-
-
-
-
+
@@ -209,7 +177,7 @@
-
+
@@ -223,6 +191,7 @@
+
@@ -253,12 +222,10 @@
-
-
TextVisualizerWindow.xaml
Code
@@ -274,7 +241,6 @@
DebuggeeExceptionForm.cs
-
@@ -284,14 +250,7 @@
Properties\GlobalAssemblyInfo.cs
-
-
-
-
-
-
-
-
+
@@ -312,9 +271,6 @@
GridVisualizerWindow.xaml
Code
-
-
-
@@ -324,7 +280,6 @@
-
@@ -379,18 +334,11 @@
-
-
-
-
+
-
-
-
-
@@ -408,8 +356,9 @@
ICSharpCode.Core.WinForms
False
+
-
+
@@ -423,7 +372,6 @@
-
diff --git a/src/AddIns/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs b/src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluator.cs
similarity index 92%
rename from src/AddIns/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs
rename to src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluator.cs
index 633d7563ab..d0e693f100 100644
--- a/src/AddIns/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluator.cs
@@ -6,17 +6,17 @@ using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
-
using Debugger;
using Debugger.MetaData;
using ICSharpCode.NRefactory.Ast;
+using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.NRefactory.Visitors
{
public class EvaluateException: GetValueException
{
- public EvaluateException(INode code, string msg):base(code, msg) {}
- public EvaluateException(INode code, string msgFmt, params string[] msgArgs):base(code, string.Format(msgFmt, msgArgs)) {}
+ public EvaluateException(INode code, string msg):base(msg) {}
+ public EvaluateException(INode code, string msgFmt, params string[] msgArgs):base(string.Format(msgFmt, msgArgs)) {}
}
class TypedValue
@@ -51,6 +51,10 @@ namespace ICSharpCode.NRefactory.Visitors
get { return context; }
}
+ public Thread EvalThread {
+ get { return this.Context.Thread; }
+ }
+
ExpressionEvaluator(StackFrame context)
{
this.context = context;
@@ -76,19 +80,12 @@ namespace ICSharpCode.NRefactory.Visitors
return Evaluate(Parse(code, language), context, data);
}
- public static Value Evaluate(INode code, Process context)
- {
- if (context.SelectedStackFrame == null && context.SelectedThread.MostRecentStackFrame == null)
- // This can happen when needed 'dll' is missing. This causes an exception dialog to be shown even before the applicaiton starts
- throw new GetValueException("Can not evaluate because the process has no managed stack frames");
-
- return Evaluate(code, context.GetCurrentExecutingFrame());
- }
-
public static Value Evaluate(INode code, StackFrame context, object data = null)
{
- if (context == null) throw new ArgumentNullException("context");
- if (context.IsInvalid) throw new DebuggerException("The context is no longer valid");
+ if (context == null)
+ throw new GetValueException("Invalid stackframe");
+ if (context.IsInvalid)
+ throw new DebuggerException("The context is no longer valid");
TypedValue val = new ExpressionEvaluator(context).Evaluate(code, false, data);
if (val == null)
@@ -113,7 +110,7 @@ namespace ICSharpCode.NRefactory.Visitors
return astExpression;
}
- public static string FormatValue(Value val)
+ public static string FormatValue(Thread evalThread, Value val)
{
if (val == null) {
return null;
@@ -127,7 +124,7 @@ namespace ICSharpCode.NRefactory.Visitors
foreach(Value item in val.GetArrayElements()) {
if (!first) sb.Append(", ");
first = false;
- sb.Append(FormatValue(item));
+ sb.Append(FormatValue(evalThread, item));
}
sb.Append("}");
return sb.ToString();
@@ -135,13 +132,13 @@ namespace ICSharpCode.NRefactory.Visitors
StringBuilder sb = new StringBuilder();
sb.Append(val.Type.Name);
sb.Append(" {");
- val = val.GetPermanentReference();
- int count = (int)val.GetMemberValue("Count").PrimitiveValue;
+ val = val.GetPermanentReference(evalThread);
+ int count = (int)val.GetMemberValue(evalThread, "Count").PrimitiveValue;
for(int i = 0; i < count; i++) {
if (i > 0) sb.Append(", ");
DebugPropertyInfo itemProperty = (DebugPropertyInfo)val.Type.GetProperty("Item");
- Value item = val.GetPropertyValue(itemProperty, Eval.CreateValue(val.AppDomain, i));
- sb.Append(FormatValue(item));
+ Value item = val.GetPropertyValue(evalThread, itemProperty, Eval.CreateValue(evalThread, i));
+ sb.Append(FormatValue(evalThread, item));
}
sb.Append("}");
return sb.ToString();
@@ -152,7 +149,7 @@ namespace ICSharpCode.NRefactory.Visitors
} else if (val.Type.IsPrimitive) {
return val.PrimitiveValue.ToString();
} else {
- return val.InvokeToString();
+ return val.InvokeToString(evalThread);
}
}
@@ -163,25 +160,16 @@ namespace ICSharpCode.NRefactory.Visitors
TypedValue Evaluate(INode expression, bool permRef, object data = null)
{
- // Try to get the value from cache
- // (the cache is cleared when the process is resumed)
TypedValue val;
- if (context.Process.ExpressionsCache.TryGetValue(expression, out val)) {
- if (val == null || !val.Value.IsInvalid)
- return val;
- }
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
try {
val = (TypedValue)expression.AcceptVisitor(this, data);
if (val != null && permRef)
- val = new TypedValue(val.Value.GetPermanentReference(), val.Type);
- } catch (GetValueException e) {
- e.Expression = expression;
- throw;
+ val = new TypedValue(val.Value.GetPermanentReference(this.EvalThread), val.Type);
} catch (NotImplementedException e) {
- throw new GetValueException(expression, "Language feature not implemented: " + e.Message);
+ throw new EvaluateException(expression, "Language feature not implemented: " + e.Message);
} finally {
watch.Stop();
context.Process.TraceMessage("Evaluated: {0} in {1} ms total", expression.PrettyPrint(), watch.ElapsedMilliseconds);
@@ -190,9 +178,6 @@ namespace ICSharpCode.NRefactory.Visitors
if (val != null && val.Value.IsInvalid)
throw new DebuggerException("Expression \"" + expression.PrettyPrint() + "\" is invalid right after evaluation");
- // Add the result to cache
- context.Process.ExpressionsCache[expression] = val;
-
return val;
}
@@ -266,7 +251,7 @@ namespace ICSharpCode.NRefactory.Visitors
TypedValue CreateValue(object primitiveValue)
{
- Value val = Eval.CreateValue(context.AppDomain, primitiveValue);
+ Value val = Eval.CreateValue(this.EvalThread, primitiveValue);
return new TypedValue(val, val.Type);
}
@@ -312,7 +297,7 @@ namespace ICSharpCode.NRefactory.Visitors
if (!left.Value.IsReference && left.Type.FullName != right.Type.FullName) {
throw new GetValueException(string.Format("Type {0} expected, {1} seen", left.Type.FullName, right.Type.FullName));
}
- left.Value.SetValue(right.Value);
+ left.Value.SetValue(this.EvalThread, right.Value);
return right;
}
@@ -367,17 +352,6 @@ namespace ICSharpCode.NRefactory.Visitors
{
string identifier = identifierExpression.Identifier;
- if (identifier == "__exception") {
- if (context.Thread.CurrentException != null) {
- return new TypedValue(
- context.Thread.CurrentException.Value,
- DebugType.CreateFromType(context.AppDomain.Mscorlib, typeof(System.Exception))
- );
- } else {
- throw new GetValueException("No current exception");
- }
- }
-
DebugParameterInfo par = context.MethodInfo.GetParameter(identifier);
if (par != null)
return new TypedValue(par.GetValue(context), (DebugType)par.ParameterType);
@@ -400,14 +374,14 @@ namespace ICSharpCode.NRefactory.Visitors
if (thisValue != null) {
IDebugMemberInfo instMember = (IDebugMemberInfo)thisValue.Type.GetMember(identifier, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, DebugType.IsFieldOrNonIndexedProperty);
if (instMember != null)
- return new TypedValue(Value.GetMemberValue(thisValue.Value, (MemberInfo)instMember), instMember.MemberType);
+ return new TypedValue(Value.GetMemberValue(this.EvalThread, thisValue.Value, (MemberInfo)instMember), instMember.MemberType);
}
// Static class members
foreach(DebugType declaringType in ((DebugType)context.MethodInfo.DeclaringType).GetSelfAndDeclaringTypes()) {
IDebugMemberInfo statMember = (IDebugMemberInfo)declaringType.GetMember(identifier, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, DebugType.IsFieldOrNonIndexedProperty);
if (statMember != null)
- return new TypedValue(Value.GetMemberValue(null, (MemberInfo)statMember), statMember.MemberType);
+ return new TypedValue(Value.GetMemberValue(this.EvalThread, null, (MemberInfo)statMember), statMember.MemberType);
}
throw new GetValueException("Identifier \"" + identifier + "\" not found in this context");
@@ -441,7 +415,7 @@ namespace ICSharpCode.NRefactory.Visitors
if (pi == null)
throw new GetValueException("The object does not have an indexer property");
return new TypedValue(
- target.Value.GetPropertyValue(pi, GetValues(indexes)),
+ target.Value.GetPropertyValue(this.EvalThread, pi, GetValues(indexes)),
(DebugType)pi.PropertyType
);
}
@@ -479,7 +453,7 @@ namespace ICSharpCode.NRefactory.Visitors
MethodInfo method = targetType.GetMethod(methodName, DebugType.BindingFlagsAllInScope, null, GetTypes(args), null);
if (method == null)
throw new GetValueException("Method " + methodName + " not found");
- Value retVal = Value.InvokeMethod(target != null ? target.Value : null, method, GetValues(args));
+ Value retVal = Value.InvokeMethod(this.EvalThread, target != null ? target.Value : null, method, GetValues(args));
if (retVal == null)
return null;
return new TypedValue(retVal, (DebugType)method.ReturnType);
@@ -492,10 +466,10 @@ namespace ICSharpCode.NRefactory.Visitors
DebugType type = objectCreateExpression.CreateType.ResolveType(context.AppDomain);
List ctorArgs = EvaluateAll(objectCreateExpression.Parameters);
- ConstructorInfo ctor = type.GetConstructor(BindingFlags.Default, null, CallingConventions.Any, GetTypes(ctorArgs), null);
+ DebugConstructorInfo ctor = (DebugConstructorInfo)type.GetConstructor(BindingFlags.Default, null, CallingConventions.Any, GetTypes(ctorArgs), null);
if (ctor == null)
throw new EvaluateException(objectCreateExpression, "Constructor not found");
- Value val = (Value)ctor.Invoke(GetValues(ctorArgs));
+ Value val = Value.InvokeMethod(this.EvalThread, null, ctor.MethodInfo, GetValues(ctorArgs));
return new TypedValue(val, type);
}
@@ -511,14 +485,14 @@ namespace ICSharpCode.NRefactory.Visitors
} else if (!arrayCreateExpression.ArrayInitializer.IsNull) {
length = arrayCreateExpression.ArrayInitializer.CreateExpressions.Count;
}
- Value array = Eval.NewArray((DebugType)type.GetElementType(), (uint)length, null);
+ Value array = Eval.NewArray(this.EvalThread, (DebugType)type.GetElementType(), (uint)length, null);
if (!arrayCreateExpression.ArrayInitializer.IsNull) {
List inits = arrayCreateExpression.ArrayInitializer.CreateExpressions;
if (inits.Count != length)
throw new EvaluateException(arrayCreateExpression, "Incorrect initializer length");
for(int i = 0; i < length; i++) {
TypedValue init = EvaluateAs(inits[i], (DebugType)type.GetElementType());
- array.SetArrayElement(new int[] { i }, init.Value);
+ array.SetArrayElement(this.EvalThread, new int[] { i }, init.Value);
}
}
return new TypedValue(array, type);
@@ -545,7 +519,7 @@ namespace ICSharpCode.NRefactory.Visitors
if (memberInfos.Length == 0)
throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found");
return new TypedValue(
- Value.GetMemberValue(target != null ? target.Value : null, memberInfos[0]),
+ Value.GetMemberValue(this.EvalThread, target != null ? target.Value : null, memberInfos[0]),
((IDebugMemberInfo)memberInfos[0]).MemberType
);
}
@@ -772,8 +746,8 @@ namespace ICSharpCode.NRefactory.Visitors
if (op == BinaryOperatorType.Add) {
if (left.Type.Is() || right.Type.Is()) {
- string a = left.Value.IsNull ? string.Empty : left.Value.InvokeToString();
- string b = right.Value.IsNull ? string.Empty : right.Value.InvokeToString();
+ string a = left.Value.IsNull ? string.Empty : left.Value.InvokeToString(this.EvalThread);
+ string b = right.Value.IsNull ? string.Empty : right.Value.InvokeToString(this.EvalThread);
return CreateValue(a + b);
}
}
diff --git a/src/AddIns/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs b/src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionExtensionMethods.cs
similarity index 97%
rename from src/AddIns/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs
rename to src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionExtensionMethods.cs
index a7cc14f177..f111bc4812 100644
--- a/src/AddIns/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionExtensionMethods.cs
@@ -4,20 +4,21 @@
using System;
using System.Collections.Generic;
using System.Reflection;
-
using Debugger;
using Debugger.MetaData;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.NRefactory.Visitors;
+using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.NRefactory.Ast
{
public static class ExpressionExtensionMethods
{
- public static Value Evaluate(this Expression expression, Process process)
+ // EXPR-EVAL (To be removed when ExpressionEvaluator is deprecated)
+ public static Value Evaluate(this Expression expression)
{
- return ExpressionEvaluator.Evaluate(expression, process);
+ return ExpressionEvaluator.Evaluate(expression, WindowsDebugger.CurrentStackFrame);
}
static M SetStaticType(this M expr, DebugType type) where M: INode
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs b/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs
index 9632eb7b95..72199e81bd 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs
@@ -4,13 +4,13 @@
using System;
using System.Drawing;
using System.Windows.Forms;
-
+using System.Xml.Serialization;
using Debugger;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Services
{
- public enum ShowIntegersAs { Auto, Decimal, Hexadecimal };
+ public enum ShowIntegersAs { Decimal, Hexadecimal, Both, Auto };
[Serializable]
public class DebuggingOptions: Options
@@ -28,7 +28,6 @@ namespace ICSharpCode.SharpDevelop.Services
DebuggeeExceptionWindowState = FormWindowState.Normal;
}
- public bool ICorDebugVisualizerEnabled { get; set; }
public ShowIntegersAs ShowIntegersAs { get; set; }
public bool ShowArgumentNames { get; set; }
public bool ShowArgumentValues { get; set; }
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs
index c93bc25bfb..97179860ed 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs
@@ -17,51 +17,16 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{
public class BreakPointsPad : BookmarkPadBase
{
- WindowsDebugger debugger;
- NDebugger debuggerCore;
-
public BreakPointsPad()
{
- InitializeComponents();
+ var res = new CommonResources();
+ res.InitializeComponent();
- myPanel.Children.Add(CreateToolBar());
+ Grid grid = (Grid)this.Control;
+ ToolBar toolbar = ToolBarService.CreateToolBar(grid, this, "/SharpDevelop/Pads/BreakpointPad/Toolbar");
+ grid.Children.Add(toolbar);
- CreateColumns();
- }
-
- void InitializeComponents()
- {
- debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
-
- if (debugger.ServiceInitialized) {
- InitializeDebugger();
- } else {
- debugger.Initialize += delegate {
- InitializeDebugger();
- };
- }
- }
-
- public void InitializeDebugger()
- {
- debuggerCore = debugger.DebuggerCore;
- }
-
- protected override ToolBar CreateToolBar()
- {
- ToolBar toolbar = ToolBarService.CreateToolBar(myPanel, this, "/SharpDevelop/Pads/BreakpointPad/Toolbar");
- toolbar.SetValue(Grid.RowProperty, 0);
- return toolbar;
- }
-
- protected override void CreateColumns()
- {
- string conditionHeader = StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.ConditionalColumnHeader}");
-
- // HACK
- DataTemplate cellTemplate = new ConditionCell().FindResource("ConditionCellTemplate") as DataTemplate;
-
- listView.AddColumn(conditionHeader, cellTemplate);
+ this.control.listView.View = (GridView)res["breakpointsGridView"];
}
protected override bool ShowBookmarkInThisPad(SDBookmark mark)
@@ -69,27 +34,16 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
return mark.IsVisibleInBookmarkPad && mark is BreakpointBookmark;
}
- protected override void OnItemActivated(object sender, EventArgs e)
+ protected override void OnItemActivated(SDBookmark bookmark)
{
- 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) {
+ if (bookmark 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);
+ if (DecompiledBreakpointBookmark.GetAssemblyAndType(bookmark.FileName, out assemblyFile, out typeName)) {
+ NavigationService.NavigateTo(assemblyFile, typeName, string.Empty, bookmark.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
+ base.OnItemActivated(bookmark);
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.cs
new file mode 100644
index 0000000000..f7fd70f8d6
--- /dev/null
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.cs
@@ -0,0 +1,210 @@
+// 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.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using Debugger;
+using Debugger.AddIn.TreeModel;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Services;
+
+namespace ICSharpCode.SharpDevelop.Gui.Pads
+{
+ public class CallStackPad : AbstractPadContent
+ {
+ ListView listView;
+
+ public override object Control {
+ get { return this.listView; }
+ }
+
+ public CallStackPad()
+ {
+ var res = new CommonResources();
+ res.InitializeComponent();
+
+ listView = new ListView();
+ listView.View = (GridView)res["callstackGridView"];
+ listView.MouseDoubleClick += listView_MouseDoubleClick;
+
+ listView.ContextMenu = CreateMenu();
+
+ WindowsDebugger.RefreshingPads += RefreshPad;
+ RefreshPad();
+ }
+
+ ContextMenu CreateMenu()
+ {
+ MenuItem extMethodsItem = new MenuItem();
+ extMethodsItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowExternalMethods");
+ extMethodsItem.IsChecked = DebuggingOptions.Instance.ShowExternalMethods;
+ extMethodsItem.Click += delegate {
+ extMethodsItem.IsChecked = DebuggingOptions.Instance.ShowExternalMethods = !DebuggingOptions.Instance.ShowExternalMethods;
+ WindowsDebugger.RefreshPads();
+ };
+
+ MenuItem moduleItem = new MenuItem();
+ moduleItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowModuleNames");
+ moduleItem.IsChecked = DebuggingOptions.Instance.ShowModuleNames;
+ moduleItem.Click += delegate {
+ moduleItem.IsChecked = DebuggingOptions.Instance.ShowModuleNames = !DebuggingOptions.Instance.ShowModuleNames;
+ WindowsDebugger.RefreshPads();
+ };
+
+ MenuItem argNamesItem = new MenuItem();
+ argNamesItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentNames");
+ argNamesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentNames;
+ argNamesItem.Click += delegate {
+ argNamesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentNames = !DebuggingOptions.Instance.ShowArgumentNames;
+ WindowsDebugger.RefreshPads();
+ };
+
+ MenuItem argValuesItem = new MenuItem();
+ argValuesItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentValues");
+ argValuesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentValues;
+ argValuesItem.Click += delegate {
+ argValuesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentValues = !DebuggingOptions.Instance.ShowArgumentValues;
+ WindowsDebugger.RefreshPads();
+ };
+
+ MenuItem lineItem = new MenuItem();
+ lineItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowLineNumber");
+ lineItem.IsChecked = DebuggingOptions.Instance.ShowLineNumbers;
+ lineItem.Click += delegate {
+ lineItem.IsChecked = DebuggingOptions.Instance.ShowLineNumbers = !DebuggingOptions.Instance.ShowLineNumbers;
+ WindowsDebugger.RefreshPads();
+ };
+
+ return new ContextMenu() {
+ Items = {
+ extMethodsItem,
+ new Separator(),
+ moduleItem,
+ argNamesItem,
+ argValuesItem,
+ lineItem
+ }
+ };
+ }
+
+ void listView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ CallStackItem item = listView.SelectedItem as CallStackItem;
+ if (item == null)
+ return;
+
+ if (item.Frame.Process.IsPaused) {
+ if (item.Frame != null) {
+ // check for options - if these options are enabled, selecting the frame should not continue
+ if (!item.Frame.HasSymbols && !item.Frame.Process.Options.DecompileCodeWithoutSymbols) {
+ MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWithoutSymbolsOrDecompiledCodeOptions}",
+ "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
+ return;
+ }
+ WindowsDebugger.CurrentStackFrame = item.Frame;
+ WindowsDebugger.Instance.JumpToCurrentLine();
+ WindowsDebugger.RefreshPads();
+ }
+ } else {
+ MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
+ }
+ }
+
+ void RefreshPad()
+ {
+ Thread thead = WindowsDebugger.CurrentThread;
+ if (thead == null) {
+ listView.ItemsSource = null;
+ } else {
+ var items = new ObservableCollection();
+ bool previousItemIsExternalMethod = false;
+ WindowsDebugger.CurrentProcess.EnqueueForEach(
+ listView.Dispatcher,
+ thead.GetCallstack(100),
+ f => items.AddIfNotNull(CreateItem(f, ref previousItemIsExternalMethod))
+ );
+ listView.ItemsSource = items;
+ }
+ }
+
+ CallStackItem CreateItem(StackFrame frame, ref bool previousItemIsExternalMethod)
+ {
+ bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods;
+ if (frame.HasSymbols || showExternalMethods) {
+ // Show the method in the list
+ previousItemIsExternalMethod = false;
+ return new CallStackItem() {
+ Frame = frame,
+ ImageSource = new ResourceServiceImage("Icons.16x16.Method").ImageSource,
+ Name = GetFullName(frame)
+ };
+ } else {
+ // Show [External methods] in the list
+ if (previousItemIsExternalMethod)
+ return null;
+ previousItemIsExternalMethod = true;
+ return new CallStackItem() {
+ Name = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods")
+ };
+ }
+ }
+
+ internal static string GetFullName(StackFrame frame)
+ {
+ StringBuilder name = new StringBuilder(64);
+ if (DebuggingOptions.Instance.ShowModuleNames) {
+ name.Append(frame.MethodInfo.DebugModule.ToString());
+ name.Append('!');
+ }
+ name.Append(frame.MethodInfo.DeclaringType.FullName);
+ name.Append('.');
+ name.Append(frame.MethodInfo.Name);
+ if (DebuggingOptions.Instance.ShowArgumentNames || DebuggingOptions.Instance.ShowArgumentValues) {
+ name.Append('(');
+ for (int i = 0; i < frame.ArgumentCount; i++) {
+ if (DebuggingOptions.Instance.ShowArgumentNames) {
+ name.Append(frame.MethodInfo.GetParameters()[i].Name);
+ if (DebuggingOptions.Instance.ShowArgumentValues) {
+ name.Append('=');
+ }
+ }
+ if (DebuggingOptions.Instance.ShowArgumentValues) {
+ try {
+ name.Append(frame.GetArgumentValue(i).AsString(100));
+ } catch (GetValueException) {
+ name.Append(ResourceService.GetString("Global.NA"));
+ }
+ }
+ if (i < frame.ArgumentCount - 1) {
+ name.Append(", ");
+ }
+ }
+ name.Append(')');
+ }
+ if (DebuggingOptions.Instance.ShowLineNumbers) {
+ if (frame.NextStatement != null) {
+ name.Append(':');
+ name.Append(frame.NextStatement.StartLine.ToString());
+ }
+ }
+ return name.ToString();
+ }
+ }
+
+ public class CallStackItem
+ {
+ public StackFrame Frame { get; set; }
+ public ImageSource ImageSource { get; set; }
+ public string Name { get; set; }
+
+ public Brush FontColor {
+ get { return this.Frame == null || this.Frame.HasSymbols ? Brushes.Black : Brushes.Gray; }
+ }
+ }
+}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml
deleted file mode 100644
index 794898464c..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs
deleted file mode 100644
index 960339446d..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs
+++ /dev/null
@@ -1,306 +0,0 @@
-// 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.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Windows.Controls;
-using System.Windows.Input;
-using System.Windows.Media;
-using Debugger;
-using Debugger.AddIn.TreeModel;
-using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Gui.Pads;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- ///
- /// Interaction logic for CallStackPadContent.xaml
- ///
- public partial class CallStackPadContent : UserControl
- {
- CallStackPad callStackPad;
- Process debuggedProcess;
-
- public CallStackPadContent(CallStackPad pad)
- {
- this.callStackPad = pad;
- InitializeComponent();
-
- view.ContextMenu = CreateMenu();
-
- ((GridView)view.View).Columns[0].Width = DebuggingOptions.Instance.ShowModuleNames ? 100d : 0d;
- ((GridView)view.View).Columns[2].Width = DebuggingOptions.Instance.ShowLineNumbers ? 50d : 0d;
- }
-
- ContextMenu CreateMenu()
- {
- MenuItem extMethodsItem = new MenuItem();
- extMethodsItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowExternalMethods");
- extMethodsItem.IsChecked = DebuggingOptions.Instance.ShowExternalMethods;
- extMethodsItem.Click += delegate {
- extMethodsItem.IsChecked = DebuggingOptions.Instance.ShowExternalMethods = !DebuggingOptions.Instance.ShowExternalMethods;
- callStackPad.InvalidatePad();
- };
-
- MenuItem moduleItem = new MenuItem();
- moduleItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowModuleNames");
- moduleItem.IsChecked = DebuggingOptions.Instance.ShowModuleNames;
- moduleItem.Click += delegate {
- moduleItem.IsChecked = DebuggingOptions.Instance.ShowModuleNames = !DebuggingOptions.Instance.ShowModuleNames;
- ((GridView)view.View).Columns[0].Width = DebuggingOptions.Instance.ShowModuleNames ? 100d : 0d;
- callStackPad.InvalidatePad();
- };
-
- MenuItem argNamesItem = new MenuItem();
- argNamesItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentNames");
- argNamesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentNames;
- argNamesItem.Click += delegate {
- argNamesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentNames = !DebuggingOptions.Instance.ShowArgumentNames;
- callStackPad.InvalidatePad();
- };
-
- MenuItem argValuesItem = new MenuItem();
- argValuesItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowArgumentValues");
- argValuesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentValues;
- argValuesItem.Click += delegate {
- argValuesItem.IsChecked = DebuggingOptions.Instance.ShowArgumentValues = !DebuggingOptions.Instance.ShowArgumentValues;
- callStackPad.InvalidatePad();
- };
-
- MenuItem lineItem = new MenuItem();
- lineItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ShowLineNumber");
- lineItem.IsChecked = DebuggingOptions.Instance.ShowLineNumbers;
- lineItem.Click += delegate {
- lineItem.IsChecked = DebuggingOptions.Instance.ShowLineNumbers = !DebuggingOptions.Instance.ShowLineNumbers;
- ((GridView)view.View).Columns[2].Width = DebuggingOptions.Instance.ShowLineNumbers ? 50d : 0d;
- callStackPad.InvalidatePad();
- };
-
- return new ContextMenu() {
- Items = {
- extMethodsItem,
- new Separator(),
- moduleItem,
- argNamesItem,
- argValuesItem,
- lineItem
- }
- };
- }
-
- public void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= debuggedProcess_Paused;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += debuggedProcess_Paused;
- }
- callStackPad.InvalidatePad();
- }
-
- void debuggedProcess_Paused(object sender, ProcessEventArgs e)
- {
- callStackPad.InvalidatePad();
- }
-
- void View_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- if (debuggedProcess == null)
- return;
- if (debuggedProcess.IsPaused) {
- CallStackItem item = view.SelectedItem as CallStackItem;
-
- if (item == null)
- return;
-
- if (item.Frame != null && debuggedProcess.SelectedThread != null) {
- // check for options - if these options are enabled, selecting the frame should not continue
- if (!item.Frame.HasSymbols && !debuggedProcess.Options.DecompileCodeWithoutSymbols) {
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWithoutSymbolsOrDecompiledCodeOptions}",
- "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
- return;
- }
- debuggedProcess.SelectedThread.SelectedStackFrame = item.Frame;
- debuggedProcess.PauseSession.PausedReason = PausedReason.CurrentFunctionChanged;
- debuggedProcess.OnPaused(); // Force refresh of pads - artificial pause
- }
- } else {
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.CallStack.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.CallStack.FunctionSwitch}");
- }
- }
-
- void View_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Enter) {
- View_MouseLeftButtonUp(sender, null);
- e.Handled = true;
- }
- }
-
- internal void RefreshPad()
- {
- if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedThread == null) {
- view.ItemsSource = null;
- return;
- }
-
- var items = new ObservableCollection();
- using(new PrintTimes("Callstack refresh")) {
- bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods;
- bool previousItemIsExternalMethod = false;
-
- debuggedProcess.EnqueueForEach(
- Dispatcher,
- debuggedProcess.SelectedThread.GetCallstack(100),
- f => items.AddIfNotNull(CreateItem(f, showExternalMethods, ref previousItemIsExternalMethod))
- );
- }
- view.ItemsSource = items;
- }
-
- CallStackItem CreateItem(StackFrame frame, bool showExternalMethods, ref bool previousItemIsExternalMethod)
- {
- CallStackItem item;
-
- // line number
- string lineNumber = string.Empty;
- if (DebuggingOptions.Instance.ShowLineNumbers) {
- if (frame.NextStatement != null)
- lineNumber = frame.NextStatement.StartLine.ToString();
- }
-
- // show modules names
- string moduleName = string.Empty;
- if (DebuggingOptions.Instance.ShowModuleNames) {
- moduleName = frame.MethodInfo.DebugModule.ToString();
- }
-
- if (frame.HasSymbols || showExternalMethods) {
- // Show the method in the list
-
- item = new CallStackItem() {
- Name = GetFullName(frame), Language = "", Line = lineNumber, ModuleName = moduleName
- };
- previousItemIsExternalMethod = false;
- item.Frame = frame;
- } else {
- // Show [External methods] in the list
- if (previousItemIsExternalMethod) return null;
- item = new CallStackItem() {
- Name = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods"),
- Language = ""
- };
- previousItemIsExternalMethod = true;
- }
-
- return item;
- }
-
- internal static string GetFullName(StackFrame frame)
- {
- bool showArgumentNames = DebuggingOptions.Instance.ShowArgumentNames;
- bool showArgumentValues = DebuggingOptions.Instance.ShowArgumentValues;
- bool showLineNumber = DebuggingOptions.Instance.ShowLineNumbers;
- bool showModuleNames = DebuggingOptions.Instance.ShowModuleNames;
-
- StringBuilder name = new StringBuilder();
- name.Append(frame.MethodInfo.DeclaringType.FullName);
- name.Append('.');
- name.Append(frame.MethodInfo.Name);
- if (showArgumentNames || showArgumentValues) {
- name.Append("(");
- for (int i = 0; i < frame.ArgumentCount; i++) {
- string parameterName = null;
- string argValue = null;
- if (showArgumentNames) {
- try {
- parameterName = frame.MethodInfo.GetParameters()[i].Name;
- } catch { }
- if (parameterName == "") parameterName = null;
- }
- if (showArgumentValues) {
- try {
- argValue = frame.GetArgumentValue(i).AsString(100);
- } catch { }
- }
- if (parameterName != null && argValue != null) {
- name.Append(parameterName);
- name.Append("=");
- name.Append(argValue);
- }
- if (parameterName != null && argValue == null) {
- name.Append(parameterName);
- }
- if (parameterName == null && argValue != null) {
- name.Append(argValue);
- }
- if (parameterName == null && argValue == null) {
- name.Append(ResourceService.GetString("Global.NA"));
- }
- if (i < frame.ArgumentCount - 1) {
- name.Append(", ");
- }
- }
- name.Append(")");
- }
-
- return name.ToString();
- }
- }
-
- public class CallStackItem
- {
- public string Name { get; set; }
- public string Language { get; set; }
- public StackFrame Frame { get; set; }
- public string Line { get; set; }
- public string ModuleName { get; set; }
-
- public Brush FontColor {
- get { return Frame == null || Frame.HasSymbols ? Brushes.Black : Brushes.Gray; }
- }
- }
-
- public class CallStackPad : DebuggerPad
- {
- CallStackPadContent callStackList;
-
- static CallStackPad instance;
-
- public static CallStackPad Instance {
- get { return instance; }
- }
-
- public CallStackPad()
- {
- instance = this;
- }
-
- public override object Control {
- get {
- return callStackList;
- }
- }
-
- protected override void InitializeComponents()
- {
- callStackList = new CallStackPadContent(this);
- }
-
- protected override void SelectProcess(Process process)
- {
- callStackList.SelectProcess(process);
- }
-
- protected override void RefreshPad()
- {
- callStackList.RefreshPad();
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs
deleted file mode 100644
index c234d50292..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs
+++ /dev/null
@@ -1,127 +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.Controls;
-using System.Windows.Input;
-
-using ICSharpCode.Core;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public sealed class JumpToAddressCommand : AbstractComboBoxCommand
- {
- MemoryPad pad;
- ComboBox comboBox;
-
- protected override void OnOwnerChanged(EventArgs e)
- {
- this.pad = this.Owner as MemoryPad;
- if (this.pad == null)
- return;
-
- comboBox = this.ComboBox as ComboBox;
-
- if (this.comboBox == null)
- return;
-
- comboBox.KeyUp += (s, ea) => { if (ea.Key == Key.Enter) Run(); };
- comboBox.IsEditable = true;
- comboBox.Width = 130;
-
- base.OnOwnerChanged(e);
- }
-
- public override void Run()
- {
- if (this.pad != null && this.comboBox != null) {
- pad.JumpToAddress(comboBox.Text);
- }
- base.Run();
- }
- }
-
- public abstract class ItemMemoryCommand : AbstractCommand
- {
- protected MemoryPad pad;
-
- protected override void OnOwnerChanged(EventArgs e)
- {
- this.pad = this.Owner as MemoryPad;
- if (this.pad == null)
- return;
-
- base.OnOwnerChanged(e);
- }
- }
-
- public sealed class RefreshAddressCommand : ItemMemoryCommand
- {
- public override void Run()
- {
- if (this.pad == null)
- return;
-
- this.pad.Refresh();
- }
- }
-
- public sealed class NextAddressCommand : ItemMemoryCommand
- {
- public override void Run()
- {
- if (this.pad == null)
- return;
-
- this.pad.MoveToNextAddress();
- }
- }
-
- public sealed class PreviousAddressCommand : ItemMemoryCommand
- {
- public override void Run()
- {
- if (this.pad == null)
- return;
-
- this.pad.MoveToPreviousAddress();
- }
- }
-
- public sealed class DisplayByteSizeCommand : AbstractComboBoxCommand
- {
- MemoryPad pad;
- ComboBox comboBox;
-
- protected override void OnOwnerChanged(EventArgs e)
- {
- this.pad = this.Owner as MemoryPad;
- if (this.pad == null)
- return;
-
- comboBox = this.ComboBox as ComboBox;
-
- if (this.comboBox == null)
- return;
-
- comboBox.SelectionChanged += (s, ea) => { Run(); };
-
- comboBox.Items.Add(1);
- comboBox.Items.Add(2);
- comboBox.Items.Add(4);
- comboBox.Text = "1";
- comboBox.Width = 30;
- comboBox.IsEditable = false;
-
- base.OnOwnerChanged(e);
- }
-
- public override void Run()
- {
- if (this.pad != null && this.comboBox != null) {
- pad.DisplayByteSize = Convert.ToByte(this.comboBox.SelectedValue);
- pad.DisplayMemory();
- }
- base.Run();
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs
index 051113efa6..14ff79c339 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs
@@ -2,20 +2,15 @@
// 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.Linq;
-using System.Windows.Forms;
-
using Debugger.AddIn.Pads;
using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
-using ICSharpCode.Core.Presentation;
using ICSharpCode.Core.WinForms;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn
{
@@ -25,24 +20,9 @@ namespace Debugger.AddIn
{
if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner;
-
- var inputWindow = new WatchInputBox(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.AddWatch}"),
- StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.EnterExpression}"));
- inputWindow.Owner = ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainWindow;
- if (inputWindow.ShowDialog() != true)
- return;
-
- string input = inputWindow.CommandText;
-
- if (!string.IsNullOrEmpty(input)) {
- var text = new TextNode(null, input, inputWindow.ScriptLanguage).ToSharpTreeNode();
- var list = pad.WatchList;
-
- if(!list.WatchItems.Any(n => text.Node.FullName == ((TreeNodeWrapper)n).Node.FullName))
- list.WatchItems.Add(text);
- }
-
- pad.InvalidatePad();
+ var node = new TreeNode(string.Empty, null).ToSharpTreeNode();
+ pad.Items.Add(node);
+ pad.Tree.FocusNode(node);
}
}
}
@@ -53,24 +33,8 @@ namespace Debugger.AddIn
{
if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner;
- var list = pad.WatchList;
- var node = list.SelectedNode;
-
- if (node == null)
- return;
-
- list.WatchItems.Remove(node);
- ((WatchPad)this.Owner).InvalidatePad();
- }
- }
- }
-
- public class RefreshWatchesCommand : AbstractMenuCommand
- {
- public override void Run()
- {
- if (this.Owner is WatchPad) {
- ((WatchPad)this.Owner).InvalidatePad();
+ pad.Items.Remove(pad.Tree.SelectedItem as SharpTreeNodeAdapter);
+ WindowsDebugger.RefreshPads();
}
}
}
@@ -81,86 +45,8 @@ namespace Debugger.AddIn
{
if (this.Owner is WatchPad) {
WatchPad pad = (WatchPad)this.Owner;
- var list = pad.WatchList;
- list.WatchItems.Clear();
+ pad.Items.Clear();
}
}
}
-
- public class CopyToClipboardCommand : AbstractMenuCommand
- {
- public override void Run()
- {
- if (this.Owner is WatchPad) {
- WatchPad pad = (WatchPad)this.Owner;
- var node = pad.WatchList.SelectedNode;
- if (node != null && node.Node is ExpressionNode) {
- string text = ((ExpressionNode)node.Node).FullText;
- ClipboardWrapper.SetText(text);
- }
- }
- }
- }
-
- public class WatchScriptingLanguageMenuBuilder : ISubmenuBuilder, IMenuItemBuilder
- {
- public ToolStripItem[] BuildSubmenu(Codon codon, object owner)
- {
- List items = new List();
-
- if (owner is WatchPad) {
- WatchPad pad = (WatchPad)owner;
-
- if (pad.WatchList.SelectedNode == null)
- return items.ToArray();
-
- var node = pad.WatchList.SelectedNode.Node;
-
- while (node.Parent != null && node.Parent.Parent != null)
- {
- node = node.Parent;
- }
-
- if (!(node is TextNode))
- return items.ToArray();
-
- foreach (string item in SupportedLanguage.GetNames(typeof(SupportedLanguage))) {
- items.Add(MakeItem(item, item, node as TextNode, (sender, e) => HandleItem(sender)));
- }
- }
-
- return items.ToArray();
- }
-
- ToolStripMenuItem MakeItem(string title, string name, TextNode tag, EventHandler onClick)
- {
- ToolStripMenuItem menuItem = new ToolStripMenuItem(StringParser.Parse(title));
- menuItem.Click += onClick;
- menuItem.Name = name;
- menuItem.Tag = tag;
-
- if (name == tag.Language.ToString())
- menuItem.Checked = true;
-
- return menuItem;
- }
-
-
- void HandleItem(object sender)
- {
- ToolStripMenuItem item = null;
- if (sender is ToolStripMenuItem)
- item = (ToolStripMenuItem)sender;
-
- if (item != null) {
- TextNode node = (TextNode)item.Tag;
- node.Language = (SupportedLanguage)SupportedLanguage.Parse(typeof(SupportedLanguage), item.Text);
- }
- }
-
- public System.Collections.ICollection BuildItems(Codon codon, object owner)
- {
- return BuildSubmenu(codon, owner).TranslateToWpf();
- }
- }
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Common/AutoCompleteTextBox.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Common/AutoCompleteTextBox.cs
new file mode 100644
index 0000000000..3d88d0130f
--- /dev/null
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Common/AutoCompleteTextBox.cs
@@ -0,0 +1,120 @@
+// 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 System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Threading;
+using ICSharpCode.AvalonEdit;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
+using ICSharpCode.SharpDevelop.Editor;
+using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.SharpDevelop.Services;
+
+namespace Debugger.AddIn.Pads.Controls
+{
+ public class AutoCompleteTextBox : UserControl
+ {
+ TextEditor editor;
+ ITextEditor editorAdapter;
+
+ public static readonly DependencyProperty TextProperty =
+ DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteTextBox),
+ new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, TextChanged));
+
+ public static readonly DependencyProperty IsEditableProperty =
+ DependencyProperty.Register("IsEditable", typeof(bool), typeof(AutoCompleteTextBox),
+ new FrameworkPropertyMetadata(true, IsEditableChanged));
+
+ public string Text {
+ get { return (string)GetValue(TextProperty); }
+ set { SetValue(TextProperty, value); }
+ }
+
+ public bool IsEditable {
+ get { return (bool)GetValue(IsEditableProperty); }
+ set { SetValue(IsEditableProperty, value); }
+ }
+
+ static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((AutoCompleteTextBox)d).editor.Text = (string)e.NewValue;
+ }
+
+ static void IsEditableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((AutoCompleteTextBox)d).editor.IsReadOnly = !(bool)e.NewValue;
+ }
+
+ public AutoCompleteTextBox()
+ {
+ object tmp;
+ this.editorAdapter = EditorControlService.CreateEditor(out tmp);
+ this.editor = (TextEditor)tmp;
+
+ this.editor.Background = Brushes.Transparent;
+ this.editor.ShowLineNumbers = false;
+ this.editor.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
+ this.editor.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
+ this.editor.TextArea.GotKeyboardFocus += delegate {
+ this.Background = Brushes.White;
+ };
+ this.editor.TextArea.LostKeyboardFocus += delegate {
+ this.Background = Brushes.Transparent;
+ this.Text = this.editor.Text;
+ this.editor.Select(0, 0);
+ };
+ this.editor.TextArea.PreviewKeyDown += editor_TextArea_PreviewKeyDown;
+ this.editor.TextArea.TextEntered += editor_TextArea_TextEntered;
+
+ this.Content = this.editor;
+ }
+
+ void editor_TextArea_PreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Return || e.Key == Key.Escape) {
+ if (e.Key == Key.Return)
+ this.Text = this.editor.Text;
+
+ e.Handled = true;
+ }
+ }
+
+ void editor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
+ {
+ StackFrame frame = WindowsDebugger.CurrentStackFrame;
+ if (e.Text == "." && frame != null)
+ ShowDotCompletion(frame, this.editor.Text);
+ }
+
+ private void ShowDotCompletion(StackFrame frame, string currentText)
+ {
+ string language = ProjectService.CurrentProject == null ? "C#" : ProjectService.CurrentProject.Language;
+ NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
+
+ var seg = frame.NextStatement;
+
+ var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
+ var info = ParserService.GetParseInformation(seg.Filename);
+
+ string text = ParserService.GetParseableFileContent(seg.Filename).Text;
+
+ int currentOffset = this.editor.CaretOffset;
+
+ var expr = expressionFinder.FindExpression(currentText, currentOffset);
+
+ expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
+
+ var rr = resolver.Resolve(expr, info, text);
+
+ if (rr != null) {
+ editorAdapter.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Common/CommonResources.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/Common/CommonResources.xaml
new file mode 100644
index 0000000000..f124ab42f0
--- /dev/null
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Common/CommonResources.xaml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ConsolePad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ConsolePad.cs
index cf257d6b6e..8d9e919511 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ConsolePad.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ConsolePad.cs
@@ -45,34 +45,27 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
string Evaluate(string code)
{
- if (process == null) {
+ Process process = WindowsDebugger.CurrentProcess;
+ StackFrame frame = WindowsDebugger.CurrentStackFrame;
+
+ if (process == null)
return "No process is being debugged";
- }
- if (process.IsRunning) {
+ if (process.IsRunning)
return "The process is running";
- }
+ if (frame == null)
+ return "No current execution frame";
+
try {
- var debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
- StackFrame frame = debugger.DebuggedProcess.GetCurrentExecutingFrame();
- if (frame == null) return "No current execution frame";
-
- object data = debugger.debuggerDecompilerService.GetLocalVariableIndex(frame.MethodInfo.DeclaringType.MetadataToken,
+ object data = ((WindowsDebugger)DebuggerService.CurrentDebugger).debuggerDecompilerService.GetLocalVariableIndex(frame.MethodInfo.DeclaringType.MetadataToken,
frame.MethodInfo.MetadataToken,
code);
Value val = ExpressionEvaluator.Evaluate(code, SelectedLanguage, frame, data);
- return ExpressionEvaluator.FormatValue(val);
+ return ExpressionEvaluator.FormatValue(WindowsDebugger.EvalThread, val);
} catch (GetValueException e) {
return e.Message;
}
}
- Process process;
-
- public Process Process {
- get { return process; }
- set { process = value; }
- }
-
protected override string Prompt {
get {
return "> ";
@@ -102,35 +95,17 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public ConsolePad()
{
WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
-
- debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) {
- this.Process = e.Process;
- };
- this.Process = debugger.DebuggedProcess;
}
protected override void AbstractConsolePadTextEntered(object sender, TextCompositionEventArgs e)
{
- if (this.process == null || this.process.IsRunning)
- return;
-
- StackFrame frame = this.process.GetCurrentExecutingFrame();
- if (frame == null)
- return;
-
- foreach (char ch in e.Text) {
- if (ch == '.') {
- ShowDotCompletion(console.CommandText);
- }
- }
+ StackFrame frame = WindowsDebugger.CurrentStackFrame;
+ if (e.Text == "." && frame != null)
+ ShowDotCompletion(frame, console.CommandText);
}
- void ShowDotCompletion(string currentText)
+ void ShowDotCompletion(StackFrame frame, string currentText)
{
- StackFrame frame = this.process.GetCurrentExecutingFrame();
- if (frame == null)
- return;
-
var seg = frame.NextStatement;
if (seg == null)
return;
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml
deleted file mode 100644
index 20ab0bae89..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml.cs
deleted file mode 100644
index eb8e1b2066..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/ConditionCell.xaml.cs
+++ /dev/null
@@ -1,196 +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.IO;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-
-using ICSharpCode.AvalonEdit;
-using ICSharpCode.Core;
-using ICSharpCode.Core.Presentation;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Bookmarks.Pad.Controls;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Dom;
-using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
-using ICSharpCode.SharpDevelop.Editor;
-using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
-using ICSharpCode.SharpDevelop.Gui;
-using ICSharpCode.SharpDevelop.Project;
-
-namespace Debugger.AddIn.Pads.Controls
-{
- public partial class ConditionCell : UserControl
- {
- private string language;
-
- protected ConsoleControl console;
-
- public static readonly DependencyProperty CommandTextProperty =
- DependencyProperty.Register("CommandText", typeof(string), typeof(ConditionCell),
- new UIPropertyMetadata(null, new PropertyChangedCallback(OnCommandTextChanged)));
-
- private NRefactoryResolver resolver;
-
- public ConditionCell()
- {
- InitializeComponent();
-
- console = new ConsoleControl();
- console.TextAreaTextEntered += new TextCompositionEventHandler(consoleControl_TextAreaTextEntered);
- console.TextAreaPreviewKeyDown += new KeyEventHandler(console_TextAreaPreviewKeyDown);
- console.LostFocus += new RoutedEventHandler(console_LostFocus);
- console.HideScrollBar();
- ConsolePanel.Content = console;
-
- // get language
- if (ProjectService.CurrentProject == null)
- language = "C#";
- else
- language = ProjectService.CurrentProject.Language;
- resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
-
- // FIXME set language
- if (language == "VB" || language == "VBNet") {
- console.SetHighlighting("VBNET");
- }
- else {
- console.SetHighlighting("C#");
- }
- }
-
- ///
- /// Gets/sets the command text displayed at the command prompt.
- ///
- public string CommandText {
- get { return console.CommandText.Trim(); }
- set { console.CommandText = value; }
- }
-
- private BreakpointBookmark Breakpoint {
- get {
- var model = Model;
- return model.Mark as BreakpointBookmark;
- }
- }
-
- private ListViewPadItemModel Model {
- get { return Tag as ListViewPadItemModel; }
- }
-
- private ITextEditor TextEditor {
- get {
- return console.TextEditor;
- }
- }
-
- private void console_TextAreaPreviewKeyDown(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Return || e.Key == Key.Escape) {
-
- if (e.Key == Key.Escape)
- CommandText = string.Empty;
- else {
- if(!CheckSyntax())
- return;
- }
-
- UpdateBreakpoint();
-
- e.Handled = true;
- }
- }
-
- private void console_LostFocus(object sender, RoutedEventArgs e)
- {
- if (string.IsNullOrEmpty(CommandText) || !this.CheckSyntax())
- return;
-
- UpdateBreakpoint();
- }
-
- private void UpdateBreakpoint()
- {
- Breakpoint.Condition = CommandText;
- Model.Condition = CommandText;
- Breakpoint.ScriptLanguage = language;
- Model.Language = language;
-
- if (!string.IsNullOrEmpty(console.CommandText)) {
- Breakpoint.Action = BreakpointAction.Condition;
- if (Breakpoint.IsEnabled)
- Model.Image = BreakpointBookmark.BreakpointConditionalImage.ImageSource;
- }
- else {
- Breakpoint.Action = BreakpointAction.Break;
- if (Breakpoint.IsEnabled)
- Model.Image = BreakpointBookmark.BreakpointImage.ImageSource;
- }
- }
-
- private bool CheckSyntax()
- {
- string command = CommandText;
- if (string.IsNullOrEmpty(command))
- return true;
-
- // FIXME workaround the NRefactory issue that needs a ; at the end
- if (language == "C#") {
- if(!command.EndsWith(";"))
- command += ";";
- // FIXME only one string should be available; highlighting expects C#, supproted language, CSharp
- language = "CSharp";
- }
-
- SupportedLanguage supportedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), language.ToString(), true);
- using (var parser = ParserFactory.CreateParser(supportedLanguage, new StringReader(TextEditor.Document.Text))) {
- parser.ParseExpression();
- if (parser.Errors.Count > 0) {
- MessageService.ShowError(parser.Errors.ErrorOutput);
- return false;
- }
- }
-
- return true;
- }
-
- private void consoleControl_TextAreaTextEntered(object sender, TextCompositionEventArgs e)
- {
- foreach (char ch in e.Text) {
- if (ch == '.') {
- ShowDotCompletion(console.CommandText);
- }
- }
- }
-
- private void ShowDotCompletion(string currentText)
- {
- var seg = Breakpoint;
-
- var expressionFinder = ParserService.GetExpressionFinder(seg.FileName.ToString());
- var info = ParserService.GetParseInformation(seg.FileName.ToString());
-
- string text = ParserService.GetParseableFileContent(seg.FileName.ToString()).Text;
-
- int currentOffset = TextEditor.Caret.Offset - console.CommandOffset - 1;
-
- var expr = expressionFinder.FindExpression(currentText, currentOffset);
-
- expr.Region = new DomRegion(seg.LineNumber, seg.ColumnNumber, seg.LineNumber, seg.ColumnNumber);
-
- var rr = resolver.Resolve(expr, info, text);
-
- if (rr != null) {
- TextEditor.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
- }
- }
-
- private static void OnCommandTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
- var cell = d as ConditionCell;
- cell.CommandText = e.NewValue.ToString();
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/Converters.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/Converters.cs
deleted file mode 100644
index 2283a4cca2..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/Converters.cs
+++ /dev/null
@@ -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;
-using System.Globalization;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Media;
-
-namespace Debugger.AddIn.Pads.Controls
-{
- public class BoolToVisibilityConverter : IMultiValueConverter
- {
- public object Convert(object[] values, Type targetType,
- object parameter, CultureInfo culture)
- {
- bool val = bool.Parse(parameter.ToString());
- return val == (bool.Parse(values[0].ToString()) && bool.Parse(values[1].ToString())) ? Visibility.Visible : Visibility.Collapsed;
- }
-
- public object[] ConvertBack(object value, Type[] targetTypes,
- object parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml
deleted file mode 100644
index f31b220086..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs
deleted file mode 100644
index 2809cb6adf..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs
+++ /dev/null
@@ -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.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Input;
-using Debugger.AddIn.TreeModel;
-using ICSharpCode.Core.Presentation;
-using ICSharpCode.SharpDevelop.Gui;
-using ICSharpCode.SharpDevelop.Gui.Pads;
-using ICSharpCode.TreeView;
-
-namespace Debugger.AddIn.Pads.Controls
-{
- public enum WatchListType
- {
- LocalVar,
- Watch
- }
-
- public partial class WatchList : UserControl
- {
- public WatchList(WatchListType type)
- {
- InitializeComponent();
- WatchType = type;
- if (type == WatchListType.Watch)
- myList.Root = new WatchRootNode();
- else
- myList.Root = new SharpTreeNode();
- }
-
- public WatchListType WatchType { get; private set; }
-
- public SharpTreeNodeCollection WatchItems {
- get { return myList.Root.Children; }
- }
-
- public TreeNodeWrapper SelectedNode {
- get { return myList.SelectedItem as TreeNodeWrapper; }
- }
-
- void OnValueTextBoxKeyUp(object sender, KeyEventArgs e)
- {
- if (e.Key != Key.Enter && e.Key != Key.Escape) {
- e.Handled = true;
- return;
- }
-
- if (e.Key == Key.Enter) {
- if(SelectedNode.Node is ExpressionNode) {
- var node = (ExpressionNode)SelectedNode.Node;
- node.SetText(((TextBox)sender).Text);
- }
- }
- if (e.Key == Key.Enter || e.Key == Key.Escape) {
- myList.UnselectAll();
- if (LocalVarPad.Instance != null)
- LocalVarPad.Instance.InvalidatePad();
- if (WatchPad.Instance != null)
- WatchPad.Instance.InvalidatePad();
- }
- }
-
- void WatchListAutoCompleteCellCommandEntered(object sender, EventArgs e)
- {
- var selectedNode = SelectedNode;
- if (selectedNode == null) return;
- if (WatchType != WatchListType.Watch) return;
-
- var cell = ((WatchListAutoCompleteCell)sender);
-
- selectedNode.Node.Name = cell.CommandText;
- myList.UnselectAll();
- if (WatchType == WatchListType.Watch && WatchPad.Instance != null) {
- WatchPad.Instance.InvalidatePad();
- }
- selectedNode.IsEditing = false;
- }
-
- void MyListPreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
- {
- if (SelectedNode == null) return;
- if (WatchType != WatchListType.Watch)
- return;
- SelectedNode.IsEditing = true;
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.cs
deleted file mode 100644
index 4cf639972f..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.cs
+++ /dev/null
@@ -1,175 +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.IO;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-
-using ICSharpCode.AvalonEdit;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Dom;
-using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
-using ICSharpCode.SharpDevelop.Editor;
-using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
-using ICSharpCode.SharpDevelop.Gui;
-using ICSharpCode.SharpDevelop.Gui.Pads;
-using ICSharpCode.SharpDevelop.Project;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace Debugger.AddIn.Pads.Controls
-{
- public partial class WatchListAutoCompleteCell : UserControl
- {
- string language;
-
- protected ConsoleControl console;
-
- public static readonly DependencyProperty CommandTextProperty =
- DependencyProperty.Register("CommandText", typeof(string), typeof(WatchListAutoCompleteCell),
- new UIPropertyMetadata(null, new PropertyChangedCallback(OnCommandTextChanged)));
-
- NRefactoryResolver resolver;
-
- public event EventHandler CommandEntered;
-
- public WatchListAutoCompleteCell()
- {
- InitializeComponent();
-
- console = new ConsoleControl();
- console.TextAreaTextEntered += new TextCompositionEventHandler(consoleControl_TextAreaTextEntered);
- console.TextAreaPreviewKeyDown += new KeyEventHandler(console_TextAreaPreviewKeyDown);
- console.LostFocus += new RoutedEventHandler(console_LostFocus);
- console.HideScrollBar();
- ConsolePanel.Content = console;
-
- // get language
- if (ProjectService.CurrentProject == null)
- language = "C#";
- else
- language = ProjectService.CurrentProject.Language;
- resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language));
-
- // FIXME set language
- if (language == "VB" || language == "VBNet") {
- console.SetHighlighting("VBNET");
- }
- else {
- console.SetHighlighting("C#");
- }
-
- // get process
- WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
-
- debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) {
- this.Process = e.Process;
- };
- this.Process = debugger.DebuggedProcess;
- }
-
- Process Process { get; set; }
-
- ///
- /// Gets/sets the command text displayed at the command prompt.
- ///
- public string CommandText {
- get { return console.CommandText.Trim(); }
- set { console.CommandText = value; }
- }
-
- ITextEditor TextEditor {
- get {
- return console.TextEditor;
- }
- }
-
- void console_TextAreaPreviewKeyDown(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Return || e.Key == Key.Escape) {
-
- if (e.Key == Key.Escape)
- CommandText = string.Empty;
- else {
- if(!CheckSyntax())
- return;
- }
-
- if (CommandEntered != null)
- CommandEntered(this, EventArgs.Empty);
-
- e.Handled = true;
- }
- }
-
- void console_LostFocus(object sender, RoutedEventArgs e)
- {
- if (string.IsNullOrEmpty(CommandText) || !this.CheckSyntax())
- return;
-
- if (CommandEntered != null)
- CommandEntered(this, EventArgs.Empty);
- }
-
- bool CheckSyntax()
- {
- string command = CommandText;
-
- // FIXME workaround the NRefactory issue that needs a ; at the end
- if (language == "C#" || language == "CSharp") {
- if (!command.EndsWith(";"))
- command += ";";
- // FIXME only one string should be available; highlighting expects C#, supported language, CSharp
- language = "CSharp";
- }
-
- SupportedLanguage supportedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), language.ToString(), true);
- using (var parser = ParserFactory.CreateParser(supportedLanguage, new StringReader(command))) {
- parser.ParseExpression();
- if (parser.Errors.Count > 0) {
- MessageService.ShowError(parser.Errors.ErrorOutput);
- return false;
- }
- }
-
- return true;
- }
-
- void consoleControl_TextAreaTextEntered(object sender, TextCompositionEventArgs e)
- {
- foreach (char ch in e.Text) {
- if (ch == '.') {
- ShowDotCompletion(console.CommandText);
- }
- }
- }
-
- void ShowDotCompletion(string currentText)
- {
- var seg = Process.SelectedStackFrame.NextStatement;
- var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
- var info = ParserService.GetParseInformation(seg.Filename);
- string text = ParserService.GetParseableFileContent(seg.Filename).Text;
- int currentOffset = TextEditor.Caret.Offset - console.CommandOffset - 1;
- var expr = expressionFinder.FindExpression(currentText, currentOffset);
- expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
- var rr = resolver.Resolve(expr, info, text);
-
- if (rr != null) {
- TextEditor.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
- }
- }
-
- static void OnCommandTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var cell = d as WatchListAutoCompleteCell;
- if (cell != null && e.NewValue != null) {
- cell.CommandText = e.NewValue.ToString();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.xaml
deleted file mode 100644
index 6148d1da83..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchListAutoCompleteCell.xaml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerPad.cs
deleted file mode 100644
index 9e712e5176..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/DebuggerPad.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.Windows.Controls;
-using Debugger;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public abstract class DebuggerPad : AbstractPadContent
- {
- protected DockPanel panel;
- ToolBar toolbar;
- protected WindowsDebugger debugger;
-
- public override object Control {
- get {
- return panel;
- }
- }
-
- public DebuggerPad()
- {
- // UI
- this.panel = new DockPanel();
- this.toolbar = BuildToolBar();
-
- if (this.toolbar != null) {
- this.toolbar.SetValue(DockPanel.DockProperty, Dock.Top);
-
- this.panel.Children.Add(toolbar);
- }
-
- // logic
- debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
-
- InitializeComponents();
-
- debugger.ProcessSelected += delegate(object sender, ProcessEventArgs e) {
- SelectProcess(e.Process);
- };
- SelectProcess(debugger.DebuggedProcess);
- }
-
- protected virtual void InitializeComponents()
- {
-
- }
-
- protected virtual void SelectProcess(Process process)
- {
-
- }
-
- ///
- /// Never call this directly. Always use InvalidatePad()
- ///
- protected virtual void RefreshPad()
- {
-
- }
-
- bool invalidatePadEnqueued;
-
- public void InvalidatePad()
- {
- WorkbenchSingleton.AssertMainThread();
- if (invalidatePadEnqueued || WorkbenchSingleton.Workbench == null)
- return;
- invalidatePadEnqueued = true;
- WorkbenchSingleton.SafeThreadAsyncCall(
- delegate {
- invalidatePadEnqueued = false;
- RefreshPad();
- });
-
- }
-
- protected virtual ToolBar BuildToolBar()
- {
- return null;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/LoadedModulesPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/LoadedModulesPad.cs
index b2d39e5b5f..279841c1d9 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/LoadedModulesPad.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/LoadedModulesPad.cs
@@ -2,6 +2,7 @@
// 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.Collections.ObjectModel;
using System.Dynamic;
using System.Windows;
@@ -11,107 +12,64 @@ using Debugger;
using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.Pads.ParallelPad;
using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
- public class LoadedModulesPad : DebuggerPad
+ public class LoadedModulesPad : AbstractPadContent
{
- ListView loadedModulesList;
- Process debuggedProcess;
- ObservableCollection loadedModules;
+ ListView listView;
- protected override void InitializeComponents()
- {
- loadedModulesList = new ListView();
- loadedModules = new ObservableCollection();
- loadedModulesList.ItemsSource = loadedModules;
- loadedModulesList.View = new GridView();
- panel.Children.Add(loadedModulesList);
- RedrawContent();
- ResourceService.LanguageChanged += delegate { RedrawContent(); };
- }
-
- public void RedrawContent()
- {
- loadedModulesList.ClearColumns();
- loadedModulesList.AddColumn(StringParser.Parse("${res:Global.Name}"),
- new Binding { Path = new PropertyPath("Name") }, 250);
- loadedModulesList.AddColumn(StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.AddressColumn}"),
- new Binding { Path = new PropertyPath("Address") }, 100);
- loadedModulesList.AddColumn(StringParser.Parse("${res:Global.Path}"),
- new Binding { Path = new PropertyPath("Path") }, 250);
- loadedModulesList.AddColumn(StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.OrderColumn}"),
- new Binding { Path = new PropertyPath("Order") }, 80);
- loadedModulesList.AddColumn(StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.SymbolsColumn}"),
- new Binding { Path = new PropertyPath("Symbols") }, 130);
- }
-
- protected override void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Modules.Added -= debuggedProcess_ModuleLoaded;
- debuggedProcess.Modules.Removed -= debuggedProcess_ModuleUnloaded;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Modules.Added += debuggedProcess_ModuleLoaded;
- debuggedProcess.Modules.Removed += debuggedProcess_ModuleUnloaded;
- }
- InvalidatePad();
- }
-
- void debuggedProcess_ModuleLoaded(object sender, CollectionItemEventArgs e)
- {
- AddModule(e.Item);
+ public override object Control {
+ get { return listView; }
}
- void debuggedProcess_ModuleUnloaded(object sender, CollectionItemEventArgs e)
+ public LoadedModulesPad()
{
- RemoveModule(e.Item);
+ var res = new CommonResources();
+ res.InitializeComponent();
+
+ listView = new ListView();
+ listView.View = (GridView)res["loadedModulesGridView"];
+
+ WindowsDebugger.RefreshingPads += RefreshPad;
+ RefreshPad();
}
- protected override void RefreshPad()
+ void RefreshPad()
{
- loadedModules.Clear();
- if (debuggedProcess != null) {
- foreach(Module module in debuggedProcess.Modules) {
- AddModule(module);
+ Process process = WindowsDebugger.CurrentProcess;
+ List loadedModules = new List();
+ if (process != null) {
+ foreach(Module module in process.Modules) {
+ loadedModules.Add(new ModuleItem(module));
}
}
- }
-
- void AddModule(Module module)
- {
- loadedModules.Add(new ModuleModel(module));
- }
-
- void RemoveModule(Module module)
- {
- loadedModules.RemoveWhere(model => model.Module == module);
+ listView.ItemsSource = loadedModules;
}
}
- static class ListViewExtensions
+ public class ModuleItem
{
- public static void ClearColumns(this ListView view)
- {
- if (view == null)
- throw new ArgumentNullException("view");
- if (view.View is GridView)
- ((GridView)view.View).Columns.Clear();
- }
+ public string Name { get; private set; }
+ public string Address { get; private set; }
+ public string Path { get; private set; }
+ public string Order { get; private set; }
+ public string Symbols { get; private set; }
- public static void AddColumn(this ListView view, string header, Binding binding, double width)
+ public ModuleItem(Module module)
{
- if (view == null)
- throw new ArgumentNullException("view");
- if (view.View is GridView) {
- GridViewColumn column = new GridViewColumn {
- Width = width,
- DisplayMemberBinding = binding,
- Header = header };
- ((GridView)view.View).Columns.Add(column);
+ this.Name = module.Name;
+ this.Address = string.Format("{0:X8}", module.BaseAdress);
+ if (module.IsDynamic) {
+ this.Path = StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.DynamicModule}");
+ } else if (module.IsInMemory) {
+ this.Path = StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.InMemoryModule}");
+ } else {
+ this.Path = module.FullPath;
}
+ this.Order = module.OrderOfLoading.ToString();
+ this.Symbols = module.HasSymbols ? StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.HasSymbols}") : StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.HasNoSymbols}");
}
}
}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
index 3b870d7418..cdc918cf61 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
@@ -1,85 +1,55 @@
// 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.Collections.ObjectModel;
using System.Linq;
+using System.Windows.Controls;
using System.Windows.Threading;
using Debugger;
-using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.TreeModel;
-using ICSharpCode.Core;
-using Exception = System.Exception;
-using TreeNode = Debugger.AddIn.TreeModel.TreeNode;
+using ICSharpCode.SharpDevelop.Services;
+using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
- public class LocalVarPad : DebuggerPad
+ public class LocalVarPad : AbstractPadContent
{
- WatchList localVarList;
- Process debuggedProcess;
- static LocalVarPad instance;
+ SharpTreeView tree;
- public LocalVarPad()
- {
- instance = this;
- }
-
- /// Always check if Instance is null, might be null if pad is not opened!
- public static LocalVarPad Instance {
- get { return instance; }
- }
-
- public Process Process {
- get { return debuggedProcess; }
- }
-
- protected override void InitializeComponents()
- {
- localVarList = new WatchList(WatchListType.LocalVar);
- panel.Children.Add(localVarList);
+ public override object Control {
+ get { return tree; }
}
- protected override void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= debuggedProcess_Paused;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += debuggedProcess_Paused;
- }
- InvalidatePad();
+ SharpTreeNodeCollection Items {
+ get { return tree.Root.Children; }
}
- void debuggedProcess_Paused(object sender, ProcessEventArgs e)
+ public LocalVarPad()
{
- InvalidatePad();
+ var res = new CommonResources();
+ res.InitializeComponent();
+
+ this.tree = new SharpTreeView();
+ this.tree.Root = new SharpTreeNode();
+ this.tree.ShowRoot = false;
+ this.tree.View = (GridView)res["variableGridView"];
+
+ WindowsDebugger.RefreshingPads += RefreshPad;
+ RefreshPad();
}
- protected override void RefreshPad()
+ void RefreshPad()
{
- if (debuggedProcess == null || debuggedProcess.IsRunning) {
- localVarList.WatchItems.Clear();
- return;
- }
+ StackFrame frame = WindowsDebugger.CurrentStackFrame;
- LoggingService.Info("Local Variables refresh");
- try {
- StackFrame frame = debuggedProcess.GetCurrentExecutingFrame();
- localVarList.WatchItems.Clear();
- if (frame == null) return;
-
- debuggedProcess.EnqueueForEach(
+ if (frame == null) {
+ this.Items.Clear();
+ } else {
+ this.Items.Clear();
+ frame.Process.EnqueueForEach(
Dispatcher.CurrentDispatcher,
- new StackFrameNode(frame).ChildNodes.ToList(),
- n => localVarList.WatchItems.Add(n.ToSharpTreeNode())
+ ValueNode.GetLocalVariables().ToList(),
+ n => this.Items.Add(n.ToSharpTreeNode())
);
- } catch (Exception ex) {
- if (debuggedProcess == null || debuggedProcess.HasExited) {
- // Process unexpectedly exited
- } else {
- MessageService.ShowException(ex);
- }
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs
deleted file mode 100644
index afae24227e..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs
+++ /dev/null
@@ -1,331 +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.ComponentModel;
-using System.Globalization;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Windows.Controls;
-
-using Debugger;
-using Debugger.Interop;
-using ICSharpCode.Core;
-using ICSharpCode.Core.Presentation;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public sealed class MemoryPad : DebuggerPad
- {
- int currentAddressIndex;
- ConsoleControl console;
- int columnsNumber = 16;
- byte displayByteSize = 1;
- byte[] memory;
- Process debuggedProcess;
- List> memoryAddresses = new List>();
- Dictionary addressesMapping = new Dictionary();
-
- ///
- /// Gets or sets the number of columns in the display
- ///
- [DefaultValue(16)]
- public int ColumnsNumber {
- get { return columnsNumber; }
- set {
- if (value != columnsNumber) {
- columnsNumber = value;
- }
- }
- }
-
- ///
- /// Gets or sets the display byte size: 1, 2, 4
- ///
- [DefaultValue(1)]
- public byte DisplayByteSize {
- get { return displayByteSize; }
- set {
- // check is value is a power of 2 between 1 and 4.
- if ((value & (value - 1)) != 0)
- return;
- if (value < 1 || value > 4)
- return;
-
- if (displayByteSize != value) {
- displayByteSize = value;
- }
- }
- }
-
- public MemoryPad()
- {
- this.console = new ConsoleControl();
- this.panel.Children.Add(console);
- this.console.Encoding = Encoding.Default;
- RefreshPad(); // exception
- this.console.SetReadonly();
-
- DebuggerService.DebugStopped += DebuggerService_DebugStopped;
- }
-
- void DebuggerService_DebugStopped(object sender, EventArgs e)
- {
- memoryAddresses.Clear();
- addressesMapping.Clear();
- memory = null;
- }
-
- protected override ToolBar BuildToolBar()
- {
- return ToolBarService.CreateToolBar(panel, this, "/SharpDevelop/Pads/MemoryPad/ToolBar");
- }
-
- protected override void SelectProcess(Process process)
- {
- if (process == null)
- return;
-
- debuggedProcess = process;
- memoryAddresses = debuggedProcess.GetVirtualMemoryAddresses();
- currentAddressIndex = 0;
- }
-
- public void JumpToAddress(string address)
- {
- try {
- if (address.StartsWith("0x"))
- address = address.Substring(2);
-
- long addr = Int64.Parse(address, NumberStyles.AllowHexSpecifier);
-
- memoryAddresses = debuggedProcess.GetVirtualMemoryAddresses();
- // find index for the address or the near addess
- currentAddressIndex = memoryAddresses.BinarySearch(addr);
- if (currentAddressIndex == -1) {
- MessageService.ShowMessage(
- string.Format(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.AddressNotFound"), address),
- ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad"));
-
- currentAddressIndex = 0;
- return;
- }
-
- // refresh pad
- if (!Refresh())
- return;
-
- // find line
- long mod = addr % (columnsNumber * displayByteSize);
- int line;
- long key = addr - mod;
- //int index = addressesMapping.BinarySearch(key);
- if (addressesMapping.ContainsKey(key))
- line = addressesMapping[key];
- else
- line = 1;
-
- // jump
- console.SelectText(line, 0, 8);
- console.JumpToLine(line);
-
- } catch (System.Exception ex) {
- LoggingService.Error(ex.Message);
- }
- }
-
- public bool Refresh(bool refreshMemoryAddresses = false)
- {
- if (console == null)
- return false;
-
- console.Clear();
- if (debuggedProcess == null || debugger.IsProcessRunning) {
- console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NotDebuggingOrProcessRunning"));
- return false;
- }
-
- if (currentAddressIndex <= -1) {
- console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NoMappings"));
- currentAddressIndex = -1;
- return false;
- }
-
- if (refreshMemoryAddresses)
- memoryAddresses = debuggedProcess.GetVirtualMemoryAddresses();
-
- if (memoryAddresses.Count == 0) {
- console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NoMappings"));
- return false;
- }
-
- if (currentAddressIndex >= memoryAddresses.Count) {
- console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NoMappings"));
- currentAddressIndex = memoryAddresses.Count ;
- return false;
- }
-
- RetrieveMemory();
- return true;
- }
-
- void RetrieveMemory()
- {
- // refresh data
- addressesMapping.Clear();
-
- // get current address
- var item = memoryAddresses[currentAddressIndex];
- long address = item.Item1;
- long size = item.Item2;
-
- memory = debuggedProcess.ReadProcessMemory(address, size);
- if (memory == null) {
- console.Append(string.Format(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.UnableToReadFormat"), address.ToString("X8"), size));
- return;
- }
-
- DisplayMemory();
- }
-
- public void DisplayMemory()
- {
- if (memory == null || memory.Length == 0)
- return;
-
- if (console == null)
- return;
-
- console.Clear();
- addressesMapping.Clear();
- var item = memoryAddresses[currentAddressIndex];
- long address = item.Item1;
-
- int totalBytesPerRow = columnsNumber * displayByteSize;
- int numberOfLines = memory.Length / totalBytesPerRow;
- int remainingMemory = memory.Length % totalBytesPerRow;
- int currentLine = 2;// line in the console
- int index = 0;// index in memory arrray of current line
-
- StringBuilder sb = new StringBuilder();
- sb.Append(string.Format(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.ReadingFromFormat"), address.ToString("X8"), (address + memory.Length).ToString("X8"), memory.Length));
- sb.Append(Environment.NewLine);
-
- while (index < numberOfLines) {
- addressesMapping.Add(address, currentLine);
- // write address
- sb.Append(address.ToString("X8"));
- address += (long)totalBytesPerRow;
- sb.Append(" ");
-
- // write bytes
- int start = index * totalBytesPerRow;
- for (int i = 0; i < columnsNumber; ++i) {
- for (int j = 0; j < displayByteSize; ++j) {
- sb.Append(memory[start++].ToString("X2"));
- }
- sb.Append(" ");
- }
-
- // write chars
- start = index * totalBytesPerRow;
- StringBuilder sb1 = new StringBuilder();
- for (int i = 0; i < totalBytesPerRow; ++i) {
- sb1.Append(((char)memory[start++]).ToString());
- }
- string s = sb1.ToString();
- s = Regex.Replace(s, "\\r\\n", string.Empty);
- s = Regex.Replace(s, "\\n", string.Empty);
- s = Regex.Replace(s, "\\r", string.Empty);
- sb.Append(s);
- sb.Append(Environment.NewLine);
- currentLine++;
- index++;
- }
-
- // write the rest of memory
- if (remainingMemory != 0) {
- addressesMapping.Add(address, currentLine);
- // write address
- sb.Append(address.ToString("X8"));
- sb.Append(" ");
-
- // write bytes
- int start = index * remainingMemory * displayByteSize;
- for (int i = 0; i < remainingMemory; ++i) {
- for (int j = 0; j < displayByteSize; j++) {
- sb.Append(memory[start++].ToString("X2"));
- }
- sb.Append(" ");
- }
-
- // write chars
- start = index * remainingMemory * displayByteSize;
- StringBuilder sb1 = new StringBuilder();
- for (int i = 0; i < remainingMemory * displayByteSize; ++i) {
- sb1.Append(((char)memory[start++]).ToString());
- }
- string s = sb1.ToString();
- s = Regex.Replace(s, "\\r\\n", string.Empty);
- s = Regex.Replace(s, "\\n", string.Empty);
- s = Regex.Replace(s, "\\r", string.Empty);
- sb.Append(s);
- }
-
- console.Append(sb.ToString());
- }
-
- public void MoveToPreviousAddress()
- {
- currentAddressIndex--;
- Refresh();
- }
-
- public void MoveToNextAddress()
- {
- currentAddressIndex++;
- Refresh();
- }
- }
-
- internal static class MemoryPadExtensions
- {
- ///
- /// Does a binary search when the Item1 from Tuple is sorted.
- ///
- /// Source of data.
- /// Item to search.
- /// The nearest index.
- internal static int BinarySearch(this List> source, long item1)
- {
- // base checks
- if (source == null)
- throw new NullReferenceException("Source is null!");
-
- if (source.Count == 0)
- return -1;
-
- if (item1 < source[0].Item1)
- return 0;
-
- if (item1 > source[source.Count - 1].Item1)
- return source.Count;
-
- // do a binary search since the source is sorted
- int first = 0; int last = source.Count;
- while (first < last - 1) {
- int middle = (first + last) / 2;
- if (source[middle].Item1 == item1)
- return middle;
- else
- if (source[middle].Item1 < item1)
- first = middle;
- else
- last = middle;
- }
-
- return first;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs
deleted file mode 100644
index 1617201833..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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 ICSharpCode.Core;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Windows;
-using Debugger;
-using Debugger.AddIn.Visualizers.Graph;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- ///
- /// Description of ObjectGraphPad.
- ///
- public class ObjectGraphPad : DebuggerPad
- {
- Process debuggedProcess;
- ObjectGraphControl objectGraphControl;
- static ObjectGraphPad instance;
-
- public ObjectGraphPad()
- {
- instance = this;
- }
-
- /// Always check if Instance is null, might be null if pad is not opened!
- public static ObjectGraphPad Instance {
- get { return instance; }
- }
-
- protected override void InitializeComponents()
- {
- objectGraphControl = new ObjectGraphControl();
- panel.Children.Add(objectGraphControl);
- }
-
-
- protected override void RefreshPad()
- {
- // BUG: if pad window is undocked and floats standalone, IsVisible == false (so pad won't refresh)
- // REQUEST: need to refresh when pad becomes visible -> VisibleChanged event?
- if (!objectGraphControl.IsVisible)
- {
- return;
- }
- if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) {
- this.objectGraphControl.Clear();
- return;
- }
- this.objectGraphControl.RefreshView();
- }
-
- protected override void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= debuggedProcess_Paused;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += debuggedProcess_Paused;
- }
- InvalidatePad();
- }
-
- void debuggedProcess_Paused(object sender, ProcessEventArgs e)
- {
- InvalidatePad();
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackFrameModel.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackFrameModel.cs
index fa8fe1eaab..e829345310 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackFrameModel.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackFrameModel.cs
@@ -63,118 +63,4 @@ namespace Debugger.AddIn.Pads.ParallelPad
}
}
}
-
- public class ThreadModel : ViewModelBase
- {
- Thread thread;
-
- public ThreadModel(Thread thread)
- {
- if (thread == null)
- throw new ArgumentNullException("thread");
- this.thread = thread;
- thread.NameChanged += delegate { RaisePropertyChanged(() => Name); };
- }
-
- public Thread Thread {
- get { return thread; }
- }
-
- public uint ID {
- get { return thread.ID; }
- }
-
- public string Name {
- get { return thread.Name; }
- }
-
- public string Priority {
- get {
- switch (thread.Priority) {
- case System.Threading.ThreadPriority.Highest:
- return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Highest");
- case System.Threading.ThreadPriority.AboveNormal:
- return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.AboveNormal");
- case System.Threading.ThreadPriority.Normal:
- return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Normal");
- case System.Threading.ThreadPriority.BelowNormal:
- return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.BelowNormal");
- case System.Threading.ThreadPriority.Lowest:
- return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Lowest");
- default:
- return thread.Priority.ToString();
- }
- }
- }
-
- public string Location {
- get {
- if (thread.Process.IsPaused && thread.MostRecentStackFrame != null)
- return thread.MostRecentStackFrame.MethodInfo.Name;
- return ResourceService.GetString("Global.NA");
- }
- }
-
- public string Frozen {
- get {
- return ResourceService.GetString(thread.Suspended ? "Global.Yes" : "Global.No");
- }
- }
- }
-
- public class ModuleModel : ViewModelBase
- {
- Module module;
-
- public ModuleModel(Module module)
- {
- if (module == null)
- throw new ArgumentNullException("module");
- this.module = module;
- this.module.SymbolsUpdated += delegate {
- RaisePropertyChanged(() => Name);
- RaisePropertyChanged(() => Address);
- RaisePropertyChanged(() => Path);
- RaisePropertyChanged(() => Order);
- RaisePropertyChanged(() => Symbols);
- };
- }
-
- public Module Module {
- get { return module; }
- }
-
- public string Name {
- get { return module.Name; }
- }
-
- public string Address {
- get { return string.Format("{0:X8}", module.BaseAdress); }
- }
-
- public string Path {
- get {
- if (module.IsDynamic)
- return StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.DynamicModule}");
- if (module.IsInMemory)
- return StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.InMemoryModule}");
-
- return module.FullPath;
- }
- }
-
- public string Order {
- get {
- return module.OrderOfLoading.ToString();
- }
- }
-
- public string Symbols {
- get {
- if (module.HasSymbols)
- return StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.HasSymbols}");
- return StringParser.Parse("${res:MainWindow.Windows.Debug.Modules.HasNoSymbols}");
- }
- }
- }
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs
index 8feecd7c33..579fc17aa4 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs
@@ -20,6 +20,7 @@ using ICSharpCode.SharpDevelop.Bookmarks;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui.Pads;
+using ICSharpCode.SharpDevelop.Services;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
@@ -29,43 +30,45 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
Tasks
}
- public class ParallelStackPad : DebuggerPad
+ public class ParallelStackPad : AbstractPadContent
{
+ DockPanel panel;
+ ToolBar toolbar;
+
DrawSurface surface;
- Process debuggedProcess;
ParallelStacksGraph graph;
List currentThreadStacks = new List();
ParallelStacksView parallelStacksView;
StackFrame selectedFrame;
bool isMethodView;
+ public override object Control {
+ get { return panel; }
+ }
+
#region Overrides
- protected override void InitializeComponents()
+ public ParallelStackPad()
{
+ this.panel = new DockPanel();
+ this.toolbar = ToolBarService.CreateToolBar(panel, this, "/SharpDevelop/Pads/ParallelStacksPad/ToolBar");
+ this.toolbar.SetValue(DockPanel.DockProperty, Dock.Top);
+ this.panel.Children.Add(toolbar);
+
surface = new DrawSurface();
panel.Children.Add(surface);
- }
-
- protected override void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= OnProcessPaused;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += OnProcessPaused;
- }
-
+
+ WindowsDebugger.RefreshingPads += RefreshPad;
+ RefreshPad();
DebuggerService.DebugStarted += OnReset;
- DebuggerService.DebugStopped += OnReset;
-
- InvalidatePad();
+ DebuggerService.DebugStopped += OnReset;
}
- protected override void RefreshPad()
+ protected void RefreshPad()
{
+ Process debuggedProcess = WindowsDebugger.CurrentProcess;
+
if (debuggedProcess == null || debuggedProcess.IsRunning) {
return;
}
@@ -95,12 +98,12 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
if (isMethodView)
{
// build method view for threads
- CreateMethodViewStacks();
+ CreateMethodViewStacks(debuggedProcess);
}
else
{
// normal view
- CreateCommonStacks();
+ CreateCommonStacks(debuggedProcess);
}
}
@@ -119,11 +122,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
surface.SetGraph(graph);
}
}
-
- protected override ToolBar BuildToolBar()
- {
- return ToolBarService.CreateToolBar(panel, this, "/SharpDevelop/Pads/ParallelStacksPad/ToolBar");
- }
#endregion
@@ -133,7 +131,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
get { return parallelStacksView; }
set {
parallelStacksView = value;
- InvalidatePad();
+ WindowsDebugger.RefreshPads();
}
}
@@ -141,7 +139,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
get { return isMethodView; }
set {
isMethodView = value;
- InvalidatePad();
+ WindowsDebugger.RefreshPads();
}
}
@@ -163,11 +161,6 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
BookmarkManager.RemoveAll(b => b is SelectedFrameBookmark);
}
- void OnProcessPaused(object sender, ProcessEventArgs e)
- {
- InvalidatePad();
- }
-
void AddChildren(ThreadStack parent)
{
if(parent.ThreadStackChildren == null || parent.ThreadStackChildren.Count == 0)
@@ -187,7 +180,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
}
}
- void CreateCommonStacks()
+ void CreateCommonStacks(Process debuggedProcess)
{
// stack.ItemCollection order
// 0 -> top of stack = S.C
@@ -311,7 +304,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
commonParent.Process = debuggedProcess;
commonParent.StackSelected += OnThreadStackSelected;
commonParent.FrameSelected += OnFrameSelected;
- commonParent.IsSelected = commonParent.ThreadIds.Contains(debuggedProcess.SelectedThread.ID);
+ commonParent.IsSelected = commonParent.ThreadIds.Contains(WindowsDebugger.CurrentThread.ID);
// add new children
foreach (var stack in listOfCurrentStacks) {
if (stack.ItemCollection.Count == 0)
@@ -369,7 +362,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
}
}
- void CreateMethodViewStacks()
+ void CreateMethodViewStacks(Process debuggedProcess)
{
var list = new List, ObservableCollection, List>>();
@@ -439,6 +432,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
void CreateThreadStack(Thread thread)
{
+ Process debuggedProcess = thread.Process;
+ Thread currentThread = WindowsDebugger.CurrentThread;
+
var items = CreateItems(thread);
if (items == null || items.Count == 0)
return;
@@ -450,10 +446,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
threadStack.ItemCollection = items;
threadStack.UpdateThreadIds(parallelStacksView == ParallelStacksView.Tasks, thread.ID);
- if (debuggedProcess.SelectedThread != null) {
- threadStack.IsSelected = threadStack.ThreadIds.Contains(debuggedProcess.SelectedThread.ID);
+ if (currentThread != null) {
+ threadStack.IsSelected = threadStack.ThreadIds.Contains(currentThread.ID);
if (selectedFrame == null)
- selectedFrame = debuggedProcess.SelectedStackFrame;
+ selectedFrame = WindowsDebugger.CurrentStackFrame;
}
currentThreadStacks.Add(threadStack);
@@ -465,6 +461,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
int noTasks = 0;
var result = new ObservableCollection();
var callstack = thread.GetCallstack(100);
+ Process debuggedProcess = thread.Process;
if (parallelStacksView == ParallelStacksView.Threads) {
foreach (StackFrame frame in callstack) {
@@ -492,10 +489,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
threadStack.ItemCollection = result.Clone();
threadStack.UpdateThreadIds(true, frame.Thread.ID);
- if (debuggedProcess.SelectedThread != null) {
- threadStack.IsSelected = threadStack.ThreadIds.Contains(debuggedProcess.SelectedThread.ID);
+ if (WindowsDebugger.CurrentThread != null) {
+ threadStack.IsSelected = threadStack.ThreadIds.Contains(WindowsDebugger.CurrentThread.ID);
if (selectedFrame == null)
- selectedFrame = debuggedProcess.SelectedStackFrame;
+ selectedFrame = WindowsDebugger.CurrentStackFrame;
}
currentThreadStacks.Add(threadStack);
@@ -535,10 +532,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
lastItemIsExternalMethod = true;
}
- if (frame.Thread.SelectedStackFrame != null &&
- frame.Thread.ID == debuggedProcess.SelectedThread.ID &&
- frame.Thread.SelectedStackFrame.IP == frame.IP &&
- frame.Thread.SelectedStackFrame.GetMethodName() == frame.GetMethodName()) {
+ if (frame.Thread.MostRecentStackFrame != null &&
+ frame.Thread.ID == WindowsDebugger.CurrentThread.ID &&
+ frame.Thread.MostRecentStackFrame.IP == frame.IP &&
+ frame.Thread.MostRecentStackFrame.GetMethodName() == frame.GetMethodName()) {
model.Image = PresentationResourceService.GetImage("Bookmarks.CurrentLine").Source;
model.IsRunningStackFrame = true;
} else {
@@ -583,7 +580,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
ToggleSelectedFrameBookmark(e.Location);
if (isMethodView)
- InvalidatePad();
+ WindowsDebugger.RefreshPads();
}
#endregion
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs
index 35d1dd92b8..345630cac6 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ThreadStack.xaml.cs
@@ -5,15 +5,16 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
-
using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui.Pads;
+using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Pads.ParallelPad
{
@@ -183,7 +184,7 @@ namespace Debugger.AddIn.Pads.ParallelPad
if (selectedItem == null)
return;
- var thread = Process.Threads.Find(t => t.ID == threadId);
+ var thread = Process.Threads.FirstOrDefault(t => t.ID == threadId);
if (thread == null)
return;
@@ -233,7 +234,7 @@ namespace Debugger.AddIn.Pads.ParallelPad
foreach (var id in ThreadIds) {
MenuItem m = new MenuItem();
m.IsCheckable = true;
- m.IsChecked = id == Process.SelectedThread.ID;
+ m.IsChecked = id == WindowsDebugger.CurrentThread.ID;
m.Click += delegate(object sender, RoutedEventArgs e) {
var menuItem = e.OriginalSource as MenuItem;
SelectFrame((uint)menuItem.Tag, item);
@@ -270,7 +271,7 @@ namespace Debugger.AddIn.Pads.ParallelPad
if (selectedItem.MethodName == frame.GetMethodName())
{
TextBlock tb = new TextBlock();
- tb.Text = thread.ID + ": " + CallStackPadContent.GetFullName(frame);
+ tb.Text = thread.ID + ": " + CallStackPad.GetFullName(frame);
panel.Children.Add(tb);
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.Menu.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.Menu.cs
deleted file mode 100644
index 5a5f60ab1f..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.Menu.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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.Collections;
-using System.Dynamic;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using Debugger;
-using Debugger.AddIn.Pads.ParallelPad;
-using ICSharpCode.Core;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public partial class RunningThreadsPad
- {
- ContextMenu CreateContextMenuStrip()
- {
- ContextMenu menu = new ContextMenu();
- menu.Opened += FillContextMenuStrip;
- return menu;
- }
-
- void FillContextMenuStrip(object sender, RoutedEventArgs e)
- {
- var items = runningThreadsList.SelectedItems;
- if (items == null || items.Count == 0) {
- e.Handled = true;
- return;
- }
-
- ThreadModel item = items[0] as ThreadModel;
- if (item == null)
- return;
-
- ContextMenu menu = sender as ContextMenu;
- menu.Items.Clear();
-
- MenuItem freezeItem;
- freezeItem = new MenuItem();
- freezeItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.Threads.Freeze");
- freezeItem.IsChecked = item.Thread.Suspended;
- freezeItem.Click +=
- delegate {
- if (items == null || items.Count == 0) {
- e.Handled = true;
- return;
- }
- bool suspended = item.Thread.Suspended;
-
- if (!debuggedProcess.IsPaused) {
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotFreezeWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.Freeze}");
- return;
- }
-
- foreach(ThreadModel current in items.OfType()) {
- current.Thread.Suspended = !suspended;
- }
- InvalidatePad();
- };
-
- menu.Items.Add(freezeItem);
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs
deleted file mode 100644
index 2f908ce001..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// 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.Collections.ObjectModel;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Threading;
-using Debugger;
-using Debugger.AddIn.Pads.Controls;
-using Debugger.AddIn.Pads.ParallelPad;
-using Debugger.AddIn.TreeModel;
-using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Services;
-using Exception = System.Exception;
-using Thread = Debugger.Thread;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public partial class RunningThreadsPad : DebuggerPad
- {
- ListView runningThreadsList;
- ObservableCollection runningThreads;
- Process debuggedProcess;
-
- protected override void InitializeComponents()
- {
- runningThreads = new ObservableCollection();
- runningThreadsList = new ListView();
- runningThreadsList.ContextMenu = CreateContextMenuStrip();
- runningThreadsList.MouseDoubleClick += RunningThreadsListItemActivate;
- runningThreadsList.ItemsSource = runningThreads;
- runningThreadsList.View = new GridView();
- panel.Children.Add(runningThreadsList);
-
- RedrawContent();
- ResourceService.LanguageChanged += delegate { RedrawContent(); };
- }
-
- public void RedrawContent()
- {
- runningThreadsList.ClearColumns();
- runningThreadsList.AddColumn(ResourceService.GetString("Global.ID"),
- new Binding { Path = new PropertyPath("ID") },
- 100);
- runningThreadsList.AddColumn(ResourceService.GetString("Global.Name"),
- new Binding { Path = new PropertyPath("Name") },
- 300);
- runningThreadsList.AddColumn(ResourceService.GetString("AddIns.HtmlHelp2.Location"),
- new Binding { Path = new PropertyPath("Location") },
- 250);
- runningThreadsList.AddColumn(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority"),
- new Binding { Path = new PropertyPath("Priority") },
- 120);
- runningThreadsList.AddColumn(ResourceService.GetString("MainWindow.Windows.Debug.Threads.Frozen"),
- new Binding { Path = new PropertyPath("Frozen") },
- 80);
- }
-
- protected override void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= debuggedProcess_Paused;
- debuggedProcess.Threads.Added -= debuggedProcess_ThreadStarted;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += debuggedProcess_Paused;
- debuggedProcess.Threads.Added += debuggedProcess_ThreadStarted;
- }
- runningThreads.Clear();
- InvalidatePad();
- }
-
- void debuggedProcess_Paused(object sender, ProcessEventArgs e)
- {
- InvalidatePad();
- }
-
- void debuggedProcess_ThreadStarted(object sender, CollectionItemEventArgs e)
- {
- AddThread(e.Item);
- }
-
- protected override void RefreshPad()
- {
- if (debuggedProcess == null || debuggedProcess.IsRunning) {
- runningThreads.Clear();
- return;
- }
-
- LoggingService.Info("Threads refresh");
-
- debuggedProcess.EnqueueForEach(
- Dispatcher.CurrentDispatcher,
- debuggedProcess.Threads.ToList(),
- t => AddThread(t)
- );
- }
-
- void RunningThreadsListItemActivate(object sender, EventArgs e)
- {
- if (debuggedProcess != null) {
- if (debuggedProcess.IsPaused) {
- ThreadModel obj = runningThreadsList.SelectedItems[0] as ThreadModel;
- Thread thread = obj.Thread;
-
- // check for options - if these options are enabled, selecting the frame should not continue
- if ((thread.MostRecentStackFrame == null || !thread.MostRecentStackFrame.HasSymbols) &&
- !DebuggingOptions.Instance.DecompileCodeWithoutSymbols) {
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWithoutDecompiledCodeOptions}",
- "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
- return;
- }
-
- debuggedProcess.SelectedThread = thread;
- debuggedProcess.SelectedThread.SelectedStackFrame = debuggedProcess.SelectedThread.MostRecentStackFrame;
- if (debuggedProcess.SelectedThread.SelectedStackFrame != null) {
- debuggedProcess.PauseSession.PausedReason = PausedReason.CurrentThreadChanged;
- debuggedProcess.OnPaused(); // Force refresh of pads - artificial pause
- } else {
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchOnNAFrame}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
- }
- } else {
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
- }
- }
- }
-
- void AddThread(Thread thread)
- {
- if (thread == null) return;
-
- // remove the object if exists
- RemoveThread(thread);
-
- ThreadModel obj = new ThreadModel(thread);
-
- runningThreads.Add(obj);
- thread.Exited += (s, e) => RemoveThread(e.Thread);
- }
-
- void RemoveThread(Thread thread)
- {
- if (thread == null)
- return;
-
- runningThreads.RemoveWhere(model => model.Thread == thread);
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/ThreadsPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/ThreadsPad.cs
new file mode 100644
index 0000000000..54817c9a99
--- /dev/null
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/ThreadsPad.cs
@@ -0,0 +1,138 @@
+// 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.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+using Debugger;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Services;
+using Thread = Debugger.Thread;
+
+namespace ICSharpCode.SharpDevelop.Gui.Pads
+{
+ public class ThreadsPad : AbstractPadContent
+ {
+ ListView listView;
+
+ public override object Control {
+ get { return listView; }
+ }
+
+ public ThreadsPad()
+ {
+ var res = new CommonResources();
+ res.InitializeComponent();
+
+ ContextMenu contextMenu = new ContextMenu();
+ contextMenu.Opened += FillContextMenuStrip;
+
+ listView = new ListView();
+ listView.View = (GridView)res["theadsGridView"];
+ listView.ContextMenu = contextMenu;
+ listView.MouseDoubleClick += listView_MouseDoubleClick;
+
+ WindowsDebugger.RefreshingPads += RefreshPad;
+ RefreshPad();
+ }
+
+ void RefreshPad()
+ {
+ Process process = WindowsDebugger.CurrentProcess;
+
+ if (process == null || process.IsRunning) {
+ listView.ItemsSource = null;
+ } else {
+ List items = new List();
+ foreach(var thread in process.Threads) {
+ items.Add(new ThreadItem(thread));
+ }
+ listView.ItemsSource = items;
+ }
+ }
+
+ void listView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ ThreadItem item = listView.SelectedItem as ThreadItem;
+
+ if (WindowsDebugger.CurrentProcess != null) {
+ if (WindowsDebugger.CurrentProcess.IsPaused) {
+ WindowsDebugger.CurrentThread = item.Thread;
+ WindowsDebugger.Instance.JumpToCurrentLine();
+ WindowsDebugger.RefreshPads();
+ } else {
+ MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotSwitchWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.ThreadSwitch}");
+ }
+ }
+ }
+
+ void FillContextMenuStrip(object sender, RoutedEventArgs e)
+ {
+ var items = listView.SelectedItems.OfType();
+ // Suspended property is safe to access at any point
+ bool suspended = items.All(t => t.Thread.Suspended);
+
+ ContextMenu menu = sender as ContextMenu;
+ menu.Items.Clear();
+
+ MenuItem freezeItem;
+ freezeItem = new MenuItem();
+ freezeItem.Header = ResourceService.GetString("MainWindow.Windows.Debug.Threads.Freeze");
+ freezeItem.IsChecked = suspended;
+ freezeItem.Click += delegate {
+ if (WindowsDebugger.CurrentProcess == null || WindowsDebugger.CurrentProcess.IsRunning) {
+ MessageService.ShowMessage("${res:MainWindow.Windows.Debug.Threads.CannotFreezeWhileRunning}", "${res:MainWindow.Windows.Debug.Threads.Freeze}");
+ return;
+ }
+ foreach(ThreadItem item in items.OfType()) {
+ item.Thread.Suspended = !suspended;
+ }
+ WindowsDebugger.RefreshPads();
+ };
+
+ menu.Items.Add(freezeItem);
+ }
+ }
+
+ public class ThreadItem
+ {
+ public Thread Thread { get; private set; }
+ public uint ID { get; private set; }
+ public string Name { get; private set; }
+ public string Priority { get; private set; }
+ public string Frozen { get; private set; }
+
+ public ThreadItem(Thread thread)
+ {
+ // We want to egarly evaluate the properties while the process is paused
+ // rather then wait until the GUI acesses them at some unspecified point
+ this.Thread = thread;
+ this.ID = thread.ID;
+ this.Name = thread.Name;
+ this.Priority = PriorityToString(thread.Priority);
+ this.Frozen = ResourceService.GetString(thread.Suspended ? "Global.Yes" : "Global.No");
+ }
+
+ static string PriorityToString(System.Threading.ThreadPriority priority)
+ {
+ switch (priority) {
+ case System.Threading.ThreadPriority.Highest:
+ return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Highest");
+ case System.Threading.ThreadPriority.AboveNormal:
+ return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.AboveNormal");
+ case System.Threading.ThreadPriority.Normal:
+ return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Normal");
+ case System.Threading.ThreadPriority.BelowNormal:
+ return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.BelowNormal");
+ case System.Threading.ThreadPriority.Lowest:
+ return ResourceService.GetString("MainWindow.Windows.Debug.Threads.Priority.Lowest");
+ default:
+ return ResourceService.GetString("Global.NA");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml
deleted file mode 100644
index 96473894e2..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml.cs
deleted file mode 100644
index 5e0ea97792..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchInputBox.xaml.cs
+++ /dev/null
@@ -1,170 +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.IO;
-using System.Windows;
-using System.Windows.Input;
-
-using ICSharpCode.AvalonEdit;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Dom;
-using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
-using ICSharpCode.SharpDevelop.Editor;
-using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
-using ICSharpCode.SharpDevelop.Gui;
-using ICSharpCode.SharpDevelop.Gui.Pads;
-using ICSharpCode.SharpDevelop.Project;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace Debugger.AddIn.Pads
-{
- ///
- /// Interaction logic for WatchBox.xaml
- ///
- public partial class WatchInputBox : BaseWatchBox
- {
- NRefactoryResolver resolver;
- SupportedLanguage language;
-
- public SupportedLanguage ScriptLanguage {
- get { return language; }
- }
-
- public WatchInputBox(string text, string caption) : base()
- {
- InitializeComponent();
-
- // UI
- text = StringParser.Parse(text);
- this.Title = StringParser.Parse(caption);
- this.ConsolePanel.Content = console;
-
- if (ProjectService.CurrentProject == null)
- language = GetLanguageFromActiveViewContent();
- else
- language = GetLanguage(ProjectService.CurrentProject.Language);
-
- resolver = new NRefactoryResolver(LanguageProperties.GetLanguage(language.ToString()));
-
- switch (language) {
- case SupportedLanguage.CSharp:
- console.SetHighlighting("C#");
- break;
- case SupportedLanguage.VBNet:
- console.SetHighlighting("VBNET");
- break;
- }
-
- // get process
- this.Process = ((WindowsDebugger)DebuggerService.CurrentDebugger).DebuggedProcess;
- }
-
- private Process Process { get; set; }
-
- protected override void AbstractConsolePadTextEntered(object sender, TextCompositionEventArgs e)
- {
- if (this.Process == null || this.Process.IsRunning)
- return;
-
- if (this.Process.SelectedStackFrame == null || this.Process.SelectedStackFrame.NextStatement == null)
- return;
-
- foreach (char ch in e.Text) {
- if (ch == '.') {
- ShowDotCompletion(console.CommandText);
- }
- }
- }
-
- void ShowDotCompletion(string currentText)
- {
- var seg = Process.SelectedStackFrame.NextStatement;
-
- var expressionFinder = ParserService.GetExpressionFinder(seg.Filename);
- var info = ParserService.GetParseInformation(seg.Filename);
-
- string text = ParserService.GetParseableFileContent(seg.Filename).Text;
-
- int currentOffset = TextEditor.Caret.Offset - console.CommandOffset - 1;
-
- var expr = expressionFinder.FindExpression(currentText, currentOffset);
-
- expr.Region = new DomRegion(seg.StartLine, seg.StartColumn, seg.EndLine, seg.EndColumn);
-
- var rr = resolver.Resolve(expr, info, text);
-
- if (rr != null) {
- TextEditor.ShowCompletionWindow(new DotCodeCompletionItemProvider().GenerateCompletionListForResolveResult(rr, expr.Context));
- }
- }
-
- bool CheckSyntax()
- {
- string command = console.CommandText.Trim();
-
- // FIXME workaround the NRefactory issue that needs a ; at the end
- if (language == SupportedLanguage.CSharp && !command.EndsWith(";"))
- command += ";";
-
- using (var parser = ParserFactory.CreateParser(language, new StringReader(command))) {
- parser.ParseExpression();
- if (parser.Errors.Count > 0) {
- MessageService.ShowError(parser.Errors.ErrorOutput);
- return false;
- }
- }
-
- return true;
- }
-
- SupportedLanguage GetLanguage(string language)
- {
- if ("VBNet".Equals(language, StringComparison.OrdinalIgnoreCase)
- || "VB".Equals(language, StringComparison.OrdinalIgnoreCase)
- || "VB.NET".Equals(language, StringComparison.OrdinalIgnoreCase))
- return SupportedLanguage.VBNet;
-
- return SupportedLanguage.CSharp;
- }
-
- ///
- /// Gets the language used in the currently active view content. This is useful, when there is no project
- /// opened and we still want to add watches (i.e. the debugger is attached to an existing process without a solution).
- ///
- SupportedLanguage GetLanguageFromActiveViewContent()
- {
- ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
-
- if (provider != null && provider.TextEditor != null) {
- string extension = Path.GetExtension(provider.TextEditor.FileName).ToLowerInvariant();
- switch (extension) {
- case ".cs":
- return SupportedLanguage.CSharp;
- case ".vb":
- return SupportedLanguage.VBNet;
- }
- }
-
- return SupportedLanguage.CSharp;
- }
-
- void AcceptButton_Click(object sender, RoutedEventArgs e)
- {
- if (!this.CheckSyntax())
- return;
-
- this.DialogResult = true;
- this.Close();
- }
-
- void CancelButton_Click(object sender, RoutedEventArgs e)
- {
- DialogResult = false;
- this.Close();
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
index f4b9e6241f..761cf7aadb 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
@@ -2,14 +2,10 @@
// 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.Collections.Specialized;
using System.Linq;
-using System.Windows;
-using System.Windows.Data;
+using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
-using System.Xml.Serialization;
using Debugger;
using Debugger.AddIn;
using Debugger.AddIn.Pads.Controls;
@@ -17,198 +13,106 @@ using Debugger.AddIn.TreeModel;
using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop.Debugging;
+using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.SharpDevelop.Project;
-using Exception = System.Exception;
+using ICSharpCode.SharpDevelop.Services;
+using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Gui.Pads
{
- public class WatchPad : DebuggerPad
+ public class WatchPad : AbstractPadContent
{
- WatchList watchList;
- Process debuggedProcess;
-
- static WatchPad instance;
+ SharpTreeView tree;
- /// Always check if Instance is null, might be null if pad is not opened!
- public static WatchPad Instance {
- get { return instance; }
+ public override object Control {
+ get { return tree; }
}
- public WatchList WatchList {
- get {
- return watchList;
- }
+ public SharpTreeView Tree {
+ get { return tree; }
}
- public WatchPad()
- {
- instance = this;
+ public SharpTreeNodeCollection Items {
+ get { return tree.Root.Children; }
}
- public Process Process {
- get { return debuggedProcess; }
- }
-
- protected override void InitializeComponents()
- {
- watchList = new WatchList(WatchListType.Watch);
- watchList.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu");
-
- watchList.MouseDoubleClick += WatchListDoubleClick;
- watchList.WatchItems.CollectionChanged += OnWatchItemsCollectionChanged;
-
- panel.Children.Add(watchList);
- panel.KeyDown += PanelKeyDown;
-
- // wire events that influence the items
- LoadSavedNodes();
- ProjectService.SolutionClosed += delegate { watchList.WatchItems.Clear(); };
- ProjectService.ProjectAdded += delegate { LoadSavedNodes(); };
- ProjectService.SolutionLoaded += delegate { LoadSavedNodes(); };
- }
-
- #region Saved nodes
-
- void LoadSavedNodes()
+ public WatchPad()
{
- var props = GetSavedVariablesProperties();
- if (props == null)
- return;
+ var res = new CommonResources();
+ res.InitializeComponent();
- foreach (var element in props.Elements) {
- watchList.WatchItems.Add(new TextNode(null, element, (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), props[element])).ToSharpTreeNode());
- }
- }
-
- void OnWatchItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems.Count > 0) {
- // add to saved data
- var data = e.NewItems.OfType().FirstOrDefault();
- if (data != null) {
- var props = GetSavedVariablesProperties();
- if (props == null) return;
- props.Set(data.FullName, data.Language.ToString());
+ this.tree = new SharpTreeView();
+ this.tree.Root = new SharpTreeNode();
+ this.tree.ShowRoot = false;
+ this.tree.View = (GridView)res["variableGridView"];
+ this.tree.ContextMenu = MenuService.CreateContextMenu(this, "/SharpDevelop/Pads/WatchPad/ContextMenu");
+ this.tree.MouseDoubleClick += delegate(object sender, MouseButtonEventArgs e) {
+ if (this.tree.SelectedItem == null) {
+ AddWatchCommand cmd = new AddWatchCommand { Owner = this };
+ cmd.Run();
}
- }
+ };
- if (e.Action == NotifyCollectionChangedAction.Remove) {
- // remove from saved data
- var data = e.OldItems.OfType().FirstOrDefault();
- if (data != null) {
- var props = GetSavedVariablesProperties();
- if (props == null) return;
- props.Remove(data.FullName);
- }
- }
- }
-
- Properties GetSavedVariablesProperties()
- {
- if (ProjectService.CurrentProject == null)
- return null;
- if (ProjectService.CurrentProject.ProjectSpecificProperties == null)
- return null;
+ ProjectService.SolutionLoaded += delegate { LoadNodes(); };
+ ProjectService.SolutionClosing += delegate { SaveNodes(); };
+ LoadNodes();
- var props = ProjectService.CurrentProject.ProjectSpecificProperties.Get("watchVars") as Properties;
- if (props == null) {
- ProjectService.CurrentProject.ProjectSpecificProperties.Set("watchVars", new Properties());
- }
-
- return ProjectService.CurrentProject.ProjectSpecificProperties.Get("watchVars") as Properties;
+ WindowsDebugger.RefreshingPads += RefreshPad;
+ RefreshPad();
}
- #endregion
-
- void PanelKeyDown(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Insert) {
- AddNewWatch();
- e.Handled = true;
- }
- }
-
- void WatchListDoubleClick(object sender, MouseEventArgs e)
+ void LoadNodes()
{
- if (watchList.SelectedNode == null)
+ if (ProjectService.OpenSolution != null &&
+ ProjectService.OpenSolution.Preferences != null &&
+ ProjectService.OpenSolution.Preferences.Properties != null)
{
- AddNewWatch();
+ var props = ProjectService.OpenSolution.Preferences.Properties.Get("Watches", new Properties());
+ foreach(var element in props.Elements) {
+ this.Items.Add(new TreeNode(element, null).ToSharpTreeNode());
+ }
}
}
-
- void AddNewWatch()
- {
- AddWatchCommand command = new AddWatchCommand { Owner = this };
- command.Run();
- }
-
- void ResetPad(object sender, EventArgs e)
- {
- string language = "CSharp";
-
- if (ProjectService.CurrentProject != null)
- language = ProjectService.CurrentProject.Language;
-
- // rebuild list
- var nodes = new List();
- foreach (var nod in watchList.WatchItems.OfType())
- nodes.Add(new TextNode(null, nod.Node.Name,
- language == "VB" || language == "VBNet" ? SupportedLanguage.VBNet : SupportedLanguage.CSharp)
- .ToSharpTreeNode());
-
- watchList.WatchItems.Clear();
- foreach (var nod in nodes)
- watchList.WatchItems.Add(nod);
- }
-
- protected override void SelectProcess(Process process)
+
+ void SaveNodes()
{
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= debuggedProcess_Paused;
- debuggedProcess.Exited -= ResetPad;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += debuggedProcess_Paused;
- debuggedProcess.Exited += ResetPad;
+ if (ProjectService.OpenSolution != null &&
+ ProjectService.OpenSolution.Preferences != null &&
+ ProjectService.OpenSolution.Preferences.Properties != null)
+ {
+ var props = new Properties();
+ ProjectService.OpenSolution.Preferences.Properties.Set("Watches", props);
+ foreach(var node in this.Items.OfType()) {
+ props.Set(node.Name, (object)null);
+ }
}
- InvalidatePad();
- }
-
- void debuggedProcess_Paused(object sender, ProcessEventArgs e)
- {
- InvalidatePad();
}
- TreeNodeWrapper UpdateNode(TreeNodeWrapper node)
+ SharpTreeNodeAdapter MakeNode(string name)
{
+ LoggingService.Info("Evaluating watch: " + name);
+ TreeNode node;
try {
- LoggingService.Info("Evaluating: " + (string.IsNullOrEmpty(node.Node.Name) ? "is null or empty!" : node.Node.Name));
- var nodExpression = debugger.GetExpression(node.Node.Name);
- //Value val = ExpressionEvaluator.Evaluate(nod.Name, nod.Language, debuggedProcess.SelectedStackFrame);
- ExpressionNode valNode = new ExpressionNode(null, null, node.Node.Name, nodExpression);
- return valNode.ToSharpTreeNode();
- } catch (GetValueException) {
- string error = String.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.InvalidExpression}"), node.Node.Name);
- ErrorInfoNode infoNode = new ErrorInfoNode(node.Node.Name, error);
- return infoNode.ToSharpTreeNode();
+ node = new ValueNode(null, name, () => ExpressionEvaluator.Evaluate(name, SupportedLanguage.CSharp, WindowsDebugger.CurrentStackFrame));
+ } catch (GetValueException e) {
+ node = new TreeNode("Icons.16x16.Error", name, e.Message, string.Empty, null);
}
+ node.CanDelete = true;
+ node.CanSetName = true;
+ node.PropertyChanged += (s, e) => { if (e.PropertyName == "Name") WindowsDebugger.RefreshPads(); };
+ return node.ToSharpTreeNode();
}
- protected override void RefreshPad()
+ protected void RefreshPad()
{
- if (debuggedProcess == null || debuggedProcess.IsRunning)
- return;
-
- using(new PrintTimes("Watch Pad refresh")) {
- var nodes = watchList.WatchItems.OfType().ToArray();
- watchList.WatchItems.Clear();
-
- debuggedProcess.EnqueueForEach(
+ Process process = WindowsDebugger.CurrentProcess;
+ if (process != null) {
+ var names = this.Items.OfType().Select(n => n.Node.Name).ToList();
+ this.Items.Clear();
+ process.EnqueueForEach(
Dispatcher.CurrentDispatcher,
- nodes,
- n => watchList.WatchItems.Add(UpdateNode(n))
+ names,
+ name => this.Items.Add(MakeNode(name))
);
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadModel.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadModel.cs
deleted file mode 100644
index 2357c06e6b..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPadModel.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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.Text;
-using Debugger.AddIn.TreeModel;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop.Project;
-
-namespace ICSharpCode.SharpDevelop.Gui.Pads
-{
- public class TextNode : TreeNode, ISetText
- {
- public TextNode(TreeNode parent, string text, SupportedLanguage language)
- : base(parent)
- {
- this.Name = text;
- this.Language = language;
- }
-
- public override bool CanSetText {
- get {
- return true;
- }
- }
-
- public override bool SetText(string text)
- {
- this.Text = text;
- return true;
- }
-
- public bool SetName(string name)
- {
- this.Name = name;
- return true;
- }
-
- public SupportedLanguage Language { get; set; }
- }
-
- public class ErrorInfoNode : ICorDebug.InfoNode
- {
- public ErrorInfoNode(string name, string text) : base(null, name, text)
- {
- IconImage = DebuggerResourceService.GetImage("Icons.16x16.Error");
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/DebuggeeExceptionForm.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/DebuggeeExceptionForm.cs
index 7411b20d30..36e4fcd32a 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Service/DebuggeeExceptionForm.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Service/DebuggeeExceptionForm.cs
@@ -104,7 +104,7 @@ namespace ICSharpCode.SharpDevelop.Services
void BtnBreakClick(object sender, EventArgs e)
{
- if (this.process.SelectedThread.CurrentExceptionIsUnhandled)
+ if (Exception.IsUnhandled)
Close();
else if (((WindowsDebugger)DebuggerService.CurrentDebugger).BreakAndInterceptHandledException(Exception))
Close();
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/RemotingConfigurationHelpper.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/RemotingConfigurationHelpper.cs
deleted file mode 100644
index b77f20be6b..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Service/RemotingConfigurationHelpper.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.IO;
-using System.Reflection;
-using System.Runtime.Remoting;
-using System.Security.Policy;
-
-namespace ICSharpCode.SharpDevelop.Services
-{
- [Serializable]
- class RemotingConfigurationHelpper
- {
- public string path;
-
- public RemotingConfigurationHelpper(string path)
- {
- this.path = path;
- }
-
- public static string GetLoadedAssemblyPath(string assemblyName)
- {
- string path = null;
- foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
- try {
- string fullFilename = assembly.Location;
- if (Path.GetFileName(fullFilename).Equals(assemblyName, StringComparison.OrdinalIgnoreCase)) {
- path = Path.GetDirectoryName(fullFilename);
- break;
- }
- } catch (NotSupportedException) {
- // assembly.Location throws NotSupportedException for assemblies emitted using
- // Reflection.Emit by custom controls used in the forms designer
- }
- }
- if (path == null) {
- throw new Exception("Assembly " + assemblyName + " is not loaded");
- }
- return path;
- }
-
- public void Configure()
- {
- AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
-
- RemotingConfiguration.Configure(Path.Combine(path, "Client.config"), false);
-
- string baseDir = Directory.GetDirectoryRoot(AppDomain.CurrentDomain.BaseDirectory);
- string relDirs = AppDomain.CurrentDomain.BaseDirectory + ";" + path;
- AppDomain serverAppDomain = AppDomain.CreateDomain("Debugging server",
- new Evidence(AppDomain.CurrentDomain.Evidence),
- baseDir,
- relDirs,
- AppDomain.CurrentDomain.ShadowCopyFiles);
- serverAppDomain.DoCallBack(new CrossAppDomainDelegate(ConfigureServer));
- }
-
- private void ConfigureServer()
- {
- AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
- RemotingConfiguration.Configure(Path.Combine(path, "Server.config"), false);
- }
-
- Assembly AssemblyResolve(object sender, ResolveEventArgs args)
- {
- foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
- try {
- string fullFilename = assembly.Location;
- if (Path.GetFileNameWithoutExtension(fullFilename).Equals(args.Name, StringComparison.OrdinalIgnoreCase) ||
- assembly.FullName == args.Name) {
- return assembly;
- }
- } catch (NotSupportedException) {
- // assembly.Location throws NotSupportedException for assemblies emitted using
- // Reflection.Emit by custom controls used in the forms designer
- }
- }
- return null;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/RunToCursorCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/RunToCursorCommand.cs
index 29752f614c..493f39993f 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Service/RunToCursorCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Service/RunToCursorCommand.cs
@@ -1,6 +1,7 @@
// 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.Linq;
using Debugger;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Debugging;
@@ -14,28 +15,12 @@ namespace ICSharpCode.SharpDevelop.Services
public override void Run()
{
ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
- WindowsDebugger winDebugger = DebuggerService.CurrentDebugger as WindowsDebugger;
- if (provider == null || winDebugger == null)
+ if (provider == null || WindowsDebugger.CurrentProcess == null)
return;
ITextEditor textEditor = provider.TextEditor;
-
- Breakpoint breakpoint = winDebugger.DebuggerCore.Breakpoints.Add(textEditor.FileName, null, textEditor.Caret.Line, textEditor.Caret.Column, true);
- // Be careful to remove the breakpoint just once
- breakpoint.Hit += delegate {
- if (breakpoint != null)
- breakpoint.Remove();
- breakpoint = null;
- };
- winDebugger.DebuggedProcess.Paused += delegate {
- if (breakpoint != null)
- breakpoint.Remove();
- breakpoint = null;
- };
- if (!winDebugger.IsProcessRunning) {
- winDebugger.Continue();
- }
+ WindowsDebugger.CurrentProcess.RunTo(textEditor.FileName, textEditor.Caret.Line, textEditor.Caret.Column);
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/SetCurrentStatementCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/SetCurrentStatementCommand.cs
index db725ed711..2517cdd4c4 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Service/SetCurrentStatementCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Service/SetCurrentStatementCommand.cs
@@ -19,7 +19,7 @@ namespace ICSharpCode.SharpDevelop.Services
ITextEditor textEditor = provider.TextEditor;
- DebuggerService.CurrentDebugger.SetInstructionPointer(textEditor.FileName, textEditor.Caret.Line, textEditor.Caret.Column);
+ DebuggerService.CurrentDebugger.SetInstructionPointer(textEditor.FileName, textEditor.Caret.Line, textEditor.Caret.Column, false);
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
index e498cfc91d..93e0811831 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
@@ -28,91 +28,87 @@ using ICSharpCode.SharpDevelop.Gui.OptionPanels;
using ICSharpCode.SharpDevelop.Project;
using Mono.Cecil;
using Process = Debugger.Process;
+using StackFrame = Debugger.StackFrame;
+using TreeNode = Debugger.AddIn.TreeModel.TreeNode;
namespace ICSharpCode.SharpDevelop.Services
{
public class WindowsDebugger : IDebugger
{
- enum StopAttachedProcessDialogResult {
- Detach = 0,
- Terminate = 1,
- Cancel = 2
- }
-
- bool useRemotingForThreadInterop = false;
- bool attached;
-
- NDebugger debugger;
-
- ICorPublish corPublish;
-
- Process debuggedProcess;
+ public static WindowsDebugger Instance { get; set; }
- internal IDebuggerDecompilerService debuggerDecompilerService;
+ public static NDebugger CurrentDebugger { get; private set; }
+ public static Process CurrentProcess { get; private set; }
+ public static Thread CurrentThread { get; set; }
+ public static StackFrame CurrentStackFrame { get; set; }
- //DynamicTreeDebuggerRow currentTooltipRow;
- //Expression currentTooltipExpression;
+ public static Action RefreshingPads;
- public event EventHandler ProcessSelected;
-
- public NDebugger DebuggerCore {
- get {
- return debugger;
+ public static void RefreshPads()
+ {
+ if (RefreshingPads != null) {
+ RefreshingPads();
}
}
- public Process DebuggedProcess {
+ ///
+ /// Gets the thread which should be used for all evaluations.
+ /// For the time being, it is the selected thread, but we might
+ /// want to have a dedicated evaluation thread in the future.
+ ///
+ ///
+ /// This exists for two reasons:
+ /// 1) So that the addin has explicit control over evaluations rather than the core
+ /// 2) The need to pass this to calls is a reminder that they might do evaluation
+ ///
+ public static Thread EvalThread {
get {
- return debuggedProcess;
+ if (CurrentProcess == null)
+ throw new GetValueException("Debugger is not running");
+ if (CurrentProcess.IsRunning)
+ throw new GetValueException("Process is not paused");
+ if (CurrentThread == null)
+ throw new GetValueException("No thread selected");
+
+ return CurrentThread;
}
}
- public static Process CurrentProcess {
- get {
- WindowsDebugger dbgr = DebuggerService.CurrentDebugger as WindowsDebugger;
- if (dbgr != null && dbgr.DebuggedProcess != null) {
- return dbgr.DebuggedProcess;
- } else {
- return null;
- }
- }
+ enum StopAttachedProcessDialogResult {
+ Detach = 0,
+ Terminate = 1,
+ Cancel = 2
}
- ///
- public bool BreakAtBeginning {
- get;
- set;
- }
+ bool attached;
- protected virtual void OnProcessSelected(ProcessEventArgs e)
- {
- if (ProcessSelected != null) {
- ProcessSelected(this, e);
- }
- }
+ ICorPublish corPublish;
+
+ internal IDebuggerDecompilerService debuggerDecompilerService;
+
+ ///
+ public bool BreakAtBeginning { get; set; }
public bool ServiceInitialized {
- get {
- return debugger != null;
- }
+ get { return CurrentDebugger != null; }
}
public WindowsDebugger()
{
-
+ Instance = this;
}
#region IDebugger Members
string errorDebugging = "${res:XML.MainMenu.DebugMenu.Error.Debugging}";
string errorNotDebugging = "${res:XML.MainMenu.DebugMenu.Error.NotDebugging}";
- string errorProcessRunning = "${res:XML.MainMenu.DebugMenu.Error.ProcessRunning}";
- string errorProcessPaused = "${res:XML.MainMenu.DebugMenu.Error.ProcessPaused}";
- string errorCannotStepNoActiveFunction = "${res:MainWindow.Windows.Debug.Threads.CannotStepNoActiveFunction}";
+ // string errorProcessRunning = "${res:XML.MainMenu.DebugMenu.Error.ProcessRunning}";
+ // string errorProcessPaused = "${res:XML.MainMenu.DebugMenu.Error.ProcessPaused}";
+ // string errorCannotStepNoActiveFunction = "${res:MainWindow.Windows.Debug.Threads.CannotStepNoActiveFunction}";
public bool IsDebugging {
get {
- return ServiceInitialized && debuggedProcess != null;
+ return ServiceInitialized && CurrentProcess != null;
}
}
@@ -124,7 +120,7 @@ namespace ICSharpCode.SharpDevelop.Services
public bool IsProcessRunning {
get {
- return IsDebugging && debuggedProcess.IsRunning;
+ return IsDebugging && CurrentProcess.IsRunning;
}
}
@@ -143,7 +139,7 @@ namespace ICSharpCode.SharpDevelop.Services
InitializeService();
}
- string version = debugger.GetProgramVersion(processStartInfo.FileName);
+ string version = CurrentDebugger.GetProgramVersion(processStartInfo.FileName);
if (version.StartsWith("v1.0")) {
MessageService.ShowMessage("${res:XML.MainMenu.DebugMenu.Error.Net10NotSupported}");
@@ -152,20 +148,20 @@ namespace ICSharpCode.SharpDevelop.Services
// } else if (string.IsNullOrEmpty(version)) {
// // Not a managed assembly
// MessageService.ShowMessage("${res:XML.MainMenu.DebugMenu.Error.BadAssembly}");
- } else if (debugger.IsKernelDebuggerEnabled) {
+ } else if (CurrentDebugger.IsKernelDebuggerEnabled) {
MessageService.ShowMessage("${res:XML.MainMenu.DebugMenu.Error.KernelDebuggerEnabled}");
} else {
attached = false;
if (DebugStarting != null)
DebugStarting(this, EventArgs.Empty);
+ UpdateBreakpointLines();
+
try {
// set the JIT flag for evaluating optimized code
Process.DebugMode = DebugModeFlag.Debug;
- Process process = debugger.Start(processStartInfo.FileName,
- processStartInfo.WorkingDirectory,
- processStartInfo.Arguments);
- SelectProcess(process);
+ CurrentProcess = CurrentDebugger.Start(processStartInfo.FileName, processStartInfo.WorkingDirectory, processStartInfo.Arguments, this.BreakAtBeginning);
+ debugger_ProcessStarted();
} catch (System.Exception e) {
// COMException: The request is not supported. (Exception from HRESULT: 0x80070032)
// COMException: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log for more detail. (Exception from HRESULT: 0x800736B1)
@@ -176,7 +172,6 @@ namespace ICSharpCode.SharpDevelop.Services
if (e is COMException || e is BadImageFormatException || e is UnauthorizedAccessException) {
string msg = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Error.CannotStartProcess}");
msg += " " + e.Message;
- // TODO: Remove
if (e is COMException && ((uint)((COMException)e).ErrorCode == 0x80070032)) {
msg += Environment.NewLine + Environment.NewLine;
msg += "64-bit debugging is not supported. Please set Project -> Project Options... -> Compiling -> Target CPU to 32bit.";
@@ -214,21 +209,22 @@ namespace ICSharpCode.SharpDevelop.Services
InitializeService();
}
- string version = debugger.GetProgramVersion(existingProcess.MainModule.FileName);
+ string version = CurrentDebugger.GetProgramVersion(existingProcess.MainModule.FileName);
if (version.StartsWith("v1.0")) {
MessageService.ShowMessage("${res:XML.MainMenu.DebugMenu.Error.Net10NotSupported}");
} else {
if (DebugStarting != null)
DebugStarting(this, EventArgs.Empty);
+ UpdateBreakpointLines();
+
try {
// set the JIT flag for evaluating optimized code
Process.DebugMode = DebugModeFlag.Debug;
- Process process = debugger.Attach(existingProcess);
+ CurrentProcess = CurrentDebugger.Attach(existingProcess);
+ debugger_ProcessStarted();
attached = true;
- SelectProcess(process);
-
- process.Modules.Added += process_Modules_Added;
+ CurrentProcess.ModuleLoaded += process_Modules_Added;
} catch (System.Exception e) {
// CORDBG_E_DEBUGGER_ALREADY_ATTACHED
if (e is COMException || e is UnauthorizedAccessException) {
@@ -246,7 +242,7 @@ namespace ICSharpCode.SharpDevelop.Services
public void Detach()
{
- debugger.Detach();
+ CurrentDebugger.Detach();
}
public void StartWithoutDebugging(ProcessStartInfo processStartInfo)
@@ -264,7 +260,7 @@ namespace ICSharpCode.SharpDevelop.Services
StopAttachedProcessDialogResult result = ShowStopAttachedProcessDialog();
switch (result) {
case StopAttachedProcessDialogResult.Terminate:
- debuggedProcess.Terminate();
+ CurrentProcess.Terminate();
attached = false;
break;
case StopAttachedProcessDialogResult.Detach:
@@ -273,46 +269,32 @@ namespace ICSharpCode.SharpDevelop.Services
break;
}
} else {
- debuggedProcess.Terminate();
+ CurrentProcess.Terminate();
}
}
- // ExecutionControl:
-
public void Break()
{
- if (!IsDebugging) {
- MessageService.ShowMessage(errorNotDebugging, "${res:XML.MainMenu.DebugMenu.Break}");
- return;
+ if (CurrentProcess != null && CurrentProcess.IsRunning) {
+ CurrentProcess.Break();
}
- if (!IsProcessRunning) {
- MessageService.ShowMessage(errorProcessPaused, "${res:XML.MainMenu.DebugMenu.Break}");
- return;
- }
- debuggedProcess.Break();
}
public void Continue()
{
- if (!IsDebugging) {
- MessageService.ShowMessage(errorNotDebugging, "${res:XML.MainMenu.DebugMenu.Continue}");
- return;
- }
- if (IsProcessRunning) {
- MessageService.ShowMessage(errorProcessRunning, "${res:XML.MainMenu.DebugMenu.Continue}");
- return;
+ if (CurrentProcess != null && CurrentProcess.IsPaused) {
+ CurrentProcess.AsyncContinue();
}
- debuggedProcess.AsyncContinue();
}
- // Stepping:
+ // TODO - What is this?
Debugger.StackFrame GetStackFrame()
{
bool isMatch = false;
int line = -1;
int[] ilRange = null;
- var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
+ var frame = CurrentStackFrame;
int typeToken = frame.MethodInfo.DeclaringType.MetadataToken;
int methodToken = frame.MethodInfo.MetadataToken;
@@ -330,76 +312,22 @@ namespace ICSharpCode.SharpDevelop.Services
public void StepInto()
{
- if (!IsDebugging) {
- MessageService.ShowMessage(errorNotDebugging, "${res:XML.MainMenu.DebugMenu.StepInto}");
- return;
- }
-
- if (debuggedProcess.IsRunning) {
- MessageService.ShowMessage(errorProcessRunning, "${res:XML.MainMenu.DebugMenu.StepInto}");
- return;
- }
-
- var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
- if (frame == null) {
- MessageService.ShowMessage(errorCannotStepNoActiveFunction, "${res:XML.MainMenu.DebugMenu.StepInto}");
- } else {
- if (!frame.HasSymbols) {
- // get frame info from external code mappings
- frame = GetStackFrame();
- }
-
- frame.AsyncStepInto();
+ if (CurrentStackFrame != null) {
+ CurrentStackFrame.AsyncStepInto();
}
}
public void StepOver()
{
- if (!IsDebugging) {
- MessageService.ShowMessage(errorNotDebugging, "${res:XML.MainMenu.DebugMenu.StepOver}");
- return;
- }
-
- if (debuggedProcess.IsRunning) {
- MessageService.ShowMessage(errorProcessRunning, "${res:XML.MainMenu.DebugMenu.StepOver}");
- return;
- }
-
- var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
- if (frame == null) {
- MessageService.ShowMessage(errorCannotStepNoActiveFunction, "${res:XML.MainMenu.DebugMenu.StepOver}");
- } else {
- if (!frame.HasSymbols) {
- // get frame info from external code mappings
- frame = GetStackFrame();
- }
-
- frame.AsyncStepOver();
+ if (CurrentStackFrame != null) {
+ CurrentStackFrame.AsyncStepOver();
}
}
public void StepOut()
{
- if (!IsDebugging) {
- MessageService.ShowMessage(errorNotDebugging, "${res:XML.MainMenu.DebugMenu.StepOut}");
- return;
- }
-
- if (debuggedProcess.IsRunning) {
- MessageService.ShowMessage(errorProcessRunning, "${res:XML.MainMenu.DebugMenu.StepOut}");
- return;
- }
-
- var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
- if (frame == null) {
- MessageService.ShowMessage(errorCannotStepNoActiveFunction, "${res:XML.MainMenu.DebugMenu.StepInto}");
- } else {
- if (!frame.HasSymbols) {
- // get frame info from external code mappings
- frame = GetStackFrame();
- }
-
- frame.AsyncStepOut();
+ if (CurrentStackFrame != null) {
+ CurrentStackFrame.AsyncStepOut();
}
}
@@ -422,18 +350,11 @@ namespace ICSharpCode.SharpDevelop.Services
///
public Value GetValueFromName(string variableName)
{
- if (!CanEvaluate) {
- return null;
+ if (CurrentStackFrame != null) {
+ object data = debuggerDecompilerService.GetLocalVariableIndex(CurrentStackFrame.MethodInfo.DeclaringType.MetadataToken, CurrentStackFrame.MethodInfo.MetadataToken, variableName);
+ return ExpressionEvaluator.Evaluate(variableName, SupportedLanguage.CSharp, CurrentStackFrame, data);
}
-
- var frame = debuggedProcess.GetCurrentExecutingFrame();
- if (frame == null)
- return null;
- object data = debuggerDecompilerService.GetLocalVariableIndex(frame.MethodInfo.DeclaringType.MetadataToken,
- frame.MethodInfo.MetadataToken,
- variableName);
- // evaluate expression
- return ExpressionEvaluator.Evaluate(variableName, SupportedLanguage.CSharp, frame, data);
+ return null;
}
///
@@ -442,10 +363,11 @@ namespace ICSharpCode.SharpDevelop.Services
///
public Expression GetExpression(string variableName)
{
- if (!CanEvaluate) {
+ if (CurrentStackFrame != null) {
+ return ExpressionEvaluator.ParseExpression(variableName, SupportedLanguage.CSharp);
+ } else {
throw new GetValueException("Cannot evaluate now - debugged process is either null or running or has no selected stack frame");
}
- return ExpressionEvaluator.ParseExpression(variableName, SupportedLanguage.CSharp);
}
public bool IsManaged(int processId)
@@ -475,14 +397,6 @@ namespace ICSharpCode.SharpDevelop.Services
}
}
- bool CanEvaluate
- {
- get {
- return debuggedProcess != null && !debuggedProcess.IsRunning &&
- (debuggedProcess.SelectedStackFrame != null || debuggedProcess.SelectedThread.MostRecentStackFrame != null);
- }
- }
-
///
/// Gets the tooltip control that shows the value of given variable.
/// Return null if no tooltip is available.
@@ -491,52 +405,29 @@ namespace ICSharpCode.SharpDevelop.Services
{
try {
var tooltipExpression = GetExpression(variableName);
- string imageName;
- var image = ExpressionNode.GetImageForLocalVariable(out imageName);
- ExpressionNode expressionNode = new ExpressionNode(null, image, variableName, tooltipExpression);
- expressionNode.ImageName = imageName;
- return new DebuggerTooltipControl(logicalPosition, expressionNode) { ShowPins = debuggedProcess.GetCurrentExecutingFrame().HasSymbols };
+ var valueNode = new ValueNode("Icons.16x16.Local", variableName, () => tooltipExpression.Evaluate());
+ return new DebuggerTooltipControl(new TreeNode[] { valueNode });
} catch (System.Exception ex) {
LoggingService.Error("Error on GetTooltipControl: " + ex.Message);
return null;
}
}
- public ITreeNode GetNode(string variable, string currentImageName = null)
+ public Debugger.AddIn.TreeModel.TreeNode GetNode(string variable, string currentImageName = null)
{
try {
- var expression = GetExpression(variable);
- string imageName;
- IImage image;
- if (string.IsNullOrEmpty(currentImageName)) {
- image = ExpressionNode.GetImageForLocalVariable(out imageName);
- }
- else {
- image = new ResourceServiceImage(currentImageName);
- imageName = currentImageName;
- }
- ExpressionNode expressionNode = new ExpressionNode(null, image, variable, expression);
- expressionNode.ImageName = imageName;
- return expressionNode;
+ return new ValueNode(currentImageName ?? "Icons.16x16.Local", variable, () => GetExpression(variable).Evaluate());
} catch (GetValueException) {
return null;
}
}
- public bool CanSetInstructionPointer(string filename, int line, int column)
- {
- if (debuggedProcess != null && debuggedProcess.IsPaused && debuggedProcess.SelectedStackFrame != null) {
- SourcecodeSegment seg = debuggedProcess.SelectedStackFrame.CanSetIP(filename, line, column);
- return seg != null;
- } else {
- return false;
- }
- }
-
- public bool SetInstructionPointer(string filename, int line, int column)
+ public bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
{
- if (CanSetInstructionPointer(filename, line, column)) {
- SourcecodeSegment seg = debuggedProcess.SelectedStackFrame.SetIP(filename, line, column);
+ if (CurrentStackFrame != null) {
+ SourcecodeSegment seg = CurrentStackFrame.SetIP(filename, line, column, dryRun);
+ WindowsDebugger.RefreshPads();
+ JumpToCurrentLine();
return seg != null;
} else {
return false;
@@ -554,23 +445,14 @@ namespace ICSharpCode.SharpDevelop.Services
public void InitializeService()
{
- if (useRemotingForThreadInterop) {
- // This needs to be called before instance of NDebugger is created
- string path = RemotingConfigurationHelpper.GetLoadedAssemblyPath("Debugger.Core.dll");
- new RemotingConfigurationHelpper(path).Configure();
- }
-
// get decompiler service
var items = AddInTree.BuildItems("/SharpDevelop/Services/DebuggerDecompilerService", null, false);
if (items.Count > 0)
debuggerDecompilerService = items[0];
// init NDebugger
- debugger = new NDebugger();
- debugger.Options = DebuggingOptions.Instance;
- debugger.DebuggerTraceMessage += debugger_TraceMessage;
- debugger.Processes.Added += debugger_ProcessStarted;
- debugger.Processes.Removed += debugger_ProcessExited;
+ CurrentDebugger = new NDebugger();
+ CurrentDebugger.Options = DebuggingOptions.Instance;
DebuggerService.BreakPointAdded += delegate (object sender, BreakpointBookmarkEventArgs e) {
AddBreakpoint(e.BreakpointBookmark);
@@ -580,18 +462,34 @@ namespace ICSharpCode.SharpDevelop.Services
AddBreakpoint(b);
}
+ BookmarkManager.Removed += (sender, e) => {
+ BreakpointBookmark bm = e.Bookmark as BreakpointBookmark;
+ if (bm != null) {
+ Breakpoint bp = bm.InternalBreakpointObject as Breakpoint;
+ bp.IsEnabled = false;
+ }
+ };
+
if (Initialize != null) {
Initialize(this, null);
}
}
- bool Compare(byte[] a, byte[] b)
+ void UpdateBreakpointLines()
{
- if (a.Length != b.Length) return false;
- for(int i = 0; i < a.Length; i++) {
- if (a[i] != b[i]) return false;
+ foreach (BreakpointBookmark bookmark in BookmarkManager.Bookmarks.OfType()) {
+ Breakpoint breakpoint = bookmark.InternalBreakpointObject as Breakpoint;
+ breakpoint.Line = bookmark.LineNumber;
+ breakpoint.Column = bookmark.ColumnNumber;
+ }
+ }
+
+ void UpdateBreakpointIcons()
+ {
+ foreach (BreakpointBookmark bookmark in BookmarkManager.Bookmarks.OfType()) {
+ Breakpoint breakpoint = bookmark.InternalBreakpointObject as Breakpoint;
+ bookmark.IsHealthy = (CurrentProcess == null) || breakpoint.IsSet;
}
- return true;
}
void AddBreakpoint(BreakpointBookmark bookmark)
@@ -619,23 +517,13 @@ namespace ICSharpCode.SharpDevelop.Services
int[] ilRanges;
int methodToken;
if (debuggerDecompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) {
- // create BP
- breakpoint = new ILBreakpoint(
- debugger,
- memberReference.FullName,
- dbb.LineNumber,
- memberReference.MetadataToken.ToInt32(),
- methodToken,
- ilRanges[0],
- dbb.IsEnabled);
-
- debugger.Breakpoints.Add(breakpoint);
+ CurrentDebugger.AddILBreakpoint(memberReference.FullName, dbb.LineNumber, memberReference.MetadataToken.ToInt32(), methodToken, ilRanges[0], dbb.IsEnabled);
}
} catch (System.Exception ex) {
LoggingService.Error("Error on DecompiledBreakpointBookmark: " + ex.Message);
}
} else {
- breakpoint = debugger.Breakpoints.Add(bookmark.FileName, null, bookmark.LineNumber, 0, bookmark.IsEnabled);
+ breakpoint = CurrentDebugger.AddBreakpoint(bookmark.FileName, bookmark.LineNumber, 0, bookmark.IsEnabled);
}
if (breakpoint == null) {
@@ -643,100 +531,16 @@ namespace ICSharpCode.SharpDevelop.Services
return;
}
- MethodInvoker setBookmarkColor = delegate {
- if (debugger.Processes.Count == 0) {
- bookmark.IsHealthy = true;
- bookmark.Tooltip = null;
- } else if (!breakpoint.IsSet) {
- bookmark.IsHealthy = false;
- bookmark.Tooltip = "Breakpoint was not found in any loaded modules";
- } else if (breakpoint.OriginalLocation == null || breakpoint.OriginalLocation.CheckSum == null) {
- bookmark.IsHealthy = true;
- bookmark.Tooltip = null;
- } else {
- if (!File.Exists(bookmark.FileName))
- return;
-
- byte[] fileMD5;
- IEditable file = FileService.GetOpenFile(bookmark.FileName) as IEditable;
- if (file != null) {
- byte[] fileContent = Encoding.UTF8.GetBytesWithPreamble(file.Text);
- fileMD5 = new MD5CryptoServiceProvider().ComputeHash(fileContent);
- } else {
- fileMD5 = new MD5CryptoServiceProvider().ComputeHash(File.ReadAllBytes(bookmark.FileName));
- }
- if (Compare(fileMD5, breakpoint.OriginalLocation.CheckSum)) {
- bookmark.IsHealthy = true;
- bookmark.Tooltip = null;
- } else {
- bookmark.IsHealthy = false;
- bookmark.Tooltip = "Check sum or file does not match to the original";
- }
- }
- };
-
- // event handlers on bookmark and breakpoint don't need deregistration
- bookmark.IsEnabledChanged += delegate {
- breakpoint.Enabled = bookmark.IsEnabled;
- };
- breakpoint.Set += delegate { setBookmarkColor(); };
-
- setBookmarkColor();
-
- EventHandler> bp_debugger_ProcessStarted = (sender, e) => {
- setBookmarkColor();
- // User can change line number by inserting or deleting lines
- breakpoint.Line = bookmark.LineNumber;
- };
- EventHandler> bp_debugger_ProcessExited = (sender, e) => {
- setBookmarkColor();
- };
-
- EventHandler bp_debugger_BreakpointHit =
- new EventHandler(
- delegate(object sender, BreakpointEventArgs e)
- {
- LoggingService.Debug(bookmark.Action + " " + bookmark.ScriptLanguage + " " + bookmark.Condition);
-
- switch (bookmark.Action) {
- case BreakpointAction.Break:
- break;
- case BreakpointAction.Condition:
- if (Evaluate(bookmark.Condition, bookmark.ScriptLanguage))
- DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAtBecause}") + "\n", bookmark.LineNumber, bookmark.FileName, bookmark.Condition));
- else
- this.debuggedProcess.AsyncContinue();
- break;
- case BreakpointAction.Trace:
- DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAt}") + "\n", bookmark.LineNumber, bookmark.FileName));
- break;
- }
- });
-
- BookmarkEventHandler bp_bookmarkManager_Removed = null;
- bp_bookmarkManager_Removed = (sender, e) => {
- if (bookmark == e.Bookmark) {
- debugger.Breakpoints.Remove(breakpoint);
-
- // unregister the events
- debugger.Processes.Added -= bp_debugger_ProcessStarted;
- debugger.Processes.Removed -= bp_debugger_ProcessExited;
- breakpoint.Hit -= bp_debugger_BreakpointHit;
- BookmarkManager.Removed -= bp_bookmarkManager_Removed;
- }
- };
- // register the events
- debugger.Processes.Added += bp_debugger_ProcessStarted;
- debugger.Processes.Removed += bp_debugger_ProcessExited;
- breakpoint.Hit += bp_debugger_BreakpointHit;
- BookmarkManager.Removed += bp_bookmarkManager_Removed;
+ bookmark.InternalBreakpointObject = breakpoint;
+ bookmark.IsHealthy = (CurrentProcess == null) || breakpoint.IsSet;
+ bookmark.IsEnabledChanged += delegate { breakpoint.IsEnabled = bookmark.IsEnabled; };
}
bool Evaluate(string code, string language)
{
try {
SupportedLanguage supportedLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), language, true);
- Value val = ExpressionEvaluator.Evaluate(code, supportedLanguage, debuggedProcess.SelectedStackFrame);
+ Value val = ExpressionEvaluator.Evaluate(code, supportedLanguage, CurrentStackFrame);
if (val != null && val.Type.IsPrimitive && val.PrimitiveValue is bool)
return (bool)val.PrimitiveValue;
@@ -755,138 +559,124 @@ namespace ICSharpCode.SharpDevelop.Services
DebuggerService.PrintDebugMessage(e.Message);
}
- void debugger_TraceMessage(object sender, MessageEventArgs e)
- {
- LoggingService.Debug("Debugger: " + e.Message);
- }
-
- void debugger_ProcessStarted(object sender, CollectionItemEventArgs e)
+ void debugger_ProcessStarted()
{
- if (debugger.Processes.Count == 1) {
- if (DebugStarted != null) {
- DebugStarted(this, EventArgs.Empty);
- }
+ if (DebugStarted != null) {
+ DebugStarted(this, EventArgs.Empty);
}
- e.Item.LogMessage += LogMessage;
- }
-
- void debugger_ProcessExited(object sender, CollectionItemEventArgs e)
- {
- if (debugger.Processes.Count == 0) {
- if (DebugStopped != null) {
- DebugStopped(this, e);
- }
- SelectProcess(null);
- } else {
- SelectProcess(debugger.Processes[0]);
- }
- }
-
- public void SelectProcess(Process process)
- {
- if (debuggedProcess != null) {
- debuggedProcess.Paused -= debuggedProcess_DebuggingPaused;
- debuggedProcess.ExceptionThrown -= debuggedProcess_ExceptionThrown;
- debuggedProcess.Resumed -= debuggedProcess_DebuggingResumed;
- debuggedProcess.ModulesAdded -= debuggedProcess_ModulesAdded;
- }
- debuggedProcess = process;
- if (debuggedProcess != null) {
- debuggedProcess.Paused += debuggedProcess_DebuggingPaused;
- debuggedProcess.ExceptionThrown += debuggedProcess_ExceptionThrown;
- debuggedProcess.Resumed += debuggedProcess_DebuggingResumed;
- debuggedProcess.ModulesAdded += debuggedProcess_ModulesAdded;
-
- debuggedProcess.BreakAtBeginning = BreakAtBeginning;
- }
- // reset
- BreakAtBeginning = false;
- JumpToCurrentLine();
- OnProcessSelected(new ProcessEventArgs(process));
+ CurrentProcess.ModuleLoaded += (s, e) => UpdateBreakpointIcons();
+ CurrentProcess.ModuleLoaded += (s, e) => RefreshPads();
+ CurrentProcess.ModuleUnloaded += (s, e) => RefreshPads();
+ CurrentProcess.LogMessage += LogMessage;
+ CurrentProcess.Paused += debuggedProcess_DebuggingPaused;
+ CurrentProcess.Resumed += debuggedProcess_DebuggingResumed;
+ CurrentProcess.Exited += (s, e) => debugger_ProcessExited();
+
+ UpdateBreakpointIcons();
}
- void debuggedProcess_ModulesAdded(object sender, ModuleEventArgs e)
+ void debugger_ProcessExited()
{
- var currentModuleTypes = e.Module.GetNamesOfDefinedTypes();
- foreach (var bookmark in DebuggerService.Breakpoints.OfType()) {
- var breakpoint = debugger.Breakpoints.FirstOrDefault(
- b => b is ILBreakpoint && b.Line == bookmark.LineNumber &&
- ((ILBreakpoint)b).MetadataToken == bookmark.MemberReference.MetadataToken.ToInt32());
- if (breakpoint == null)
- continue;
- // set the breakpoint only if the module contains the type
- if (!currentModuleTypes.Contains(breakpoint.TypeName))
- continue;
-
- breakpoint.SetBreakpoint(e.Module);
+ if (DebugStopped != null) {
+ DebugStopped(this, EventArgs.Empty);
}
+
+ CurrentProcess = null;
+ CurrentThread = null;
+ CurrentStackFrame = null;
+
+ UpdateBreakpointIcons();
+ RefreshPads();
}
- void debuggedProcess_DebuggingPaused(object sender, ProcessEventArgs e)
+ void debuggedProcess_DebuggingPaused(object sender, DebuggerEventArgs e)
{
OnIsProcessRunningChanged(EventArgs.Empty);
- using(new PrintTimes("Jump to current line")) {
- JumpToCurrentLine();
+ CurrentProcess = e.Process;
+ CurrentThread = e.Thread;
+ CurrentStackFrame = CurrentThread != null ? CurrentThread.MostRecentUserStackFrame : null;
+
+ LoggingService.Info("Jump to current line");
+ JumpToCurrentLine();
+
+ if (e.ExceptionThrown != null) {
+ HandleException(e);
}
- // TODO update tooltip
- /*if (currentTooltipRow != null && currentTooltipRow.IsShown) {
- using(new PrintTimes("Update tooltip")) {
- try {
- Utils.DoEvents(debuggedProcess);
- AbstractNode updatedNode = ValueNode.Create(currentTooltipExpression);
- currentTooltipRow.SetContentRecursive(updatedNode);
- } catch (AbortedBecauseDebuggeeResumedException) {
- }
+
+ foreach (Breakpoint breakpoint in e.BreakpointsHit) {
+ var bookmark = BookmarkManager.Bookmarks.OfType().First(bm => bm.InternalBreakpointObject == breakpoint);
+
+ LoggingService.Debug(bookmark.Action + " " + bookmark.ScriptLanguage + " " + bookmark.Condition);
+
+ switch (bookmark.Action) {
+ case BreakpointAction.Break:
+ break;
+ case BreakpointAction.Condition:
+ if (Evaluate(bookmark.Condition, bookmark.ScriptLanguage))
+ DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAtBecause}") + "\n", bookmark.LineNumber, bookmark.FileName, bookmark.Condition));
+ else
+ CurrentProcess.AsyncContinue();
+ break;
+ case BreakpointAction.Trace:
+ DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAt}") + "\n", bookmark.LineNumber, bookmark.FileName));
+ break;
}
- }*/
+ }
+
+ RefreshPads();
}
- void debuggedProcess_DebuggingResumed(object sender, ProcessEventArgs e)
+ void debuggedProcess_DebuggingResumed(object sender, DebuggerEventArgs e)
{
OnIsProcessRunningChanged(EventArgs.Empty);
DebuggerService.RemoveCurrentLineMarker();
+
+ CurrentThread = null;
+ CurrentStackFrame = null;
+
+ RefreshPads();
}
- void debuggedProcess_ExceptionThrown(object sender, ExceptionEventArgs e)
+ void HandleException(DebuggerEventArgs e)
{
JumpToCurrentLine();
StringBuilder stacktraceBuilder = new StringBuilder();
- if (e.IsUnhandled) {
+ if (e.ExceptionThrown.IsUnhandled) {
// Need to intercept now so that we can evaluate properties
- if (e.Process.SelectedThread.InterceptException(e.Exception)) {
- stacktraceBuilder.AppendLine(e.Exception.ToString());
+ if (e.Thread.InterceptException(e.ExceptionThrown)) {
+ stacktraceBuilder.AppendLine(e.ExceptionThrown.ToString());
string stackTrace;
try {
- stackTrace = e.Exception.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.EndOfInnerException}"));
+ stackTrace = e.ExceptionThrown.GetStackTrace(e.Thread, StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.EndOfInnerException}"));
} catch (GetValueException) {
- stackTrace = e.Process.SelectedThread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}"));
+ stackTrace = e.Thread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}"));
}
stacktraceBuilder.Append(stackTrace);
} else {
// For example, happens on stack overflow
stacktraceBuilder.AppendLine(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Error.CannotInterceptException}"));
- stacktraceBuilder.AppendLine(e.Exception.ToString());
- stacktraceBuilder.Append(e.Process.SelectedThread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}")));
+ stacktraceBuilder.AppendLine(e.ExceptionThrown.ToString());
+ stacktraceBuilder.Append(e.Thread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}")));
}
} else {
- stacktraceBuilder.AppendLine(e.Exception.ToString());
- stacktraceBuilder.Append(e.Process.SelectedThread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}")));
+ stacktraceBuilder.AppendLine(e.ExceptionThrown.ToString());
+ stacktraceBuilder.Append(e.Thread.GetStackTrace(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.Symbols}"), StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.LineFormat.NoSymbols}")));
}
- string title = e.IsUnhandled ? StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Unhandled}") : StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Handled}");
- string message = string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Message}"), e.Exception.Type);
- Bitmap icon = WinFormsResourceService.GetBitmap(e.IsUnhandled ? "Icons.32x32.Error" : "Icons.32x32.Warning");
+ string title = e.ExceptionThrown.IsUnhandled ? StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Unhandled}") : StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Title.Handled}");
+ string message = string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.ExceptionForm.Message}"), e.ExceptionThrown.Type);
+ Bitmap icon = WinFormsResourceService.GetBitmap(e.ExceptionThrown.IsUnhandled ? "Icons.32x32.Error" : "Icons.32x32.Warning");
- DebuggeeExceptionForm.Show(debuggedProcess, title, message, stacktraceBuilder.ToString(), icon, e.IsUnhandled, e.Exception);
+ DebuggeeExceptionForm.Show(e.Process, title, message, stacktraceBuilder.ToString(), icon, e.ExceptionThrown.IsUnhandled, e.ExceptionThrown);
}
public bool BreakAndInterceptHandledException(Debugger.Exception exception)
{
- if (!debuggedProcess.SelectedThread.InterceptException(exception)) {
+ if (!CurrentThread.InterceptException(exception)) {
MessageService.ShowError("${res:MainWindow.Windows.Debug.ExceptionForm.Error.CannotInterceptHandledException}");
return false;
}
@@ -896,35 +686,35 @@ namespace ICSharpCode.SharpDevelop.Services
public void JumpToCurrentLine()
{
- if (debuggedProcess == null || debuggedProcess.SelectedThread == null)
+ if (CurrentThread == null)
return;
WorkbenchSingleton.MainWindow.Activate();
- if (debuggedProcess.IsSelectedFrameForced()) {
- if (debuggedProcess.SelectedStackFrame != null && debuggedProcess.SelectedStackFrame.HasSymbols) {
+ // if (debuggedProcess.IsSelectedFrameForced()) {
+ if (CurrentThread != null && CurrentStackFrame.HasSymbols) {
JumpToSourceCode();
} else {
- JumpToDecompiledCode(debuggedProcess.SelectedStackFrame);
+ JumpToDecompiledCode(CurrentStackFrame);
}
- } else {
- var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
- // other pause reasons
- if (frame != null && frame.HasSymbols) {
- JumpToSourceCode();
- } else {
- // use most recent stack frame because we don't have the symbols
- JumpToDecompiledCode(debuggedProcess.SelectedThread.MostRecentStackFrame);
- }
- }
+// } else {
+// var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
+// // other pause reasons
+// if (frame != null && frame.HasSymbols) {
+// JumpToSourceCode();
+// } else {
+// // use most recent stack frame because we don't have the symbols
+// JumpToDecompiledCode(debuggedProcess.SelectedThread.MostRecentStackFrame);
+// }
+// }
}
void JumpToSourceCode()
{
- if (debuggedProcess == null || debuggedProcess.SelectedThread == null)
+ if (CurrentProcess == null || CurrentStackFrame == null)
return;
- SourcecodeSegment nextStatement = debuggedProcess.NextStatement;
+ SourcecodeSegment nextStatement = CurrentStackFrame.NextStatement;
if (nextStatement != null) {
DebuggerService.RemoveCurrentLineMarker();
DebuggerService.JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
@@ -944,7 +734,7 @@ namespace ICSharpCode.SharpDevelop.Services
}
// check for options - if these options are enabled, debugging decompiled code should not continue
- if (!debuggedProcess.Options.DecompileCodeWithoutSymbols) {
+ if (!CurrentProcess.Options.DecompileCodeWithoutSymbols) {
LoggingService.Info("Decompiled code debugging is disabled!");
return;
}
@@ -982,14 +772,14 @@ namespace ICSharpCode.SharpDevelop.Services
return (StopAttachedProcessDialogResult)MessageService.ShowCustomDialog(caption, message, (int)StopAttachedProcessDialogResult.Detach, (int)StopAttachedProcessDialogResult.Cancel, buttonLabels);
}
- void process_Modules_Added(object sender, CollectionItemEventArgs e)
+ void process_Modules_Added(object sender, ModuleEventArgs e)
{
if (ProjectService.OpenSolution == null)
return;
ProjectService.OpenSolution.Projects
- .Where(p => e.Item.Name.IndexOf(p.Name) >= 0)
- .ForEach(p => e.Item.LoadSymbolsFromDisk(new []{ Path.GetDirectoryName(p.OutputAssemblyFullPath) }));
+ .Where(p => e.Module.Name.IndexOf(p.Name) >= 0)
+ .ForEach(p => e.Module.LoadSymbolsFromDisk(new []{ Path.GetDirectoryName(p.OutputAssemblyFullPath) }));
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerPopup.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerPopup.cs
deleted file mode 100644
index acf3663258..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerPopup.cs
+++ /dev/null
@@ -1,102 +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.Windows;
-using System.Windows.Controls.Primitives;
-using System.Windows.Input;
-
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Gui;
-
-namespace Debugger.AddIn.Tooltips
-{
- ///
- /// Popup containing .
- ///
- public class DebuggerPopup : Popup
- {
- internal DebuggerTooltipControl innerControl;
-
- public DebuggerPopup(DebuggerTooltipControl parentControl, Location logicalPosition, bool showPins = true)
- {
- this.innerControl = new DebuggerTooltipControl(parentControl, logicalPosition) { ShowPins = showPins };
- this.innerControl.containingPopup = this;
- this.Child = this.innerControl;
- this.IsLeaf = false;
-
- //this.KeyDown += new KeyEventHandler(DebuggerPopup_KeyDown);
-
- //this.innerControl.Focusable = true;
- //Keyboard.Focus(this.innerControl);
- //this.AllowsTransparency = true;
- //this.PopupAnimation = PopupAnimation.Slide;
- }
-
- // attempt to propagate shortcuts to main windows when Popup is focusable (needed for keyboard scrolling + editing)
- /*void DebuggerPopup_KeyDown(object sender, KeyEventArgs e)
- {
- LoggingService.Debug("Unhandled popup key down: " + e.Key);
- RaiseEventPair(WorkbenchSingleton.MainWindow, PreviewKeyDownEvent, KeyDownEvent,
- new KeyEventArgs(e.KeyboardDevice, e.InputSource, e.Timestamp, e.Key));
- }
-
- // copied from CompletionWindowBase
- static bool RaiseEventPair(UIElement target, RoutedEvent previewEvent, RoutedEvent @event, RoutedEventArgs args)
- {
- if (target == null)
- throw new ArgumentNullException("target");
- if (previewEvent == null)
- throw new ArgumentNullException("previewEvent");
- if (@event == null)
- throw new ArgumentNullException("event");
- if (args == null)
- throw new ArgumentNullException("args");
- args.RoutedEvent = previewEvent;
- target.RaiseEvent(args);
- args.RoutedEvent = @event;
- target.RaiseEvent(args);
- return args.Handled;
- }*/
-
- public IEnumerable ItemsSource
- {
- get { return this.innerControl.ItemsSource; }
- set { this.innerControl.SetItemsSource(value); }
- }
-
- private bool isLeaf;
- public bool IsLeaf
- {
- get { return isLeaf; }
- set
- {
- isLeaf = value;
- // leaf popup closes on lost focus
- this.StaysOpen = !isLeaf;
- }
- }
-
- protected override void OnClosed(EventArgs e)
- {
- base.OnClosed(e);
- if (isLeaf) {
- this.innerControl.CloseOnLostFocus();
- }
- }
-
- public void Open()
- {
- this.IsOpen = true;
- }
-
- public void CloseSelfAndChildren()
- {
- this.innerControl.CloseChildPopups();
- this.IsOpen = false;
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml
index b28e746732..1ad63cf46b 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml
+++ b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml
@@ -1,29 +1,123 @@
-
-
-
+ xmlns:debugging="clr-namespace:Debugger.AddIn.Tooltips"
+ AllowsTransparency="True"
+>
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
-
+
+
+ Margin="0"
+ Focusable="False"
+ Width="19"
+ Height="13"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -133,24 +225,16 @@
-
+
-
-
+
+
-
-
+
+
@@ -159,82 +243,48 @@
-
+
-
-
+
+
-
-
+
+
+ Text="{Binding Value}"
+ >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs
index cd217e85b9..9785ef6763 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs
@@ -3,425 +3,117 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
-using System.Windows.Documents;
+using System.Windows.Data;
using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
+
using Debugger.AddIn.TreeModel;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Bookmarks;
-using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
-using ICSharpCode.SharpDevelop.Gui;
namespace Debugger.AddIn.Tooltips
{
- ///
- /// Default Control used as content of SharpDevelop debugger tooltips.
- ///
- public partial class DebuggerTooltipControl : UserControl, ITooltip
+ public partial class DebuggerTooltipControl : Popup, ITooltip
{
- private const double ChildPopupOpenXOffet = 16;
- private const double ChildPopupOpenYOffet = 15;
- private const int InitialItemsCount = 12;
- private const int VisibleItemsCount = 11;
+ static Point ChildPopupOffset = new Point(16, 15);
- private bool showPins = true;
- private LazyItemsControl lazyGrid;
- private IEnumerable itemsSource;
- readonly Location logicalPosition;
+ public DebuggerTooltipControl ChildTooltip { get; private set; }
+ public IEnumerable TreeNodes { get; set; }
- public DebuggerTooltipControl(Location logicalPosition)
+ public DebuggerTooltipControl(IEnumerable treeNodes)
{
- this.logicalPosition = logicalPosition;
InitializeComponent();
- Loaded += new RoutedEventHandler(OnLoaded);
- }
-
- public DebuggerTooltipControl(Location logicalPosition, ITreeNode node)
- : this(logicalPosition, new ITreeNode[] { node })
- {
+ this.TreeNodes = treeNodes;
+ this.dataGrid.ItemsSource = treeNodes;
- }
-
- public DebuggerTooltipControl(Location logicalPosition, IEnumerable nodes)
- : this(logicalPosition)
- {
- this.itemsSource = nodes;
- }
-
- public DebuggerTooltipControl(DebuggerTooltipControl parentControl, Location logicalPosition)
- : this(logicalPosition)
- {
- this.parentControl = parentControl;
+ // Only the leaf of the tooltip has this set to false
+ // Therefore it will automatically close if something else gets focus
+ this.StaysOpen = false;
+ this.Placement = PlacementMode.Absolute;
}
- private void OnLoaded(object sender, RoutedEventArgs e)
- {
- if (!showPins) {
- dataGrid.Columns[5].Visibility = Visibility.Collapsed;
- }
-
- SetItemsSource(this.itemsSource);
- }
-
- public event RoutedEventHandler Closed;
- protected void OnClosed()
+ private void Expand_Click(object sender, RoutedEventArgs e)
{
- if (this.Closed != null) {
- this.Closed(this, new RoutedEventArgs());
- }
- }
-
- public bool ShowPins {
- get { return showPins; }
- set { showPins = value; }
- }
-
- public IEnumerable ItemsSource {
- get { return this.itemsSource; }
- }
-
- public void SetItemsSource(IEnumerable value) {
- this.itemsSource = value;
- this.lazyGrid = new LazyItemsControl(this.dataGrid, InitialItemsCount);
-
- // HACK for updating the pins in tooltip
- var observable = new List();
- this.itemsSource.ForEach(item => observable.Add(item));
-
- // verify if at the line of the root there's a pin bookmark
- ITextEditor editor;
- var viewContent = WorkbenchSingleton.Workbench.ActiveViewContent;
- ITextEditorProvider provider = viewContent as ITextEditorProvider;
- if (provider != null) {
- editor = provider.TextEditor;
- } else {
- editor = viewContent.GetService(typeof(ITextEditor)) as ITextEditor;
- }
+ var clickedButton = (ToggleButton)e.OriginalSource;
+ var clickedNode = (TreeNode)clickedButton.DataContext;
- if (editor != null) {
- var pin = BookmarkManager.Bookmarks.Find(
- b => b is PinBookmark &&
- b.Location.Line == logicalPosition.Line &&
- b.FileName == editor.FileName) as PinBookmark;
+ if (clickedButton.IsChecked == true && clickedNode.GetChildren != null) {
+ Point popupPos = clickedButton.PointToScreen(ChildPopupOffset).TransformFromDevice(clickedButton);
+ this.ChildTooltip = new DebuggerTooltipControl(clickedNode.GetChildren().ToList()) {
+ // We can not use placement target otherwise we would get too deep logical tree
+ Placement = PlacementMode.Absolute,
+ HorizontalOffset = popupPos.X,
+ VerticalOffset = popupPos.Y,
+ };
- if (pin != null) {
- observable.ForEach(item => { // TODO: find a way not to use "observable"
- if (pin.ContainsNode(item))
- item.IsPinned = true;
- });
- }
- }
-
- var source = new VirtualizingIEnumerable(observable);
- lazyGrid.ItemsSource = source;
- this.dataGrid.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(handleScroll));
-
- if (this.lazyGrid.ItemsSourceTotalCount != null) {
- // hide up/down buttons if too few items
- btnUp.Visibility = btnDown.Visibility =
- this.lazyGrid.ItemsSourceTotalCount.Value <= VisibleItemsCount ? Visibility.Collapsed : Visibility.Visible;
+ // The child is now tracking the focus
+ this.StaysOpen = true;
+ this.ChildTooltip.StaysOpen = false;
+
+ this.ChildTooltip.Closed += delegate {
+ // The null will have the effect of ignoring the next click
+ clickedButton.IsChecked = clickedButton.IsMouseOver ? (bool?)null : false;
+ // Either keep closing or make us the new leaf
+ if (this.IsMouseOver) {
+ this.StaysOpen = false;
+ } else {
+ this.IsOpen = false;
+ }
+ };
+ this.ChildTooltip.IsOpen = true;
}
}
- //public Location LogicalPosition { get; set; }
-
- ///
- public bool ShowAsPopup
- {
- get
- {
- return true;
- }
- }
-
- ///
- public bool Close(bool mouseClick)
- {
- if (mouseClick || (!mouseClick && !isChildExpanded)) {
- CloseChildPopups();
- return true;
- } else {
- return false;
- }
- }
-
- private DebuggerPopup childPopup { get; set; }
- private DebuggerTooltipControl parentControl { get; set; }
- internal DebuggerPopup containingPopup { get; set; }
-
- bool isChildExpanded
- {
- get
- {
- return this.childPopup != null && this.childPopup.IsOpen;
- }
- }
-
- private ToggleButton expandedButton;
-
- ///
- /// Closes the child popup of this control, if it exists.
- ///
- public void CloseChildPopups()
- {
- if (this.expandedButton != null) {
- this.expandedButton.IsChecked = false;
- this.expandedButton = null;
- // nice simple example of indirect recursion
- this.childPopup.CloseSelfAndChildren();
- }
- }
-
- public void CloseOnLostFocus()
- {
- // when we close, parent becomes leaf
- if (this.containingPopup != null) {
- this.containingPopup.IsLeaf = true;
- }
- if (!this.IsMouseOver) {
- if (this.containingPopup != null) {
- this.containingPopup.IsOpen = false;
- this.containingPopup.IsLeaf = false;
- }
- if (this.parentControl != null) {
- this.parentControl.CloseOnLostFocus();
- }
- OnClosed();
- } else {
- // leaf closed because of click inside this control - stop the closing chain
- if (this.expandedButton != null && !this.expandedButton.IsMouseOver) {
- this.expandedButton.IsChecked = false;
- this.expandedButton = null;
- }
+ bool ITooltip.CloseOnHoverEnd {
+ get {
+ return this.ChildTooltip == null;
}
}
- private void btnExpander_Click(object sender, RoutedEventArgs e)
+ protected override void OnClosed(EventArgs e)
{
- var clickedButton = (ToggleButton)e.OriginalSource;
- var clickedNode = (ITreeNode)clickedButton.DataContext;
- // use device independent units, because child popup Left/Top are in independent units
- Point buttonPos = clickedButton.PointToScreen(new Point(0, 0)).TransformFromDevice(clickedButton);
-
- if (clickedButton.IsChecked.GetValueOrDefault(false)) {
- CloseChildPopups();
- this.expandedButton = clickedButton;
-
- // open child Popup
- if (this.childPopup == null) {
- this.childPopup = new DebuggerPopup(this, logicalPosition, showPins);
- this.childPopup.Placement = PlacementMode.Absolute;
- }
- if (this.containingPopup != null) {
- this.containingPopup.IsLeaf = false;
- }
- this.childPopup.IsLeaf = true;
- this.childPopup.HorizontalOffset = buttonPos.X + ChildPopupOpenXOffet;
- this.childPopup.VerticalOffset = buttonPos.Y + ChildPopupOpenYOffet;
- if (clickedNode.ChildNodes != null) {
- this.childPopup.ItemsSource = clickedNode.ChildNodes;
- this.childPopup.Open();
- }
- } else {
- CloseChildPopups();
+ // Closing the popup does not normally cause LostFocus on the textbox so we have to update it manually
+ TextBox textBox = FocusManager.GetFocusedElement(this) as TextBox;
+ if (textBox != null) {
+ BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
+ be.UpdateSource();
}
- }
-
- private void handleScroll(object sender, ScrollChangedEventArgs e)
- {
- btnUp.IsEnabled = !this.lazyGrid.IsScrolledToStart;
- btnDown.IsEnabled = !this.lazyGrid.IsScrolledToEnd;
- }
- void BtnUp_Click(object sender, RoutedEventArgs e)
- {
- this.lazyGrid.ScrollViewer.ScrollUp(1);
- }
-
- void BtnDown_Click(object sender, RoutedEventArgs e)
- {
- this.lazyGrid.ScrollViewer.ScrollDown(1);
- }
-
- #region Edit value in tooltip
-
- void TextBox_KeyUp(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Escape) {
- dataGrid.Focus();
- return;
- }
+ base.OnClosed(e);
- if (e.Key == Key.Enter) {
- dataGrid.Focus();
- // set new value
- var textBox = (TextBox)e.OriginalSource;
- var newValue = textBox.Text;
- var node = ((FrameworkElement)sender).DataContext as ITreeNode;
- SaveNewValue(node, textBox.Text);
- }
- }
-
- void TextBox_LostFocus(object sender, RoutedEventArgs e)
- {
- var textBox = (TextBox)e.OriginalSource;
- var newValue = textBox.Text;
- var node = ((FrameworkElement)sender).DataContext as ITreeNode;
- SaveNewValue(node, textBox.Text);
- }
-
- void SaveNewValue(ITreeNode node, string newValue)
- {
- if(node != null && node.SetText(newValue)) {
- // show adorner
- var adornerLayer = AdornerLayer.GetAdornerLayer(dataGrid);
- var adorners = adornerLayer.GetAdorners(dataGrid);
- if (adorners != null && adorners.Length != 0)
- adornerLayer.Remove(adorners[0]);
- SavedAdorner adorner = new SavedAdorner(dataGrid);
- adornerLayer.Add(adorner);
- }
- }
-
- #endregion
-
- #region Pining checked/unchecked
-
- void PinButton_Checked(object sender, RoutedEventArgs e)
- {
- ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
- var editor = provider.TextEditor;
- if (editor == null) return;
- var node = (ITreeNode)(((ToggleButton)(e.OriginalSource)).DataContext);
-
- if (!string.IsNullOrEmpty(editor.FileName)) {
-
- // verify if at the line of the root there's a pin bookmark
- var pin = BookmarkManager.Bookmarks.Find(
- b => b is PinBookmark &&
- b.LineNumber == logicalPosition.Line &&
- b.FileName == editor.FileName) as PinBookmark;
-
- if (pin == null) {
- pin = new PinBookmark(editor.FileName, logicalPosition);
- // show pinned DebuggerPopup
- if (pin.Popup == null) {
- pin.Popup = new PinDebuggerControl();
- pin.Popup.Mark = pin;
- Rect rect = new Rect(this.DesiredSize);
- var point = this.PointToScreen(rect.TopRight);
- pin.Popup.Location = new Point { X = 500, Y = point.Y - 150 };
- pin.Nodes.Add(node);
- pin.Popup.ItemsSource = pin.Nodes;
- }
-
- // do actions
- pin.Popup.Open();
- BookmarkManager.AddMark(pin);
- }
- else
- {
- if (!pin.ContainsNode(node)) {
- pin.Nodes.Add(node);
- pin.Popup.ItemsSource = pin.Nodes;
- }
- }
- }
- }
-
- void PinButton_Unchecked(object sender, RoutedEventArgs e)
- {
- ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider;
- var editor = provider.TextEditor;
- if (editor == null) return;
-
- if (!string.IsNullOrEmpty(editor.FileName)) {
- // remove from pinned DebuggerPopup
- var pin = BookmarkManager.Bookmarks.Find(
- b => b is PinBookmark &&
- b.LineNumber == logicalPosition.Line &&
- b.FileName == editor.FileName) as PinBookmark;
- if (pin == null) return;
-
- ToggleButton button = (ToggleButton)e.OriginalSource;
- pin.RemoveNode((ITreeNode)button.DataContext);
- pin.Popup.ItemsSource = pin.Nodes;
- // remove if no more data pins are available
- if (pin.Nodes.Count == 0) {
- pin.Popup.Close();
-
- BookmarkManager.RemoveMark(pin);
- }
+ if (this.ChildTooltip != null) {
+ this.ChildTooltip.IsOpen = false;
}
}
void CopyMenuItemClick(object sender, RoutedEventArgs e)
{
- ExpressionNode node = ((MenuItem)sender).DataContext as ExpressionNode;
+ ValueNode node = ((MenuItem)sender).DataContext as ValueNode;
if (node != null) {
Clipboard.SetText(node.FullText);
}
}
- #endregion
-
- #region Saved Adorner
-
- class SavedAdorner : Adorner
+ /*
+ void AnimateCloseControl(bool show)
{
- public SavedAdorner(UIElement adornedElement) : base(adornedElement)
- {
- Loaded += delegate { Show(); };
- }
+ DoubleAnimation animation = new DoubleAnimation();
+ animation.From = show ? 0 : 1;
+ animation.To = show ? 1 : 0;
+ animation.BeginTime = new TimeSpan(0, 0, show ? 0 : 1);
+ animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
+ animation.SetValue(Storyboard.TargetProperty, this.PinCloseControl);
+ animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Rectangle.OpacityProperty));
- protected override void OnRender(DrawingContext drawingContext)
- {
- Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
-
- // Some arbitrary drawing implements.
- var formatedText = new FormattedText(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Debugging.SavedString}"),
- CultureInfo.CurrentCulture,
- FlowDirection.LeftToRight,
- new Typeface(new FontFamily("Arial"),
- FontStyles.Normal,
- FontWeights.Black,
- FontStretches.Expanded),
- 8d,
- Brushes.Black);
-
-
- drawingContext.DrawText(formatedText,
- new Point(adornedElementRect.TopRight.X - formatedText.Width - 2,
- adornedElementRect.TopRight.Y));
- }
+ Storyboard board = new Storyboard();
+ board.Children.Add(animation);
- private void Show()
- {
- DoubleAnimation animation = new DoubleAnimation();
- animation.From = 1;
- animation.To = 0;
-
- animation.Duration = new Duration(TimeSpan.FromSeconds(2));
- animation.SetValue(Storyboard.TargetProperty, this);
- animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Rectangle.OpacityProperty));
-
- Storyboard board = new Storyboard();
- board.Children.Add(animation);
-
- board.Begin(this);
- }
+ board.Begin(this);
}
-
- #endregion
+ */
}
}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/LazyItemsControl.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/LazyItemsControl.cs
deleted file mode 100644
index f4af8a0aa7..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/LazyItemsControl.cs
+++ /dev/null
@@ -1,113 +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.Windows.Controls;
-
-using ICSharpCode.SharpDevelop;
-
-namespace Debugger.AddIn.Tooltips
-{
- ///
- /// ItemsControl wrapper that takes VirtualizingIEnumerable as source,
- /// and adds additional items from the source to underlying ItemsControl when scrolled to bottom.
- ///
- public class LazyItemsControl
- {
- private ItemsControl itemsControl;
- private int initialItemsCount;
-
- ///
- /// Creates new instance of LazyItemsControl.
- ///
- /// ItemsControl to wrap and add items to it when scrolled to bottom.
- /// Number of items to be initially displayed in wrapped ItemsControl.
- public LazyItemsControl(ItemsControl wrappedItemsControl, int initialItemsCount)
- {
- if (wrappedItemsControl == null)
- throw new ArgumentNullException("wrappedItemsControl");
-
- this.initialItemsCount = initialItemsCount;
- this.itemsControl = wrappedItemsControl;
- this.itemsControl.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(handleScroll));
- }
-
- private ScrollViewer scrollViewerCached;
- public ScrollViewer ScrollViewer
- {
- get
- {
- if (this.scrollViewerCached == null)
- this.scrollViewerCached = this.itemsControl.GetScrollViewer();
- return this.scrollViewerCached;
- }
- }
-
- public bool IsScrolledToStart
- {
- get
- {
- if (ScrollViewer == null) // Visual tree not initialized yet
- return false;
- return ScrollViewer.VerticalOffset == 0;
- }
- }
-
- public bool IsScrolledToEnd
- {
- get
- {
- if (itemsSourceTotalCount == null) {
- // not scrolled to end of IEnumerable yet
- return false;
- }
- // already scrolled to end of IEnumerable
- int totalItems = itemsSourceTotalCount.Value;
- return (ScrollViewer.VerticalOffset >= totalItems - ScrollViewer.ViewportHeight);
- }
- }
-
- private int? itemsSourceTotalCount = null;
- /// Items count of underlying IEnumerable. Null until scrolled to the end of IEnumerable.
- public int? ItemsSourceTotalCount
- {
- get
- {
- return this.itemsSourceTotalCount;
- }
- }
-
- private VirtualizingIEnumerable itemsSource;
- /// The collection that underlying ItemsControl sees.
- public VirtualizingIEnumerable ItemsSource
- {
- get { return itemsSource; }
- set
- {
- this.itemsSource = value;
- addNextItems(this.itemsSource, initialItemsCount);
- this.itemsControl.ItemsSource = value;
- }
- }
-
- private void addNextItems(VirtualizingIEnumerable sourceToAdd, int nItems)
- {
- sourceToAdd.AddNextItems(nItems);
- if (!sourceToAdd.HasNext) {
- // all items from IEnumerable have been added
- this.itemsSourceTotalCount = sourceToAdd.Count;
- }
- }
-
- private void handleScroll(object sender, ScrollChangedEventArgs e)
- {
- if (e.VerticalChange > 0) {
- // scrolled to bottom
- if (e.VerticalOffset >= this.itemsSource.Count - e.ViewportHeight) {
- addNextItems(this.itemsSource, (int)e.VerticalChange);
- }
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml
deleted file mode 100644
index c2fc077e1e..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml.cs
deleted file mode 100644
index d417c5ba38..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml.cs
+++ /dev/null
@@ -1,74 +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 System.Windows.Controls;
-
-namespace Debugger.AddIn.Tooltips
-{
- public class ShowingCommentEventArgs : EventArgs
- {
- public bool ShowComment { get; private set; }
-
- public ShowingCommentEventArgs(bool showComment)
- {
- ShowComment = showComment;
- }
- }
-
- public partial class PinCloseControl : UserControl
- {
- public event EventHandler Closed;
-
- public event EventHandler PinningChanged;
-
- public event EventHandler ShowingComment;
-
- public PinCloseControl()
- {
- InitializeComponent();
- }
-
- public bool IsChecked {
- get {
- return UnpinButton.IsChecked.GetValueOrDefault(false);
- }
- }
-
- void CloseButton_Click(object sender, RoutedEventArgs e)
- {
- var handler = Closed;
- if (handler != null)
- handler(this, EventArgs.Empty);
- }
-
- void CommentButton_Checked(object sender, RoutedEventArgs e)
- {
- var handler = ShowingComment;
- if (handler != null)
- handler(this, new ShowingCommentEventArgs(true));
- }
-
- void CommentButton_Unchecked(object sender, RoutedEventArgs e)
- {
- var handler = ShowingComment;
- if (handler != null)
- handler(this, new ShowingCommentEventArgs(false));
- }
-
- void UnpinButton_Checked(object sender, RoutedEventArgs e)
- {
- var handler = PinningChanged;
- if (handler != null)
- handler(this, EventArgs.Empty);
- }
-
- void UnpinButton_Unchecked(object sender, RoutedEventArgs e)
- {
- var handler = PinningChanged;
- if (handler != null)
- handler(this, EventArgs.Empty);
- }
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinControlsDictionary.xaml b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinControlsDictionary.xaml
deleted file mode 100644
index f06219eeb6..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinControlsDictionary.xaml
+++ /dev/null
@@ -1,363 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinDebuggerControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinDebuggerControl.xaml
deleted file mode 100644
index 32218a3b76..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinDebuggerControl.xaml
+++ /dev/null
@@ -1,240 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinDebuggerControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinDebuggerControl.xaml.cs
deleted file mode 100644
index 132d996603..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinDebuggerControl.xaml.cs
+++ /dev/null
@@ -1,384 +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.Windows;
-using System.Windows.Controls;
-using System.Windows.Controls.Primitives;
-using System.Windows.Input;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Bookmarks;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Editor;
-using ICSharpCode.SharpDevelop.Gui;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace Debugger.AddIn.Tooltips
-{
- public partial class PinDebuggerControl : UserControl, IPinDebuggerControl
- {
- private const double ChildPopupOpenXOffet = 16;
- private const double ChildPopupOpenYOffet = 15;
- private const int InitialItemsCount = 12;
- private const double MINIMUM_OPACITY = .3d;
-
- private WindowsDebugger currentDebugger;
- private DebuggerPopup childPopup;
- private LazyItemsControl lazyExpandersGrid;
- private LazyItemsControl lazyGrid;
- private LazyItemsControl lazyImagesGrid;
- private IEnumerable itemsSource;
-
- public PinDebuggerControl()
- {
- InitializeComponent();
-
- if (!DebuggerService.IsDebuggerStarted)
- Opacity = MINIMUM_OPACITY;
- this.PinCloseControl.Opacity = 0;
-
- Loaded += OnLoaded;
- this.PinCloseControl.Closed += PinCloseControl_Closed;
- this.PinCloseControl.ShowingComment += PinCloseControl_ShowingComment;
- this.PinCloseControl.PinningChanged += PinCloseControl_PinningChanged;
-
- BookmarkManager.Removed += OnBookmarkRemoved;
-
- currentDebugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
-
- currentDebugger.DebugStopped += OnDebugStopped;
- currentDebugger.ProcessSelected += OnProcessSelected;
-
- if (currentDebugger.DebuggedProcess != null)
- currentDebugger.DebuggedProcess.Paused += OnDebuggedProcessPaused;
- }
-
- #region Properties
-
- public PinBookmark Mark { get; set; }
-
- public IEnumerable ItemsSource
- {
- get { return this.itemsSource; }
- set {
- itemsSource = value;
- var items = new VirtualizingIEnumerable(value);
- lazyExpandersGrid = new LazyItemsControl(this.ExpandersGrid, InitialItemsCount);
- lazyExpandersGrid.ItemsSource = items;
-
- lazyGrid = new LazyItemsControl(this.dataGrid, InitialItemsCount);
- lazyGrid.ItemsSource = items;
-
- lazyImagesGrid = new LazyItemsControl(this.ImagesGrid, InitialItemsCount);
- lazyImagesGrid.ItemsSource = items;
- }
- }
-
- ///
- /// Relative position of the pin with respect to the screen.
- ///
- public Point Location { get; set; }
-
- #endregion
-
- #region Main operations
-
- public void Open()
- {
- Pin();
- }
-
- public void Close()
- {
- CloseChildPopups();
- Unpin();
-
- BookmarkManager.Removed -= OnBookmarkRemoved;
- if (currentDebugger != null) {
- currentDebugger.DebugStopped -= OnDebugStopped;
- currentDebugger.ProcessSelected -= OnProcessSelected;
- currentDebugger = null;
- }
- }
-
- void Pin()
- {
- var provider = WorkbenchSingleton.Workbench.ActiveContent as ITextEditorProvider;
- if(provider != null) {
- var pinLayer = PinningBinding.GetPinlayer(provider.TextEditor);
- if (pinLayer != null)
- pinLayer.Pin(this);
- }
- }
-
- void Unpin()
- {
- var provider = WorkbenchSingleton.Workbench.ActiveContent as ITextEditorProvider;
- if(provider != null) {
- var pinLayer = PinningBinding.GetPinlayer(provider.TextEditor);
- if (pinLayer != null)
- pinLayer.Unpin(this);
- }
- }
-
- #endregion
-
- #region Debugger events
-
- void OnDebugStopped(object sender, EventArgs e)
- {
- if (currentDebugger.DebuggedProcess != null)
- currentDebugger.DebuggedProcess.Paused -= OnDebuggedProcessPaused;
- }
-
- void OnProcessSelected(object sender, ProcessEventArgs e)
- {
- Opacity = 1d;
- if (currentDebugger.DebuggedProcess != null)
- currentDebugger.DebuggedProcess.Paused += OnDebuggedProcessPaused;
- }
-
- void OnDebuggedProcessPaused(object sender, ProcessEventArgs e)
- {
- //var nodes = new StackFrameNode(e.Process.SelectedStackFrame).ChildNodes;
-
-// if (!lazyGrid.ItemsSource.ContainsNode(node))
-// return;
- // TODO : find the current expression so we don't update every pin
-// var observable = new List();
-//
-// foreach (var node in lazyGrid.ItemsSource) {
-// var resultNode = currentDebugger.GetNode(node.FullName);
-// // HACK for updating the pins in tooltip
-// observable.Add(resultNode);
-// }
-//
-// // update UI
-// var newSource = new VirtualizingIEnumerable(observable);
-// lazyGrid.ItemsSource = newSource;
-// lazyExpandersGrid.ItemsSource = newSource;
- }
-
- #endregion
-
- #region Expand button
-
- private ToggleButton expandedButton;
-
- ///
- /// Closes the child popup of this control, if it exists.
- ///
- void CloseChildPopups()
- {
- if (this.expandedButton != null) {
- this.expandedButton = null;
- // nice simple example of indirect recursion
- this.childPopup.CloseSelfAndChildren();
- }
- }
-
- void BtnExpander_Checked(object sender, RoutedEventArgs e)
- {
- if (!DebuggerService.IsDebuggerStarted)
- return;
-
- var clickedButton = (ToggleButton)e.OriginalSource;
- var clickedNode = (ITreeNode)clickedButton.DataContext;
- // use device independent units, because child popup Left/Top are in independent units
- Point buttonPos = clickedButton.PointToScreen(new Point(0, 0)).TransformFromDevice(clickedButton);
-
- if (clickedButton.IsChecked.GetValueOrDefault(false)) {
-
- this.expandedButton = clickedButton;
-
- // open child Popup
- if (this.childPopup == null) {
- this.childPopup = new DebuggerPopup(null, ICSharpCode.NRefactory.Location.Empty, false);
- this.childPopup.PlacementTarget = this;
- this.childPopup.Closed += new EventHandler(PinDebuggerControl_Closed);
- this.childPopup.Placement = PlacementMode.Absolute;
- }
-
- this.childPopup.IsLeaf = true;
- this.childPopup.HorizontalOffset = buttonPos.X + ChildPopupOpenXOffet;
- this.childPopup.VerticalOffset = buttonPos.Y + ChildPopupOpenYOffet;
- if (clickedNode.ChildNodes != null) {
- this.childPopup.ItemsSource = clickedNode.ChildNodes;
- this.childPopup.Open();
- }
- } else {
-
- }
- }
-
- void PinDebuggerControl_Closed(object sender, EventArgs e)
- {
- if (expandedButton != null && expandedButton.IsChecked.GetValueOrDefault(false))
- expandedButton.IsChecked = false;
- }
-
- void BtnExpander_Unchecked(object sender, RoutedEventArgs e)
- {
- CloseChildPopups();
- }
-
- #endregion
-
- #region PinCloseControl
-
- void PinCloseControl_Closed(object sender, EventArgs e)
- {
- BookmarkManager.RemoveMark(Mark);
- Close();
- }
-
- void PinCloseControl_PinningChanged(object sender, EventArgs e)
- {
- if (this.PinCloseControl.IsChecked) {
- BookmarkManager.RemoveMark(Mark);
- }
- else {
- if(BookmarkManager.Bookmarks.Contains(Mark))
- BookmarkManager.RemoveMark(Mark);
-
- BookmarkManager.AddMark(Mark);
- }
- }
-
- void PinCloseControl_ShowingComment(object sender, ShowingCommentEventArgs e)
- {
- ShowComment(e.ShowComment);
- }
-
- void AnimateCloseControl(bool show)
- {
- DoubleAnimation animation = new DoubleAnimation();
- animation.From = show ? 0 : 1;
- animation.To = show ? 1 : 0;
- animation.BeginTime = new TimeSpan(0, 0, show ? 0 : 1);
- animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
- animation.SetValue(Storyboard.TargetProperty, this.PinCloseControl);
- animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Rectangle.OpacityProperty));
-
- Storyboard board = new Storyboard();
- board.Children.Add(animation);
-
- board.Begin(this);
- }
-
- #endregion
-
- void OnBookmarkRemoved(object sender, BookmarkEventArgs e)
- {
- // if the bookmark was removed from pressing the button, return
- if (this.PinCloseControl.IsChecked)
- return;
-
- if (e.Bookmark is PinBookmark) {
- var pin = (PinBookmark)e.Bookmark;
- if (pin.Location == Mark.Location && pin.FileName == Mark.FileName) {
- Close();
- }
- }
- }
-
- private void OnLoaded(object sender, RoutedEventArgs e)
- {
- this.CommentTextBox.Text = Mark.Comment;
- }
-
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- if (!DebuggerService.IsDebuggerStarted)
- return;
-
- // refresh content
- ITreeNode node = ((FrameworkElement)e.OriginalSource).DataContext as ITreeNode;
-
- var resultNode = currentDebugger.GetNode(node.FullName, node.ImageName);
- if (resultNode == null)
- return;
- // HACK for updating the pins in tooltip
- var observable = new ObservableCollection();
- var source = lazyGrid.ItemsSource;
- source.ForEach(item => {
- if (item.CompareTo(node) == 0)
- observable.Add(resultNode);
- else
- observable.Add(item);
- });
-
- Mark.Nodes = observable;
- // update UI
- var newSource = new VirtualizingIEnumerable(observable);
- lazyGrid.ItemsSource = newSource;
- lazyExpandersGrid.ItemsSource = newSource;
- }
-
- #region Comment
-
- void ShowComment(bool show)
- {
- if(show && BorderComment.Height != 0)
- return;
- if(!show && BorderComment.Height != 40)
- return;
-
- DoubleAnimation animation = new DoubleAnimation();
- animation.From = show ? 0 : 40;
- animation.To = show ? 40 : 0;
-
- animation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
- animation.SetValue(Storyboard.TargetProperty, BorderComment);
- animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Border.HeightProperty));
-
- Storyboard board = new Storyboard();
- board.Children.Add(animation);
- board.Begin(this);
- }
-
- void CommentTextBox_TextChanged(object sender, TextChangedEventArgs e)
- {
- Mark.Comment = this.CommentTextBox.Text;
- }
-
- #endregion
-
- #region Overrides
-
- protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
- {
- AnimateCloseControl(true);
- Opacity = 1d;
- Cursor = Cursors.Arrow;
- base.OnMouseEnter(e);
- }
-
- protected override void OnMouseMove(MouseEventArgs e)
- {
- Opacity = 1d;
- Cursor = Cursors.Arrow;
- base.OnMouseMove(e);
- }
-
- protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e)
- {
- if (DebuggerService.IsDebuggerStarted)
- Opacity = 1;
- else
- Opacity = MINIMUM_OPACITY;
-
- AnimateCloseControl(false);
-
- Cursor = Cursors.IBeam;
- base.OnMouseLeave(e);
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinLayer.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinLayer.cs
deleted file mode 100644
index cfc901f57f..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinLayer.cs
+++ /dev/null
@@ -1,184 +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 System.Windows.Controls;
-using System.Windows.Controls.Primitives;
-using System.Windows.Input;
-using System.Windows.Media;
-
-using ICSharpCode.AvalonEdit.Editing;
-using ICSharpCode.AvalonEdit.Rendering;
-using ICSharpCode.Core.Presentation;
-using ICSharpCode.SharpDevelop.Refactoring;
-
-namespace Debugger.AddIn.Tooltips
-{
- ///
- /// Pin layer class. This class handles the pinning and unpinning operations.
- ///
- public class PinLayer : Canvas
- {
- private double verticalOffset = 0;
- private double horizontalOffset = 0;
-
- private TextView textView;
-
- ///
- /// PinLayer constructor.
- ///
- /// Text area for this layer.
- public PinLayer(TextArea textArea)
- {
- textView = textArea.TextView;
- textView.VisualLinesChanged += textView_VisualLinesChanged;
- }
-
- ///
- /// Pins an element;
- ///
- /// Element to pin.
- public void Pin(PinDebuggerControl element)
- {
- if (element == null)
- throw new NullReferenceException("Element is null!");
-
- Thumb currentThumb = new Thumb();
- // check for saved position
- if (!element.Mark.PinPosition.HasValue) {
- // this is satisfied when pinning the first time
- element.Mark.PinPosition = new Point {
- X = element.Location.X + textView.HorizontalOffset,
- Y = element.Location.Y + textView.VerticalOffset
- };
-
- Canvas.SetTop(currentThumb, element.Location.Y);
- Canvas.SetLeft(currentThumb, element.Location.X);
- }
- else {
- // this is satisfied when loading the pins - so we might have hidden pins
- element.Location = new Point {
- X = element.Mark.PinPosition.Value.X - textView.HorizontalOffset,
- Y = element.Mark.PinPosition.Value.Y - textView.VerticalOffset
- };
-
- Canvas.SetTop(currentThumb, element.Mark.PinPosition.Value.Y);
- Canvas.SetLeft(currentThumb, element.Mark.PinPosition.Value.X);
- }
-
- currentThumb.Style = element.TryFindResource("PinThumbStyle") as Style;
- currentThumb.ApplyTemplate();
- currentThumb.DragDelta += onDragDelta;
- currentThumb.DragStarted += currentThumb_DragStarted;
- currentThumb.DragCompleted += currentThumb_DragCompleted;
-
- var container = TryFindChild(currentThumb);
- container.Children.Add(element);
- this.Children.Add(currentThumb);
- }
-
- ///
- /// Unpins an element.
- ///
- /// Element to unpin.
- public void Unpin(PinDebuggerControl element)
- {
- if (element == null)
- throw new NullReferenceException("Element is null!");
-
- foreach (var thumb in this.Children) {
- PinDebuggerControl pinControl = TryFindChild((DependencyObject)thumb);
- if (pinControl != null && pinControl == element)
- {
- this.Children.Remove((UIElement)thumb);
- element.Close();
- break;
- }
- }
- }
-
- void textView_VisualLinesChanged(object sender, EventArgs e)
- {
- foreach (var ctrl in this.Children) {
- var currentThumb = ctrl as Thumb;
- PinDebuggerControl pinControl = TryFindChild(currentThumb);
- if (pinControl != null)
- {
- // update relative location
- Point location = pinControl.Location;
- location.X += horizontalOffset - textView.HorizontalOffset;
- location.Y += verticalOffset - textView.VerticalOffset;
-
- Canvas.SetLeft(currentThumb, location.X);
- Canvas.SetTop(currentThumb, location.Y);
-
- pinControl.Location = location;
- pinControl.Mark.PinPosition = new Point {
- X = location.X + textView.HorizontalOffset,
- Y = location.Y + textView.VerticalOffset,
- };
- }
- }
-
- verticalOffset = textView.VerticalOffset;
- horizontalOffset = textView.HorizontalOffset;
- }
-
- #region Mouse move
-
- void onDragDelta(object sender, DragDeltaEventArgs e)
- {
- Thumb currnetThumb = (Thumb)sender;
- currnetThumb.Cursor = Cursors.Arrow;
- double left = Canvas.GetLeft(currnetThumb) + e.HorizontalChange;
- double top = Canvas.GetTop(currnetThumb) + e.VerticalChange;
-
- Canvas.SetLeft(currnetThumb, left);
- Canvas.SetTop(currnetThumb, top);
- }
-
- void currentThumb_DragCompleted(object sender, DragCompletedEventArgs e)
- {
- Thumb currnetThumb = (Thumb)sender;
- currnetThumb.Cursor = Cursors.Arrow;
-
- var pinControl = TryFindChild(currnetThumb);
- if (pinControl != null) {
- double left = Canvas.GetLeft(currnetThumb);
- double top = Canvas.GetTop(currnetThumb);
- pinControl.Opacity = 1d;
- pinControl.Location = new Point { X = left, Y = top };
-
- // pin's position is with respect to the layer.
- pinControl.Mark.PinPosition =
- new Point
- {
- X = textView.HorizontalOffset + left,
- Y = textView.VerticalOffset + top
- };
- }
- }
-
- void currentThumb_DragStarted(object sender, DragStartedEventArgs e)
- {
- Thumb currnetThumb = (Thumb)sender;
- currnetThumb.Cursor = Cursors.Arrow;
-
- var pinControl = TryFindChild(currnetThumb);
- if (pinControl != null)
- pinControl.Opacity = 1d;
- }
-
- #endregion
-
- #region Static helpers
-
- static T TryFindChild(DependencyObject root) where T : DependencyObject
- {
- return WpfTreeNavigation.TryFindChild(root);
- }
-
- #endregion
- }
-}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinningBinding.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinningBinding.cs
deleted file mode 100644
index 9811669d03..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinningBinding.cs
+++ /dev/null
@@ -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.ObjectModel;
-using ICSharpCode.AvalonEdit;
-using ICSharpCode.AvalonEdit.Rendering;
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Bookmarks;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Editor;
-
-namespace Debugger.AddIn.Tooltips
-{
- public class PinningBinding : DefaultLanguageBinding
- {
- ITextEditor _editor;
- PinLayer pinLayer;
-
- public PinningBinding()
- {}
-
- public override void Attach(ITextEditor editor)
- {
- if (editor == null)
- return;
-
- var textEditor = editor.GetService(typeof(TextEditor)) as TextEditor;
- if (textEditor != null) {
- pinLayer = new PinLayer(textEditor.TextArea);
- textEditor.TextArea.TextView.InsertLayer(
- pinLayer,
- KnownLayer.Caret,
- LayerInsertionPosition.Above);
- }
-
- _editor = editor;
- CreatePins(_editor);
-
- base.Attach(editor);
- }
-
- public override void Detach()
- {
- ClosePins(_editor);
- pinLayer = null;
- base.Detach();
- }
-
- public void CreatePins(ITextEditor editor)
- {
- // load pins
- var pins = BookmarkManager.Bookmarks.FindAll(
- b => b is PinBookmark && b.FileName == editor.FileName);
-
- foreach (var bookmark in pins) {
- var pin = (PinBookmark)bookmark;
- pin.Popup = new PinDebuggerControl();
- pin.Popup.Mark = pin;
-
- var nodes = new ObservableCollection();
- foreach (var tuple in pin.SavedNodes) {
- string imageName = !string.IsNullOrEmpty(tuple.Item1) ? tuple.Item1 : "Icons.16x16.Field";
- var node = new Debugger.AddIn.TreeModel.SavedTreeNode(
- new ResourceServiceImage(imageName),
- tuple.Item2,
- tuple.Item3);
- node.ImageName = imageName;
- nodes.Add(node);
- }
-
- pin.SavedNodes.Clear();
- pin.Popup.ItemsSource = nodes;
- pin.Nodes = nodes;
-
- pinLayer.Pin((PinDebuggerControl)pin.Popup);
- }
- }
-
- public void ClosePins(ITextEditor editor)
- {
- // save pins
- var pins = BookmarkManager.Bookmarks.FindAll(
- b => b is PinBookmark && b.FileName == editor.FileName);
-
- foreach (var bookmark in pins) {
- var pin = (PinBookmark)bookmark;
- if (!pin.PinPosition.HasValue)
- pin.PinPosition = pin.Popup.Location;
-
- // nodes
- if (pin.SavedNodes == null)
- pin.SavedNodes = new System.Collections.Generic.List>();
-
- foreach (var node in pin.Nodes) {
- pin.SavedNodes.Add(
- new Tuple(
- "Icons.16x16.Field",
- node.FullName,
- node.Text));
- }
-
- pinLayer.Unpin((PinDebuggerControl)pin.Popup);
- pin.Popup = null;
- }
- }
-
- public static PinLayer GetPinlayer(ITextEditor editor) {
- var textEditor = editor.GetService(typeof(TextEditor)) as TextEditor;
- if (textEditor != null) {
- return textEditor.TextArea.TextView.Layers[3] as PinLayer;
- }
-
- return null;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/VirtualizingIEnumerable.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/VirtualizingIEnumerable.cs
deleted file mode 100644
index ca51500f2e..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/VirtualizingIEnumerable.cs
+++ /dev/null
@@ -1,53 +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;
-
-namespace Debugger.AddIn.Tooltips
-{
- ///
- /// A wrapper around IEnumerable<T> with AddNextItems method for pulling additional items
- /// from underlying IEnumerable<T>.
- /// Can be used as source for .
- ///
- public class VirtualizingIEnumerable : ObservableCollection
- {
- private IEnumerator originalSourceEnumerator;
-
- public VirtualizingIEnumerable(IEnumerable originalSource)
- {
- if (originalSource == null)
- throw new ArgumentNullException("originalSource");
-
- this.originalSourceEnumerator = originalSource.GetEnumerator();
- }
-
- private bool hasNext = true;
- ///
- /// False if all items from underlying IEnumerable have already been added.
- ///
- public bool HasNext
- {
- get
- {
- return this.hasNext;
- }
- }
-
- ///
- /// Requests next items from underlying IEnumerable source and adds them to the collection.
- ///
- public void AddNextItems(int count)
- {
- for (int i = 0; i < count; i++) {
- if (!originalSourceEnumerator.MoveNext()) {
- this.hasNext = false;
- break;
- }
- this.Add(originalSourceEnumerator.Current);
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs
deleted file mode 100644
index 309071608c..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-// 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.Collections.Generic;
-using System.Text;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace Debugger.AddIn.TreeModel
-{
- public partial class Utils
- {
- public static IEnumerable LazyGetChildNodesOfArray(TreeNode parent, Expression expression, ArrayDimensions dimensions)
- {
- if (dimensions.TotalElementCount == 0)
- return new TreeNode[] { new TreeNode(null, "(empty)", null, null, parent, _ => null) };
-
- return new ArrayRangeNode(parent, expression, dimensions, dimensions).ChildNodes;
- }
- }
-
- /// This is a partent node for all elements within a given bounds
- public class ArrayRangeNode: TreeNode
- {
- const int MaxElementCount = 100;
-
- Expression arrayTarget;
- ArrayDimensions bounds;
- ArrayDimensions originalBounds;
-
- public ArrayRangeNode(TreeNode parent, Expression arrayTarget, ArrayDimensions bounds, ArrayDimensions originalBounds)
- : base(parent)
- {
- this.arrayTarget = arrayTarget;
- this.bounds = bounds;
- this.originalBounds = originalBounds;
-
- this.Name = GetName();
- this.childNodes = LazyGetChildren();
- }
-
- public override IEnumerable ChildNodes {
- get { return base.ChildNodes; }
- }
-
- string GetName()
- {
- StringBuilder name = new StringBuilder();
- bool isFirst = true;
- name.Append("[");
- for(int i = 0; i < bounds.Count; i++) {
- if (!isFirst) name.Append(", ");
- isFirst = false;
- ArrayDimension dim = bounds[i];
- ArrayDimension originalDim = originalBounds[i];
-
- if (dim.Count == 0) {
- throw new DebuggerException("Empty dimension");
- } else if (dim.Count == 1) {
- name.Append(dim.LowerBound.ToString());
- } else if (dim.Equals(originalDim)) {
- name.Append("*");
- } else {
- name.Append(dim.LowerBound);
- name.Append("..");
- name.Append(dim.UpperBound);
- }
- }
- name.Append("]");
- return name.ToString();
- }
-
- static string GetName(int[] indices)
- {
- StringBuilder sb = new StringBuilder(indices.Length * 4);
- sb.Append("[");
- bool isFirst = true;
- foreach(int index in indices) {
- if (!isFirst) sb.Append(", ");
- sb.Append(index.ToString());
- isFirst = false;
- }
- sb.Append("]");
- return sb.ToString();
- }
-
- IEnumerable LazyGetChildren()
- {
- // The whole array is small - just add all elements as childs
- if (bounds.TotalElementCount <= MaxElementCount) {
- foreach(int[] indices in bounds.Indices) {
- string imageName;
- var image = ExpressionNode.GetImageForArrayIndexer(out imageName);
- var expression = new ExpressionNode(this, image, GetName(indices), arrayTarget.AppendIndexer(indices));
- expression.ImageName = imageName;
- yield return expression;
- }
- yield break;
- }
-
- // Find a dimension of size at least 2
- int splitDimensionIndex = bounds.Count - 1;
- for(int i = 0; i < bounds.Count; i++) {
- if (bounds[i].Count > 1) {
- splitDimensionIndex = i;
- break;
- }
- }
- ArrayDimension splitDim = bounds[splitDimensionIndex];
-
- // Split the dimension
- int elementsPerSegment = 1;
- while (splitDim.Count > elementsPerSegment * MaxElementCount) {
- elementsPerSegment *= MaxElementCount;
- }
- for(int i = splitDim.LowerBound; i <= splitDim.UpperBound; i += elementsPerSegment) {
- List newDims = new List(bounds);
- newDims[splitDimensionIndex] = new ArrayDimension(i, Math.Min(i + elementsPerSegment - 1, splitDim.UpperBound));
- yield return new ArrayRangeNode(this, arrayTarget, new ArrayDimensions(newDims), originalBounds);
- }
- yield break;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs
deleted file mode 100644
index 7463c29cae..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-// 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.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-
-using Debugger.AddIn.Visualizers.Utils;
-using Debugger.MetaData;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Services;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace Debugger.AddIn.TreeModel
-{
- public partial class Utils
- {
- public static IEnumerable LazyGetChildNodesOfObject(TreeNode current, Expression targetObject, DebugType shownType)
- {
- MemberInfo[] publicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
- MemberInfo[] publicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
- MemberInfo[] nonPublicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly);
- MemberInfo[] nonPublicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
-
- DebugType baseType = (DebugType)shownType.BaseType;
- if (baseType != null) {
- yield return new TreeNode(
- DebuggerResourceService.GetImage("Icons.16x16.Class"),
- StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}"),
- baseType.Name,
- baseType.FullName,
- current,
- newNode => baseType.FullName == "System.Object" ? null : Utils.LazyGetChildNodesOfObject(newNode, targetObject, baseType)
- );
- }
-
- if (nonPublicInstance.Length > 0) {
- yield return new TreeNode(
- null,
- StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"),
- string.Empty,
- string.Empty,
- current,
- newNode => Utils.LazyGetMembersOfObject(newNode, targetObject, nonPublicInstance)
- );
- }
-
- if (publicStatic.Length > 0 || nonPublicStatic.Length > 0) {
- yield return new TreeNode(
- null,
- StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.StaticMembers}"),
- string.Empty,
- string.Empty,
- current,
- p => {
- var children = Utils.LazyGetMembersOfObject(p, targetObject, publicStatic);
- if (nonPublicStatic.Length > 0) {
- TreeNode nonPublicStaticNode = new TreeNode(
- null,
- StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicStaticMembers}"),
- string.Empty,
- string.Empty,
- p,
- newNode => Utils.LazyGetMembersOfObject(newNode, targetObject, nonPublicStatic)
- );
- children = Utils.PrependNode(nonPublicStaticNode, children);
- }
- return children;
- }
- );
- }
-
- DebugType iListType = (DebugType)shownType.GetInterface(typeof(IList).FullName);
- if (iListType != null) {
- yield return new IListNode(current, targetObject);
- } else {
- DebugType iEnumerableType, itemType;
- if (shownType.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) {
- yield return new IEnumerableNode(current, targetObject, itemType);
- }
- }
-
- foreach(TreeNode node in LazyGetMembersOfObject(current, targetObject, publicInstance)) {
- yield return node;
- }
- }
-
- public static IEnumerable LazyGetMembersOfObject(TreeNode parent, Expression expression, MemberInfo[] members)
- {
- List nodes = new List();
- foreach(MemberInfo memberInfo in members) {
- string imageName;
- var image = ExpressionNode.GetImageForMember((IDebugMemberInfo)memberInfo, out imageName);
- var exp = new ExpressionNode(parent, image, memberInfo.Name, expression.AppendMemberReference((IDebugMemberInfo)memberInfo));
- exp.ImageName = imageName;
- nodes.Add(exp);
- }
- nodes.Sort();
- return nodes;
- }
-
-
- public static IEnumerable LazyGetItemsOfIList(TreeNode parent, Expression targetObject)
- {
- // Add a cast, so that we are sure the expression has an indexer.
- // (The expression can be e.g. of type 'object' but its value is a List.
- // Without the cast, evaluating "expr[i]" would fail, because object does not have an indexer).
- targetObject = targetObject.CastToIList();
- int count = 0;
- GetValueException error = null;
- try {
- count = targetObject.GetIListCount();
- } catch (GetValueException e) {
- // Cannot yield a value in the body of a catch clause (CS1631)
- error = e;
- }
- if (error != null) {
- yield return new TreeNode(null, "(error)", error.Message, null, null, _ => null);
- } else if (count == 0) {
- yield return new TreeNode(null, "(empty)", null, null, null, _ => null);
- } else {
- for(int i = 0; i < count; i++) {
- string imageName;
- var image = ExpressionNode.GetImageForArrayIndexer(out imageName);
- var itemNode = new ExpressionNode(parent, image, "[" + i + "]", targetObject.AppendIndexer(i));
- itemNode.ImageName = imageName;
- yield return itemNode;
- }
- }
- }
-
- public static IEnumerable PrependNode(TreeNode node, IEnumerable rest)
- {
- yield return node;
- if (rest != null) {
- foreach(TreeNode absNode in rest) {
- yield return absNode;
- }
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/DebuggerResourceService.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/DebuggerResourceService.cs
deleted file mode 100644
index 1f5e272874..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/DebuggerResourceService.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 ICSharpCode.SharpDevelop;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Debugger.AddIn.TreeModel
-{
- ///
- /// Gets resources the way suitable for Debugger.AddIn.
- ///
- public static class DebuggerResourceService
- {
- ///
- /// Gets image with given name from resources.
- ///
- /// Resource name of the image.
- public static IImage GetImage(string resourceName)
- {
- return new ResourceServiceImage(resourceName);
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs
deleted file mode 100644
index 91ab606863..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs
+++ /dev/null
@@ -1,462 +0,0 @@
-// 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.Collections.Generic;
-using System.ComponentModel;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Windows.Forms;
-
-using Debugger.AddIn.Visualizers;
-using Debugger.MetaData;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Services;
-using TreeNode = Debugger.AddIn.TreeModel.TreeNode;
-
-namespace Debugger.AddIn.TreeModel
-{
- ///
- /// Node in the tree which can be defined by a debugger expression.
- /// The expression will be lazily evaluated when needed.
- ///
- public class ExpressionNode: TreeNode, ISetText, INotifyPropertyChanged
- {
- bool evaluated;
-
- Expression expression;
- bool canSetText;
- GetValueException error;
- string fullText;
-
- public bool Evaluated {
- get { return evaluated; }
- set { evaluated = value; }
- }
-
- public Expression Expression {
- get { return expression; }
- }
-
- public override bool CanSetText {
- get {
- if (!evaluated) EvaluateExpression();
- return canSetText;
- }
- }
-
- public GetValueException Error {
- get {
- if (!evaluated) EvaluateExpression();
- return error;
- }
- }
-
- public string FullText {
- get { return fullText; }
- }
-
- public override string Text {
- get {
- if (!evaluated) EvaluateExpression();
- return base.Text;
- }
- set {
- if (value != base.Text) {
- base.Text = value;
- NotifyPropertyChanged("Text");
- }
- }
- }
-
- public override string FullName {
- get {
- return this.expression.PrettyPrint() ?? Name.Trim();
- }
- }
-
- public override string Type {
- get {
- if (!evaluated) EvaluateExpression();
- return base.Type;
- }
- }
-
- public override IEnumerable ChildNodes {
- get {
- if (!evaluated) EvaluateExpression();
- return base.ChildNodes;
- }
- }
-
- public override bool HasChildNodes {
- get {
- if (!evaluated) EvaluateExpression();
- return base.HasChildNodes;
- }
- }
-
- /// Used to determine available VisualizerCommands
- private DebugType expressionType;
- /// Used to determine available VisualizerCommands
- private bool valueIsNull = true;
-
- private IEnumerable visualizerCommands;
- public override IEnumerable VisualizerCommands {
- get {
- if (visualizerCommands == null) {
- visualizerCommands = getAvailableVisualizerCommands();
- }
- return visualizerCommands;
- }
- }
-
- private IEnumerable getAvailableVisualizerCommands()
- {
- if (!evaluated) EvaluateExpression();
-
- if (this.expressionType == null) {
- // no visualizers if EvaluateExpression failed
- yield break;
- }
- if (this.valueIsNull) {
- // no visualizers if evaluated value is null
- yield break;
- }
- /*if (this.expressionType.IsPrimitive || this.expressionType.IsSystemDotObject() || this.expressionType.IsEnum()) {
- // no visualizers for primitive types
- yield break;
- }*/
-
- foreach (var descriptor in VisualizerDescriptors.GetAllDescriptors()) {
- if (descriptor.IsVisualizerAvailable(this.expressionType)) {
- yield return descriptor.CreateVisualizerCommand(this.Expression);
- }
- }
- }
-
- public ExpressionNode(TreeNode parent, IImage image, string name, Expression expression)
- : base(parent)
- {
- this.IconImage = image;
- this.Name = name;
- this.expression = expression;
- }
-
- void EvaluateExpression()
- {
- evaluated = true;
-
- Value val;
- try {
- var process = WindowsDebugger.DebuggedProcess;
- if (process == null) return;
- StackFrame frame = process.GetCurrentExecutingFrame();
- if (frame == null) return;
- var debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
- object data = debugger.debuggerDecompilerService.GetLocalVariableIndex(frame.MethodInfo.DeclaringType.MetadataToken,
- frame.MethodInfo.MetadataToken,
- Name);
-
- if (expression is MemberReferenceExpression) {
- var memberExpression = (MemberReferenceExpression)expression;
- memberExpression.TargetObject.UserData = data;
- } else {
- expression.UserData = data;
- }
- // evaluate expression
- val = expression.Evaluate(process);
- } catch (GetValueException e) {
- error = e;
- this.Text = e.Message;
- return;
- }
-
- this.canSetText = val.Type.IsPrimitive;
-
- this.expressionType = val.Type;
- this.Type = val.Type.Name;
- this.valueIsNull = val.IsNull;
-
- // Note that these return enumerators so they are lazy-evaluated
- if (val.IsNull) {
- } else if (val.Type.IsPrimitive || val.Type.FullName == typeof(string).FullName) { // Must be before IsClass
- } else if (val.Type.IsArray) { // Must be before IsClass
- if (val.ArrayLength > 0)
- this.childNodes = Utils.LazyGetChildNodesOfArray(this, this.Expression, val.ArrayDimensions);
- } else if (val.Type.IsClass || val.Type.IsValueType) {
- if (val.Type.FullNameWithoutGenericArguments == typeof(List<>).FullName) {
- if ((int)val.GetMemberValue("_size").PrimitiveValue > 0)
- this.childNodes = Utils.LazyGetItemsOfIList(this, this.expression);
- } else {
- this.childNodes = Utils.LazyGetChildNodesOfObject(this, this.Expression, val.Type);
- }
- } else if (val.Type.IsPointer) {
- Value deRef = val.Dereference();
- if (deRef != null) {
- this.childNodes = new ExpressionNode [] { new ExpressionNode(this, this.IconImage, "*" + this.Name, this.Expression.AppendDereference()) };
- }
- }
-
- if (DebuggingOptions.Instance.ICorDebugVisualizerEnabled) {
- TreeNode info = ICorDebug.GetDebugInfoRoot(val.AppDomain, val.CorValue);
- this.childNodes = Utils.PrependNode(info, this.ChildNodes);
- }
-
- // Do last since it may expire the object
- if (val.Type.IsInteger) {
- fullText = FormatInteger(val.PrimitiveValue);
- } else if (val.Type.IsPointer) {
- fullText = String.Format("0x{0:X}", val.PointerAddress);
- } else if ((val.Type.FullName == typeof(string).FullName ||
- val.Type.FullName == typeof(char).FullName) && !val.IsNull) {
- try {
- fullText = '"' + Escape(val.InvokeToString()) + '"';
- } catch (GetValueException e) {
- error = e;
- fullText = e.Message;
- return;
- }
- } else if ((val.Type.IsClass || val.Type.IsValueType) && !val.IsNull) {
- try {
- fullText = val.InvokeToString();
- } catch (GetValueException e) {
- error = e;
- fullText = e.Message;
- return;
- }
- } else {
- fullText = val.AsString();
- }
-
- this.Text = (fullText.Length > 256) ? fullText.Substring(0, 256) + "..." : fullText;
- }
-
- string Escape(string source)
- {
- return source.Replace("\n", "\\n")
- .Replace("\t", "\\t")
- .Replace("\r", "\\r")
- .Replace("\0", "\\0")
- .Replace("\b", "\\b")
- .Replace("\a", "\\a")
- .Replace("\f", "\\f")
- .Replace("\v", "\\v")
- .Replace("\"", "\\\"");
- }
-
- string FormatInteger(object i)
- {
- if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Decimal)
- return i.ToString();
-
- string hex = null;
- for(int len = 1;; len *= 2) {
- hex = string.Format("{0:X" + len + "}", i);
- if (hex.Length == len)
- break;
- }
-
- if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Hexadecimal) {
- return "0x" + hex;
- } else {
- if (ShowAsHex(i)) {
- return String.Format("{0} (0x{1})", i, hex);
- } else {
- return i.ToString();
- }
- }
- }
-
- bool ShowAsHex(object i)
- {
- ulong val;
- if (i is sbyte || i is short || i is int || i is long) {
- unchecked { val = (ulong)Convert.ToInt64(i); }
- if (val > (ulong)long.MaxValue)
- val = ~val + 1;
- } else {
- val = Convert.ToUInt64(i);
- }
- if (val >= 0x10000)
- return true;
-
- int ones = 0; // How many 1s there is
- int runs = 0; // How many runs of 1s there is
- int size = 0; // Size of the integer in bits
- while(val != 0) { // There is at least one 1
- while((val & 1) == 0) { // Skip 0s
- val = val >> 1;
- size++;
- }
- while((val & 1) == 1) { // Skip 1s
- val = val >> 1;
- size++;
- ones++;
- }
- runs++;
- }
-
- return size >= 7 && runs <= (size + 7) / 8;
- }
-
- public override bool SetText(string newText)
- {
- string fullName = FullName;
-
- Value val = null;
- try {
- val = this.Expression.Evaluate(WindowsDebugger.DebuggedProcess);
- if (val.Type.IsInteger && newText.StartsWith("0x")) {
- try {
- val.PrimitiveValue = long.Parse(newText.Substring(2), NumberStyles.HexNumber);
- } catch (FormatException) {
- throw new NotSupportedException();
- } catch (OverflowException) {
- throw new NotSupportedException();
- }
- } else {
- val.PrimitiveValue = newText;
- }
- this.Text = newText;
- return true;
- } catch (NotSupportedException) {
- string format = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.CannotSetValue.BadFormat");
- string msg = string.Format(format, newText, val.Type.PrimitiveType);
- MessageService.ShowMessage(msg ,"${res:MainWindow.Windows.Debug.LocalVariables.CannotSetValue.Title}");
- } catch (COMException) {
- // COMException (0x80131330): Cannot perfrom SetValue on non-leaf frames.
- // Happens if trying to set value after exception is breaked
- MessageService.ShowMessage("${res:MainWindow.Windows.Debug.LocalVariables.CannotSetValue.UnknownError}",
- "${res:MainWindow.Windows.Debug.LocalVariables.CannotSetValue.Title}");
- }
- return false;
- }
-
- public static IImage GetImageForThis(out string imageName)
- {
- imageName = "Icons.16x16.Parameter";
- return DebuggerResourceService.GetImage(imageName);
- }
-
- public static IImage GetImageForParameter(out string imageName)
- {
- imageName = "Icons.16x16.Parameter";
- return DebuggerResourceService.GetImage(imageName);
- }
-
- public static IImage GetImageForLocalVariable(out string imageName)
- {
- imageName = "Icons.16x16.Local";
- return DebuggerResourceService.GetImage(imageName);
- }
-
- public static IImage GetImageForArrayIndexer(out string imageName)
- {
- imageName = "Icons.16x16.Field";
- return DebuggerResourceService.GetImage(imageName);
- }
-
- public static IImage GetImageForMember(IDebugMemberInfo memberInfo, out string imageName)
- {
- string name = string.Empty;
- if (memberInfo.IsPublic) {
- } else if (memberInfo.IsAssembly) {
- name += "Internal";
- } else if (memberInfo.IsFamily) {
- name += "Protected";
- } else if (memberInfo.IsPrivate) {
- name += "Private";
- }
- if (memberInfo is FieldInfo) {
- name += "Field";
- } else if (memberInfo is PropertyInfo) {
- name += "Property";
- } else if (memberInfo is MethodInfo) {
- name += "Method";
- } else {
- throw new DebuggerException("Unknown member type " + memberInfo.GetType().FullName);
- }
-
- imageName = "Icons.16x16." + name;
- return DebuggerResourceService.GetImage(imageName);
- }
-
-// public ContextMenuStrip GetContextMenu()
-// {
-// if (this.Error != null) return GetErrorContextMenu();
-//
-// ContextMenuStrip menu = new ContextMenuStrip();
-//
-// ToolStripMenuItem copyItem;
-// copyItem = new ToolStripMenuItem();
-// copyItem.Text = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.CopyToClipboard");
-// copyItem.Checked = false;
-// copyItem.Click += delegate {
-// ClipboardWrapper.SetText(fullText);
-// };
-
-// ToolStripMenuItem hexView;
-// hexView = new ToolStripMenuItem();
-// hexView.Text = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.ShowInHexadecimal");
-// hexView.Checked = DebuggingOptions.Instance.ShowValuesInHexadecimal;
-// hexView.Click += delegate {
-// // refresh all pads that use ValueNode for display
-// DebuggingOptions.Instance.ShowValuesInHexadecimal = !DebuggingOptions.Instance.ShowValuesInHexadecimal;
-// // always check if instance is null, might be null if pad is not opened
-// if (LocalVarPad.Instance != null)
-// LocalVarPad.Instance.RefreshPad();
-// if (WatchPad.Instance != null)
-// WatchPad.Instance.RefreshPad();
-// };
-
-// menu.Items.AddRange(new ToolStripItem[] {
-// copyItem,
-// //hexView
-// });
-//
-// return menu;
-// }
-
- public ContextMenuStrip GetErrorContextMenu()
- {
- ContextMenuStrip menu = new ContextMenuStrip();
-
- ToolStripMenuItem showError;
- showError = new ToolStripMenuItem();
- showError.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.ShowFullError}");
- showError.Checked = false;
- showError.Click += delegate {
- MessageService.ShowException(error, null);
- };
-
- menu.Items.AddRange(new ToolStripItem[] {
- showError
- });
-
- return menu;
- }
-
- public static WindowsDebugger WindowsDebugger {
- get {
- return (WindowsDebugger)DebuggerService.CurrentDebugger;
- }
- }
-
- public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
-
- private void NotifyPropertyChanged(string info)
- {
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(info));
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IContextMenu.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IContextMenu.cs
deleted file mode 100644
index 0830a6d0b9..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IContextMenu.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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.Windows.Forms;
-
-namespace Debugger.AddIn.TreeModel
-{
- public interface IContextMenu
- {
- ContextMenuStrip GetContextMenu();
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ICorDebug.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ICorDebug.cs
deleted file mode 100644
index fe054da52d..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ICorDebug.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-// 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 Debugger.Interop.CorDebug;
-using System;
-using System.Collections.Generic;
-using Debugger.MetaData;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace Debugger.AddIn.TreeModel
-{
- public class ICorDebug
- {
- public class InfoNode: TreeNode
- {
- List children;
-
- public InfoNode(TreeNode parent, string name, string text)
- : this(parent, name, text, _ => null)
- {
-
- }
-
- public InfoNode(TreeNode parent, string name, string text, Func> children)
- : base(parent)
- {
- this.Name = name;
- this.Text = text;
- this.children = children(this);
- }
-
- public override IEnumerable ChildNodes {
- get { return children; }
- }
-
- public void AddChild(string name, string text)
- {
- if (children == null) {
- children = new List();
- }
- children.Add(new InfoNode(this, name, text));
- }
-
- public void AddChild(string name, string text, Func> subChildren)
- {
- if (children == null) {
- children = new List();
- }
- children.Add(new InfoNode(this, name, text, p => subChildren(p)));
- }
- }
-
- public static InfoNode GetDebugInfoRoot(AppDomain appDomain, ICorDebugValue corValue)
- {
- return new InfoNode(null, "ICorDebug", "", p => GetDebugInfo(p, appDomain, corValue));
- }
-
- public static List GetDebugInfo(TreeNode parent, AppDomain appDomain, ICorDebugValue corValue)
- {
- List items = new List();
-
- if (corValue is ICorDebugValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugValue", "");
- info.AddChild("Address", corValue.GetAddress().ToString("X8"));
- info.AddChild("Type", ((CorElementType)corValue.GetTheType()).ToString());
- info.AddChild("Size", corValue.GetSize().ToString());
- items.Add(info);
- }
- if (corValue is ICorDebugValue2) {
- InfoNode info = new InfoNode(parent, "ICorDebugValue2", "");
- ICorDebugValue2 corValue2 = (ICorDebugValue2)corValue;
- string fullname;
- try {
- fullname = DebugType.CreateFromCorType(appDomain, corValue2.GetExactType()).FullName;
- } catch (DebuggerException e) {
- fullname = e.Message;
- }
- info.AddChild("ExactType", fullname);
- items.Add(info);
- }
- if (corValue is ICorDebugGenericValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugGenericValue", "");
- try {
- byte[] bytes = ((ICorDebugGenericValue)corValue).GetRawValue();
- for(int i = 0; i < bytes.Length; i += 8) {
- string val = "";
- for(int j = i; j < bytes.Length && j < i + 8; j++) {
- val += bytes[j].ToString("X2") + " ";
- }
- info.AddChild("Value" + i.ToString("X2"), val);
- }
- } catch (ArgumentException) {
- info.AddChild("Value", "N/A");
- }
- items.Add(info);
- }
- if (corValue is ICorDebugReferenceValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugReferenceValue", "");
- ICorDebugReferenceValue refValue = (ICorDebugReferenceValue)corValue;
- info.AddChild("IsNull", (refValue.IsNull() != 0).ToString());
- if (refValue.IsNull() == 0) {
- info.AddChild("Value", refValue.GetValue().ToString("X8"));
- if (refValue.Dereference() != null) {
- info.AddChild("Dereference", "", p => GetDebugInfo(p, appDomain, refValue.Dereference()));
- } else {
- info.AddChild("Dereference", "N/A");
- }
- }
- items.Add(info);
- }
- if (corValue is ICorDebugHeapValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugHeapValue", "");
- items.Add(info);
- }
- if (corValue is ICorDebugHeapValue2) {
- InfoNode info = new InfoNode(parent, "ICorDebugHeapValue2", "");
- items.Add(info);
- }
- if (corValue is ICorDebugObjectValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugObjectValue", "");
- ICorDebugObjectValue objValue = (ICorDebugObjectValue)corValue;
- info.AddChild("Class", objValue.GetClass().GetToken().ToString("X8"));
- info.AddChild("IsValueClass", (objValue.IsValueClass() != 0).ToString());
- items.Add(info);
- }
- if (corValue is ICorDebugObjectValue2) {
- InfoNode info = new InfoNode(parent, "ICorDebugObjectValue2", "");
- items.Add(info);
- }
- if (corValue is ICorDebugBoxValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugBoxValue", "");
- ICorDebugBoxValue boxValue = (ICorDebugBoxValue)corValue;
- info.AddChild("Object", "", p => GetDebugInfo(p, appDomain, boxValue.GetObject()));
- items.Add(info);
- }
- if (corValue is ICorDebugStringValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugStringValue", "");
- ICorDebugStringValue stringValue = (ICorDebugStringValue)corValue;
- info.AddChild("Length", stringValue.GetLength().ToString());
- info.AddChild("String", stringValue.GetString());
- items.Add(info);
- }
- if (corValue is ICorDebugArrayValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugArrayValue", "");
- info.AddChild("...", "...");
- items.Add(info);
- }
- if (corValue is ICorDebugHandleValue) {
- InfoNode info = new InfoNode(parent, "ICorDebugHandleValue", "");
- ICorDebugHandleValue handleValue = (ICorDebugHandleValue)corValue;
- info.AddChild("HandleType", handleValue.GetHandleType().ToString());
- items.Add(info);
- }
-
- return items;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IEnumerableNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IEnumerableNode.cs
deleted file mode 100644
index 35845151c9..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IEnumerableNode.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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 Debugger.AddIn.Visualizers.Utils;
-using Debugger.MetaData;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace Debugger.AddIn.TreeModel
-{
- ///
- /// IEnumerable node in the variable tree.
- ///
- public class IEnumerableNode : TreeNode
- {
- Expression targetObject;
- Expression debugListExpression;
-
- public IEnumerableNode(TreeNode parent, Expression targetObject, DebugType itemType)
- : base(parent)
- {
- this.targetObject = targetObject;
-
- this.Name = "IEnumerable";
- this.Text = "Expanding will enumerate the IEnumerable";
- DebugType debugListType;
- this.debugListExpression = DebuggerHelpers.CreateDebugListExpression(targetObject, itemType, out debugListType);
- this.childNodes = Utils.LazyGetItemsOfIList(this, this.debugListExpression);
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IListNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IListNode.cs
deleted file mode 100644
index 41d21d86ac..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/IListNode.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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 Debugger.AddIn.Visualizers.Utils;
-using ICSharpCode.NRefactory.Ast;
-using System.Collections;
-using System.Collections.Generic;
-using Debugger.MetaData;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace Debugger.AddIn.TreeModel
-{
- public class IListNode : TreeNode
- {
- Expression targetList;
- int listCount;
-
- public IListNode(TreeNode parent, Expression targetListObject)
- : base(parent)
- {
- this.targetList = targetListObject;
-
- this.Name = "IList";
- this.listCount = this.targetList.GetIListCount();
- this.childNodes = Utils.LazyGetItemsOfIList(this, this.targetList);
- }
-
- public override bool HasChildNodes {
- get { return this.listCount > 0; }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ISetText.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ISetText.cs
deleted file mode 100644
index 99978cd589..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ISetText.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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)
-
-namespace Debugger.AddIn.TreeModel
-{
- public interface ISetText
- {
- bool CanSetText { get; }
-
- bool SetText(string text);
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/SavedTreeNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/SavedTreeNode.cs
deleted file mode 100644
index 40a6e5bb5d..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/SavedTreeNode.cs
+++ /dev/null
@@ -1,31 +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.SharpDevelop;
-
-namespace Debugger.AddIn.TreeModel
-{
- ///
- /// Description of SavedTreeNode.
- ///
- public class SavedTreeNode : TreeNode
- {
- public override bool CanSetText {
- get { return true; }
- }
-
- public SavedTreeNode(IImage image, string fullname, string text)
- : base(null)
- {
- base.IconImage = image;
- FullName = fullname;
- Text = text;
- }
-
- public override bool SetText(string newValue) {
- Text = newValue;
- return false;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs
similarity index 63%
rename from src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs
rename to src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs
index 048c0a26b2..2aed8dd6e5 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/SharpTreeNodeAdapter.cs
@@ -15,33 +15,29 @@ using ICSharpCode.TreeView;
namespace Debugger.AddIn.Pads.Controls
{
- public class TreeNodeWrapper : SharpTreeNode
+ public class SharpTreeNodeAdapter : SharpTreeNode
{
- public TreeNodeWrapper(TreeNode node)
+ public SharpTreeNodeAdapter(TreeNode node)
{
if (node == null)
throw new ArgumentNullException("node");
- Node = node;
- LazyLoading = true;
+ this.Node = node;
+ this.LazyLoading = true;
}
public TreeNode Node { get; private set; }
- public override object Text {
- get { return Node.Name; }
- }
-
public override object Icon {
- get { return Node.ImageSource; }
+ get { return this.Node.Image != null ? this.Node.Image.ImageSource : null; }
}
public override bool ShowExpander {
- get { return Node.HasChildNodes; }
+ get { return this.Node.GetChildren != null; }
}
public override bool CanDelete()
{
- return Parent is WatchRootNode;
+ return this.Node.CanDelete;
}
public override void Delete()
@@ -51,15 +47,13 @@ namespace Debugger.AddIn.Pads.Controls
protected override void LoadChildren()
{
- if (Node.HasChildNodes) {
- ((WindowsDebugger)DebuggerService.CurrentDebugger).DebuggedProcess
- .EnqueueWork(Dispatcher.CurrentDispatcher, () => Children.AddRange(Node.ChildNodes.Select(node => node.ToSharpTreeNode())));
+ if (this.Node.GetChildren != null) {
+ var process = WindowsDebugger.CurrentProcess;
+ process.EnqueueWork(Dispatcher.CurrentDispatcher, () => Children.AddRange(this.Node.GetChildren().Select(node => node.ToSharpTreeNode())));
}
}
- }
-
- public class WatchRootNode : SharpTreeNode
- {
+
+ /*
public override bool CanDrop(System.Windows.DragEventArgs e, int index)
{
e.Effects = DragDropEffects.None;
@@ -79,15 +73,14 @@ namespace Debugger.AddIn.Pads.Controls
string language = ProjectService.CurrentProject.Language;
- // FIXME languages
- TextNode text = new TextNode(null, e.Data.GetData(DataFormats.StringFormat).ToString(),
- language == "VB" || language == "VBNet" ? SupportedLanguage.VBNet : SupportedLanguage.CSharp);
+ var text = new TreeNode(e.Data.GetData(DataFormats.StringFormat).ToString(), null);
var node = text.ToSharpTreeNode();
- if (!WatchPad.Instance.WatchList.WatchItems.Any(n => text.FullName == ((TreeNodeWrapper)n).Node.FullName))
+ if (!WatchPad.Instance.WatchList.WatchItems.Any(n => text.Name == ((SharpTreeNodeAdapter)n).Node.Name))
WatchPad.Instance.WatchList.WatchItems.Add(node);
- WatchPad.Instance.InvalidatePad();
+ WindowsDebugger.RefreshPads();
}
+ */
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/StackFrameNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/StackFrameNode.cs
deleted file mode 100644
index 176b2d0d26..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/StackFrameNode.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.Collections.Generic;
-using Debugger.MetaData;
-using ICSharpCode.NRefactory;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.NRefactory.Visitors;
-using ICSharpCode.SharpDevelop.Debugging;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace Debugger.AddIn.TreeModel
-{
- public class StackFrameNode: TreeNode
- {
- StackFrame stackFrame;
-
- public StackFrame StackFrame {
- get { return stackFrame; }
- }
-
- public StackFrameNode(StackFrame stackFrame)
- : base(null)
- {
- this.stackFrame = stackFrame;
-
- this.Name = stackFrame.MethodInfo.Name;
- this.childNodes = LazyGetChildNodes();
- }
-
- IEnumerable LazyGetChildNodes()
- {
- foreach(DebugParameterInfo par in stackFrame.MethodInfo.GetParameters()) {
- string imageName;
- var image = ExpressionNode.GetImageForParameter(out imageName);
- var expression = new ExpressionNode(this, image, par.Name, par.GetExpression());
- expression.ImageName = imageName;
- yield return expression;
- }
- if (this.stackFrame.HasSymbols) {
- foreach(DebugLocalVariableInfo locVar in stackFrame.MethodInfo.GetLocalVariables(this.StackFrame.IP)) {
- string imageName;
- var image = ExpressionNode.GetImageForLocalVariable(out imageName);
- var expression = new ExpressionNode(this, image, locVar.Name, locVar.GetExpression());
- expression.ImageName = imageName;
- yield return expression;
- }
- } else {
- WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
- if (debugger.debuggerDecompilerService != null) {
- int typeToken = this.stackFrame.MethodInfo.DeclaringType.MetadataToken;
- int methodToken = this.stackFrame.MethodInfo.MetadataToken;
- foreach (var localVar in debugger.debuggerDecompilerService.GetLocalVariables(typeToken, methodToken)) {
- string imageName;
- var image = ExpressionNode.GetImageForLocalVariable(out imageName);
- var expression = new ExpressionNode(this, image, localVar, ExpressionEvaluator.ParseExpression(localVar, SupportedLanguage.CSharp));
- expression.ImageName = imageName;
- yield return expression;
- }
- }
- }
- if (stackFrame.Thread.CurrentException != null) {
- yield return new ExpressionNode(this, null, "__exception", new IdentifierExpression("__exception"));
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/TreeNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/TreeNode.cs
index d00eb1df01..40f5195451 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/TreeNode.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/TreeNode.cs
@@ -15,140 +15,117 @@ namespace Debugger.AddIn.TreeModel
{
///
/// A node in the variable tree.
- /// The node is immutable.
///
- public class TreeNode : ITreeNode
+ public class TreeNode : INotifyPropertyChanged
{
- IImage iconImage = null;
- string name = string.Empty;
- string imageName = string.Empty;
- string text = string.Empty;
- string type = string.Empty;
- protected IEnumerable childNodes = null;
-
- ///
- /// The image displayed for this node.
- ///
- public IImage IconImage {
- get { return iconImage; }
- protected set { iconImage = value; }
- }
-
- ///
- /// System.Windows.Media.ImageSource version of .
- ///
- public ImageSource ImageSource {
- get {
- return iconImage == null ? null : iconImage.ImageSource;
- }
- }
-
- ///
- /// System.Drawing.Image version of .
- ///
- public Image Image {
- get {
- return iconImage == null ? null : iconImage.Bitmap;
- }
- }
-
- public string Name {
- get { return name; }
- set { name = value; }
- }
-
- public string ImageName {
- get { return imageName; }
- set { imageName = value; }
- }
-
- public virtual string FullName {
- get { return name; }
- set { name = value; }
- }
-
- public virtual string Text
- {
- get { return text; }
- set { text = value; }
- }
-
- public virtual string Type {
- get { return type; }
- protected set { type = value; }
- }
+ public event EventHandler PropertyRead;
+ public event PropertyChangedEventHandler PropertyChanged;
- public virtual TreeNode Parent { get; protected set; }
+ IImage image;
+ string name;
+ string value;
+ string type;
- public virtual IEnumerable ChildNodes {
- get { return childNodes; }
- }
+ public bool CanDelete { get; set; }
- IEnumerable ITreeNode.ChildNodes {
- get { return childNodes; }
+ public IImage Image {
+ get {
+ OnPropertyRead("Image");
+ return this.image;
+ }
+ set {
+ if (this.image != value) {
+ this.image = value;
+ OnPropertyChanged("Image");
+ }
+ }
}
- public virtual bool HasChildNodes {
- get { return childNodes != null; }
+ public string Name {
+ get {
+ OnPropertyRead("Name");
+ return this.name;
+ }
+ set {
+ if (this.name != value) {
+ this.name = value;
+ OnPropertyChanged("Name");
+ }
+ }
}
- public virtual bool CanSetText {
- get { return false; }
- }
+ public bool CanSetName { get; set; }
- public virtual IEnumerable VisualizerCommands {
+ public string Value {
get {
- return null;
+ OnPropertyRead("Value");
+ return this.value;
+ }
+ set {
+ if (this.value != value) {
+ this.value = value;
+ OnPropertyChanged("Value");
+ }
}
}
- public virtual bool HasVisualizerCommands {
+ public bool CanSetValue { get; set; }
+
+ public string Type {
get {
- return (VisualizerCommands != null) && (VisualizerCommands.Count() > 0);
+ OnPropertyRead("Type");
+ return this.type;
+ }
+ set {
+ if (this.type != value) {
+ this.type = value;
+ OnPropertyChanged("Type");
+ }
}
}
- public bool IsPinned { get; set; }
+ public Func> GetChildren { get; protected set; }
- public TreeNode(TreeNode parent)
- {
- this.Parent = parent;
+ public bool HasChildren {
+ get { return GetChildren != null; }
}
- public TreeNode(IImage iconImage, string name, string text, string type, TreeNode parent, Func> childNodes)
- : this(parent)
- {
- if (childNodes == null)
- throw new ArgumentNullException("childNodes");
- this.iconImage = iconImage;
- this.name = name;
- this.text = text;
- this.type = type;
- this.childNodes = childNodes(this);
- }
+ public IEnumerable VisualizerCommands { get; protected set; }
+
+ public bool HasVisualizerCommands { get; protected set; }
- #region Equals and GetHashCode implementation
- public override bool Equals(object obj)
+ public TreeNode(string name, Func> getChildren)
{
- TreeNode other = obj as TreeNode;
- if (other == null)
- return false;
- return this.FullName == other.FullName;
+ this.Name = name;
+ this.GetChildren = getChildren;
}
- public override int GetHashCode()
+ public TreeNode(string imageName, string name, string value, string type, Func> getChildren)
{
- return this.FullName.GetHashCode();
+ this.Image = string.IsNullOrEmpty(imageName) ? null : new ResourceServiceImage(imageName);
+ this.Name = name;
+ this.Value = value;
+ this.Type = type;
+ this.GetChildren = getChildren;
}
- #endregion
-
- public int CompareTo(ITreeNode other)
+
+ protected virtual void OnPropertyRead(string name)
{
- return this.FullName.CompareTo(other.FullName);
+ if (PropertyRead != null) {
+ PropertyRead(this, new PropertyEventArgs() { Name = name});
+ }
}
- public virtual bool SetText(string newValue) {
- return false;
+ protected virtual void OnPropertyChanged(string name)
+ {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(name));
+ }
}
}
+
+ public class PropertyEventArgs: EventArgs
+ {
+ public string Name { get; set; }
+ }
}
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs
index 90488e6d7e..cf83f852b9 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs
@@ -19,7 +19,7 @@ namespace Debugger.AddIn.TreeModel
{
public static void EnqueueWork(this Process process, Dispatcher dispatcher, Action work)
{
- var debuggeeStateWhenEnqueued = process.DebuggeeState;
+ long debuggeeStateWhenEnqueued = process.DebuggeeState;
// Always ask the scheduler to do only one piece of work at a time
// - this might actually be completely ok as we are not waiting anywhere between thread
dispatcher.BeginInvoke(
@@ -44,7 +44,7 @@ namespace Debugger.AddIn.TreeModel
public static void EnqueueForEach(this Process process, Dispatcher dispatcher, IList items, Action work)
{
- DebuggeeState debuggeeStateWhenEnqueued = process.DebuggeeState;
+ long debuggeeStateWhenEnqueued = process.DebuggeeState;
dispatcher.BeginInvoke(
DispatcherPriority.Normal,
@@ -52,7 +52,7 @@ namespace Debugger.AddIn.TreeModel
);
}
- static void ProcessItems(Process process, Dispatcher dispatcher, int startIndex, IList items, Action work, DebuggeeState debuggeeStateWhenEnqueued)
+ static void ProcessItems(Process process, Dispatcher dispatcher, int startIndex, IList items, Action work, long debuggeeStateWhenEnqueued)
{
var watch = new System.Diagnostics.Stopwatch();
watch.Start();
@@ -122,9 +122,9 @@ namespace Debugger.AddIn.TreeModel
public static class ExtensionMethods
{
- public static TreeNodeWrapper ToSharpTreeNode(this TreeNode node)
+ public static SharpTreeNodeAdapter ToSharpTreeNode(this TreeNode node)
{
- return new TreeNodeWrapper(node);
+ return new SharpTreeNodeAdapter(node);
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs
new file mode 100644
index 0000000000..ec53c093b1
--- /dev/null
+++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs
@@ -0,0 +1,478 @@
+// 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.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Windows.Forms;
+using Debugger.AddIn.Visualizers;
+using Debugger.AddIn.Visualizers.Utils;
+using Debugger.MetaData;
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Debugging;
+using ICSharpCode.SharpDevelop.Gui.Pads;
+using ICSharpCode.SharpDevelop.Services;
+
+namespace Debugger.AddIn.TreeModel
+{
+ ///
+ /// Tree node which represents debuggee's .
+ /// The node stores a lambda which can be used to reobtain the value
+ /// at any time (possibly even after some stepping).
+ ///
+ ///
+ /// The general rule is that getting a value or getting children will
+ /// either succeed or result in .
+ ///
+ public class ValueNode: TreeNode
+ {
+ Func getValue;
+ Action setValue;
+
+ Value cachedValue;
+ Debugger.Process cachedValueProcess;
+ long cachedValueDebuggeeState;
+
+ string fullValue;
+ GetValueException error;
+
+ public string FullText {
+ get { return this.Value; }
+ }
+
+ public ValueNode(string imageName, string name, Func getValue, Action setValue = null)
+ : base(imageName, name, string.Empty, string.Empty, null)
+ {
+ if (getValue == null)
+ throw new ArgumentNullException("getValue");
+
+ this.getValue = getValue;
+ this.setValue = setValue;
+
+ GetValueAndUpdateUI();
+ }
+
+ ///
+ /// Get the value of the node and cache it as long-lived reference.
+ /// We assume that the user will need this value a lot.
+ ///
+ public Value GetValue()
+ {
+ // The value still survives across debuggee state, but we want a fresh one for the UI
+ if (cachedValue == null || cachedValueProcess.DebuggeeState != cachedValueDebuggeeState)
+ {
+ Stopwatch watch = new Stopwatch();
+ watch.Start();
+ cachedValue = this.getValue().GetPermanentReference(WindowsDebugger.EvalThread);
+ cachedValueProcess = cachedValue.Process;
+ cachedValueDebuggeeState = cachedValue.Process.DebuggeeState;
+ LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms (result cached for future use)", this.Name, watch.ElapsedMilliseconds);
+ }
+ return cachedValue;
+ }
+
+ public void SetValue(Value value)
+ {
+ if (setValue == null)
+ throw new DebuggerException("Setting of value is not supported for this node");
+
+ try
+ {
+ this.setValue(value);
+ }
+ catch(GetValueException e)
+ {
+ MessageService.ShowMessage(e.Message, "${res:MainWindow.Windows.Debug.LocalVariables.CannotSetValue.Title}");
+ }
+ }
+
+ ///
+ /// Get the value of the node and update the UI text fields.
+ ///
+ void GetValueAndUpdateUI()
+ {
+ try {
+ Stopwatch watch = new Stopwatch();
+ watch.Start();
+
+ // Do not keep permanent reference
+ Value val = this.getValue();
+
+ // Note that the child collections are lazy-evaluated
+ if (val.IsNull) {
+ this.GetChildren = null;
+ } else if (val.Type.IsPrimitive || val.Type.FullName == typeof(string).FullName) { // Must be before IsClass
+ this.GetChildren = null;
+ } else if (val.Type.IsArray) { // Must be before IsClass
+ var dims = val.ArrayDimensions; // Eval now
+ if (dims.TotalElementCount > 0) {
+ this.GetChildren = () => GetArrayChildren(dims, dims);
+ }
+ } else if (val.Type.IsClass || val.Type.IsValueType) {
+ if (val.Type.FullNameWithoutGenericArguments == typeof(List<>).FullName) {
+ if ((int)val.GetFieldValue("_size").PrimitiveValue > 0)
+ this.GetChildren = () => GetIListChildren(this.GetValue);
+ } else {
+ this.GetChildren = () => GetObjectChildren(val.Type);
+ }
+ } else if (val.Type.IsPointer) {
+ if (val.Dereference() != null) {
+ this.GetChildren = () => new[] { new ValueNode("Icons.16x16.Local", "*" + this.Name, () => GetValue().Dereference()) };
+ }
+ }
+
+ // Do last since it may expire the object
+ if (val.IsNull) {
+ fullValue = "null";
+ } else if (val.Type.IsInteger) {
+ var i = val.PrimitiveValue;
+ if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Decimal) {
+ fullValue = i.ToString();
+ } else {
+ string hex = string.Format("0x{0:X4}", i);
+ if (hex.Length > 6 ) hex = string.Format("0x{0:X8}", i);
+ if (hex.Length > 10) hex = string.Format("0x{0:X16}", i);
+ if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Hexadecimal) {
+ fullValue = hex;
+ } else {
+ fullValue = string.Format("{0} ({1})", i, hex);
+ }
+ }
+ } else if (val.Type.IsPointer) {
+ fullValue = String.Format("0x{0:X}", val.PointerAddress);
+ } else if (val.Type.FullName == typeof(string).FullName) {
+ fullValue = '"' + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + '"';
+ } else if (val.Type.FullName == typeof(char).FullName) {
+ fullValue = "'" + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + "'";
+ } else if ((val.Type.IsClass || val.Type.IsValueType)) {
+ fullValue = val.InvokeToString(WindowsDebugger.EvalThread);
+ } else {
+ fullValue = val.AsString();
+ }
+
+ this.error = null;
+ this.Value = (fullValue.Length > 256) ? fullValue.Substring(0, 256) + "..." : fullValue;
+ this.Type = val.Type.Name;
+
+ if (!val.IsNull) {
+ this.VisualizerCommands = VisualizerDescriptors.GetAllDescriptors()
+ .Where(descriptor => descriptor.IsVisualizerAvailable(val.Type))
+ .Select(descriptor => descriptor.CreateVisualizerCommand(this.Name, this.GetValue))
+ .ToList();
+ }
+
+ LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms", this.Name, watch.ElapsedMilliseconds);
+
+ } catch (GetValueException e) {
+ error = e;
+ this.Value = e.Message;
+ this.Type = string.Empty;
+ this.GetChildren = null;
+ this.VisualizerCommands = null;
+ return;
+ }
+ }
+
+// public ContextMenuStrip GetContextMenu()
+// {
+// if (this.Error != null) return GetErrorContextMenu();
+//
+// ContextMenuStrip menu = new ContextMenuStrip();
+//
+// ToolStripMenuItem copyItem;
+// copyItem = new ToolStripMenuItem();
+// copyItem.Text = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.CopyToClipboard");
+// copyItem.Checked = false;
+// copyItem.Click += delegate {
+// ClipboardWrapper.SetText(fullText);
+// };
+
+// ToolStripMenuItem hexView;
+// hexView = new ToolStripMenuItem();
+// hexView.Text = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.ShowInHexadecimal");
+// hexView.Checked = DebuggingOptions.Instance.ShowValuesInHexadecimal;
+// hexView.Click += delegate {
+// // refresh all pads that use ValueNode for display
+// DebuggingOptions.Instance.ShowValuesInHexadecimal = !DebuggingOptions.Instance.ShowValuesInHexadecimal;
+// // always check if instance is null, might be null if pad is not opened
+// if (LocalVarPad.Instance != null)
+// LocalVarPad.Instance.RefreshPad();
+// if (WatchPad.Instance != null)
+// WatchPad.Instance.RefreshPad();
+// };
+
+// menu.Items.AddRange(new ToolStripItem[] {
+// copyItem,
+// //hexView
+// });
+//
+// return menu;
+// }
+
+ ContextMenuStrip GetErrorContextMenu()
+ {
+ ContextMenuStrip menu = new ContextMenuStrip();
+
+ ToolStripMenuItem showError = new ToolStripMenuItem();
+ showError.Text = StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.ShowFullError}");
+ showError.Click += delegate { MessageService.ShowException(error, null); };
+ menu.Items.Add(showError);
+
+ return menu;
+ }
+
+ public static string GetImageForMember(IDebugMemberInfo memberInfo)
+ {
+ string name = string.Empty;
+
+ if (memberInfo.IsPublic) {
+ } else if (memberInfo.IsAssembly) {
+ name += "Internal";
+ } else if (memberInfo.IsFamily) {
+ name += "Protected";
+ } else if (memberInfo.IsPrivate) {
+ name += "Private";
+ }
+
+ if (memberInfo is FieldInfo) {
+ name += "Field";
+ } else if (memberInfo is PropertyInfo) {
+ name += "Property";
+ } else if (memberInfo is MethodInfo) {
+ name += "Method";
+ } else {
+ throw new DebuggerException("Unknown member type " + memberInfo.GetType().FullName);
+ }
+
+ return "Icons.16x16." + name;
+ }
+
+ ///
+ /// The root of any node evaluation is valid stack frame.
+ ///
+ static StackFrame GetCurrentStackFrame()
+ {
+ if (WindowsDebugger.CurrentProcess == null)
+ throw new GetValueException("Debugger is not running");
+ if (WindowsDebugger.CurrentProcess.IsRunning)
+ throw new GetValueException("Process is not paused");
+ if (WindowsDebugger.CurrentStackFrame == null)
+ throw new GetValueException("No stack frame selected");
+
+ return WindowsDebugger.CurrentStackFrame;
+ }
+
+ public static IEnumerable GetLocalVariables()
+ {
+ var stackFrame = GetCurrentStackFrame();
+ foreach(DebugParameterInfo par in stackFrame.MethodInfo.GetParameters()) {
+ var parCopy = par;
+ yield return new ValueNode("Icons.16x16.Parameter", par.Name, () => parCopy.GetValue(GetCurrentStackFrame()));
+ }
+ if (stackFrame.HasSymbols) {
+ foreach(DebugLocalVariableInfo locVar in stackFrame.MethodInfo.GetLocalVariables(stackFrame.IP)) {
+ var locVarCopy = locVar;
+ yield return new ValueNode("Icons.16x16.Local", locVar.Name, () => locVarCopy.GetValue(GetCurrentStackFrame()));
+ }
+ } else {
+ WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
+ if (debugger.debuggerDecompilerService != null) {
+ int typeToken = stackFrame.MethodInfo.DeclaringType.MetadataToken;
+ int methodToken = stackFrame.MethodInfo.MetadataToken;
+ foreach (var localVar in debugger.debuggerDecompilerService.GetLocalVariables(typeToken, methodToken)) {
+ int index = ((int[])debugger.debuggerDecompilerService.GetLocalVariableIndex(typeToken, methodToken, localVar))[0];
+ yield return new ValueNode("Icons.16x16.Local", localVar, () => {
+ var newStackFrame = GetCurrentStackFrame();
+ if (newStackFrame.MethodInfo != stackFrame.MethodInfo)
+ throw new GetValueException("Expected stack frame: " + stackFrame.MethodInfo.ToString());
+
+ return newStackFrame.GetLocalVariableValue((uint)index);
+ });
+ }
+ }
+ }
+ }
+
+ IEnumerable GetObjectChildren(DebugType shownType)
+ {
+ MemberInfo[] publicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
+ MemberInfo[] publicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
+ MemberInfo[] nonPublicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly);
+ MemberInfo[] nonPublicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
+
+ DebugType baseType = (DebugType)shownType.BaseType;
+ if (baseType != null) {
+ yield return new TreeNode(
+ "Icons.16x16.Class",
+ StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}"),
+ baseType.Name,
+ baseType.FullName,
+ baseType.FullName == "System.Object" ? (Func>) null : () => GetObjectChildren(baseType)
+ );
+ }
+
+ if (nonPublicInstance.Length > 0) {
+ yield return new TreeNode(
+ StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"),
+ () => GetMembers(nonPublicInstance)
+ );
+ }
+
+ if (publicStatic.Length > 0 || nonPublicStatic.Length > 0) {
+ yield return new TreeNode(
+ StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.StaticMembers}"),
+ () => {
+ var children = GetMembers(publicStatic).ToList();
+ if (nonPublicStatic.Length > 0) {
+ children.Insert(0, new TreeNode(
+ StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicStaticMembers}"),
+ () => GetMembers(nonPublicStatic)
+ ));
+ }
+ return children;
+ }
+ );
+ }
+
+ if (shownType.GetInterface(typeof(IList).FullName) != null) {
+ yield return new TreeNode(
+ "IList",
+ () => GetIListChildren(GetValue)
+ );
+ } else {
+ DebugType iEnumerableType, itemType;
+ if (shownType.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) {
+ yield return new TreeNode(
+ null,
+ "IEnumerable",
+ "Expanding will enumerate the IEnumerable",
+ string.Empty,
+ () => GetIListChildren(() => DebuggerHelpers.CreateListFromIEnumerable(GetValue()))
+ );
+ }
+ }
+
+ foreach(TreeNode node in GetMembers(publicInstance)) {
+ yield return node;
+ }
+ }
+
+ IEnumerable GetMembers(MemberInfo[] members)
+ {
+ foreach(MemberInfo memberInfo in members.OrderBy(m => m.Name)) {
+ var memberInfoCopy = memberInfo;
+ string imageName = GetImageForMember((IDebugMemberInfo)memberInfo);
+ yield return new ValueNode(imageName, memberInfo.Name, () => GetValue().GetMemberValue(WindowsDebugger.EvalThread, memberInfoCopy));
+ }
+ }
+
+ static IEnumerable GetIListChildren(Func getValue)
+ {
+ Value list;
+ PropertyInfo itemProp;
+ int count = 0;
+ try {
+ // TODO: We want new list on reeval
+ // We need the list to survive generation of index via Eval
+ list = getValue().GetPermanentReference(WindowsDebugger.EvalThread);
+ DebugType iListType = (DebugType)list.Type.GetInterface(typeof(IList).FullName);
+ itemProp = iListType.GetProperty("Item");
+ // Do not get string representation since it can be printed in hex
+ count = (int)list.GetPropertyValue(WindowsDebugger.EvalThread, iListType.GetProperty("Count")).PrimitiveValue;
+ } catch (GetValueException e) {
+ return new [] { new TreeNode(null, "(error)", e.Message, string.Empty, null) };
+ }
+ if (count == 0) {
+ return new [] { new TreeNode("(empty)", null) };
+ } else {
+ return Enumerable.Range(0, count).Select(i => new ValueNode("Icons.16x16.Field", "[" + i + "]", () => list.GetPropertyValue(WindowsDebugger.EvalThread, itemProp, Eval.CreateValue(WindowsDebugger.EvalThread, i))));
+ }
+ }
+
+ TreeNode GetArraySubsetNode(ArrayDimensions bounds, ArrayDimensions originalBounds)
+ {
+ StringBuilder name = new StringBuilder();
+ bool isFirst = true;
+ name.Append("[");
+ for(int i = 0; i < bounds.Count; i++) {
+ if (!isFirst) name.Append(", ");
+ isFirst = false;
+ ArrayDimension dim = bounds[i];
+ ArrayDimension originalDim = originalBounds[i];
+
+ if (dim.Count == 0) {
+ name.Append("-");
+ } else if (dim.Count == 1) {
+ name.Append(dim.LowerBound.ToString());
+ } else if (dim.Equals(originalDim)) {
+ name.Append("*");
+ } else {
+ name.Append(dim.LowerBound);
+ name.Append("..");
+ name.Append(dim.UpperBound);
+ }
+ }
+ name.Append("]");
+
+ return new TreeNode(name.ToString(), () => GetArrayChildren(bounds, originalBounds));
+ }
+
+ IEnumerable GetArrayChildren(ArrayDimensions bounds, ArrayDimensions originalBounds)
+ {
+ const int MaxElementCount = 1000;
+
+ if (bounds.TotalElementCount == 0)
+ {
+ yield return new TreeNode("(empty)", null);
+ yield break;
+ }
+
+ // The whole array is small - just add all elements as childs
+ if (bounds.TotalElementCount <= MaxElementCount * 2) {
+ foreach(int[] indices in bounds.Indices) {
+ StringBuilder sb = new StringBuilder(indices.Length * 4);
+ sb.Append("[");
+ bool isFirst = true;
+ foreach(int index in indices) {
+ if (!isFirst) sb.Append(", ");
+ sb.Append(index.ToString());
+ isFirst = false;
+ }
+ sb.Append("]");
+ int[] indicesCopy = indices;
+ yield return new ValueNode("Icons.16x16.Field", sb.ToString(), () => GetValue().GetArrayElement(indicesCopy));
+ }
+ yield break;
+ }
+
+ // Find a dimension of size at least 2
+ int splitDimensionIndex = bounds.Count - 1;
+ for(int i = 0; i < bounds.Count; i++) {
+ if (bounds[i].Count > 1) {
+ splitDimensionIndex = i;
+ break;
+ }
+ }
+ ArrayDimension splitDim = bounds[splitDimensionIndex];
+
+ // Split the dimension
+ int elementsPerSegment = 1;
+ while (splitDim.Count > elementsPerSegment * MaxElementCount) {
+ elementsPerSegment *= MaxElementCount;
+ }
+ for(int i = splitDim.LowerBound; i <= splitDim.UpperBound; i += elementsPerSegment) {
+ List newDims = new List(bounds);
+ newDims[splitDimensionIndex] = new ArrayDimension(i, Math.Min(i + elementsPerSegment - 1, splitDim.UpperBound));
+ yield return GetArraySubsetNode(new ArrayDimensions(newDims), originalBounds);
+ }
+ yield break;
+ }
+ }
+}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ExpressionVisualizerCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ExpressionVisualizerCommand.cs
index 0a77ff8d44..daf3fffc81 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ExpressionVisualizerCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ExpressionVisualizerCommand.cs
@@ -16,11 +16,15 @@ namespace Debugger.AddIn.Visualizers
// should we make visualizer command available for Expression, or any TreeNode?
public abstract class ExpressionVisualizerCommand : IVisualizerCommand
{
- public Expression Expression { get; private set; }
+ public string ValueName { get; private set; }
+ public Func GetValue { get; private set; }
- public ExpressionVisualizerCommand(Expression expression)
+ public ExpressionVisualizerCommand(string valueName, Func getValue)
{
- this.Expression = expression;
+ if (getValue == null)
+ throw new ArgumentNullException("getValue");
+ this.ValueName = valueName;
+ this.GetValue = getValue;
}
public abstract void Execute();
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerCommand.cs
index 5a62f133ee..5387c98922 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerCommand.cs
@@ -25,9 +25,9 @@ namespace Debugger.AddIn.Visualizers
return type.ResolveIEnumerableImplementation(out collectionType, out itemType);
}
- public IVisualizerCommand CreateVisualizerCommand(Expression expression)
+ public IVisualizerCommand CreateVisualizerCommand(string valueName, Func getValue)
{
- return new GridVisualizerCommand(expression);
+ return new GridVisualizerCommand(valueName, getValue);
}
}
@@ -36,8 +36,7 @@ namespace Debugger.AddIn.Visualizers
///
public class GridVisualizerCommand : ExpressionVisualizerCommand
{
- public GridVisualizerCommand(Expression expression)
- :base(expression)
+ public GridVisualizerCommand(string valueName, Func getValue) : base(valueName, getValue)
{
}
@@ -48,10 +47,8 @@ namespace Debugger.AddIn.Visualizers
public override void Execute()
{
- if (this.Expression == null)
- return;
- var gridVisualizerWindow = GridVisualizerWindow.EnsureShown();
- gridVisualizerWindow.ShownExpression = this.Expression;
+ GridVisualizerWindow window = new GridVisualizerWindow(this.ValueName, this.GetValue);
+ window.ShowDialog();
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerMenuCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerMenuCommand.cs
index c4dcbefcbf..2b480fc5c6 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerMenuCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/GridVisualizerMenuCommand.cs
@@ -14,9 +14,7 @@ namespace Debugger.AddIn.Visualizers
{
public override void Run()
{
- GridVisualizerWindow window = new GridVisualizerWindow();
- window.Topmost = true;
- window.Show();
+
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/IVisualizerDescriptor.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/IVisualizerDescriptor.cs
index 3ffb8114f9..b87da05866 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/IVisualizerDescriptor.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/IVisualizerDescriptor.cs
@@ -16,6 +16,6 @@ namespace Debugger.AddIn.Visualizers
public interface IVisualizerDescriptor
{
bool IsVisualizerAvailable(DebugType type);
- IVisualizerCommand CreateVisualizerCommand(Expression expression);
+ IVisualizerCommand CreateVisualizerCommand(string valueName, Func getValue);
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ObjectGraphVisualizerCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ObjectGraphVisualizerCommand.cs
index 877880b5e8..85d699e89f 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ObjectGraphVisualizerCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/ObjectGraphVisualizerCommand.cs
@@ -21,9 +21,9 @@ namespace Debugger.AddIn.Visualizers
return !type.IsAtomic() && !type.IsSystemDotObject();
}
- public IVisualizerCommand CreateVisualizerCommand(Expression expression)
+ public IVisualizerCommand CreateVisualizerCommand(string valueName, Func getValue)
{
- return new ObjectGraphVisualizerCommand(expression);
+ return new ObjectGraphVisualizerCommand(valueName, getValue);
}
}
@@ -32,8 +32,7 @@ namespace Debugger.AddIn.Visualizers
///
public class ObjectGraphVisualizerCommand : ExpressionVisualizerCommand
{
- public ObjectGraphVisualizerCommand(Expression expression)
- :base(expression)
+ public ObjectGraphVisualizerCommand(string valueName, Func getValue) : base(valueName, getValue)
{
}
@@ -44,10 +43,8 @@ namespace Debugger.AddIn.Visualizers
public override void Execute()
{
- if (this.Expression == null)
- return;
var objectGraphWindow = ObjectGraphWindow.EnsureShown();
- objectGraphWindow.ShownExpression = this.Expression;
+ objectGraphWindow.ShownExpression = new GraphExpression(new IdentifierExpression(this.ValueName), this.GetValue);
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/TextVisualizerCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/TextVisualizerCommand.cs
index 7b1747882d..1c31cc2df6 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/TextVisualizerCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/TextVisualizerCommand.cs
@@ -20,16 +20,15 @@ namespace Debugger.AddIn.Visualizers
return type.FullName == typeof(string).FullName;
}
- public IVisualizerCommand CreateVisualizerCommand(Expression expression)
+ public IVisualizerCommand CreateVisualizerCommand(string valueName, Func getValue)
{
- return new TextVisualizerCommand(expression);
+ return new TextVisualizerCommand(valueName, getValue);
}
}
public class TextVisualizerCommand : ExpressionVisualizerCommand
{
- public TextVisualizerCommand(Expression expression)
- :base(expression)
+ public TextVisualizerCommand(string valueName, Func getValue) : base(valueName, getValue)
{
}
@@ -40,10 +39,7 @@ namespace Debugger.AddIn.Visualizers
public override void Execute()
{
- if (this.Expression == null)
- return;
- string expressionValue = this.Expression.Evaluate(WindowsDebugger.CurrentProcess).AsString();
- var textVisualizerWindow = new TextVisualizerWindow(this.Expression.PrettyPrint(), expressionValue);
+ var textVisualizerWindow = new TextVisualizerWindow(this.ValueName, this.GetValue().AsString());
textVisualizerWindow.ShowDialog();
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/XmlVisualizerCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/XmlVisualizerCommand.cs
index 77f8ba988e..665e002482 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/XmlVisualizerCommand.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Commands/XmlVisualizerCommand.cs
@@ -20,9 +20,9 @@ namespace Debugger.AddIn.Visualizers
return type.FullName == typeof(string).FullName;
}
- public IVisualizerCommand CreateVisualizerCommand(Expression expression)
+ public IVisualizerCommand CreateVisualizerCommand(string valueName, Func getValue)
{
- return new XmlVisualizerCommand(expression);
+ return new XmlVisualizerCommand(valueName, getValue);
}
}
@@ -31,8 +31,7 @@ namespace Debugger.AddIn.Visualizers
///
public class XmlVisualizerCommand : ExpressionVisualizerCommand
{
- public XmlVisualizerCommand(Expression expression)
- :base(expression)
+ public XmlVisualizerCommand(string valueName, Func getValue) : base(valueName, getValue)
{
}
@@ -43,11 +42,7 @@ namespace Debugger.AddIn.Visualizers
public override void Execute()
{
- if (this.Expression == null)
- return;
- var textVisualizerWindow = new TextVisualizerWindow(
- this.Expression.PrettyPrint(), this.Expression.Evaluate(WindowsDebugger.CurrentProcess).AsString());
- textVisualizerWindow.Mode = TextVisualizerMode.Xml;
+ var textVisualizerWindow = new TextVisualizerWindow(this.ValueName, this.GetValue().AsString(), ".xml");
textVisualizerWindow.ShowDialog();
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/IListValuesProvider.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/IListValuesProvider.cs
deleted file mode 100644
index d373860ad4..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/IListValuesProvider.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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;
-
-namespace Debugger.AddIn.Visualizers
-{
- ///
- /// Can provide individial items for a lazy collection, as well as total count of items.
- ///
- public interface IListValuesProvider
- {
- int GetCount();
- T GetItemAt(int index);
- }
-}
diff --git a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/IVisualizerCommand.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/IVisualizerCommand.cs
similarity index 100%
rename from src/Main/Base/Project/Src/Services/Debugger/Tooltips/IVisualizerCommand.cs
rename to src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/IVisualizerCommand.cs
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/ObjectProperty.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/ObjectProperty.cs
index 879559757c..01e5d98725 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/ObjectProperty.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/ObjectProperty.cs
@@ -2,6 +2,7 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System;
+using Debugger.AddIn.Visualizers.Graph;
using ICSharpCode.NRefactory.Ast;
namespace Debugger.AddIn.Visualizers
@@ -24,7 +25,7 @@ namespace Debugger.AddIn.Visualizers
///
/// Expression used for obtaining value of this property
///
- public Expression Expression { get; set; }
+ public GraphExpression Expression { get; set; }
///
/// Is this property of atomic type? (int, string, etc.)
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingCollection.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingCollection.cs
index 6ec03cb2ab..cb87dcb028 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingCollection.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingCollection.cs
@@ -8,21 +8,23 @@ using System.Collections.Generic;
namespace Debugger.AddIn.Visualizers
{
///
- /// IList<T> with data vitualization - the indexer is lazy, uses IListValuesProvider to obtain values when needed.
+ /// IList<T> with data vitualization - the indexer is lazy, uses lamda function to obtain values when needed.
///
public class VirtualizingCollection : IList, IList
{
- private IListValuesProvider valueProvider;
- private Dictionary itemCache = new Dictionary();
+ int count;
+ Func getItem;
+ Dictionary itemCache = new Dictionary();
- public VirtualizingCollection(IListValuesProvider valueProvider)
+ public VirtualizingCollection(int count, Func getItem)
{
- this.valueProvider = valueProvider;
+ this.count = count;
+ this.getItem = getItem;
}
public int Count
{
- get { return this.valueProvider.GetCount(); }
+ get { return count; }
}
public T this[int index]
@@ -32,7 +34,7 @@ namespace Debugger.AddIn.Visualizers
T cachedItem;
if (!itemCache.TryGetValue(index, out cachedItem))
{
- cachedItem = this.valueProvider.GetItemAt(index);
+ cachedItem = getItem(index);
this.itemCache[index] = cachedItem;
}
return cachedItem;
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/GraphExpression.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/GraphExpression.cs
new file mode 100644
index 0000000000..f892f18949
--- /dev/null
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/GraphExpression.cs
@@ -0,0 +1,28 @@
+// 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 ICSharpCode.NRefactory.Ast;
+
+namespace Debugger.AddIn.Visualizers.Graph
+{
+ ///
+ /// NRefactory Expression plus a method that can evaluate it,
+ /// as the Debugger does not support evaluating NRefactory expressions directly.
+ ///
+ public class GraphExpression
+ {
+ public Expression Expr { get; set; }
+ public Func GetValue { get; set; }
+
+ public GraphExpression(Expression expr, Func getValue)
+ {
+ if (expr == null) throw new ArgumentNullException("expr");
+ if (getValue == null) throw new ArgumentNullException("getValue");
+ this.Expr = expr;
+ this.GetValue = getValue;
+ }
+ }
+}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNodeProperty.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNodeProperty.cs
index 4d26ac12d3..c691a05509 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNodeProperty.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNodeProperty.cs
@@ -70,7 +70,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
///
/// Full Debugger expression used to obtain value of this property.
///
- public Expression Expression { get { return this.objectGraphProperty.Expression; } }
+ public GraphExpression Expression { get { return this.objectGraphProperty.Expression; } }
///
/// Is this property of atomic type? (int, string, etc.)
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs
index c9574ad957..90fcfcf004 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs
@@ -36,7 +36,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
///
public string FullPath
{
- get { return this.containingNode.ObjectNode.Expression.PrettyPrint() + "/" + this.Path; }
+ get { return this.containingNode.ObjectNode.Expression.Expr.PrettyPrint() + "/" + this.Path; }
}
private ContentNode parent;
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs
index 53b4a1e2db..44b27de6bf 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs
@@ -6,6 +6,7 @@ using System.ComponentModel;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph.Drawing;
using Debugger.MetaData;
+using ICSharpCode.SharpDevelop;
namespace Debugger.AddIn.Visualizers.Graph.Layout
{
@@ -65,7 +66,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
this.IsExpanded = false; // always false, Property nodes are never expanded (they have IsPropertyExpanded)
this.Property = new PositionedNodeProperty(
sourcePropertyNode.Property, this.ContainingNode,
- expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression));
+ expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression.Expr));
if (PositionedGraphNodeControl.IsShowMemberIcon) {
EvalMemberIcon();
}
@@ -77,8 +78,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
if ((this.Property != null) && (this.Property.ObjectGraphProperty != null)) {
var memberInfo = (IDebugMemberInfo)this.Property.ObjectGraphProperty.MemberInfo;
if (memberInfo != null) {
- string imageName;
- var image = ExpressionNode.GetImageForMember(memberInfo, out imageName);
+ var image = new ResourceServiceImage(ValueNode.GetImageForMember(memberInfo));
this.MemberIcon = image.ImageSource;
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
index ac10dd7d92..f32a83fdf5 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
@@ -79,26 +79,20 @@ namespace Debugger.AddIn.Visualizers.Graph
///
/// Expression valid in the program being debugged (eg. variable name)
/// Object graph
- public ObjectGraph BuildGraphForExpression(string expression, ExpandedExpressions expandedNodes)
+ public ObjectGraph BuildGraphForExpression(GraphExpression expression, ExpandedExpressions expandedNodes)
{
- if (string.IsNullOrEmpty(expression)) {
- throw new DebuggerVisualizerException("Please specify an expression.");
- }
-
- var debuggedProcess = this.debuggerService.DebuggedProcess;
- if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) {
+ if (WindowsDebugger.CurrentStackFrame == null) {
throw new DebuggerVisualizerException("Please use the visualizer when debugging.");
}
- var rootExpression = ExpressionEvaluator.ParseExpression(expression, SupportedLanguage.CSharp);
- Value rootValue = rootExpression.Evaluate(debuggedProcess);
+ Value rootValue = expression.GetValue();
if (rootValue.IsNull) {
throw new DebuggerVisualizerException(expression + " is null.");
}
- return buildGraphForValue(rootValue.GetPermanentReference(), rootExpression, expandedNodes);
+ return buildGraphForValue(rootValue.GetPermanentReference(WindowsDebugger.EvalThread), expression, expandedNodes);
}
- private ObjectGraph buildGraphForValue(Value rootValue, Expression rootExpression, ExpandedExpressions expandedNodes)
+ private ObjectGraph buildGraphForValue(Value rootValue, GraphExpression rootExpression, ExpandedExpressions expandedNodes)
{
resultGraph = new ObjectGraph();
//resultGraph.Root = buildGraphRecursive(debuggerService.GetValueFromName(expression).GetPermanentReference(), expandedNodes);
@@ -108,15 +102,15 @@ namespace Debugger.AddIn.Visualizers.Graph
return resultGraph;
}
- public ObjectGraphNode ObtainNodeForExpression(Expression expr)
+ public ObjectGraphNode ObtainNodeForExpression(GraphExpression expr)
{
bool createdNewNode; // ignored (caller is not interested, otherwise he would use the other overload)
return ObtainNodeForExpression(expr, out createdNewNode);
}
- public ObjectGraphNode ObtainNodeForExpression(Expression expr, out bool createdNewNode)
+ public ObjectGraphNode ObtainNodeForExpression(GraphExpression expr, out bool createdNewNode)
{
- return ObtainNodeForValue(expr.EvalPermanentReference(), expr, out createdNewNode);
+ return ObtainNodeForValue(expr.GetValue().GetPermanentReference(WindowsDebugger.EvalThread), expr, out createdNewNode);
}
///
@@ -124,7 +118,7 @@ namespace Debugger.AddIn.Visualizers.Graph
///
/// Value for which to obtain the node/
/// True if new node was created, false if existing node was returned.
- public ObjectGraphNode ObtainNodeForValue(Value value, Expression expression, out bool createdNew)
+ public ObjectGraphNode ObtainNodeForValue(Value value, GraphExpression expression, out bool createdNew)
{
createdNew = false;
ObjectGraphNode nodeForValue = getExistingNodeForValue(value);
@@ -158,7 +152,10 @@ namespace Debugger.AddIn.Visualizers.Graph
//AddRawViewNode(contentRoot, thisNode);
// it is an IEnumerable
DebugType debugListType;
- var debugListExpression = DebuggerHelpers.CreateDebugListExpression(thisNode.Expression, itemType, out debugListType);
+ var debugListExpression = new GraphExpression(
+ DebuggerHelpers.CreateDebugListExpression(thisNode.Expression.Expr, itemType, out debugListType),
+ () => DebuggerHelpers.CreateListFromIEnumerable(thisNode.Expression.GetValue())
+ );
LoadNodeCollectionContent(contentRoot, debugListExpression, debugListType);
} else {
// it is an object
@@ -173,21 +170,26 @@ namespace Debugger.AddIn.Visualizers.Graph
LoadNodeObjectContent(rawViewNode, thisNode.Expression, thisNode.PermanentReference.Type);
}
- void LoadNodeCollectionContent(AbstractNode node, Expression thisObject, DebugType iListType)
+ void LoadNodeCollectionContent(AbstractNode node, GraphExpression thisObject, DebugType iListType)
{
- thisObject = thisObject.CastToIList();
- int listCount = thisObject.GetIListCount();
+ var thisObjectAsIList = new GraphExpression(thisObject.Expr.CastToIList(), thisObject.GetValue);
+ int listCount = thisObjectAsIList.GetValue().GetIListCount();
PropertyInfo indexerProp = iListType.GetProperty("Item");
+ var v = new List();
+
for (int i = 0; i < listCount; i++) {
- Expression itemExpr = thisObject.AppendIndexer(i);
+ var itemExpr = new GraphExpression(
+ thisObjectAsIList.Expr.AppendIndexer(i),
+ () => thisObjectAsIList.GetValue().GetIListItem(i) // EXPR-EVAL, Does a 'cast' to IList
+ );
PropertyNode itemNode = new PropertyNode(
new ObjectGraphProperty { Name = "[" + i + "]", MemberInfo = indexerProp, Expression = itemExpr, Value = "", IsAtomic = true, TargetNode = null });
node.AddChild(itemNode);
}
}
- void LoadNodeObjectContent(AbstractNode node, Expression expression, DebugType type)
+ void LoadNodeObjectContent(AbstractNode node, GraphExpression expression, DebugType type)
{
// base
if (type.BaseType != null && type.BaseType.FullName != "System.Object")
@@ -216,7 +218,7 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}
- private List getProperties(Expression expression, DebugType shownType, BindingFlags flags)
+ private List getProperties(GraphExpression expression, DebugType shownType, BindingFlags flags)
{
List propertyList = new List();
@@ -233,7 +235,10 @@ namespace Debugger.AddIn.Visualizers.Graph
// ObjectGraphProperty needs an expression
// to know whether it is expanded, and to evaluate
- Expression propExpression = expression.AppendMemberReference((IDebugMemberInfo)memberProp);
+ var propExpression = new GraphExpression(
+ expression.Expr.AppendMemberReference((IDebugMemberInfo)memberProp),
+ () => expression.GetValue().GetMemberValue(WindowsDebugger.EvalThread, memberProp) // EXPR-EVAL
+ );
// Value, IsAtomic are lazy evaluated
propertyList.Add(new ObjectGraphProperty
{ Name = memberProp.Name,
@@ -258,10 +263,10 @@ namespace Debugger.AddIn.Visualizers.Graph
// We are only evaluating expanded nodes here.
// We have to do this to know the "shape" of the graph.
// We do not evaluate atomic and non-expanded properties, those will be lazy evaluated when drawn.
- if (expandedNodes.IsExpanded(complexProperty.Expression))
+ if (expandedNodes.IsExpanded(complexProperty.Expression.Expr))
{
// if expanded, evaluate this property
- Value memberValue = complexProperty.Expression.Evaluate(this.debuggerService.DebuggedProcess);
+ Value memberValue = complexProperty.Expression.GetValue();
if (memberValue.IsNull)
{
continue;
@@ -269,7 +274,7 @@ namespace Debugger.AddIn.Visualizers.Graph
else
{
// if property value is not null, create neighbor
- memberValue = memberValue.GetPermanentReference();
+ memberValue = memberValue.GetPermanentReference(WindowsDebugger.EvalThread);
bool createdNew;
// get existing node (loop) or create new
@@ -295,7 +300,7 @@ namespace Debugger.AddIn.Visualizers.Graph
///
/// Value, has to be valid.
/// New empty object node representing the value.
- private ObjectGraphNode createNewNode(Value permanentReference, Expression expression)
+ private ObjectGraphNode createNewNode(Value permanentReference, GraphExpression expression)
{
if (permanentReference == null) throw new ArgumentNullException("permanentReference");
@@ -341,32 +346,5 @@ namespace Debugger.AddIn.Visualizers.Graph
return nodeWithSameAddress;
}
}
-
- public ObjectGraphProperty createAtomicProperty(string name, Expression expression)
- {
- // value is empty (will be lazy-evaluated later)
- return new ObjectGraphProperty
- { Name = name, Value = "", Expression = expression, IsAtomic = true, TargetNode = null };
- }
-
- public ObjectGraphProperty createComplexProperty(string name, Expression expression, ObjectGraphNode targetNode, bool isNull)
- {
- // value is empty (will be lazy-evaluated later)
- return new ObjectGraphProperty
- { Name = name, Value = "", Expression = expression, IsAtomic = false, TargetNode = targetNode, IsNull = isNull };
- }
-
- ///
- /// Checks whether given expression's type is supported by the graph builder.
- ///
- /// Expression to be checked.
- private void checkIsOfSupportedType(Expression expr)
- {
- DebugType typeOfValue = expr.Evaluate(debuggerService.DebuggedProcess).Type;
- if (typeOfValue.IsArray)
- {
- throw new DebuggerVisualizerException("Arrays are not supported yet");
- }
- }
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphNode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphNode.cs
index 87502b469d..17869eb941 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphNode.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphNode.cs
@@ -27,7 +27,7 @@ namespace Debugger.AddIn.Visualizers.Graph
///
/// Expression used to obtain this node.
///
- public Expression Expression { get; set; }
+ public GraphExpression Expression { get; set; }
///
/// Property tree of this node.
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphProperty.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphProperty.cs
index c9b642c0e7..3ba59d7c26 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphProperty.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphProperty.cs
@@ -39,7 +39,7 @@ namespace Debugger.AddIn.Visualizers.Graph
if (this.Expression == null) throw new DebuggerVisualizerException("Cannot evaluate property with missing Expression");
Value debuggerVal;
try {
- debuggerVal = this.Expression.Evaluate(WindowsDebugger.CurrentProcess);
+ debuggerVal = this.Expression.GetValue();
} catch (System.Exception ex) {
this.Value = "Exception: " + ex.Message;
this.IsEvaluated = true;
@@ -49,7 +49,7 @@ namespace Debugger.AddIn.Visualizers.Graph
this.IsAtomic = debuggerVal.Type.IsAtomic();
this.IsNull = debuggerVal.IsNull;
// null and complex properties will show empty string
- this.Value = debuggerVal.IsNull || (!this.IsAtomic) ? string.Empty : debuggerVal.InvokeToString();
+ this.Value = debuggerVal.IsNull || (!this.IsAtomic) ? string.Empty : debuggerVal.InvokeToString(WindowsDebugger.EvalThread);
this.IsEvaluated = true;
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml
index 1495a27854..f22358061f 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml
@@ -25,8 +25,7 @@
Expression:
-
- Layout:
+ Layout:
Zoom:
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs
index 074b42de3f..33ffe9d9b0 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs
@@ -62,7 +62,7 @@ namespace Debugger.AddIn.Visualizers.Graph
public void RefreshView()
{
- debuggerService.DebuggedProcess.EnqueueWork(Dispatcher, () => Refresh());
+ WindowsDebugger.CurrentProcess.EnqueueWork(Dispatcher, () => Refresh());
}
void Refresh()
@@ -78,7 +78,7 @@ namespace Debugger.AddIn.Visualizers.Graph
}
bool isSuccess = true;
try {
- this.objectGraph = RebuildGraph(txtExpression.Text);
+ this.objectGraph = RebuildGraph();
} catch(DebuggerVisualizerException ex) {
isSuccess = false;
ErrorMessage(ex.Message);
@@ -94,8 +94,8 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}
- private ICSharpCode.NRefactory.Ast.Expression shownExpression;
- public ICSharpCode.NRefactory.Ast.Expression ShownExpression
+ private GraphExpression shownExpression;
+ public GraphExpression ShownExpression
{
get {
return shownExpression;
@@ -107,23 +107,17 @@ namespace Debugger.AddIn.Visualizers.Graph
RefreshView();
return;
}
- if (shownExpression == null || value.PrettyPrint() != shownExpression.PrettyPrint()) {
- txtExpression.Text = value.PrettyPrint();
+ if (shownExpression == null || value.Expr.PrettyPrint() != shownExpression.Expr.PrettyPrint()) {
+ txtExpression.Text = value.Expr.PrettyPrint();
RefreshView();
}
}
}
- private void Inspect_Button_Click(object sender, RoutedEventArgs e)
- {
- RefreshView();
- }
-
- ObjectGraph RebuildGraph(string expression)
+ ObjectGraph RebuildGraph()
{
this.objectGraphBuilder = new ObjectGraphBuilder(debuggerService);
- Log.Debug("Debugger visualizer: Building graph for expression: " + txtExpression.Text);
- return this.objectGraphBuilder.BuildGraphForExpression(expression, expanded.Expressions);
+ return this.objectGraphBuilder.BuildGraphForExpression(this.ShownExpression, expanded.Expressions);
}
void LayoutGraph(ObjectGraph graph)
@@ -185,7 +179,7 @@ namespace Debugger.AddIn.Visualizers.Graph
void node_PropertyExpanded(object sender, PositionedPropertyEventArgs e)
{
// remember this property is expanded (for later graph rebuilds)
- expanded.Expressions.SetExpanded(e.Property.Expression);
+ expanded.Expressions.SetExpanded(e.Property.Expression.Expr);
// add edge (+ possibly nodes) to underlying object graph (no need to fully rebuild)
e.Property.ObjectGraphProperty.TargetNode = this.objectGraphBuilder.ObtainNodeForExpression(e.Property.Expression);
@@ -195,7 +189,7 @@ namespace Debugger.AddIn.Visualizers.Graph
void node_PropertyCollapsed(object sender, PositionedPropertyEventArgs e)
{
// remember this property is collapsed (for later graph rebuilds)
- expanded.Expressions.SetCollapsed(e.Property.Expression);
+ expanded.Expressions.SetCollapsed(e.Property.Expression.Expr);
// just remove edge from underlying object graph (no need to fully rebuild)
e.Property.ObjectGraphProperty.TargetNode = null;
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphWindow.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphWindow.xaml.cs
index eb4056d1a9..0bccfe5dcf 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphWindow.xaml.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphWindow.xaml.cs
@@ -42,7 +42,7 @@ namespace Debugger.AddIn.Visualizers.Graph
ObjectGraphWindow.Instance = null; // allow release
}
- public ICSharpCode.NRefactory.Ast.Expression ShownExpression
+ public GraphExpression ShownExpression
{
get { return this.objectGraphControl.ShownExpression; }
set { this.objectGraphControl.ShownExpression = value; }
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml
index 664da36dd7..954552e85d 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml
@@ -27,9 +27,6 @@
- Expression:
-
-
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs
index 80703cd997..db8f1eabdd 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/GridVisualizerWindow.xaml.cs
@@ -2,25 +2,15 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
using System.Reflection;
-using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.PresentationBindings;
using Debugger.AddIn.Visualizers.Utils;
using Debugger.MetaData;
using ICSharpCode.Core;
-using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop;
-using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
namespace Debugger.AddIn.Visualizers.GridVisualizer
@@ -30,160 +20,94 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
///
public partial class GridVisualizerWindow : Window
{
- WindowsDebugger debuggerService;
- GridViewColumnHider columnHider;
+ Func getValue;
- public GridVisualizerWindow()
+ public GridVisualizerWindow(string valueName, Func getValue)
{
InitializeComponent();
- this.debuggerService = DebuggerService.CurrentDebugger as WindowsDebugger;
- if (debuggerService == null)
- throw new ApplicationException("Only windows debugger is currently supported");
+ this.Title = valueName;
+ this.getValue = getValue;
- instance = this;
- this.Deactivated += GridVisualizerWindow_Deactivated;
- }
-
- void GridVisualizerWindow_Deactivated(object sender, EventArgs e)
- {
- this.Close();
- }
-
- private ICSharpCode.NRefactory.Ast.Expression shownExpression;
- public ICSharpCode.NRefactory.Ast.Expression ShownExpression
- {
- get {
- return shownExpression;
- }
- set {
- if (value == null) {
- shownExpression = null;
- txtExpression.Text = null;
-
- Refresh();
- return;
- }
- if (shownExpression == null || value.PrettyPrint() != shownExpression.PrettyPrint()) {
- txtExpression.Text = value.PrettyPrint();
- Refresh();
- }
- }
- }
-
- static GridVisualizerWindow instance;
- /// When Window is visible, returns reference to the Window. Otherwise returns null.
- public static GridVisualizerWindow Instance
- {
- get { return instance; }
- }
-
- public static GridVisualizerWindow EnsureShown()
- {
- var window = GridVisualizerWindow.Instance ?? new GridVisualizerWindow();
- window.Topmost = true;
- window.Show();
- return window;
- }
-
- protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
- {
- this.Deactivated -= GridVisualizerWindow_Deactivated;
- base.OnClosing(e);
- }
-
- protected override void OnClosed(EventArgs e)
- {
- base.OnClosed(e);
- instance = null;
- }
-
- private void btnInspect_Click(object sender, RoutedEventArgs e)
- {
Refresh();
}
-
+
public void Refresh()
{
- try {
+ try {
// clear ListView
listView.ItemsSource = null;
- ScrollViewer listViewScroller = listView.GetScrollViewer();
- if (listViewScroller != null) {
- listViewScroller.ScrollToVerticalOffset(0);
- }
- Value shownValue = null;
- ICSharpCode.NRefactory.Ast.Expression shownExpr = null;
- try {
- shownExpr = debuggerService.GetExpression(txtExpression.Text);
- shownValue = shownExpr.Evaluate(debuggerService.DebuggedProcess);
- } catch(GetValueException e) {
- MessageService.ShowMessage(e.Message);
- }
- if (shownValue != null && !shownValue.IsNull) {
- GridValuesProvider gridValuesProvider;
- // Value is IList
- DebugType iListType, listItemType;
- if (shownValue.Type.ResolveIListImplementation(out iListType, out listItemType)) {
- gridValuesProvider = CreateListValuesProvider(shownExpr.CastToIList(), listItemType);
+
+ Value shownValue = getValue();
+
+ DebugType iListType, iEnumerableType, itemType;
+ // Value is IList
+ if (shownValue.Type.ResolveIListImplementation(out iListType, out itemType)) {
+ // Ok
+ } else {
+ // Value is IEnumerable
+ if (shownValue.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) {
+ shownValue = DebuggerHelpers.CreateListFromIEnumerable(shownValue);
+ iListType = DebugType.CreateFromType(shownValue.AppDomain, typeof(System.Collections.Generic.IList<>), itemType);
} else {
- // Value is IEnumerable
- DebugType iEnumerableType, itemType;
- if (shownValue.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) {
- DebugType debugListType;
- var debugListExpression = DebuggerHelpers.CreateDebugListExpression(shownExpr, itemType, out debugListType);
- gridValuesProvider = CreateListValuesProvider(debugListExpression, itemType);
- } else {
- // Not IList or IEnumerable - can't be displayed in GridVisualizer
- return;
- }
+ // Not IList or IEnumerable - can't be displayed in GridVisualizer
+ return;
}
-
- IList itemTypeMembers = gridValuesProvider.GetItemTypeMembers();
- InitializeColumns((GridView)this.listView.View, itemTypeMembers);
- this.columnHider = new GridViewColumnHider((GridView)this.listView.View);
- cmbColumns.ItemsSource = this.columnHider.HideableColumns;
}
- } catch (GetValueException e) {
- MessageService.ShowMessage(e.Message);
- } catch (DebuggerVisualizerException e) {
+ shownValue = shownValue.GetPermanentReference(WindowsDebugger.EvalThread);
+
+ MemberInfo[] members = itemType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance);
+ PropertyInfo itemGetter = iListType.GetProperty("Item");
+ int rowCount = (int)shownValue.GetPropertyValue(WindowsDebugger.EvalThread, iListType.GetProperty("Count")).PrimitiveValue;
+ int columnCount = members.Length + 1;
+
+ var rowCollection = new VirtualizingCollection>(
+ rowCount,
+ (rowIndex) => new VirtualizingCollection(
+ columnCount,
+ (columnIndex) => {
+ if (columnIndex == members.Length)
+ return "[" + rowIndex + "]";
+ try {
+ var rowValue = shownValue.GetPropertyValue(WindowsDebugger.EvalThread, itemGetter, Eval.CreateValue(WindowsDebugger.EvalThread, rowIndex));
+ return rowValue.GetMemberValue(WindowsDebugger.EvalThread, members[columnIndex]).InvokeToString(WindowsDebugger.EvalThread);
+ } catch (GetValueException e) {
+ return "Exception: " + e.Message;
+ }
+ }
+ )
+ );
+ this.listView.ItemsSource = rowCollection;
+
+ InitializeColumns((GridView)this.listView.View, members);
+
+ GridViewColumnHider columnHider = new GridViewColumnHider((GridView)this.listView.View);
+ cmbColumns.ItemsSource = columnHider.HideableColumns;
+
+ } catch(GetValueException e) {
MessageService.ShowMessage(e.Message);
}
}
- ListValuesProvider CreateListValuesProvider(ICSharpCode.NRefactory.Ast.Expression targetExpression, DebugType listItemType)
- {
- var listValuesProvider = new ListValuesProvider(targetExpression, listItemType);
- var virtCollection = new VirtualizingCollection(listValuesProvider);
- this.listView.ItemsSource = virtCollection;
- return listValuesProvider;
- }
-
- void InitializeColumns(GridView gridView, IList itemTypeMembers)
+ void InitializeColumns(GridView gridView, MemberInfo[] members)
{
gridView.Columns.Clear();
- AddIndexColumn(gridView);
- AddMembersColumns(gridView, itemTypeMembers);
- }
-
- void AddIndexColumn(GridView gridView)
- {
+
+ // Index column
var indexColumn = new GridViewHideableColumn();
indexColumn.CanBeHidden = false;
indexColumn.Width = 36;
indexColumn.Header = string.Empty;
- indexColumn.DisplayMemberBinding = new Binding("Index");
+ indexColumn.DisplayMemberBinding = new Binding("[" + members.Length + "]");
gridView.Columns.Add(indexColumn);
- }
-
- void AddMembersColumns(GridView gridView, IList itemTypeMembers)
- {
- foreach (var member in itemTypeMembers) {
+
+ // Member columns
+ for (int i = 0; i < members.Length; i++) {
var memberColumn = new GridViewHideableColumn();
memberColumn.CanBeHidden = true;
- memberColumn.Header = member.Name;
- // "{Binding Path=[Name].Value}"
- memberColumn.DisplayMemberBinding = new Binding("[" + member.Name + "].Value");
+ memberColumn.Header = members[i].Name;
+ memberColumn.IsVisibleDefault = ((IDebugMemberInfo)members[i]).IsPublic;
+ memberColumn.DisplayMemberBinding = new Binding("[" + i + "]");
gridView.Columns.Add(memberColumn);
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ObjectValue.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ObjectValue.cs
deleted file mode 100644
index 6663528bca..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ObjectValue.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.Collections.Generic;
-using Debugger.AddIn.Visualizers.Utils;
-using Debugger.MetaData;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop.Services;
-using System.Reflection;
-
-namespace Debugger.AddIn.Visualizers.GridVisualizer
-{
- ///
- /// Item of a collection in the debugee, with lazy evaluated properties.
- ///
- public class ObjectValue
- {
- /// Index of this item in the collection.
- public int Index { get; private set; }
-
- // PermanentReference for one row.
- public Value PermanentReference { get; private set; }
-
- private Dictionary properties = new Dictionary();
-
- /// Used to quickly find MemberInfo by member name - DebugType.GetMember(name) uses a loop to search members
- private Dictionary memberForNameMap;
-
- internal ObjectValue(int index, Dictionary memberFromNameMap)
- {
- this.Index = index;
- this.memberForNameMap = memberFromNameMap;
- }
-
- ///
- /// Returns property with given name.
- ///
- public ObjectProperty this[string propertyName]
- {
- get
- {
- ObjectProperty property;
- // has property with name 'propertyName' already been evaluated?
- if(!this.properties.TryGetValue(propertyName, out property))
- {
- if (this.PermanentReference == null) {
- throw new DebuggerVisualizerException("Cannot get member of this ObjectValue - ObjectValue.PermanentReference is null");
- }
- MemberInfo memberInfo = this.memberForNameMap.GetValue(propertyName);
- if (memberInfo == null) {
- throw new DebuggerVisualizerException("Cannot get member value - no member found with name " + propertyName);
- }
- property = CreatePropertyFromValue(propertyName, this.PermanentReference.GetMemberValue(memberInfo));
- this.properties.Add(propertyName, property);
- }
- return property;
- }
- }
-
- public static ObjectValue Create(Debugger.Value value, int index, Dictionary memberFromName)
- {
- ObjectValue result = new ObjectValue(index, memberFromName);
-
- // remember PermanentReference for expanding IEnumerable
- Value permanentReference = value.GetPermanentReference();
- result.PermanentReference = permanentReference;
-
- return result;
- }
-
- private static ObjectProperty CreatePropertyFromValue(string propertyName, Value value)
- {
- ObjectProperty property = new ObjectProperty();
- property.Name = propertyName;
- // property.Expression = ?.Age
- // - cannot use expression,
- // if the value is returned from an enumerator, it has no meaningful expression
- property.IsAtomic = value.Type.IsPrimitive;
- property.IsNull = value.IsNull;
- property.Value = value.IsNull ? "" : value.InvokeToString();
- return property;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/EnumerableValuesProvider.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/EnumerableValuesProvider.cs
deleted file mode 100644
index 09b9a5cf9f..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/EnumerableValuesProvider.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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.Collections;
-using System.Collections.Generic;
-
-using Debugger.AddIn.Visualizers.Utils;
-using Debugger.MetaData;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop.Services;
-using System.Reflection;
-
-namespace Debugger.AddIn.Visualizers.GridVisualizer
-{
- ///
- /// Provides s for debugee objects implementing IEnumerable.
- ///
- /*public class EnumerableValuesProvider : GridValuesProvider
- {
- public EnumerableValuesProvider(Expression targetObject, DebugType iEnumerableType, DebugType itemType)
- :base(targetObject, iEnumerableType, itemType)
- {
- this.itemsSource = enumerateItems();
- }
-
- private IEnumerable itemsSource;
- public IEnumerable ItemsSource
- {
- get { return this.itemsSource; }
- }
-
- private IEnumerable enumerateItems()
- {
- MethodInfo enumeratorMethod = collectionType.GetMethod("GetEnumerator");
- Value enumerator = targetObject.Evaluate(WindowsDebugger.CurrentProcess).InvokeMethod(enumeratorMethod, null).GetPermanentReference();
-
- MethodInfo moveNextMethod = enumerator.Type.GetMethod("MoveNext");
- PropertyInfo currentproperty = enumerator.Type.GetInterface(typeof(IEnumerator).FullName).GetProperty("Current");
-
- int index = 0;
- while ((bool)enumerator.InvokeMethod(moveNextMethod, null).PrimitiveValue)
- {
- Value currentValue = enumerator.GetPropertyValue(currentproperty);
- yield return ObjectValue.Create(currentValue, index++, this.memberFromNameMap);
- }
- }
- }*/
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs
deleted file mode 100644
index f656934db6..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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.Collections.Generic;
-using Debugger.AddIn.Visualizers.Utils;
-using Debugger.MetaData;
-using ICSharpCode.NRefactory.Ast;
-using System.Reflection;
-
-namespace Debugger.AddIn.Visualizers.GridVisualizer
-{
- ///
- /// Provides s to be displayed in Grid visualizer.
- /// Descandants implement getting values for IList and IEnumerable.
- ///
- public class GridValuesProvider
- {
- /// Used to quickly find MemberInfo by member name - DebugType.GetMember(name) uses a loop to search members
- protected Dictionary memberFromNameMap;
-
- protected Expression targetObject;
- protected DebugType itemType;
-
- public GridValuesProvider(Expression targetObject, DebugType itemType)
- {
- this.targetObject = targetObject;
- this.itemType = itemType;
-
- this.memberFromNameMap = this.GetItemTypeMembers().MakeDictionary(memberInfo => memberInfo.Name);
- }
-
- ///
- /// Gets members that will be displayed as columns.
- ///
- public IList GetItemTypeMembers()
- {
- var publicPropetiesAndFields = itemType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance);
- return publicPropetiesAndFields;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/ListValuesProvider.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/ListValuesProvider.cs
deleted file mode 100644
index 457566d0cf..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/GridVisualizer/ValueProviders/ListValuesProvider.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using Debugger.AddIn.Visualizers.Utils;
-using Debugger.MetaData;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.SharpDevelop.Services;
-
-namespace Debugger.AddIn.Visualizers.GridVisualizer
-{
- ///
- /// Provides s for debugee objects implementing IList.
- ///
- public class ListValuesProvider : GridValuesProvider, IListValuesProvider
- {
- int? listCount = null;
- ///
- /// After evaluating how many items to clear debugger Expression cache,
- /// so that the cache does not keep too many PermanentReferences.
- ///
- static readonly int ClearCacheThreshold = 50;
-
- public ListValuesProvider(Expression targetObject, DebugType listItemType)
- :base(targetObject, listItemType)
- {
- }
-
- public int GetCount()
- {
- if (this.listCount == null) {
- this.listCount = this.targetObject.GetIListCount();
- }
- return this.listCount.Value;
- }
-
- /// When this reaches ClearCacheThreshold, the debugger Expression cache is cleared.
- int itemClearCacheCounter = 0;
-
- public ObjectValue GetItemAt(int index)
- {
- if (itemClearCacheCounter++ > ClearCacheThreshold) {
- // clear debugger Expression cache to avoid holding too many PermanentReferences
- WindowsDebugger.CurrentProcess.ClearExpressionCache();
- LoggingService.Info("Cleared debugger Expression cache.");
- itemClearCacheCounter = 0;
- }
- return ObjectValue.Create(
- targetObject.AppendIndexer(index).Evaluate(WindowsDebugger.CurrentProcess),
- //targetObject.AppendIndexer(index), // use Expression instead of value - possible only for IList though
- index,
- this.memberFromNameMap);
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerMode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerMode.cs
deleted file mode 100644
index f084773b26..0000000000
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerMode.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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.Collections.Generic;
-using System.Linq;
-using System;
-
-public enum TextVisualizerMode
-{
- PlainText,
- Xml
-}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerWindow.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerWindow.xaml.cs
index 56c8a75dc3..ab35e503ca 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerWindow.xaml.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/TextVisualizer/TextVisualizerWindow.xaml.cs
@@ -1,17 +1,9 @@
// 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 ICSharpCode.AvalonEdit.Highlighting;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
+using ICSharpCode.AvalonEdit.Highlighting;
namespace Debugger.AddIn.Visualizers.TextVisualizer
{
@@ -20,42 +12,14 @@ namespace Debugger.AddIn.Visualizers.TextVisualizer
///
public partial class TextVisualizerWindow : Window
{
- public TextVisualizerWindow()
- {
- InitializeComponent();
- Mode = TextVisualizerMode.PlainText;
- textEditor.IsReadOnly = true;
- }
-
- public TextVisualizerWindow(string title, string text)
+ public TextVisualizerWindow(string title, string text, string highlighting = null)
{
InitializeComponent();
- Title= title;
- Text = text;
- }
-
- public string Text
- {
- get { return this.textEditor.Text; }
- set { this.textEditor.Text = value; }
- }
-
- private TextVisualizerMode mode;
- public TextVisualizerMode Mode
- {
- get { return mode; }
- set {
- mode = value;
- switch (mode) {
- case TextVisualizerMode.PlainText:
- textEditor.SyntaxHighlighting = null;
- break;
- case TextVisualizerMode.Xml:
- textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(".xml");
- break;
- }
- }
+ Title = title;
+ this.textEditor.Text = text;
+ if (highlighting != null)
+ this.textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(highlighting);
}
void CheckBox_CheckedChanged(object sender, RoutedEventArgs e)
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/AtomicType.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/AtomicType.cs
index c029bb0f12..16bad38635 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/AtomicType.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/AtomicType.cs
@@ -22,16 +22,5 @@ namespace Debugger.AddIn.Visualizers.Utils
{
return type.IsPrimitive || type.FullName == "System.String" || type.IsEnum();
}
-
- ///
- /// Checks whether given expression's type is atomic.
- ///
- /// Expression.
- /// True if expression's type is atomic, False otherwise.
- public static bool IsOfAtomicType(this Expression expr)
- {
- DebugType typeOfValue = expr.Evaluate(WindowsDebugger.CurrentProcess).Type;
- return AtomicType.IsAtomic(typeOfValue);
- }
}
}
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
index c962d91625..e880e3741e 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
@@ -2,6 +2,7 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System.Linq;
+using Debugger.AddIn.Visualizers.Graph;
using Debugger.Interop.CorDebug;
using System;
using System.Collections.Generic;
@@ -33,6 +34,24 @@ namespace Debugger.AddIn.Visualizers.Utils
return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.SingleItemList());
}
+ ///
+ /// Evaluates 'new List<T>(iEnumerableValue)' in the debuggee.
+ ///
+ public static Value CreateListFromIEnumerable(Value iEnumerableValue)
+ {
+ DebugType iEnumerableType, itemType;
+ if (!iEnumerableValue.Type.ResolveIEnumerableImplementation(out iEnumerableType, out itemType))
+ throw new GetValueException("Value is not IEnumerable");
+
+ DebugType listType = DebugType.CreateFromType(iEnumerableValue.AppDomain, typeof(System.Collections.Generic.List<>), itemType);
+ DebugConstructorInfo ctor = (DebugConstructorInfo)listType.GetConstructor(BindingFlags.Default, null, CallingConventions.Any, new System.Type[] { iEnumerableType }, null);
+ if (ctor == null)
+ throw new DebuggerException("List constructor not found");
+
+ // Keep reference since we do not want to keep reenumerating it
+ return Value.InvokeMethod(WindowsDebugger.EvalThread, null, ctor.MethodInfo, new Value[] { iEnumerableValue }).GetPermanentReferenceOfHeapValue();
+ }
+
///
/// Gets underlying address of object in the debuggee.
///
@@ -59,14 +78,6 @@ namespace Debugger.AddIn.Visualizers.Utils
return type.FullName == "System.Object";
}
- ///
- /// Evaluates expression and gets underlying address of object in the debuggee.
- ///
- public static ulong GetObjectAddress(this Expression expr)
- {
- return expr.Evaluate(WindowsDebugger.CurrentProcess).GetObjectAddress();
- }
-
///
/// System.Runtime.CompilerServices.GetHashCode method, for obtaining non-overriden hash codes from debuggee.
///
@@ -86,7 +97,7 @@ namespace Debugger.AddIn.Visualizers.Utils
throw new DebuggerException("Cannot obtain method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode");
}
}
- Value defaultHashCode = Eval.InvokeMethod(DebuggerHelpers.hashCodeMethod, null, new Value[]{value});
+ Value defaultHashCode = Eval.InvokeMethod(WindowsDebugger.EvalThread, DebuggerHelpers.hashCodeMethod, null, new Value[]{value});
//MethodInfo method = value.Type.GetMember("GetHashCode", BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo;
//string hashCode = value.InvokeMethod(method, null).AsString;
@@ -106,23 +117,34 @@ namespace Debugger.AddIn.Visualizers.Utils
}
}
- public static Value EvalPermanentReference(this Expression expr)
- {
- return expr.Evaluate(WindowsDebugger.CurrentProcess).GetPermanentReference();
- }
-
///
- /// Evaluates System.Collections.ICollection.Count property on given object.
+ /// Evaluates 'System.Collections.ICollection.Count' on given Value.
///
/// Evaluating System.Collections.ICollection.Count on targetObject failed.
- public static int GetIListCount(this Expression targetObject)
+ public static int GetIListCount(this Value list)
{
- Value list = targetObject.Evaluate(WindowsDebugger.CurrentProcess);
var iCollectionType = list.Type.GetInterface(typeof(System.Collections.ICollection).FullName);
if (iCollectionType == null)
- throw new GetValueException(targetObject, targetObject.PrettyPrint() + " does not implement System.Collections.ICollection");
+ throw new GetValueException("Object does not implement System.Collections.ICollection");
// Do not get string representation since it can be printed in hex
- return (int)list.GetPropertyValue(iCollectionType.GetProperty("Count")).PrimitiveValue;
+ return (int)list.GetPropertyValue(WindowsDebugger.EvalThread, iCollectionType.GetProperty("Count")).PrimitiveValue;
+ }
+
+ ///
+ /// Evaluates 'System.Collection.IList.Item(i)' on given Value.
+ ///
+ ///
+ ///
+ ///
+ public static Value GetIListItem(this Value target, int index)
+ {
+ var iListType = target.Type.GetInterface(typeof(System.Collections.IList).FullName);
+ if (iListType == null)
+ throw new GetValueException("Object does not implement System.Collections.IList");
+ DebugPropertyInfo indexerProperty = (DebugPropertyInfo)iListType.GetProperty("Item");
+ if (indexerProperty == null)
+ throw new GetValueException("The object does not have an indexer property");
+ return target.GetPropertyValue(WindowsDebugger.EvalThread, indexerProperty, Eval.CreateValue(WindowsDebugger.EvalThread, index));
}
///
diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/LinqUtils.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/LinqUtils.cs
index 1c8ad1ddef..07bab775c8 100644
--- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/LinqUtils.cs
+++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/LinqUtils.cs
@@ -7,9 +7,6 @@ using System;
namespace Debugger.AddIn.Visualizers.Utils
{
- ///
- /// Description of LinqUtils.
- ///
public static class LinqUtils
{
public static int MaxOrDefault(this IEnumerable source, Func selector, int defaultValue)
diff --git a/src/AddIns/Debugger/Debugger.Core/AppDomainCollection.cs b/src/AddIns/Debugger/Debugger.Core/AppDomainCollection.cs
deleted file mode 100644
index 19c92e40f6..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/AppDomainCollection.cs
+++ /dev/null
@@ -1,24 +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 Debugger.Interop.CorDebug;
-
-namespace Debugger
-{
- public class AppDomainCollection: CollectionWithEvents
- {
- public AppDomainCollection(NDebugger dbgr): base(dbgr) {}
-
- public AppDomain this[ICorDebugAppDomain corAppDomain] {
- get {
- foreach(AppDomain a in this) {
- if (a.CorAppDomain.Equals(corAppDomain)) {
- return a;
- }
- }
- throw new DebuggerException("AppDomain not found");
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs b/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
index bca887514f..56a4924610 100644
--- a/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
@@ -11,103 +11,43 @@ namespace Debugger
{
public class Breakpoint: DebuggerObject
{
- NDebugger debugger;
-
- string fileName;
- byte[] checkSum;
- int line;
- int column;
- bool enabled;
-
- SourcecodeSegment originalLocation;
-
+ bool enabled;
protected List corBreakpoints = new List();
- public event EventHandler Hit;
- public event EventHandler Set;
-
- [Debugger.Tests.Ignore]
- public NDebugger Debugger {
- get { return debugger; }
- protected set { debugger = value; }
- }
-
- public string FileName {
- get { return fileName; }
- }
-
- public byte[] CheckSum {
- get { return checkSum; }
- }
-
- public int Line {
- get { return line; }
- set { line = value; }
- }
+ public string FileName { get; private set; }
+ public int Line { get; set; }
+ public int Column { get; set; }
+ public SourcecodeSegment OriginalLocation { get; private set; }
- public int Column {
- get { return column; }
- }
-
- public bool Enabled {
+ public bool IsEnabled {
get { return enabled; }
set {
enabled = value;
foreach(ICorDebugFunctionBreakpoint corBreakpoint in corBreakpoints) {
- corBreakpoint.Activate(enabled ? 1 : 0);
+ try {
+ corBreakpoint.Activate(enabled ? 1 : 0);
+ } catch(COMException e) {
+ // Sometimes happens, but we had not repro yet.
+ // 0x80131301: Process was terminated.
+ if ((uint)e.ErrorCode == 0x80131301)
+ continue;
+ throw;
+ }
}
}
}
- public SourcecodeSegment OriginalLocation {
- get { return originalLocation; }
- }
-
public bool IsSet {
- get {
- return corBreakpoints.Count > 0;
- }
- }
-
- public string TypeName {
- get; protected set;
- }
-
- protected virtual void OnHit(BreakpointEventArgs e)
- {
- if (Hit != null) {
- Hit(this, e);
- }
- }
-
- internal void NotifyHit()
- {
- OnHit(new BreakpointEventArgs(this));
- debugger.Breakpoints.OnHit(this);
- }
-
- protected virtual void OnSet(BreakpointEventArgs e)
- {
- if (Set != null) {
- Set(this, e);
- }
+ get { return corBreakpoints.Count > 0; }
}
- public Breakpoint() { }
+ public string TypeName { get; protected set; }
- public Breakpoint(NDebugger debugger, ICorDebugFunctionBreakpoint corBreakpoint)
+ internal Breakpoint(string fileName, int line, int column, bool enabled)
{
- this.debugger = debugger;
- this.corBreakpoints.Add(corBreakpoint);
- }
-
- public Breakpoint(NDebugger debugger, string fileName, byte[] checkSum, int line, int column, bool enabled)
- {
- this.debugger = debugger;
- this.fileName = fileName;
- this.checkSum = checkSum;
- this.line = line;
- this.column = column;
+ this.FileName = fileName;
+ this.Line = line;
+ this.Column = column;
this.enabled = enabled;
}
@@ -119,70 +59,38 @@ namespace Debugger
return false;
}
- internal void Deactivate()
- {
- foreach(ICorDebugFunctionBreakpoint corBreakpoint in corBreakpoints) {
- #if DEBUG
- // Get repro
- corBreakpoint.Activate(0);
- #else
- try {
- corBreakpoint.Activate(0);
- } catch(COMException e) {
- // Sometimes happens, but we had not repro yet.
- // 0x80131301: Process was terminated.
- if ((uint)e.ErrorCode == 0x80131301)
- continue;
- throw;
- }
- #endif
- }
- corBreakpoints.Clear();
- }
-
- internal void MarkAsDeactivated()
+ internal void NotifyDebuggerTerminated()
{
corBreakpoints.Clear();
}
public virtual bool SetBreakpoint(Module module)
{
- if (this.fileName == null)
+ SourcecodeSegment segment = SourcecodeSegment.Resolve(module, FileName, Line, Column);
+ if (segment == null)
return false;
- SourcecodeSegment segment = SourcecodeSegment.Resolve(module, FileName, CheckSum, Line, Column);
- if (segment == null) return false;
-
- originalLocation = segment;
+ OriginalLocation = segment;
ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart);
corBreakpoint.Activate(enabled ? 1 : 0);
corBreakpoints.Add(corBreakpoint);
- OnSet(new BreakpointEventArgs(this));
-
return true;
}
-
- /// Remove this breakpoint
- public void Remove()
- {
- debugger.Breakpoints.Remove(this);
- }
}
public class ILBreakpoint : Breakpoint
{
- public ILBreakpoint(NDebugger debugger, string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled)
+ public ILBreakpoint(string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled)
+ : base(null, line, 0, enabled)
{
- this.Debugger = debugger;
- this.Line = line;
this.TypeName = typeName;
this.MetadataToken = metadataToken;
this.MemberMetadataToken = memberToken;
this.ILOffset = offset;
- this.Enabled = enabled;
+ this.IsEnabled = enabled;
}
public int MetadataToken { get; private set; }
@@ -193,36 +101,23 @@ namespace Debugger
public override bool SetBreakpoint(Module module)
{
+ var currentModuleTypes = module.GetNamesOfDefinedTypes();
+ // set the breakpoint only if the module contains the type
+ if (!currentModuleTypes.Contains(this.TypeName))
+ return false;
+
SourcecodeSegment segment = SourcecodeSegment.CreateForIL(module, this.Line, MemberMetadataToken, ILOffset);
if (segment == null)
return false;
try {
ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart);
- corBreakpoint.Activate(Enabled ? 1 : 0);
+ corBreakpoint.Activate(this.IsEnabled ? 1 : 0);
corBreakpoints.Add(corBreakpoint);
- OnSet(new BreakpointEventArgs(this));
return true;
- } catch
- #if DEBUG
- (System.Exception)
- #endif
- {
+ } catch {
return false;
}
}
}
-
- [Serializable]
- public class BreakpointEventArgs : DebuggerEventArgs
- {
- public Breakpoint Breakpoint {
- get; private set;
- }
-
- public BreakpointEventArgs(Breakpoint breakpoint): base(breakpoint.Debugger)
- {
- this.Breakpoint = breakpoint;
- }
- }
}
diff --git a/src/AddIns/Debugger/Debugger.Core/BreakpointCollection.cs b/src/AddIns/Debugger/Debugger.Core/BreakpointCollection.cs
deleted file mode 100644
index 0e114f5cd8..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/BreakpointCollection.cs
+++ /dev/null
@@ -1,102 +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 Debugger.Interop.CorDebug;
-
-namespace Debugger
-{
- public class BreakpointCollection: CollectionWithEvents
- {
- public event EventHandler> Hit;
-
- protected internal void OnHit(Breakpoint item)
- {
- if (Hit != null) {
- Hit(this, new CollectionItemEventArgs(item));
- }
- }
-
- public BreakpointCollection(NDebugger debugger):base(debugger) { }
-
- internal Breakpoint this[ICorDebugBreakpoint corBreakpoint] {
- get {
- foreach (Breakpoint breakpoint in this) {
- if (breakpoint.IsOwnerOf(corBreakpoint)) {
- return breakpoint;
- }
- }
- return null;
- }
- }
-
- public new void Add(Breakpoint breakpoint)
- {
- base.Add(breakpoint);
- }
-
- public Breakpoint Add(string filename, int line)
- {
- Breakpoint breakpoint = new Breakpoint(this.Debugger, filename, null, line, 0, true);
- Add(breakpoint);
- return breakpoint;
- }
-
- public Breakpoint Add(string fileName, byte[] checkSum, int line, int column, bool enabled)
- {
- Breakpoint breakpoint = new Breakpoint(this.Debugger, fileName, checkSum, line, column, enabled);
- Add(breakpoint);
- return breakpoint;
- }
-
- protected override void OnAdded(Breakpoint breakpoint)
- {
- foreach(Process process in this.Debugger.Processes) {
- foreach(Module module in process.Modules) {
- if (breakpoint is ILBreakpoint) {
- var currentModuleTypes = module.GetNamesOfDefinedTypes();
- // set the breakpoint only if the module contains the type
- if (!currentModuleTypes.Contains(breakpoint.TypeName))
- continue;
- }
- breakpoint.SetBreakpoint(module);
- }
- }
-
- base.OnAdded(breakpoint);
- }
-
- public new void Remove(Breakpoint breakpoint)
- {
- base.Remove(breakpoint);
- }
-
- protected override void OnRemoved(Breakpoint breakpoint)
- {
- breakpoint.Deactivate();
-
- base.OnRemoved(breakpoint);
- }
-
- internal void SetInModule(Module module)
- {
- // This is in case that the client modifies the collection as a response to set breakpoint
- // NB: If client adds new breakpoint, it will be set directly as a result of his call, not here (because module is already loaded)
- List collection = new List();
- collection.AddRange(this);
-
- var currentModuleTypes = module.GetNamesOfDefinedTypes();
- foreach (Breakpoint b in collection) {
- if (b is ILBreakpoint) {
- // set the breakpoint only if the module contains the type
- if (!currentModuleTypes.Contains(b.TypeName))
- continue;
- b.SetBreakpoint(module);
- } else {
- b.SetBreakpoint(module);
- }
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/CollectionWithEvents.cs b/src/AddIns/Debugger/Debugger.Core/CollectionWithEvents.cs
deleted file mode 100644
index 1a1715f113..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/CollectionWithEvents.cs
+++ /dev/null
@@ -1,109 +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;
-using System.Collections.Generic;
-
-namespace Debugger
-{
- public class CollectionItemEventArgs : EventArgs
- {
- T item;
-
- public T Item {
- get {
- return item;
- }
- }
-
- public CollectionItemEventArgs(T item)
- {
- this.item = item;
- }
- }
-
- ///
- /// A collection that fires events when items are added or removed.
- ///
- public class CollectionWithEvents : IEnumerable
- {
- NDebugger debugger;
-
- List list = new List();
-
- public event EventHandler> Added;
- public event EventHandler> Removed;
-
- protected virtual void OnAdded(T item)
- {
- if (Added != null) {
- Added(this, new CollectionItemEventArgs(item));
- }
- }
-
- protected virtual void OnRemoved(T item)
- {
- if (Removed != null) {
- Removed(this, new CollectionItemEventArgs(item));
- }
- }
-
- public CollectionWithEvents(NDebugger debugger)
- {
- this.debugger = debugger;
- }
-
- protected NDebugger Debugger {
- get {
- return debugger;
- }
- }
-
- public int Count {
- get {
- return list.Count;
- }
- }
-
- public T this[int index] {
- get {
- return list[index];
- }
- }
-
- internal void Add(T item)
- {
- list.Add(item);
- OnAdded(item);
- }
-
- internal void Remove(T item)
- {
- if (list.Remove(item)) {
- OnRemoved(item);
- } else {
- throw new DebuggerException("Item is not in the collection");
- }
- }
-
- internal void Clear()
- {
- List oldList = list;
- list = new List();
- foreach (T item in oldList) {
- OnRemoved(item);
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return list.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return list.GetEnumerator();
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/DebuggeeState.cs b/src/AddIns/Debugger/Debugger.Core/DebuggeeState.cs
deleted file mode 100644
index 179125c37b..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/DebuggeeState.cs
+++ /dev/null
@@ -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)
-
-namespace Debugger
-{
- ///
- /// Represents span of time in which the debugger state is assumed to
- /// be unchanged.
- ///
- ///
- /// For example, although property evaluation can in theory change
- /// any memory, it is assumed that they behave 'correctly' and thus
- /// property evaluation does not change debugger state.
- ///
- public class DebuggeeState: DebuggerObject
- {
- Process process;
-
- public Process Process {
- get { return process; }
- }
-
- public DebuggeeState(Process process)
- {
- this.process = process;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj b/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj
index d59af38cff..33ac0f2f23 100644
--- a/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj
+++ b/src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj
@@ -64,19 +64,12 @@
-
-
-
-
-
-
-
@@ -102,7 +95,6 @@
-
@@ -144,14 +136,8 @@
-
-
-
-
-
-
@@ -159,9 +145,7 @@
-
-
@@ -198,17 +182,7 @@
-
-
-
-
-
- {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}
- NRefactory
- False
-
-
\ No newline at end of file
diff --git a/src/AddIns/Debugger/Debugger.Core/DebuggerObject.cs b/src/AddIns/Debugger/Debugger.Core/DebuggerObject.cs
deleted file mode 100644
index 714ef27792..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/DebuggerObject.cs
+++ /dev/null
@@ -1,15 +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 Debugger
-{
- ///
- /// A base class for all classes declared by the debugger
- ///
- public class DebuggerObject: MarshalByRefObject
- {
-
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Eval.cs b/src/AddIns/Debugger/Debugger.Core/Eval.cs
index 4c70596375..7dae8165ed 100644
--- a/src/AddIns/Debugger/Debugger.Core/Eval.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Eval.cs
@@ -46,11 +46,11 @@ namespace Debugger
get { return description; }
}
- public ICorDebugEval CorEval {
+ internal ICorDebugEval CorEval {
get { return corEval; }
}
- public ICorDebugEval2 CorEval2 {
+ internal ICorDebugEval2 CorEval2 {
get { return (ICorDebugEval2)corEval; }
}
@@ -81,14 +81,25 @@ namespace Debugger
}
}
- Eval(AppDomain appDomain, string description, EvalStarter evalStarter)
+ Eval(Thread evalThread, string description, EvalStarter evalStarter)
{
- this.appDomain = appDomain;
+ if (evalThread == null)
+ throw new DebuggerException("No evaluation thread was provided");
+
+ this.appDomain = evalThread.AppDomain;
this.process = appDomain.Process;
this.description = description;
this.state = EvalState.Evaluating;
- this.thread = GetEvaluationThread(appDomain);
- this.corEval = thread.CorThread.CreateEval();
+ this.thread = evalThread;
+
+ if (evalThread.Suspended)
+ throw new GetValueException("Can not evaluate because thread is suspended");
+ if (evalThread.IsInNativeCode)
+ throw new GetValueException("Can not evaluate because thread is in native code");
+ if (!evalThread.IsAtSafePoint)
+ throw new GetValueException("Can not evaluate because thread is not at safe point");
+
+ this.corEval = evalThread.CorThread.CreateEval();
try {
evalStarter(this);
@@ -120,37 +131,14 @@ namespace Debugger
}
}
- appDomain.Process.ActiveEvals.Add(this);
+ appDomain.Process.activeEvals.Add(this);
if (appDomain.Process.Options.SuspendOtherThreads) {
- appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] { thread }, CorDebugThreadState.THREAD_SUSPEND);
+ appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] { evalThread }, CorDebugThreadState.THREAD_SUSPEND);
} else {
appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep, this.Process.UnsuspendedThreads, CorDebugThreadState.THREAD_RUN);
}
}
-
- static Thread GetEvaluationThread(AppDomain appDomain)
- {
- appDomain.Process.AssertPaused();
-
- Thread st = appDomain.Process.SelectedThread;
- if (st != null && !st.Suspended && !st.IsInNativeCode && st.IsAtSafePoint && st.CorThread.GetAppDomain().GetID() == appDomain.ID) {
- return st;
- }
-
- foreach(Thread t in appDomain.Process.Threads) {
- if (!t.Suspended && !t.IsInNativeCode && t.IsAtSafePoint && t.CorThread.GetAppDomain().GetID() == appDomain.ID) {
- return t;
- }
- }
-
- throw new GetValueException("No suitable thread for evaluation");
- }
-
- internal bool IsCorEval(ICorDebugEval corEval)
- {
- return this.corEval == corEval;
- }
/// Evaluation can not be stopped
/// Process exited
@@ -200,19 +188,19 @@ namespace Debugger
}
/// Synchronously calls a function and returns its return value
- public static Value InvokeMethod(DebugMethodInfo method, Value thisValue, Value[] args)
+ public static Value InvokeMethod(Thread evalThread, DebugMethodInfo method, Value thisValue, Value[] args)
{
if (method.BackingField != null) {
method.Process.TraceMessage("Using backing field for " + method.FullName);
- return Value.GetMemberValue(thisValue, method.BackingField, args);
+ return Value.GetMemberValue(evalThread, thisValue, method.BackingField, args);
}
- return AsyncInvokeMethod(method, thisValue, args).WaitForResult();
+ return AsyncInvokeMethod(evalThread, method, thisValue, args).WaitForResult();
}
- public static Eval AsyncInvokeMethod(DebugMethodInfo method, Value thisValue, Value[] args)
+ public static Eval AsyncInvokeMethod(Thread evalThread, DebugMethodInfo method, Value thisValue, Value[] args)
{
return new Eval(
- method.AppDomain,
+ evalThread,
"Function call: " + method.FullName,
delegate(Eval eval) {
MethodInvokeStarter(eval, method, thisValue, args);
@@ -246,19 +234,21 @@ namespace Debugger
Value arg = args[i];
DebugType paramType = (DebugType)method.GetParameters()[i].ParameterType;
if (!arg.Type.CanImplicitelyConvertTo(paramType))
- throw new GetValueException("Inncorrect parameter type");
+ throw new GetValueException("Inncorrect parameter type. Expected " + paramType.ToString());
// Implicitely convert to correct primitve type
if (paramType.IsPrimitive && args[i].Type != paramType) {
object oldPrimVal = arg.PrimitiveValue;
object newPrimVal = Convert.ChangeType(oldPrimVal, paramType.PrimitiveType);
- arg = CreateValue(method.AppDomain, newPrimVal);
+ // Eval - TODO: Is this dangerous?
+ arg = CreateValue(eval.thread, newPrimVal);
}
// It is importatnt to pass the parameted in the correct form (boxed/unboxed)
if (paramType.IsValueType) {
corArgs.Add(arg.CorGenericValue);
} else {
if (args[i].Type.IsValueType) {
- corArgs.Add(arg.Box().CorValue);
+ // Eval - TODO: Is this dangerous?
+ corArgs.Add(arg.Box(eval.thread).CorValue);
} else {
corArgs.Add(arg.CorValue);
}
@@ -272,25 +262,24 @@ namespace Debugger
(uint)corArgs.Count, corArgs.ToArray()
);
}
-
- public static Value CreateValue(AppDomain appDomain, object value)
- {
- if (value == null) {
- ICorDebugClass corClass = appDomain.ObjectType.CorType.GetClass();
- Thread thread = GetEvaluationThread(appDomain);
- ICorDebugEval corEval = thread.CorThread.CreateEval();
+
+ public static Value CreateValue(Thread evalThread, object value)
+ {
+ if (value == null) {
+ ICorDebugClass corClass = evalThread.AppDomain.ObjectType.CorType.GetClass();
+ ICorDebugEval corEval = evalThread.CorThread.CreateEval();
ICorDebugValue corValue = corEval.CreateValue((uint)CorElementType.CLASS, corClass);
- return new Value(appDomain, corValue);
+ return new Value(evalThread.AppDomain, corValue);
} else if (value is string) {
- return Eval.NewString(appDomain, (string)value);
+ return Eval.NewString(evalThread, (string)value);
} else {
- if (!value.GetType().IsPrimitive)
- throw new DebuggerException("Value must be primitve type. Seen " + value.GetType());
- Value val = Eval.NewObjectNoConstructor(DebugType.CreateFromType(appDomain.Mscorlib, value.GetType()));
- val.PrimitiveValue = value;
+ if (!value.GetType().IsPrimitive)
+ throw new DebuggerException("Value must be primitve type. Seen " + value.GetType());
+ Value val = Eval.NewObjectNoConstructor(evalThread, DebugType.CreateFromType(evalThread.AppDomain.Mscorlib, value.GetType()));
+ val.SetPrimitiveValue(evalThread, value);
return val;
}
- }
+ }
/*
// The following function create values only for the purpuse of evalutaion
@@ -318,19 +307,15 @@ namespace Debugger
}
*/
- #region Convenience methods
-
- public static Value NewString(AppDomain appDomain, string textToCreate)
+ public static Value NewString(Thread evalThread, string textToCreate)
{
- return AsyncNewString(appDomain, textToCreate).WaitForResult();
+ return AsyncNewString(evalThread, textToCreate).WaitForResult();
}
- #endregion
-
- public static Eval AsyncNewString(AppDomain appDomain, string textToCreate)
+ public static Eval AsyncNewString(Thread evalThread, string textToCreate)
{
return new Eval(
- appDomain,
+ evalThread,
"New string: " + textToCreate,
delegate(Eval eval) {
eval.CorEval2.NewStringWithLength(textToCreate, (uint)textToCreate.Length);
@@ -338,20 +323,16 @@ namespace Debugger
);
}
- #region Convenience methods
-
- public static Value NewArray(DebugType type, uint length, uint? lowerBound)
+ public static Value NewArray(Thread evalThread, DebugType type, uint length, uint? lowerBound)
{
- return AsyncNewArray(type, length, lowerBound).WaitForResult();
+ return AsyncNewArray(evalThread, type, length, lowerBound).WaitForResult();
}
- #endregion
-
- public static Eval AsyncNewArray(DebugType type, uint length, uint? lowerBound)
+ public static Eval AsyncNewArray(Thread evalThread, DebugType type, uint length, uint? lowerBound)
{
lowerBound = lowerBound ?? 0;
return new Eval(
- type.AppDomain,
+ evalThread,
"New array: " + type + "[" + length + "]",
delegate(Eval eval) {
// Multi-dimensional arrays not supported in .NET 2.0
@@ -360,43 +341,37 @@ namespace Debugger
);
}
- #region Convenience methods
-
- public static Value NewObject(DebugMethodInfo constructor, Value[] constructorArguments)
+ public static Value NewObject(Thread evalThread, DebugMethodInfo constructor, Value[] constructorArguments)
{
- return AsyncNewObject(constructor, constructorArguments).WaitForResult();
+ return AsyncNewObject(evalThread, constructor, constructorArguments).WaitForResult();
}
- #endregion
-
- public static Eval AsyncNewObject(DebugMethodInfo constructor, Value[] constructorArguments)
+ public static Eval AsyncNewObject(Thread evalThread, DebugMethodInfo constructor, Value[] constructorArguments)
{
ICorDebugValue[] constructorArgsCorDebug = ValuesAsCorDebug(constructorArguments);
return new Eval(
- constructor.AppDomain,
+ evalThread,
"New object: " + constructor.FullName,
delegate(Eval eval) {
eval.CorEval2.NewParameterizedObject(
constructor.CorFunction,
- (uint)constructor.DeclaringType.GetGenericArguments().Length, ((DebugType)constructor.DeclaringType).GenericArgumentsAsCorDebugType,
- (uint)constructorArgsCorDebug.Length, constructorArgsCorDebug);
+ (uint)constructor.DeclaringType.GetGenericArguments().Length,
+ ((DebugType)constructor.DeclaringType).GenericArgumentsAsCorDebugType,
+ (uint)constructorArgsCorDebug.Length,
+ constructorArgsCorDebug);
}
);
}
- #region Convenience methods
-
- public static Value NewObjectNoConstructor(DebugType debugType)
+ public static Value NewObjectNoConstructor(Thread evalThread, DebugType debugType)
{
- return AsyncNewObjectNoConstructor(debugType).WaitForResult();
+ return AsyncNewObjectNoConstructor(evalThread, debugType).WaitForResult();
}
- #endregion
-
- public static Eval AsyncNewObjectNoConstructor(DebugType debugType)
+ public static Eval AsyncNewObjectNoConstructor(Thread evalThread, DebugType debugType)
{
return new Eval(
- debugType.AppDomain,
+ evalThread,
"New object: " + debugType.FullName,
delegate(Eval eval) {
eval.CorEval2.NewParameterizedObjectNoConstructor(debugType.CorType.GetClass(), (uint)debugType.GetGenericArguments().Length, debugType.GenericArgumentsAsCorDebugType);
diff --git a/src/AddIns/Debugger/Debugger.Core/EvalCollection.cs b/src/AddIns/Debugger/Debugger.Core/EvalCollection.cs
deleted file mode 100644
index 6004c9dabd..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/EvalCollection.cs
+++ /dev/null
@@ -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 Debugger.Interop.CorDebug;
-
-namespace Debugger
-{
- public class EvalCollection: CollectionWithEvents
- {
- public EvalCollection(NDebugger debugger): base(debugger) {}
-
- internal Eval this[ICorDebugEval corEval] {
- get {
- foreach(Eval eval in this) {
- if (eval.IsCorEval(corEval)) {
- return eval;
- }
- }
- throw new DebuggerException("Eval not found for given ICorDebugEval");
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Exception.cs b/src/AddIns/Debugger/Debugger.Core/Exception.cs
index ee75897de2..6486f4ba3e 100644
--- a/src/AddIns/Debugger/Debugger.Core/Exception.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Exception.cs
@@ -4,7 +4,15 @@
using System.Text;
namespace Debugger
-{
+{
+ enum ExceptionType
+ {
+ FirstChance = 1,
+ UserFirstChance = 2,
+ CatchHandlerFound = 3,
+ Unhandled = 4,
+ }
+
/// This convenience class provides access to an exception within the debugee.
///
public class Exception: DebuggerObject
@@ -15,9 +23,16 @@ namespace Debugger
get { return exception; }
}
- public Exception(Value exception)
+ ExceptionType ExceptionType { get; set; }
+
+ public bool IsUnhandled {
+ get { return this.ExceptionType == ExceptionType.Unhandled; }
+ }
+
+ internal Exception(Value exception, ExceptionType exceptionType)
{
this.exception = exception;
+ this.ExceptionType = exceptionType;
}
/// The GetType().FullName of the exception.
@@ -32,7 +47,7 @@ namespace Debugger
///
public string Message {
get {
- Value message = exception.GetMemberValue("_message");
+ Value message = exception.GetFieldValue("_message");
return message.IsNull ? string.Empty : message.AsString();
}
}
@@ -41,14 +56,14 @@ namespace Debugger
///
public Exception InnerException {
get {
- Value innerException = exception.GetMemberValue("_innerException");
- return innerException.IsNull ? null : new Exception(innerException);
+ Value innerException = exception.GetFieldValue("_innerException");
+ return innerException.IsNull ? null : new Exception(innerException, this.ExceptionType);
}
}
public void MakeValuePermanent()
{
- exception = exception.GetPermanentReference();
+ exception = exception.GetPermanentReferenceOfHeapValue();
}
public override string ToString()
@@ -66,25 +81,25 @@ namespace Debugger
return sb.ToString();
}
- public string GetStackTrace()
+ public string GetStackTrace(Thread evalThread)
{
- return GetStackTrace("--- End of inner exception stack trace ---");
+ return GetStackTrace(evalThread, "--- End of inner exception stack trace ---");
}
/// Returs formated stacktrace for the exception
/// Getting the stacktrace involves property
/// evaluation so GetValueException can be thrown in some cicumstances.
- public string GetStackTrace(string endOfInnerExceptionFormat)
+ public string GetStackTrace(Thread evalThread, string endOfInnerExceptionFormat)
{
StringBuilder sb = new StringBuilder();
if (this.InnerException != null) {
- sb.Append(this.InnerException.GetStackTrace(endOfInnerExceptionFormat));
+ sb.Append(this.InnerException.GetStackTrace(evalThread, endOfInnerExceptionFormat));
sb.Append(" ");
sb.Append(endOfInnerExceptionFormat);
sb.AppendLine();
}
// Note that evaluation is not possible after a stackoverflow exception
- Value stackTrace = exception.GetMemberValue("StackTrace");
+ Value stackTrace = exception.GetMemberValue(evalThread, "StackTrace");
if (!stackTrace.IsNull) {
sb.Append(stackTrace.AsString());
sb.AppendLine();
@@ -92,30 +107,4 @@ namespace Debugger
return sb.ToString();
}
}
-
- public class ExceptionEventArgs: ProcessEventArgs
- {
- readonly Exception exception;
- readonly ExceptionType exceptionType;
- readonly bool isUnhandled;
-
- public Exception Exception {
- get { return exception; }
- }
-
- public ExceptionType ExceptionType {
- get { return exceptionType; }
- }
-
- public bool IsUnhandled {
- get { return isUnhandled; }
- }
-
- public ExceptionEventArgs(Process process, Exception exception, ExceptionType exceptionType, bool isUnhandled):base(process)
- {
- this.exception = exception;
- this.exceptionType = exceptionType;
- this.isUnhandled = isUnhandled;
- }
- }
}
diff --git a/src/AddIns/Debugger/Debugger.Core/ExceptionType.cs b/src/AddIns/Debugger/Debugger.Core/ExceptionType.cs
deleted file mode 100644
index 287bcf31d1..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/ExceptionType.cs
+++ /dev/null
@@ -1,13 +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)
-
-namespace Debugger
-{
- public enum ExceptionType
- {
- FirstChance = 1,
- UserFirstChance = 2,
- CatchHandlerFound = 3,
- Unhandled = 4,
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/GetValueException.cs b/src/AddIns/Debugger/Debugger.Core/GetValueException.cs
index a1adb2fa4f..0183d9d199 100644
--- a/src/AddIns/Debugger/Debugger.Core/GetValueException.cs
+++ b/src/AddIns/Debugger/Debugger.Core/GetValueException.cs
@@ -2,55 +2,21 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
-using ICSharpCode.NRefactory.Ast;
namespace Debugger
{
public class GetValueException: DebuggerException
{
- INode expression;
- string error;
-
- /// Expression that has caused this exception to occur
- public INode Expression {
- get { return expression; }
- set { expression = value; }
- }
-
- public string Error {
- get { return error; }
- }
-
- public override string Message {
- get {
- if (expression == null) {
- return error;
- } else {
- return error;
- // return String.Format("Error evaluating \"{0}\": {1}", expression.PrettyPrint(), error);
- }
- }
- }
-
- public GetValueException(INode expression, string error):base(error)
- {
- this.expression = expression;
- this.error = error;
- }
-
public GetValueException(string error, System.Exception inner):base(error, inner)
{
- this.error = error;
}
public GetValueException(string errorFmt, params object[] args):base(string.Format(errorFmt, args))
{
- this.error = string.Format(errorFmt, args);
}
public GetValueException(string error):base(error)
{
- this.error = error;
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs b/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs
index 5c9e6c2d8d..54b585701d 100644
--- a/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs
@@ -12,89 +12,6 @@ using Debugger.Interop.CorDebug;
namespace Debugger.Interop
{
- [StructLayout(LayoutKind.Sequential)]
- public struct MEMORY_BASIC_INFORMATION
- {
- public IntPtr BaseAddress;
- public IntPtr AllocationBase;
- public uint AllocationProtect;
- public IntPtr RegionSize;
- public uint State;
- public uint Protect;
- public uint Type;
- }
-
- [Flags]
- public enum ProcessAccessFlags : uint
- {
- All = 0x001F0FFF,
- Terminate = 0x00000001,
- CreateThread = 0x00000002,
- VMOperation = 0x00000008,
- VMRead = 0x00000010,
- VMWrite = 0x00000020,
- DupHandle = 0x00000040,
- SetInformation = 0x00000200,
- QueryInformation = 0x00000400,
- Synchronize = 0x00100000
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public struct SYSTEM_INFO
- {
- internal _PROCESSOR_INFO_UNION uProcessorInfo;
- public uint dwPageSize;
- public IntPtr lpMinimumApplicationAddress;
- public IntPtr lpMaximumApplicationAddress;
- public IntPtr dwActiveProcessorMask;
- public uint dwNumberOfProcessors;
- public uint dwProcessorType;
- public uint dwAllocationGranularity;
- public ushort dwProcessorLevel;
- public ushort dwProcessorRevision;
- }
-
- [StructLayout(LayoutKind.Explicit)]
- public struct _PROCESSOR_INFO_UNION
- {
- [FieldOffset(0)]
- internal uint dwOemId;
- [FieldOffset(0)]
- internal ushort wProcessorArchitecture;
- [FieldOffset(2)]
- internal ushort wReserved;
- }
-
- [Flags]
- public enum AllocationType
- {
- Commit = 0x1000,
- Reserve = 0x2000,
- Decommit = 0x4000,
- Release = 0x8000,
- Reset = 0x80000,
- Physical = 0x400000,
- TopDown = 0x100000,
- WriteWatch = 0x200000,
- LargePages = 0x20000000
- }
-
- [Flags]
- public enum MemoryProtection
- {
- Execute = 0x10,
- ExecuteRead = 0x20,
- ExecuteReadWrite = 0x40,
- ExecuteWriteCopy = 0x80,
- NoAccess = 0x01,
- ReadOnly = 0x02,
- ReadWrite = 0x04,
- WriteCopy = 0x08,
- GuardModifierflag = 0x100,
- NoCacheModifierflag = 0x200,
- WriteCombineModifierflag = 0x400
- }
-
public static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
@@ -108,88 +25,6 @@ namespace Debugger.Interop
[DllImport("mscoree.dll", CharSet=CharSet.Unicode)]
public static extern int GetRequestedRuntimeVersion(string exeFilename, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pVersion, Int32 cchBuffer, out Int32 dwLength);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool VirtualQueryEx(IntPtr hProcess,
- IntPtr lpAddress,
- out MEMORY_BASIC_INFORMATION lpBuffer,
- uint dwLength);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress,
- UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool ReadProcessMemory(
- IntPtr hProcess,
- IntPtr lpBaseAddress,
- [Out] byte[] lpBuffer,
- int dwSize,
- out int lpNumberOfBytesRead
- );
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
-
- public static List> GetVirtualMemoryAddresses(this Process process)
- {
- var result = new List>();
- SYSTEM_INFO sysinfo = new SYSTEM_INFO();
- GetSystemInfo(out sysinfo);
-
- long address = 0;
- MEMORY_BASIC_INFORMATION m = new MEMORY_BASIC_INFORMATION();
- IntPtr openedProcess = IntPtr.Zero;
- try {
- openedProcess = OpenProcess(ProcessAccessFlags.All, false, (int)process.Id);
-
- while (address < sysinfo.lpMaximumApplicationAddress.ToInt64())
- {
- try {
- if (!VirtualQueryEx(openedProcess, new IntPtr(address), out m, (uint)Marshal.SizeOf(m)))
- continue;
- } finally {
- // next address
- address = m.BaseAddress.ToInt64() + m.RegionSize.ToInt64();
- }
-
- result.Add(new Tuple(m.BaseAddress.ToInt64(), m.RegionSize.ToInt64()));
- }
- } finally {
- if (openedProcess != IntPtr.Zero)
- CloseHandle(openedProcess);
- }
-
- return result;
- }
-
- public static byte[] ReadProcessMemory(this Process process, long startAddress, long size)
- {
- IntPtr openedProcess = IntPtr.Zero;
- byte[] temp = null;
- try {
- temp = new byte[size];
- openedProcess = OpenProcess(ProcessAccessFlags.All, false, (int)process.Id);
-
- int outSize;
- bool success = ReadProcessMemory(openedProcess, new IntPtr(startAddress), temp, temp.Length, out outSize);
-
- if (!success || outSize == 0) {
- var proc = System.Diagnostics.Process.GetProcessById((int)process.Id);
- return process.ReadProcessMemory(proc.MainModule.BaseAddress.ToInt64(), (long)4096);
- }
- } catch {
- return null;
- } finally {
- if (openedProcess != IntPtr.Zero)
- CloseHandle(openedProcess);
- }
-
- return temp;
- }
}
}
diff --git a/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs b/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs
index 7842aa06fa..a598cfbdd9 100644
--- a/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs
+++ b/src/AddIns/Debugger/Debugger.Core/ManagedCallback.cs
@@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Debugger.Interop;
@@ -22,7 +23,12 @@ namespace Debugger
{
Process process;
bool pauseOnNextExit;
- bool isInCallback = false;
+ bool raiseEventsOnNextExit;
+ bool isInCallback;
+
+ Thread threadToReport;
+ List breakpointsHit = new List();
+ Exception exceptionThrown;
[Debugger.Tests.Ignore]
public Process Process {
@@ -38,7 +44,7 @@ namespace Debugger
this.process = process;
}
- void EnterCallback(PausedReason pausedReason, string name, ICorDebugProcess pProcess)
+ void EnterCallback(string name, ICorDebugProcess pProcess)
{
isInCallback = true;
@@ -46,35 +52,32 @@ namespace Debugger
System.Diagnostics.Debug.Assert(process.CorProcess == pProcess);
// After break is pressed we may receive some messages that were already queued
- if (process.IsPaused && process.PauseSession.PausedReason == PausedReason.ForcedBreak) {
- // TODO: This does not work well if exception if being processed and the user continues it
+ if (process.IsPaused) {
process.TraceMessage("Processing post-break callback");
- // This compensates for the break call and we are in normal callback handling mode
+ // Decrese the "break count" from 2 to 1 - does not actually continue
process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] {}, null);
- // Start of call back - create new pause session (as usual)
- process.NotifyPaused(pausedReason);
- // Make sure we stay pause after the callback is handled
+ // Make sure we stay pauses after the callback is handled
pauseOnNextExit = true;
return;
}
if (process.IsRunning) {
- process.NotifyPaused(pausedReason);
+ process.NotifyPaused();
return;
}
throw new DebuggerException("Invalid state at the start of callback");
}
- void EnterCallback(PausedReason pausedReason, string name, ICorDebugAppDomain pAppDomain)
+ void EnterCallback(string name, ICorDebugAppDomain pAppDomain)
{
- EnterCallback(pausedReason, name, pAppDomain.GetProcess());
+ EnterCallback(name, pAppDomain.GetProcess());
}
- void EnterCallback(PausedReason pausedReason, string name, ICorDebugThread pThread)
+ void EnterCallback(string name, ICorDebugThread pThread)
{
- EnterCallback(pausedReason, name, pThread.GetProcess());
- process.SelectedThread = process.GetThread(pThread);
+ EnterCallback(name, pThread.GetProcess());
+ threadToReport = process.GetThread(pThread);
}
void ExitCallback()
@@ -83,10 +86,8 @@ namespace Debugger
if (hasQueuedCallbacks)
process.TraceMessage("Process has queued callbacks");
- // only process callbacks if no exception occurred
- // if no thread is selected CurrentException must be null
- if (hasQueuedCallbacks && (process.SelectedThread == null || process.SelectedThread.CurrentException == null)) {
- // Exception has Exception2 queued after it
+ if (hasQueuedCallbacks && exceptionThrown == null) {
+ // Process queued callbacks if no exception occurred
process.AsyncContinue(DebuggeeStateAction.Keep, null, null);
} else if (process.Evaluating) {
// Ignore events during property evaluation
@@ -94,8 +95,25 @@ namespace Debugger
} else if (pauseOnNextExit) {
if (process.Options.Verbose)
process.TraceMessage("Callback exit: Paused");
+
+ process.DisableAllSteppers();
+ if (raiseEventsOnNextExit) {
+ DebuggerEventArgs e = new DebuggerEventArgs();
+ e.Process = process;
+ e.Thread = threadToReport;
+ e.BreakpointsHit = breakpointsHit.ToArray();
+ e.ExceptionThrown = exceptionThrown;
+ threadToReport = null;
+ breakpointsHit.Clear();
+ exceptionThrown = null;
+
+ // Raise the pause event outside the callback
+ // Warning: Make sure that process in not resumed in the meantime
+ process.Debugger.MTA2STA.AsyncCall(delegate { process.OnPaused(e); });
+ }
+
pauseOnNextExit = false;
- Pause();
+ raiseEventsOnNextExit = false;
} else {
process.AsyncContinue(DebuggeeStateAction.Keep, null, null);
}
@@ -103,35 +121,16 @@ namespace Debugger
isInCallback = false;
}
- void Pause()
- {
- if (process.PauseSession.PausedReason == PausedReason.EvalComplete ||
- process.PauseSession.PausedReason == PausedReason.ExceptionIntercepted) {
- // TODO: There might be qued callback after EvalComplete making this unrealiable
- process.DisableAllSteppers();
- process.CheckSelectedStackFrames();
- // Do not set selected stack frame
- // Do not raise events
- } else {
- // Raise the pause event outside the callback
- // Warning: Make sure that process in not resumed in the meantime
- process.Debugger.MTA2STA.AsyncCall(process.RaisePausedEvents);
-
- // The event might probably get called out of order when the process is running again
- }
- }
-
-
#region Program folow control
public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugStepper pStepper, CorDebugStepReason reason)
{
- EnterCallback(PausedReason.StepComplete, "StepComplete (" + reason.ToString() + ")", pThread);
+ EnterCallback("StepComplete (" + reason.ToString() + ")", pThread);
Thread thread = process.GetThread(pThread);
Stepper stepper = process.GetStepper(pStepper);
- StackFrame currentStackFrame = process.SelectedThread.MostRecentStackFrame;
+ StackFrame currentStackFrame = thread.MostRecentStackFrame;
process.TraceMessage(" - stopped at {0} because of {1}", currentStackFrame.MethodInfo.FullName, stepper.ToString());
process.Steppers.Remove(stepper);
@@ -158,6 +157,7 @@ namespace Debugger
} else {
// User-code method
pauseOnNextExit = true;
+ raiseEventsOnNextExit = true;
process.TraceMessage(" - pausing in user code");
}
@@ -167,37 +167,42 @@ namespace Debugger
// Warning! Marshaing of ICorBreakpoint fails in .NET 1.1
public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint corBreakpoint)
{
- EnterCallback(PausedReason.Breakpoint, "Breakpoint", pThread);
+ EnterCallback("Breakpoint", pThread);
- Breakpoint breakpoint = process.Debugger.Breakpoints[corBreakpoint];
- // The event will be risen outside the callback
- process.BreakpointHitEventQueue.Enqueue(breakpoint);
+ Breakpoint breakpoint = process.Debugger.GetBreakpoint(corBreakpoint);
+ // Could be tempBreakpoint
+ if (breakpoint != null) {
+ breakpointsHit.Add(breakpoint);
+ }
pauseOnNextExit = true;
+ raiseEventsOnNextExit = true;
ExitCallback();
}
public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint pBreakpoint, uint dwError)
{
- EnterCallback(PausedReason.Other, "BreakpointSetError", pThread);
+ EnterCallback("BreakpointSetError", pThread);
ExitCallback();
}
public void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
{
- EnterCallback(PausedReason.Break, "Break", pThread);
+ EnterCallback("Break", pThread);
pauseOnNextExit = true;
+ raiseEventsOnNextExit = true;
ExitCallback();
}
public void ControlCTrap(ICorDebugProcess pProcess)
{
- EnterCallback(PausedReason.ControlCTrap, "ControlCTrap", pProcess);
+ EnterCallback("ControlCTrap", pProcess);
pauseOnNextExit = true;
+ raiseEventsOnNextExit = true;
ExitCallback();
}
@@ -211,7 +216,7 @@ namespace Debugger
Exception2(pAppDomain, pThread, null, 0, (CorDebugExceptionCallbackType)exceptionType, 0);
} else {
// This callback should be ignored in v2 applications
- EnterCallback(PausedReason.Other, "Exception", pThread);
+ EnterCallback("Exception", pThread);
ExitCallback();
}
@@ -223,14 +228,14 @@ namespace Debugger
public void LogSwitch(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, uint ulReason, string pLogSwitchName, string pParentName)
{
- EnterCallback(PausedReason.Other, "LogSwitch", pThread);
+ EnterCallback("LogSwitch", pThread);
ExitCallback();
}
public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage)
{
- EnterCallback(PausedReason.Other, "LogMessage", pThread);
+ EnterCallback("LogMessage", pThread);
process.OnLogMessage(new MessageEventArgs(process, lLevel, pMessage, pLogSwitchName));
@@ -239,21 +244,21 @@ namespace Debugger
public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate)
{
- EnterCallback(PausedReason.Other, "EditAndContinueRemap", pThread);
+ EnterCallback("EditAndContinueRemap", pThread);
ExitCallback();
}
public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval)
{
- EnterCallback(PausedReason.EvalComplete, "EvalException", pThread);
+ EnterCallback("EvalException (" + process.GetActiveEval(corEval).Description + ")", pThread);
HandleEvalComplete(pAppDomain, pThread, corEval, true);
}
public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval)
{
- EnterCallback(PausedReason.EvalComplete, "EvalComplete", pThread);
+ EnterCallback("EvalComplete (" + process.GetActiveEval(corEval).Description + ")", pThread);
HandleEvalComplete(pAppDomain, pThread, corEval, false);
}
@@ -261,9 +266,9 @@ namespace Debugger
void HandleEvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval, bool exception)
{
// Let the eval know that the CorEval has finished
- Eval eval = process.ActiveEvals[corEval];
+ Eval eval = process.GetActiveEval(corEval);
eval.NotifyEvaluationComplete(!exception);
- process.ActiveEvals.Remove(eval);
+ process.activeEvals.Remove(eval);
pauseOnNextExit = true;
ExitCallback();
@@ -271,7 +276,7 @@ namespace Debugger
public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode)
{
- EnterCallback(PausedReason.DebuggerError, "DebuggerError", pProcess);
+ EnterCallback("DebuggerError", pProcess);
string errorText = String.Format("Debugger error: \nHR = 0x{0:X} \nCode = 0x{1:X}", errorHR, errorCode);
@@ -288,6 +293,7 @@ namespace Debugger
try {
pauseOnNextExit = true;
+ raiseEventsOnNextExit = true;
ExitCallback();
} catch (COMException) {
} catch (InvalidComObjectException) {
@@ -297,9 +303,9 @@ namespace Debugger
public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, IStream pSymbolStream)
{
- EnterCallback(PausedReason.Other, "UpdateModuleSymbols", pAppDomain);
+ EnterCallback("UpdateModuleSymbols", pAppDomain);
- Module module = process.Modules[pModule];
+ Module module = process.GetModule(pModule);
if (module.CorModule is ICorDebugModule3 && module.IsDynamic) {
// In .NET 4.0, we use the LoadClass callback to load dynamic modules
// because it always works - UpdateModuleSymbols does not.
@@ -320,7 +326,7 @@ namespace Debugger
public void CreateProcess(ICorDebugProcess pProcess)
{
- EnterCallback(PausedReason.Other, "CreateProcess", pProcess);
+ EnterCallback("CreateProcess", pProcess);
// Process is added in NDebugger.Start
// disable NGen
@@ -340,27 +346,28 @@ namespace Debugger
public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
{
- EnterCallback(PausedReason.Other, "CreateAppDomain", pAppDomain);
+ EnterCallback("CreateAppDomain", pAppDomain);
pAppDomain.Attach();
- process.AppDomains.Add(new AppDomain(process, pAppDomain));
+ process.appDomains.Add(new AppDomain(process, pAppDomain));
ExitCallback();
}
public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
{
- EnterCallback(PausedReason.Other, "LoadAssembly", pAppDomain);
+ EnterCallback("LoadAssembly", pAppDomain);
ExitCallback();
}
public void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
{
- EnterCallback(PausedReason.Other, "LoadModule " + pModule.GetName(), pAppDomain);
+ EnterCallback("LoadModule " + pModule.GetName(), pAppDomain);
- Module module = new Module(process.AppDomains[pAppDomain], pModule);
- process.Modules.Add(module);
+ Module module = new Module(process.GetAppDomain(pAppDomain), pModule);
+ process.modules.Add(module);
+ process.OnModuleLoaded(module);
ExitCallback();
}
@@ -369,17 +376,14 @@ namespace Debugger
{
if (pAppDomain != null) {
- EnterCallback(PausedReason.Other, "NameChange: pAppDomain", pAppDomain);
+ EnterCallback("NameChange: pAppDomain", pAppDomain);
ExitCallback();
}
if (pThread != null) {
- EnterCallback(PausedReason.Other, "NameChange: pThread", pThread);
-
- Thread thread = process.GetThread(pThread);
- thread.NotifyNameChanged();
+ EnterCallback("NameChange: pThread", pThread);
ExitCallback();
@@ -390,10 +394,10 @@ namespace Debugger
{
// We can not use pThread since it has not been added yet
// and we continue from this callback anyway
- EnterCallback(PausedReason.Other, "CreateThread " + pThread.GetID(), pAppDomain);
+ EnterCallback("CreateThread " + pThread.GetID(), pAppDomain);
Thread thread = new Thread(process, pThread);
- process.Threads.Add(thread);
+ process.threads.Add(thread);
thread.CorThread.SetDebugState(process.NewThreadState);
@@ -402,9 +406,9 @@ namespace Debugger
public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
{
- EnterCallback(PausedReason.Other, "LoadClass", pAppDomain);
+ EnterCallback("LoadClass", pAppDomain);
- Module module = process.Modules[c.GetModule()];
+ Module module = process.GetModule(c.GetModule());
// Dynamic module has been extended - reload symbols to inlude new class
module.LoadSymbolsDynamic();
@@ -418,36 +422,40 @@ namespace Debugger
public void UnloadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c)
{
- EnterCallback(PausedReason.Other, "UnloadClass", pAppDomain);
+ EnterCallback("UnloadClass", pAppDomain);
ExitCallback();
}
public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule)
{
- EnterCallback(PausedReason.Other, "UnloadModule", pAppDomain);
+ EnterCallback("UnloadModule", pAppDomain);
- process.Modules.Remove(process.Modules[pModule]);
+ Module module = process.GetModule(pModule);
+ process.modules.Remove(module);
+ process.OnModuleUnloaded(module);
ExitCallback();
}
public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly)
{
- EnterCallback(PausedReason.Other, "UnloadAssembly", pAppDomain);
+ EnterCallback("UnloadAssembly", pAppDomain);
ExitCallback();
}
public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread)
{
+ Thread thread = process.GetThread(pThread);
+
// ICorDebugThread is still not dead and can be used for some operations
- if (process.Threads.Contains(pThread)) {
- EnterCallback(PausedReason.Other, "ExitThread " + pThread.GetID(), pThread);
+ if (thread != null) {
+ EnterCallback("ExitThread " + pThread.GetID(), pThread);
- process.GetThread(pThread).NotifyExited();
+ thread.NotifyExited();
} else {
- EnterCallback(PausedReason.Other, "ExitThread " + pThread.GetID(), process.CorProcess);
+ EnterCallback("ExitThread " + pThread.GetID(), process.CorProcess);
// .NET 4.0 - It seems that the API is reporting exits of threads without announcing their creation.
// TODO: Remove in next .NET 4.0 beta and investigate
@@ -464,9 +472,9 @@ namespace Debugger
public void ExitAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain)
{
- EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain);
+ EnterCallback("ExitAppDomain", pAppDomain);
- process.AppDomains.Remove(process.AppDomains[pAppDomain]);
+ process.appDomains.Remove(process.GetAppDomain(pAppDomain));
ExitCallback();
}
@@ -476,7 +484,7 @@ namespace Debugger
// ExitProcess may be called at any time when debuggee is killed
process.TraceMessage("Callback: ExitProcess");
- process.NotifyHasExited();
+ process.OnExited();
}
#endregion
@@ -485,28 +493,28 @@ namespace Debugger
public void ChangeConnection(ICorDebugProcess pProcess, uint dwConnectionId)
{
- EnterCallback(PausedReason.Other, "ChangeConnection", pProcess);
+ EnterCallback("ChangeConnection", pProcess);
ExitCallback();
}
public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, IntPtr pConnName)
{
- EnterCallback(PausedReason.Other, "CreateConnection", pProcess);
+ EnterCallback("CreateConnection", pProcess);
ExitCallback();
}
public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId)
{
- EnterCallback(PausedReason.Other, "DestroyConnection", pProcess);
+ EnterCallback("DestroyConnection", pProcess);
ExitCallback();
}
public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType _exceptionType, uint dwFlags)
{
- EnterCallback(PausedReason.Exception, "Exception2 (type=" + _exceptionType.ToString() + ")", pThread);
+ EnterCallback("Exception2 (type=" + _exceptionType.ToString() + ")", pThread);
// This callback is also called from Exception(...)!!!! (the .NET 1.1 version)
// Watch out for the zeros and null!
@@ -518,13 +526,12 @@ namespace Debugger
if (exceptionType == ExceptionType.Unhandled || (pauseOnHandled && exceptionType == ExceptionType.CatchHandlerFound)) {
// sanity check: we can only handle one exception after another
// TODO : create Exception queue if CLR throws multiple exceptions
- Debug.Assert(process.SelectedThread.CurrentException == null);
- process.SelectedThread.CurrentException = new Exception(new Value(process.AppDomains[pAppDomain], process.SelectedThread.CorThread.GetCurrentException()).GetPermanentReference());
- process.SelectedThread.CurrentException_DebuggeeState = process.DebuggeeState;
- process.SelectedThread.CurrentExceptionType = exceptionType;
- process.SelectedThread.CurrentExceptionIsUnhandled = exceptionType == ExceptionType.Unhandled;
+ Debug.Assert(exceptionThrown == null);
+ Value value = new Value(process.GetAppDomain(pAppDomain), pThread.GetCurrentException()).GetPermanentReferenceOfHeapValue();
+ exceptionThrown = new Exception(value, exceptionType);
pauseOnNextExit = true;
+ raiseEventsOnNextExit = true;
}
ExitCallback();
@@ -532,7 +539,7 @@ namespace Debugger
public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags)
{
- EnterCallback(PausedReason.ExceptionIntercepted, "ExceptionUnwind", pThread);
+ EnterCallback("ExceptionUnwind", pThread);
if (dwEventType == CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED) {
pauseOnNextExit = true;
@@ -542,14 +549,14 @@ namespace Debugger
public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction)
{
- EnterCallback(PausedReason.Other, "FunctionRemapComplete", pThread);
+ EnterCallback("FunctionRemapComplete", pThread);
ExitCallback();
}
public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset)
{
- EnterCallback(PausedReason.Other, "FunctionRemapOpportunity", pThread);
+ EnterCallback("FunctionRemapOpportunity", pThread);
ExitCallback();
}
@@ -558,9 +565,9 @@ namespace Debugger
public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda)
{
if (c is ICorDebugAppDomain) {
- EnterCallback(PausedReason.Other, "MDANotification", (ICorDebugAppDomain)c);
+ EnterCallback("MDANotification", (ICorDebugAppDomain)c);
} else if (c is ICorDebugProcess){
- EnterCallback(PausedReason.Other, "MDANotification", (ICorDebugProcess)c);
+ EnterCallback("MDANotification", (ICorDebugProcess)c);
} else {
throw new System.Exception("Unknown callback argument");
}
diff --git a/src/AddIns/Debugger/Debugger.Core/ManagedCallbackSwitch.cs b/src/AddIns/Debugger/Debugger.Core/ManagedCallbackSwitch.cs
index c7abb50974..968b28cc76 100644
--- a/src/AddIns/Debugger/Debugger.Core/ManagedCallbackSwitch.cs
+++ b/src/AddIns/Debugger/Debugger.Core/ManagedCallbackSwitch.cs
@@ -73,7 +73,7 @@ namespace Debugger
Process process;
// We have to wait until the created process is added into the collection
lock(debugger.ProcessIsBeingCreatedLock) {
- process = debugger.Processes[pProcess];
+ process = debugger.GetProcess(pProcess);
}
// Make *really* sure the process is not dead
if (process == null) {
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs
index 1fd8775669..55b2686fb5 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs
@@ -19,6 +19,10 @@ namespace Debugger.MetaData
{
DebugMethodInfo methodInfo;
+ public DebugMethodInfo MethodInfo {
+ get { return methodInfo; }
+ }
+
internal DebugConstructorInfo(DebugMethodInfo methodInfo)
{
this.methodInfo = methodInfo;
@@ -109,13 +113,13 @@ namespace Debugger.MetaData
///
public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
{
- return methodInfo.Invoke(null, invokeAttr, binder, parameters, culture);
+ throw new NotImplementedException("Use Debugger.Value directly");
}
///
public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
{
- return methodInfo.Invoke(null, invokeAttr, binder, parameters, culture);
+ throw new NotImplementedException("Use Debugger.Value directly");
}
///
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs
index 8ad8cb9cca..33404f1cb7 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs
@@ -109,13 +109,13 @@ namespace Debugger.MetaData
///
public override object GetValue(object obj)
{
- return Value.GetFieldValue((Value)obj, this);
+ throw new NotImplementedException("Use Debugger.Value directly");
}
///
public override void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, Binder binder, CultureInfo culture)
{
- Value.SetFieldValue((Value)obj, this, (Value)value);
+ throw new NotImplementedException("Use Debugger.Value directly");
}
///
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs
index 72afa64446..b5b97f7aaa 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs
@@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using System.Reflection;
namespace Debugger.MetaData
{
@@ -11,6 +12,8 @@ namespace Debugger.MetaData
int localIndex;
DebugType localType;
+ public DebugMethodInfo Member { get; private set; }
+
///
public override int LocalIndex {
get { return localIndex; }
@@ -34,8 +37,9 @@ namespace Debugger.MetaData
public bool IsThis { get; internal set; }
public bool IsCaptured { get; internal set; }
- public DebugLocalVariableInfo(string name, int localIndex, int startOffset, int endOffset, DebugType localType, ValueGetter getter)
+ public DebugLocalVariableInfo(DebugMethodInfo member, string name, int localIndex, int startOffset, int endOffset, DebugType localType, ValueGetter getter)
{
+ this.Member = member;
this.Name = name;
this.localIndex = localIndex;
this.StartOffset = startOffset;
@@ -46,6 +50,11 @@ namespace Debugger.MetaData
public Value GetValue(StackFrame context)
{
+ if (context == null)
+ throw new ArgumentNullException("context");
+ if (context.MethodInfo != this.Member)
+ throw new GetValueException("Expected stack frame: " + this.Member.ToString());
+
return getter(context);
}
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs
index 2f8f659726..fe9d8b716f 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs
@@ -160,17 +160,7 @@ namespace Debugger.MetaData
///
public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
{
- List args = new List();
- foreach(object arg in parameters) {
- args.Add((Value)arg);
- }
- if (this.IsSpecialName && this.Name == ".ctor") {
- if (obj != null)
- throw new GetValueException("'obj' must be null for constructor call");
- return Eval.NewObject(this, args.ToArray());
- } else {
- return Eval.InvokeMethod(this, (Value)obj, args.ToArray());
- }
+ throw new NotImplementedException("Use Debugger.Value directly");
}
///
@@ -575,7 +565,8 @@ namespace Debugger.MetaData
localVariables,
0, int.MaxValue,
delegate(StackFrame context) {
- return context.GetThisValue().GetFieldValue(fieldInfoCopy);
+ // TODO: Use eval thread
+ return context.GetThisValue().GetFieldValue(context.Thread, fieldInfoCopy);
},
(DebugType)fieldInfo.FieldType
);
@@ -585,6 +576,7 @@ namespace Debugger.MetaData
// Add this
if (!this.IsStatic) {
DebugLocalVariableInfo thisVar = new DebugLocalVariableInfo(
+ this,
"this",
-1,
0, int.MaxValue,
@@ -600,20 +592,22 @@ namespace Debugger.MetaData
return localVariables;
}
- static void AddCapturedLocalVariables(List vars, int scopeStartOffset, int scopeEndOffset, ValueGetter getCaptureClass, DebugType captureClassType)
+ void AddCapturedLocalVariables(List vars, int scopeStartOffset, int scopeEndOffset, ValueGetter getCaptureClass, DebugType captureClassType)
{
if (captureClassType.IsDisplayClass || captureClassType.IsYieldEnumerator || captureClassType.IsAsyncStateMachine) {
foreach(DebugFieldInfo fieldInfo in captureClassType.GetFields()) {
DebugFieldInfo fieldInfoCopy = fieldInfo;
if (fieldInfo.Name.StartsWith("CS$")) continue; // Ignore
DebugLocalVariableInfo locVar = new DebugLocalVariableInfo(
+ this,
fieldInfo.Name,
-1,
scopeStartOffset,
scopeEndOffset,
(DebugType)fieldInfo.FieldType,
delegate(StackFrame context) {
- return getCaptureClass(context).GetFieldValue(fieldInfoCopy);
+ // TODO: Use eval thread
+ return getCaptureClass(context).GetFieldValue(context.Thread, fieldInfoCopy);
}
);
locVar.IsCaptured = true;
@@ -646,7 +640,7 @@ namespace Debugger.MetaData
{
List vars = new List();
foreach (ISymUnmanagedVariable symVar in symScope.GetLocals()) {
- ISymUnmanagedVariable symVarCopy = symVar;
+ uint address = (uint)symVar.GetAddressField1();
int start;
SignatureReader sigReader = new SignatureReader(symVar.GetSignature());
LocalVarSig.LocalVariable locVarSig = sigReader.ReadLocalVariable(sigReader.Blob, 0, out start);
@@ -661,13 +655,14 @@ namespace Debugger.MetaData
(int)symScope.GetStartOffset(),
(int)symScope.GetEndOffset(),
delegate(StackFrame context) {
- return GetLocalVariableValue(context, symVarCopy);
+ return context.GetLocalVariableValue(address);
},
locVarType
);
}
} else {
DebugLocalVariableInfo locVar = new DebugLocalVariableInfo(
+ this,
symVar.GetName(),
(int)symVar.GetAddressField1(),
// symVar also has Get*Offset methods, but the are not implemented
@@ -675,7 +670,7 @@ namespace Debugger.MetaData
(int)symScope.GetEndOffset(),
locVarType,
delegate(StackFrame context) {
- return GetLocalVariableValue(context, symVarCopy);
+ return context.GetLocalVariableValue(address);
}
);
vars.Add(locVar);
@@ -687,18 +682,6 @@ namespace Debugger.MetaData
return vars;
}
- static Value GetLocalVariableValue(StackFrame context, ISymUnmanagedVariable symVar)
- {
- ICorDebugValue corVal;
- try {
- corVal = context.CorILFrame.GetLocalVariable((uint)symVar.GetAddressField1());
- } catch (COMException e) {
- if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Unavailable in optimized code");
- throw;
- }
- return new Value(context.AppDomain, corVal);
- }
-
///
public override string ToString()
{
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs
index cf95f75558..84cc7203ad 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs
@@ -45,6 +45,11 @@ namespace Debugger.MetaData
public Value GetValue(StackFrame context)
{
+ if (context == null)
+ throw new ArgumentNullException("context");
+ if (context.MethodInfo != this.Member)
+ throw new GetValueException("Expected stack frame: " + this.Member.ToString());
+
return getter(context);
}
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs
index 35b0bc252a..36937d52d6 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs
@@ -184,21 +184,13 @@ namespace Debugger.MetaData
///
public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
{
- List args = new List();
- foreach(object arg in index) {
- args.Add((Value)arg);
- }
- return Value.GetPropertyValue((Value)obj, this, args.ToArray());
+ throw new NotImplementedException("Use Debugger.Value directly");
}
///
public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
{
- List args = new List();
- foreach(object arg in index) {
- args.Add((Value)arg);
- }
- Value.SetPropertyValue((Value)obj, this, args.ToArray(), (Value)value);
+ throw new NotImplementedException("Use Debugger.Value directly");
}
public bool IsPublic {
diff --git a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugType.cs b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugType.cs
index fa6b205543..4a9afee7a3 100644
--- a/src/AddIns/Debugger/Debugger.Core/MetaData/DebugType.cs
+++ b/src/AddIns/Debugger/Debugger.Core/MetaData/DebugType.cs
@@ -9,7 +9,6 @@ using System.Text;
using Debugger.Interop.CorDebug;
using Debugger.Interop.MetaData;
-using ICSharpCode.NRefactory.Ast;
using Mono.Cecil.Signatures;
namespace Debugger.MetaData
@@ -1076,7 +1075,7 @@ namespace Debugger.MetaData
public static DebugType CreateFromCorClass(AppDomain appDomain, bool? valueType, ICorDebugClass corClass, DebugType[] genericArguments)
{
- MetaDataImport metaData = appDomain.Process.Modules[corClass.GetModule()].MetaData;
+ MetaDataImport metaData = appDomain.Process.GetModule(corClass.GetModule()).MetaData;
if (valueType == null) {
uint superClassToken = metaData.GetTypeDefProps(corClass.GetToken()).SuperClassToken;
@@ -1176,7 +1175,7 @@ namespace Debugger.MetaData
genericArguments.Add(DebugType.CreateFromCorType(appDomain, t));
}
// Get class props
- this.module = appDomain.Process.Modules[corType.GetClass().GetModule()];
+ this.module = appDomain.Process.GetModule(corType.GetClass().GetModule());
this.classProps = module.MetaData.GetTypeDefProps(corType.GetClass().GetToken());
if (this.DebugModule.AppDomain != appDomain)
throw new DebuggerException("The specified AppDomain was inccorect");
diff --git a/src/AddIns/Debugger/Debugger.Core/Module.cs b/src/AddIns/Debugger/Debugger.Core/Module.cs
index db6c99dbd8..d6c1704682 100644
--- a/src/AddIns/Debugger/Debugger.Core/Module.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Module.cs
@@ -29,11 +29,6 @@ namespace Debugger
internal Dictionary LoadedDebugTypes = new Dictionary();
- ///
- /// Occurs when symbols are loaded or unloaded (for memory modules)
- ///
- public event EventHandler SymbolsUpdated;
-
public AppDomain AppDomain {
get { return appDomain; }
}
@@ -222,11 +217,11 @@ namespace Debugger
///
/// Load symblos for on-disk module
///
- public void LoadSymbolsFromDisk(string[] searchPath)
+ public void LoadSymbolsFromDisk(string[] symbolsSearchPaths)
{
if (!IsDynamic && !IsInMemory) {
if (symReader == null) {
- symReader = metaData.GetSymReader(fullPath, string.Join("; ", searchPath ?? new string[0]));
+ symReader = metaData.GetSymReader(fullPath, string.Join("; ", symbolsSearchPaths ?? new string[0]));
if (symReader != null) {
process.TraceMessage("Loaded symbols from disk for " + this.Name);
OnSymbolsUpdated();
@@ -280,31 +275,10 @@ namespace Debugger
void OnSymbolsUpdated()
{
- SetBreakpoints();
- ResetJustMyCodeStatus();
- if (SymbolsUpdated != null) {
- SymbolsUpdated(this, new ModuleEventArgs(this));
- }
- }
-
- void SetBreakpoints()
- {
- if (this.HasSymbols) {
- // This is in case that the client modifies the collection as a response to set breakpoint
- // NB: If client adds new breakpoint, it will be set directly as a result of his call, not here (because module is already loaded)
- List collection = new List();
- collection.AddRange(this.Debugger.Breakpoints);
-
- var currentModuleTypes = this.GetNamesOfDefinedTypes();
- foreach (Breakpoint b in collection) {
- if (b is ILBreakpoint) {
- // set the breakpoint only if the module contains the type
- if (!currentModuleTypes.Contains(b.TypeName))
- continue;
- }
- b.SetBreakpoint(this);
- }
+ foreach (Breakpoint b in this.Debugger.Breakpoints) {
+ b.SetBreakpoint(this);
}
+ ResetJustMyCodeStatus();
}
void SetJITCompilerFlags()
@@ -396,21 +370,4 @@ namespace Debugger
return jcf;
}
}
-
- [Serializable]
- public class ModuleEventArgs : ProcessEventArgs
- {
- Module module;
-
- public Module Module {
- get {
- return module;
- }
- }
-
- public ModuleEventArgs(Module module): base(module.Process)
- {
- this.module = module;
- }
- }
}
diff --git a/src/AddIns/Debugger/Debugger.Core/ModuleCollection.cs b/src/AddIns/Debugger/Debugger.Core/ModuleCollection.cs
deleted file mode 100644
index d01fd53af5..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/ModuleCollection.cs
+++ /dev/null
@@ -1,50 +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 Debugger.Interop.CorDebug;
-
-namespace Debugger
-{
- public class ModuleCollection: CollectionWithEvents
- {
- public ModuleCollection(NDebugger debugger):base (debugger) {}
-
- int lastAssignedModuleOrderOfLoading = 0;
-
- public Module this[string filename] {
- get {
- foreach(Module module in this) {
- if (module.Name == filename) {
- return module;
- }
- }
- throw new DebuggerException("Module \"" + filename + "\" is not in collection");
- }
- }
-
- internal Module this[ICorDebugModule corModule] {
- get {
- foreach(Module module in this) {
- if (module.CorModule == corModule) {
- return module;
- }
- }
- throw new DebuggerException("Module is not in collection");
- }
- }
-
- protected override void OnAdded(Module module)
- {
- module.OrderOfLoading = lastAssignedModuleOrderOfLoading;
- lastAssignedModuleOrderOfLoading++;
- base.OnAdded(module);
- }
-
- protected override void OnRemoved(Module module)
- {
- base.OnRemoved(module);
- module.Dispose();
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/NDebugger.cs b/src/AddIns/Debugger/Debugger.Core/NDebugger.cs
index 61ecb39eb5..0858212982 100644
--- a/src/AddIns/Debugger/Debugger.Core/NDebugger.cs
+++ b/src/AddIns/Debugger/Debugger.Core/NDebugger.cs
@@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
@@ -11,14 +12,22 @@ using Microsoft.Win32;
namespace Debugger
{
+ ///
+ /// A base class for all classes declared by the debugger
+ ///
+ public class DebuggerObject: MarshalByRefObject
+ {
+
+ }
+
public class NDebugger: DebuggerObject
{
ICorDebug corDebug;
ManagedCallbackSwitch managedCallbackSwitch;
ManagedCallbackProxy managedCallbackProxy;
- BreakpointCollection breakpoints;
- ProcessCollection processes;
+ internal List breakpoints = new List();
+ internal List processes = new List();
MTA2STA mta2sta = new MTA2STA();
@@ -49,19 +58,16 @@ namespace Debugger
set { options = value; }
}
- public BreakpointCollection Breakpoints {
- get { return breakpoints; }
+ public IEnumerable Breakpoints {
+ get { return this.breakpoints; }
}
- public ProcessCollection Processes {
- get { return processes; }
+ public IEnumerable Processes {
+ get { return this.processes; }
}
public NDebugger()
{
- processes = new ProcessCollection(this);
- breakpoints = new BreakpointCollection(this);
-
if (ApartmentState.STA == System.Threading.Thread.CurrentThread.GetApartmentState()) {
mta2sta.CallMethod = CallMethod.HiddenFormWithTimeout;
} else {
@@ -69,6 +75,15 @@ namespace Debugger
}
}
+ internal Process GetProcess(ICorDebugProcess corProcess) {
+ foreach (Process process in this.Processes) {
+ if (process.CorProcess == corProcess) {
+ return process;
+ }
+ }
+ return null;
+ }
+
///
/// Get the .NET version of the process that called this function
///
@@ -137,38 +152,57 @@ namespace Debugger
internal void TerminateDebugger()
{
- // Mark breakpints as deactivated
- foreach (Breakpoint b in this.Breakpoints) {
- b.MarkAsDeactivated();
+ foreach(Breakpoint breakpoint in this.Breakpoints) {
+ breakpoint.NotifyDebuggerTerminated();
}
- TraceMessage("Reset done");
-
corDebug.Terminate();
-
TraceMessage("ICorDebug terminated");
int released = TrackedComObjects.ReleaseAll();
-
TraceMessage("Released " + released + " tracked COM objects");
}
- ///
- /// Internal: Used to debug the debugger library.
- ///
- public event EventHandler DebuggerTraceMessage;
+ public Breakpoint AddBreakpoint(string fileName, int line, int column = 0, bool enabled = true)
+ {
+ Breakpoint breakpoint = new Breakpoint(fileName, line, column, enabled);
+ AddBreakpoint(breakpoint);
+ return breakpoint;
+ }
- protected internal virtual void OnDebuggerTraceMessage(MessageEventArgs e)
+ public ILBreakpoint AddILBreakpoint(string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled)
{
- if (DebuggerTraceMessage != null) {
- DebuggerTraceMessage(this, e);
+ ILBreakpoint breakpoint = new ILBreakpoint(typeName, line, metadataToken, memberToken, offset, enabled);
+ AddBreakpoint(breakpoint);
+ return breakpoint;
+ }
+
+ void AddBreakpoint(Breakpoint breakpoint)
+ {
+ this.breakpoints.Add(breakpoint);
+
+ foreach (Process process in this.Processes) {
+ foreach(Module module in process.Modules) {
+ breakpoint.SetBreakpoint(module);
+ }
+ }
+ }
+
+ internal Breakpoint GetBreakpoint(ICorDebugBreakpoint corBreakpoint)
+ {
+ foreach (Breakpoint breakpoint in this.Breakpoints) {
+ if (breakpoint.IsOwnerOf(corBreakpoint)) {
+ return breakpoint;
+ }
}
+ return null;
}
internal void TraceMessage(string message)
{
- System.Diagnostics.Debug.WriteLine("Debugger:" + message);
- OnDebuggerTraceMessage(new MessageEventArgs(null, message));
+ message = "Debugger: " + message;
+ System.Console.WriteLine(message);
+ System.Diagnostics.Debug.WriteLine(message);
}
public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi)
@@ -181,39 +215,36 @@ namespace Debugger
internal object ProcessIsBeingCreatedLock = new object();
- public Process Start(string filename, string workingDirectory, string arguments)
+ public Process Start(string filename, string workingDirectory, string arguments, bool breakInMain)
{
InitDebugger(GetProgramVersion(filename));
lock(ProcessIsBeingCreatedLock) {
Process process = Process.CreateProcess(this, filename, workingDirectory, arguments);
// Expose a race conditon
System.Threading.Thread.Sleep(0);
- this.Processes.Add(process);
+ process.BreakInMain = breakInMain;
+ this.processes.Add(process);
return process;
}
}
- public Process Attach(System.Diagnostics.Process existingProcess)
+ public Process Attach(System.Diagnostics.Process existingProcess)
{
string mainModule = existingProcess.MainModule.FileName;
InitDebugger(GetProgramVersion(mainModule));
- ICorDebugProcess corDebugProcess = corDebug.DebugActiveProcess((uint)existingProcess.Id, 0);
- // TODO: Can we get the acutal working directory?
- Process process = new Process(this, corDebugProcess, Path.GetDirectoryName(mainModule));
- this.Processes.Add(process);
- return process;
+ lock(ProcessIsBeingCreatedLock) {
+ ICorDebugProcess corDebugProcess = corDebug.DebugActiveProcess((uint)existingProcess.Id, 0);
+ // TODO: Can we get the acutal working directory?
+ Process process = new Process(this, corDebugProcess, Path.GetDirectoryName(mainModule));
+ this.processes.Add(process);
+ return process;
+ }
}
public void Detach()
{
- // Deactivate breakpoints
- foreach (Breakpoint b in this.Breakpoints) {
- b.Deactivate();
- }
-
// Detach all processes.
- for (int i = 0; i < this.Processes.Count; ++i) {
- Process process = this.Processes[i];
+ foreach(Process process in this.Processes) {
if (process == null || process.HasExited)
continue;
process.Detach();
@@ -264,57 +295,48 @@ namespace Debugger
}
[Serializable]
- public class DebuggerEventArgs : EventArgs
+ public class DebuggerEventArgs: EventArgs
{
- NDebugger debugger;
-
- public NDebugger Debugger {
- get {
- return debugger;
- }
- }
+ /// The process on which the event occured. Can be null.
+ public Process Process { get; set; }
+ /// The thread on which the event occured. Can be null if the event was not thread specific.
+ public Thread Thread { get; set; }
+ public Breakpoint[] BreakpointsHit { get; set; }
+ public Exception ExceptionThrown { get; set; }
+ }
+
+ [Serializable]
+ public class ModuleEventArgs: DebuggerEventArgs
+ {
+ public Module Module { get; private set; }
- public DebuggerEventArgs(NDebugger debugger)
+ public ModuleEventArgs(Module module)
{
- this.debugger = debugger;
+ this.Process = module.Process;
+ this.Module = module;
}
}
[Serializable]
- public class MessageEventArgs : ProcessEventArgs
+ public class MessageEventArgs : EventArgs
{
- int level;
- string message;
- string category;
-
- public int Level {
- get {
- return level;
- }
- }
-
- public string Message {
- get {
- return message;
- }
- }
-
- public string Category {
- get {
- return category;
- }
- }
+ public Process Process { get; private set; }
+ public int Level { get; private set; }
+ public string Message { get; private set; }
+ public string Category { get; private set; }
- public MessageEventArgs(Process process, string message): this(process, 0, message, String.Empty)
+ public MessageEventArgs(Process process, string message)
{
- this.message = message;
+ this.Process = process;
+ this.Message = message;
}
- public MessageEventArgs(Process process, int level, string message, string category): base(process)
+ public MessageEventArgs(Process process, int level, string message, string category)
{
- this.level = level;
- this.message = message;
- this.category = category;
+ this.Process = process;
+ this.Level = level;
+ this.Message = message;
+ this.Category = category;
}
}
}
diff --git a/src/AddIns/Debugger/Debugger.Core/PauseSession.cs b/src/AddIns/Debugger/Debugger.Core/PauseSession.cs
deleted file mode 100644
index 6af85f12bf..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/PauseSession.cs
+++ /dev/null
@@ -1,30 +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)
-
-namespace Debugger
-{
- ///
- /// Holds information about the state of paused debugger.
- /// Expires when when Continue is called on debugger.
- ///
- public class PauseSession: DebuggerObject
- {
- Process process;
- PausedReason pausedReason;
-
- public Process Process {
- get { return process; }
- }
-
- public PausedReason PausedReason {
- get { return pausedReason; }
- set { pausedReason = value; }
- }
-
- public PauseSession(Process process, PausedReason pausedReason)
- {
- this.process = process;
- this.pausedReason = pausedReason;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/PausedReason.cs b/src/AddIns/Debugger/Debugger.Core/PausedReason.cs
deleted file mode 100644
index c424718673..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/PausedReason.cs
+++ /dev/null
@@ -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)
-
-namespace Debugger
-{
- public enum PausedReason : int
- {
- EvalComplete,
- StepComplete,
- Breakpoint,
- Break,
- ControlCTrap,
- Exception,
- ForcedBreak, // Process.Break called
- DebuggerError,
- CurrentThreadChanged,
- CurrentFunctionChanged,
- ExceptionIntercepted,
- SetIP,
- Other
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Process.cs b/src/AddIns/Debugger/Debugger.Core/Process.cs
index 268bd63f3f..c6c879ed11 100644
--- a/src/AddIns/Debugger/Debugger.Core/Process.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Process.cs
@@ -7,8 +7,6 @@ using System.Runtime.InteropServices;
using Debugger.Interop.CorDebug;
using Debugger.Interop.CorSym;
-using ICSharpCode.NRefactory.Ast;
-using ICSharpCode.NRefactory.Visitors;
namespace Debugger
{
@@ -44,13 +42,21 @@ namespace Debugger
ICorDebugProcess corProcess;
ManagedCallback callbackInterface;
- EvalCollection activeEvals;
- ModuleCollection modules;
- ThreadCollection threads;
- AppDomainCollection appDomains;
+ List tempBreakpoints = new List();
+
+ internal List activeEvals = new List();
+ internal List modules = new List();
+ internal List threads = new List();
+ internal List appDomains = new List();
string workingDirectory;
+ public event EventHandler LogMessage;
+ public event EventHandler ModuleLoaded;
+ public event EventHandler ModuleUnloaded;
+ public event EventHandler Paused;
+ public event EventHandler Resumed;
+ public event EventHandler Exited;
public NDebugger Debugger {
get { return debugger; }
@@ -72,53 +78,21 @@ namespace Debugger
get { return callbackInterface; }
}
- public EvalCollection ActiveEvals {
- get { return activeEvals; }
- }
-
internal bool Evaluating {
get { return activeEvals.Count > 0; }
}
- public ModuleCollection Modules {
- get { return modules; }
- }
-
- public ThreadCollection Threads {
- get { return threads; }
- }
-
- public Thread SelectedThread {
- get { return this.Threads.Selected; }
- set { this.Threads.Selected = value; }
- }
-
- public StackFrame SelectedStackFrame {
- get {
- if (SelectedThread == null) {
- return null;
- } else {
- return SelectedThread.SelectedStackFrame;
- }
- }
+ public IEnumerable Modules {
+ get { return this.modules; }
}
- public SourcecodeSegment NextStatement {
- get {
- if (SelectedStackFrame == null || IsRunning) {
- return null;
- } else {
- return SelectedStackFrame.NextStatement;
- }
- }
+ public IEnumerable Threads {
+ get { return this.threads; }
}
- public bool BreakAtBeginning {
- get;
- set;
- }
+ internal bool BreakInMain { get; set; }
- public AppDomainCollection AppDomains {
+ public IEnumerable AppDomains {
get { return appDomains; }
}
@@ -141,12 +115,6 @@ namespace Debugger
this.workingDirectory = workingDirectory;
this.callbackInterface = new ManagedCallback(this);
-
- activeEvals = new EvalCollection(debugger);
- modules = new ModuleCollection(debugger);
- modules.Added += OnModulesAdded;
- threads = new ThreadCollection(debugger);
- appDomains = new AppDomainCollection(debugger);
}
static unsafe public Process CreateProcess(NDebugger debugger, string filename, string workingDirectory, string arguments)
@@ -189,14 +157,10 @@ namespace Debugger
return new Process(debugger, outProcess, workingDirectory);
}
- /// Fired when System.Diagnostics.Trace.WriteLine() is called in debuged process
- public event EventHandler LogMessage;
-
- protected internal virtual void OnLogMessage(MessageEventArgs arg)
+ internal void OnLogMessage(MessageEventArgs arg)
{
- TraceMessage ("Debugger event: OnLogMessage");
- if (LogMessage != null) {
- LogMessage(this, arg);
+ if (this.LogMessage != null) {
+ this.LogMessage(this, arg);
}
}
@@ -204,8 +168,61 @@ namespace Debugger
{
if (args.Length > 0)
message = string.Format(message, args);
- System.Diagnostics.Debug.WriteLine("Debugger:" + message);
- debugger.OnDebuggerTraceMessage(new MessageEventArgs(this, message));
+ this.Debugger.TraceMessage(message);
+ }
+
+ internal AppDomain GetAppDomain(ICorDebugAppDomain corAppDomain)
+ {
+ foreach(AppDomain a in this.AppDomains) {
+ if (a.CorAppDomain.Equals(corAppDomain)) {
+ return a;
+ }
+ }
+ throw new DebuggerException("AppDomain not found");
+ }
+
+ internal Eval GetActiveEval(ICorDebugEval corEval)
+ {
+ foreach(Eval eval in this.activeEvals) {
+ if (eval.CorEval == corEval) {
+ return eval;
+ }
+ }
+ throw new DebuggerException("Eval not found for given ICorDebugEval");
+ }
+
+ public Module GetModule(string filename)
+ {
+ foreach(Module module in this.Modules) {
+ if (module.Name == filename) {
+ return module;
+ }
+ }
+ throw new DebuggerException("Module \"" + filename + "\" is not in collection");
+ }
+
+ internal Module GetModule(ICorDebugModule corModule)
+ {
+ foreach(Module module in this.Modules) {
+ if (module.CorModule == corModule) {
+ return module;
+ }
+ }
+ throw new DebuggerException("Module is not in collection");
+ }
+
+ internal Thread GetThread(ICorDebugThread corThread)
+ {
+ foreach(Thread thread in this.Threads) {
+ if (thread.CorThread == corThread) {
+ return thread;
+ }
+ }
+ // Sometimes, the thread is not reported for some unkown reason
+ TraceMessage("Thread not found in collection");
+ Thread newThread = new Thread(this, corThread);
+ this.threads.Add(newThread);
+ return newThread;
}
/// Read the specified amount of memory at the given memory address
@@ -233,47 +250,22 @@ namespace Debugger
return written;
}
- internal Thread GetThread(ICorDebugThread corThread)
- {
- foreach(Thread thread in this.Threads) {
- if (thread.CorThread == corThread) {
- return thread;
- }
- }
- Thread t = new Thread(this, corThread);
- this.Threads.Add(t);
- return t;
- }
-
- #region Exceptions
-
- public event EventHandler ExceptionThrown;
-
- protected internal virtual void OnExceptionThrown(ExceptionEventArgs e)
- {
- TraceMessage ("Debugger event: OnExceptionThrown()");
- if (ExceptionThrown != null) {
- ExceptionThrown(this, e);
- }
- }
-
- #endregion
-
// State control for the process
internal bool TerminateCommandIssued = false;
- internal Queue BreakpointHitEventQueue = new Queue();
- internal Dictionary ExpressionsCache = new Dictionary();
#region Events
- public event EventHandler Paused;
- public event EventHandler Resumed;
-
- // HACK: public
- public virtual void OnPaused()
+ internal void OnPaused(DebuggerEventArgs e)
{
AssertPaused();
+ DisableAllSteppers();
+
+ foreach (var corBreakpoint in tempBreakpoints) {
+ corBreakpoint.Activate(0);
+ }
+ tempBreakpoints.Clear();
+
// No real purpose - just additional check
if (callbackInterface.IsInCallback) throw new DebuggerException("Can not raise event within callback.");
TraceMessage ("Debugger event: OnPaused()");
@@ -287,19 +279,19 @@ namespace Debugger
TraceMessage ("Skipping OnPaused delegate because process has exited");
break;
}
- d.DynamicInvoke(this, new ProcessEventArgs(this));
+ d.DynamicInvoke(this, e);
}
}
}
- protected virtual void OnResumed()
+ void OnResumed()
{
AssertRunning();
if (callbackInterface.IsInCallback)
throw new DebuggerException("Can not raise event within callback.");
TraceMessage ("Debugger event: OnResumed()");
if (Resumed != null) {
- Resumed(this, new ProcessEventArgs(this));
+ Resumed(this, new DebuggerEventArgs() { Process = this });
}
}
@@ -307,30 +299,32 @@ namespace Debugger
#region PauseSession & DebugeeState
- PauseSession pauseSession;
- DebuggeeState debuggeeState;
+ long pauseSession;
+ long nextPauseSession = 1;
+ long debuggeeState;
+ long nextDebuggeeState = 1;
///
/// Indentification of the current debugger session. This value changes whenever debugger is continued
///
- public PauseSession PauseSession {
+ public long PauseSession {
get { return pauseSession; }
}
///
/// Indentification of the state of the debugee. This value changes whenever the state of the debugee significatntly changes
///
- public DebuggeeState DebuggeeState {
+ public long DebuggeeState {
get { return debuggeeState; }
}
/// Puts the process into a paused state
- internal void NotifyPaused(PausedReason pauseReason)
+ internal void NotifyPaused()
{
AssertRunning();
- pauseSession = new PauseSession(this, pauseReason);
- if (debuggeeState == null) {
- debuggeeState = new DebuggeeState(this);
+ pauseSession = nextPauseSession++;
+ if (debuggeeState == 0) {
+ debuggeeState = nextDebuggeeState++;
}
}
@@ -338,44 +332,13 @@ namespace Debugger
internal void NotifyResumed(DebuggeeStateAction action)
{
AssertPaused();
- pauseSession = null;
+ pauseSession = 0;
if (action == DebuggeeStateAction.Clear) {
- if (debuggeeState == null) throw new DebuggerException("Debugee state already cleared");
- debuggeeState = null;
- this.ExpressionsCache.Clear();
+ if (debuggeeState == 0) throw new DebuggerException("Debugee state already cleared");
+ debuggeeState = 0;
}
}
- /// Sets up the eviroment and raises user events
- internal void RaisePausedEvents()
- {
- AssertPaused();
- DisableAllSteppers();
- CheckSelectedStackFrames();
- SelectMostRecentStackFrameWithLoadedSymbols();
-
- // if CurrentException is set an exception has occurred.
- if (SelectedThread.CurrentException != null) {
- ExceptionEventArgs args = new ExceptionEventArgs(this, this.SelectedThread.CurrentException, this.SelectedThread.CurrentExceptionType, this.SelectedThread.CurrentExceptionIsUnhandled);
- OnExceptionThrown(args);
- // clear exception, it is being processed by the debugger.
- this.SelectedThread.CurrentException = null;
- // The event could have resumed or killed the process
- if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return;
- }
-
- while(BreakpointHitEventQueue.Count > 0) {
- Breakpoint breakpoint = BreakpointHitEventQueue.Dequeue();
- breakpoint.NotifyHit();
- // The event could have resumed or killed the process
- if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return;
- }
-
- OnPaused();
- // The event could have resumed the process
- if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return;
- }
-
#endregion
internal void AssertPaused()
@@ -393,7 +356,7 @@ namespace Debugger
}
public bool IsRunning {
- get { return pauseSession == null; }
+ get { return pauseSession == 0; }
}
public uint Id {
@@ -406,26 +369,29 @@ namespace Debugger
bool hasExited = false;
- public event EventHandler Exited;
-
public bool HasExited {
get {
return hasExited;
}
}
- internal void NotifyHasExited()
+ internal void OnExited()
{
if(!hasExited) {
hasExited = true;
if (Exited != null) {
- Exited(this, new ProcessEventArgs(this));
+ Exited(this, new DebuggerEventArgs() { Process = this });
}
// Expire pause seesion first
if (IsPaused) {
NotifyResumed(DebuggeeStateAction.Clear);
}
- debugger.Processes.Remove(this);
+ debugger.processes.Remove(this);
+
+ if (debugger.processes.Count == 0) {
+ // Exit callback and then terminate the debugger
+ this.Debugger.MTA2STA.AsyncCall( delegate { this.Debugger.TerminateDebugger(); } );
+ }
}
}
@@ -435,15 +401,20 @@ namespace Debugger
corProcess.Stop(uint.MaxValue); // Infinite; ignored anyway
- NotifyPaused(PausedReason.ForcedBreak);
- RaisePausedEvents();
+ NotifyPaused();
+ OnPaused(new DebuggerEventArgs() { Process = this });
}
public void Detach()
{
if (IsRunning) {
corProcess.Stop(uint.MaxValue);
- NotifyPaused(PausedReason.ForcedBreak);
+ NotifyPaused();
+ }
+
+ // Deactivate breakpoints
+ foreach (Breakpoint b in this.Debugger.Breakpoints) {
+ b.IsEnabled = false;
}
// This is necessary for detach
@@ -457,8 +428,7 @@ namespace Debugger
corProcess.Detach();
// modules
- foreach(Module m in this.Modules)
- {
+ foreach(Module m in this.Modules) {
m.Dispose();
}
@@ -467,7 +437,7 @@ namespace Debugger
// threads
this.threads.Clear();
- NotifyHasExited();
+ OnExited();
}
public void Continue()
@@ -476,9 +446,24 @@ namespace Debugger
WaitForPause();
}
+ public void RunTo(string fileName, int line, int column)
+ {
+ foreach(Module module in this.Modules) {
+ SourcecodeSegment segment = SourcecodeSegment.Resolve(module, fileName, line, column);
+ if (segment != null) {
+ ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart);
+ corBreakpoint.Activate(1);
+ this.tempBreakpoints.Add(corBreakpoint);
+ }
+ }
+ if (this.IsPaused) {
+ AsyncContinue();
+ }
+ }
+
internal Thread[] UnsuspendedThreads {
get {
- List unsuspendedThreads = new List(this.Threads.Count);
+ List unsuspendedThreads = new List();
foreach(Thread t in this.Threads) {
if (!t.Suspended)
unsuspendedThreads.Add(t);
@@ -569,63 +554,6 @@ namespace Debugger
// This is done once ExitProcess callback is received
}
- ///
- /// Clears the internal Expression cache used too speed up Expression evaluation.
- /// Use this if your code evaluates expressions in a way which would cause
- /// the cache to grow too large. The cache holds PermanentReferences so it
- /// shouldn't grow larger than a few hundred items.
- ///
- public void ClearExpressionCache()
- {
- if (this.ExpressionsCache != null ){
- this.ExpressionsCache.Clear();
- }
- }
-
- void SelectSomeThread()
- {
- if (this.SelectedThread != null && !this.SelectedThread.IsInValidState) {
- this.SelectedThread = null;
- }
- if (this.SelectedThread == null) {
- foreach(Thread thread in this.Threads) {
- if (thread.IsInValidState) {
- this.SelectedThread = thread;
- break;
- }
- }
- }
- }
-
- internal void CheckSelectedStackFrames()
- {
- foreach(Thread thread in this.Threads) {
- if (thread.IsInValidState) {
- if (thread.SelectedStackFrame != null && thread.SelectedStackFrame.IsInvalid) {
- thread.SelectedStackFrame = null;
- }
- } else {
- thread.SelectedStackFrame = null;
- }
- }
- }
-
- internal void SelectMostRecentStackFrameWithLoadedSymbols()
- {
- SelectSomeThread();
- if (this.SelectedThread != null) {
- this.SelectedThread.SelectedStackFrame = null;
- foreach (StackFrame stackFrame in this.SelectedThread.Callstack) {
- if (stackFrame.HasSymbols) {
- if (this.Options.StepOverDebuggerAttributes && stackFrame.MethodInfo.IsNonUserCode)
- continue;
- this.SelectedThread.SelectedStackFrame = stackFrame;
- break;
- }
- }
- }
- }
-
internal Stepper GetStepper(ICorDebugStepper corStepper)
{
foreach(Stepper stepper in this.Steppers) {
@@ -686,69 +614,47 @@ namespace Debugger
#region Break at begining
- private void OnModulesAdded(object sender, CollectionItemEventArgs e)
+ int lastAssignedModuleOrderOfLoading = 0;
+
+ internal void OnModuleLoaded(Module module)
{
- if (BreakAtBeginning) {
- if (e.Item.SymReader == null) return; // No symbols
+ module.OrderOfLoading = lastAssignedModuleOrderOfLoading++;
+
+ foreach (Breakpoint b in this.Debugger.Breakpoints) {
+ b.SetBreakpoint(module);
+ }
+
+ if (this.BreakInMain) {
+ if (module.SymReader == null) return; // No symbols
try {
// create a BP at entry point
- uint entryPoint = e.Item.SymReader.GetUserEntryPoint();
+ uint entryPoint = module.SymReader.GetUserEntryPoint();
if (entryPoint == 0) return; // no EP
- var mainFunction = e.Item.CorModule.GetFunctionFromToken(entryPoint);
- var corBreakpoint = mainFunction.CreateBreakpoint();
+ var corBreakpoint = module.CorModule.GetFunctionFromToken(entryPoint).CreateBreakpoint();
corBreakpoint.Activate(1);
-
- // create a SD BP
- var breakpoint = new Breakpoint(this.debugger, corBreakpoint);
- this.debugger.Breakpoints.Add(breakpoint);
- breakpoint.Hit += delegate {
- if (breakpoint != null)
- breakpoint.Remove();
- breakpoint = null;
- };
+ this.tempBreakpoints.Add(corBreakpoint);
} catch {
// the app does not have an entry point - COM exception
}
- BreakAtBeginning = false;
+
+ this.BreakInMain = false;
}
- if (ModulesAdded != null)
- ModulesAdded(this, new ModuleEventArgs(e.Item));
+ if (this.ModuleLoaded != null) {
+ this.ModuleLoaded(this, new ModuleEventArgs(module));
+ }
}
- #endregion
-
- public event EventHandler ModulesAdded;
-
- public StackFrame GetCurrentExecutingFrame()
+ internal void OnModuleUnloaded(Module module)
{
- if (IsRunning || SelectedThread == null)
- return null;
-
- if (IsSelectedFrameForced()) {
- return SelectedStackFrame; // selected from callstack or threads pads
- }
+ module.Dispose();
- if (SelectedStackFrame != null) {
- if (SelectedThread.MostRecentStackFrame != null) {
- if (SelectedStackFrame.HasSymbols && SelectedThread.MostRecentStackFrame.HasSymbols)
- return SelectedStackFrame;
- else
- return SelectedThread.MostRecentStackFrame;
- } else {
- return SelectedThread.MostRecentStackFrame;
- }
- } else {
- return SelectedThread.MostRecentStackFrame;
+ if (this.ModuleUnloaded != null) {
+ this.ModuleUnloaded(this, new ModuleEventArgs(module));
}
}
- public bool IsSelectedFrameForced()
- {
- return pauseSession.PausedReason == PausedReason.CurrentFunctionChanged ||
- pauseSession.PausedReason == PausedReason.CurrentThreadChanged ||
- pauseSession.PausedReason == PausedReason.EvalComplete;
- }
+ #endregion
}
}
diff --git a/src/AddIns/Debugger/Debugger.Core/ProcessCollection.cs b/src/AddIns/Debugger/Debugger.Core/ProcessCollection.cs
deleted file mode 100644
index b155531926..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/ProcessCollection.cs
+++ /dev/null
@@ -1,34 +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 Debugger.Interop.CorDebug;
-
-namespace Debugger
-{
- public class ProcessCollection: CollectionWithEvents
- {
- public ProcessCollection(NDebugger debugger): base(debugger) {}
-
- internal Process this[ICorDebugProcess corProcess] {
- get {
- foreach (Process process in this) {
- if (process.CorProcess == corProcess) {
- return process;
- }
- }
- return null;
- }
- }
-
- protected override void OnRemoved(Process item)
- {
- base.OnRemoved(item);
-
- if (this.Count == 0) {
- // Exit callback and then terminate the debugger
- this.Debugger.MTA2STA.AsyncCall( delegate { this.Debugger.TerminateDebugger(); } );
- }
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/ProcessEventArgs.cs b/src/AddIns/Debugger/Debugger.Core/ProcessEventArgs.cs
deleted file mode 100644
index e28f81aa15..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/ProcessEventArgs.cs
+++ /dev/null
@@ -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;
-
-namespace Debugger
-{
- [Serializable]
- public class ProcessEventArgs: DebuggerEventArgs
- {
- Process process;
-
- public Process Process {
- get { return process; }
- }
-
- public ProcessEventArgs(Process process): base(process == null ? null : process.Debugger)
- {
- this.process = process;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Properties/AssemblyInfo.cs b/src/AddIns/Debugger/Debugger.Core/Properties/AssemblyInfo.cs
index 6c9f5b87c5..ecd6793867 100644
--- a/src/AddIns/Debugger/Debugger.Core/Properties/AssemblyInfo.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Properties/AssemblyInfo.cs
@@ -13,5 +13,5 @@ using System.Reflection;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyCopyright("2005-2008 David Srbecký")]
+[assembly: AssemblyCopyright("2005-2012 David Srbecký")]
[assembly: AssemblyVersion("4.0.0.0")]
diff --git a/src/AddIns/Debugger/Debugger.Core/SourcecodeSegment.cs b/src/AddIns/Debugger/Debugger.Core/SourcecodeSegment.cs
index 55b5f92b68..af985081b4 100644
--- a/src/AddIns/Debugger/Debugger.Core/SourcecodeSegment.cs
+++ b/src/AddIns/Debugger/Debugger.Core/SourcecodeSegment.cs
@@ -13,68 +13,18 @@ namespace Debugger
{
public class SourcecodeSegment: DebuggerObject
{
- Module module;
-
- string filename;
- string typename;
- byte[] checkSum;
- int startLine;
- int startColumn;
- int endLine;
- int endColumn;
-
- ICorDebugFunction corFunction;
- int ilStart;
- int ilEnd;
- int[] stepRanges;
-
- public Module Module {
- get { return module; }
- }
-
- public string Filename {
- get { return filename; }
- }
-
- public string Typename {
- get { return typename; }
- }
-
- public byte[] CheckSum {
- get { return checkSum; }
- }
-
- public int StartLine {
- get { return startLine; }
- }
-
- public int StartColumn {
- get { return startColumn; }
- }
-
- public int EndLine {
- get { return endLine; }
- }
-
- public int EndColumn {
- get { return endColumn; }
- }
-
- internal ICorDebugFunction CorFunction {
- get { return corFunction; }
- }
-
- public int ILStart {
- get { return ilStart; }
- }
-
- public int ILEnd {
- get { return ilEnd; }
- }
-
- public int[] StepRanges {
- get { return stepRanges; }
- }
+ public Module Module { get; private set; }
+ public string Filename { get; private set; }
+ public string Typename { get; private set; }
+ public byte[] CheckSum { get; private set; }
+ public int StartLine { get; private set; }
+ public int StartColumn { get; private set; }
+ public int EndLine { get; private set; }
+ public int EndColumn { get; private set; }
+ internal ICorDebugFunction CorFunction { get; private set; }
+ public int ILStart { get; private set; }
+ public int ILEnd { get; private set; }
+ public int[] StepRanges { get; private set; }
private SourcecodeSegment()
{
@@ -150,7 +100,7 @@ namespace Debugger
}
}
- static ISymUnmanagedDocument GetSymDocumentFromFilename(Module module, string filename, byte[] checksum)
+ static ISymUnmanagedDocument GetSymDocumentFromFilename(Module module, string filename)
{
if (filename == null) throw new ArgumentNullException("filename");
@@ -174,15 +124,17 @@ namespace Debugger
return null;
}
- public static SourcecodeSegment Resolve(Module module, string fileName, byte[] checkSum, int line, int column)
+ public static SourcecodeSegment Resolve(Module module, string fileName, int line, int column)
{
// Do not use ISymUnmanagedReader.GetDocument! It is broken if two files have the same name
// Do not use ISymUnmanagedMethod.GetOffset! It sometimes returns negative offset
+ if (fileName == null) return null;
+
ISymUnmanagedReader symReader = module.SymReader;
if (symReader == null) return null; // No symbols
- ISymUnmanagedDocument symDoc = GetSymDocumentFromFilename(module, fileName, checkSum);
+ ISymUnmanagedDocument symDoc = GetSymDocumentFromFilename(module, fileName);
if (symDoc == null) return null; // Document not found
ISymUnmanagedMethod symMethod;
@@ -202,17 +154,17 @@ namespace Debugger
// If the desired breakpoint position is before the end of the sequence point
if (line < sqPoint.EndLine || (line == sqPoint.EndLine && column < sqPoint.EndColumn)) {
SourcecodeSegment segment = new SourcecodeSegment();
- segment.module = module;
- segment.filename = symDoc.GetURL();
- segment.checkSum = symDoc.GetCheckSum();
- segment.startLine = (int)sqPoint.Line;
- segment.startColumn = (int)sqPoint.Column;
- segment.endLine = (int)sqPoint.EndLine;
- segment.endColumn = (int)sqPoint.EndColumn;
- segment.corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken());
- segment.ilStart = (int)sqPoint.Offset;
- segment.ilEnd = (int)sqPoint.Offset;
- segment.stepRanges = null;
+ segment.Module = module;
+ segment.Filename = symDoc.GetURL();
+ segment.CheckSum = symDoc.GetCheckSum();
+ segment.StartLine = (int)sqPoint.Line;
+ segment.StartColumn = (int)sqPoint.Column;
+ segment.EndLine = (int)sqPoint.EndLine;
+ segment.EndColumn = (int)sqPoint.EndColumn;
+ segment.CorFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken());
+ segment.ILStart = (int)sqPoint.Offset;
+ segment.ILEnd = (int)sqPoint.Offset;
+ segment.StepRanges = null;
return segment;
}
}
@@ -300,21 +252,21 @@ namespace Debugger
}
SourcecodeSegment segment = new SourcecodeSegment();
- segment.module = module;
- segment.filename = GetFilenameFromSymDocument(module, sequencePoints[i].Document);
- segment.checkSum = sequencePoints[i].Document.GetCheckSum();
- segment.startLine = (int)sequencePoints[i].Line;
- segment.startColumn = (int)sequencePoints[i].Column;
- segment.endLine = (int)sequencePoints[i].EndLine;
- segment.endColumn = (int)sequencePoints[i].EndColumn;
- segment.corFunction = corFunction;
- segment.ilStart = ilStart;
- segment.ilEnd = ilEnd;
- segment.stepRanges = stepRanges.ToArray();
+ segment.Module = module;
+ segment.Filename = GetFilenameFromSymDocument(module, sequencePoints[i].Document);
+ segment.CheckSum = sequencePoints[i].Document.GetCheckSum();
+ segment.StartLine = (int)sequencePoints[i].Line;
+ segment.StartColumn = (int)sequencePoints[i].Column;
+ segment.EndLine = (int)sequencePoints[i].EndLine;
+ segment.EndColumn = (int)sequencePoints[i].EndColumn;
+ segment.CorFunction = corFunction;
+ segment.ILStart = ilStart;
+ segment.ILEnd = ilEnd;
+ segment.StepRanges = stepRanges.ToArray();
// VB.NET sometimes produces temporary files which it then deletes
// (eg 17d14f5c-a337-4978-8281-53493378c1071.vb)
- string filename = Path.GetFileName(segment.filename);
+ string filename = Path.GetFileName(segment.Filename);
if (filename.Length == 40 && filename.EndsWith(".vb")) {
bool guidName = true;
foreach(char c in filename.Substring(0, filename.Length - 3)) {
@@ -343,7 +295,7 @@ namespace Debugger
{
return string.Format("{0}:{1},{2}-{3},{4}",
Path.GetFileName(this.Filename ?? string.Empty),
- this.startLine, this.startColumn, this.endLine, this.endColumn);
+ this.StartLine, this.StartColumn, this.EndLine, this.EndColumn);
}
#region Decompiled breakpoint
@@ -352,17 +304,17 @@ namespace Debugger
{
try {
SourcecodeSegment segment = new SourcecodeSegment();
- segment.module = module;
- segment.typename = null;
- segment.checkSum = null;
- segment.startLine = line;
- segment.startColumn = 0;
- segment.endLine = line;
- segment.endColumn = 0;
- segment.corFunction = module.CorModule.GetFunctionFromToken((uint)metadataToken);
- segment.ilStart = iLOffset;
- segment.ilEnd = iLOffset;
- segment.stepRanges = null;
+ segment.Module = module;
+ segment.Typename = null;
+ segment.CheckSum = null;
+ segment.StartLine = line;
+ segment.StartColumn = 0;
+ segment.EndLine = line;
+ segment.EndColumn = 0;
+ segment.CorFunction = module.CorModule.GetFunctionFromToken((uint)metadataToken);
+ segment.ILStart = iLOffset;
+ segment.ILEnd = iLOffset;
+ segment.StepRanges = null;
return segment;
} catch {
@@ -372,19 +324,19 @@ namespace Debugger
public static SourcecodeSegment ResolveForIL(Module module, ICorDebugFunction corFunction, int line, int offset, int[] ranges)
{
- try {
+ try {
SourcecodeSegment segment = new SourcecodeSegment();
- segment.module = module;
- segment.typename = null;
- segment.checkSum = null;
- segment.startLine = line;
- segment.startColumn = 0;
- segment.endLine = line;
- segment.endColumn = 0;
- segment.corFunction = corFunction;
- segment.ilStart = offset;
- segment.ilEnd = ranges[1];
- segment.stepRanges = ranges;
+ segment.Module = module;
+ segment.Typename = null;
+ segment.CheckSum = null;
+ segment.StartLine = line;
+ segment.StartColumn = 0;
+ segment.EndLine = line;
+ segment.EndColumn = 0;
+ segment.CorFunction = corFunction;
+ segment.ILStart = offset;
+ segment.ILEnd = ranges[1];
+ segment.StepRanges = ranges;
return segment;
} catch {
diff --git a/src/AddIns/Debugger/Debugger.Core/StackFrame.cs b/src/AddIns/Debugger/Debugger.Core/StackFrame.cs
index 0b6cf9e53b..c5aecad628 100644
--- a/src/AddIns/Debugger/Debugger.Core/StackFrame.cs
+++ b/src/AddIns/Debugger/Debugger.Core/StackFrame.cs
@@ -22,7 +22,7 @@ namespace Debugger
Process process;
ICorDebugILFrame corILFrame;
- object corILFramePauseSession;
+ long corILFramePauseSession;
ICorDebugFunction corFunction;
DebugMethodInfo methodInfo;
@@ -83,14 +83,14 @@ namespace Debugger
{
this.process = thread.Process;
this.thread = thread;
- this.appDomain = process.AppDomains[corILFrame.GetFunction().GetClass().GetModule().GetAssembly().GetAppDomain()];
+ this.appDomain = process.GetAppDomain(corILFrame.GetFunction().GetClass().GetModule().GetAssembly().GetAppDomain());
this.corILFrame = corILFrame;
this.corILFramePauseSession = process.PauseSession;
this.corFunction = corILFrame.GetFunction();
this.chainIndex = chainIndex;
this.frameIndex = frameIndex;
- MetaDataImport metaData = thread.Process.Modules[corFunction.GetClass().GetModule()].MetaData;
+ MetaDataImport metaData = thread.Process.GetModule(corFunction.GetClass().GetModule()).MetaData;
int methodGenArgs = metaData.EnumGenericParams(corFunction.GetToken()).Length;
// Class parameters are first, then the method ones
List corGenArgs = ((ICorDebugILFrame2)corILFrame).EnumerateTypeParameters().ToList();
@@ -241,40 +241,21 @@ namespace Debugger
}
}
- ///
- /// Determine whether the instrustion pointer can be set to given location
- ///
- /// Best possible location. Null is not possible.
- public SourcecodeSegment CanSetIP(string filename, int line, int column)
- {
- return SetIP(true, filename, line, column);
- }
-
- ///
- /// Set the instrustion pointer to given location
- ///
- /// Best possible location. Null is not possible.
- public SourcecodeSegment SetIP(string filename, int line, int column)
- {
- return SetIP(false, filename, line, column);
- }
-
- SourcecodeSegment SetIP(bool simulate, string filename, int line, int column)
+ public SourcecodeSegment SetIP(string filename, int line, int column, bool dryRun)
{
process.AssertPaused();
- SourcecodeSegment segment = SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, filename, null, line, column);
+ SourcecodeSegment segment = SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, filename, line, column);
if (segment != null && segment.CorFunction.GetToken() == this.MethodInfo.MetadataToken) {
try {
- if (simulate) {
+ if (dryRun) {
CorILFrame.CanSetIP((uint)segment.ILStart);
} else {
- // Invalidates all frames and chains for the current thread
CorILFrame.SetIP((uint)segment.ILStart);
+ // Invalidates all frames and chains for the current thread
process.NotifyResumed(DebuggeeStateAction.Keep);
- process.NotifyPaused(PausedReason.SetIP);
- process.RaisePausedEvents();
+ process.NotifyPaused();
}
} catch {
return null;
@@ -345,6 +326,8 @@ namespace Debugger
ICorDebugValue GetArgumentCorValue(int index)
{
+ this.Process.AssertPaused();
+
ICorDebugValue corValue;
try {
// Non-static methods include 'this' as first argument
@@ -380,6 +363,17 @@ namespace Debugger
return loc.GetValue(this);
}
+ public Value GetLocalVariableValue(uint address)
+ {
+ this.Process.AssertPaused();
+ try {
+ return new Value(this.AppDomain, this.CorILFrame.GetLocalVariable(address));
+ } catch (COMException e) {
+ if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Unavailable in optimized code");
+ throw;
+ }
+ }
+
/// Get instance of 'this'. It works well with delegates and enumerators.
[Debugger.Tests.Ignore]
public Value GetLocalVariableThis()
diff --git a/src/AddIns/Debugger/Debugger.Core/Stepper.cs b/src/AddIns/Debugger/Debugger.Core/Stepper.cs
index c8bb8c8d94..3320242df4 100644
--- a/src/AddIns/Debugger/Debugger.Core/Stepper.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Stepper.cs
@@ -8,6 +8,14 @@ namespace Debugger
{
enum StepperOperation {StepIn, StepOver, StepOut};
+ ///
+ /// - During evaluation some chains may be temporarly removed
+ /// - When two events are invoked and JMC is active, step out skips the second function
+ /// - Step out and step over works properly for exceptions
+ /// - Evaluation kills stepper overs on active frame
+ /// - StepRange callbacks go first (probably in order), StepOut callback are called after that
+ /// - StepRange is much slower then StepOut
+ ///
class Stepper
{
StackFrame stackFrame;
@@ -118,7 +126,7 @@ namespace Debugger
}
[Serializable]
- class StepperEventArgs: ProcessEventArgs
+ class StepperEventArgs: EventArgs
{
Stepper stepper;
CorDebugStepReason reason;
@@ -131,7 +139,7 @@ namespace Debugger
get { return reason; }
}
- public StepperEventArgs(Stepper stepper, CorDebugStepReason reason): base(stepper.Process)
+ public StepperEventArgs(Stepper stepper, CorDebugStepReason reason)
{
this.stepper = stepper;
this.reason = reason;
diff --git a/src/AddIns/Debugger/Debugger.Core/Stepping.txt b/src/AddIns/Debugger/Debugger.Core/Stepping.txt
deleted file mode 100644
index e83afbac90..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/Stepping.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-== Notes ==
-- During evaluation some chains may be temporarly removed
-- When two events are invoked and JMC is active, step out skips the second function
-- Step out and step over works properly for exceptions
-- Evaluation kills stepper overs on active frame
-- StepRange callbacks go first (probably in order), StepOut callback are called after that
-- StepRange is much slower then StepOut
diff --git a/src/AddIns/Debugger/Debugger.Core/Thread.cs b/src/AddIns/Debugger/Debugger.Core/Thread.cs
index 9f25b02822..0d7226a707 100644
--- a/src/AddIns/Debugger/Debugger.Core/Thread.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Thread.cs
@@ -22,19 +22,13 @@ namespace Debugger
Stepper currentStepIn;
- StackFrame selectedStackFrame;
-
- Exception currentException;
- DebuggeeState currentException_DebuggeeState;
- ExceptionType currentExceptionType;
- bool currentExceptionIsUnhandled;
-
- public event EventHandler NameChanged;
- public event EventHandler Exited;
-
public Process Process {
get { return process; }
}
+
+ public AppDomain AppDomain {
+ get { return process.GetAppDomain(this.corThread.GetAppDomain()); }
+ }
[Debugger.Tests.Ignore]
public uint ID {
@@ -89,20 +83,9 @@ namespace Debugger
if (this.HasExited) throw new DebuggerException("Already exited");
process.TraceMessage("Thread " + this.ID + " exited");
- if (process.SelectedThread == this) {
- process.SelectedThread = null;
- }
this.HasExited = true;
- OnExited(new ThreadEventArgs(this));
- process.Threads.Remove(this);
- }
-
- protected virtual void OnExited(ThreadEventArgs e)
- {
- if (Exited != null) {
- Exited(this, e);
- }
+ process.threads.Remove(this);
}
/// If the thread is not at safe point, it is not posible to evaluate
@@ -129,7 +112,7 @@ namespace Debugger
Value runTimeValue = RuntimeValue;
if (runTimeValue.IsNull) return ThreadPriority.Normal;
- return (ThreadPriority)(int)runTimeValue.GetMemberValue("m_Priority").PrimitiveValue;
+ return (ThreadPriority)(int)runTimeValue.GetFieldValue("m_Priority").PrimitiveValue;
}
}
@@ -142,7 +125,7 @@ namespace Debugger
process.AssertPaused();
ICorDebugValue corValue = this.CorThread.GetObject();
- return new Value(process.AppDomains[this.CorThread.GetAppDomain()], corValue);
+ return new Value(process.GetAppDomain(this.CorThread.GetAppDomain()), corValue);
}
}
@@ -154,50 +137,12 @@ namespace Debugger
if (!IsInValidState) return string.Empty;
Value runtimeValue = RuntimeValue;
if (runtimeValue.IsNull) return string.Empty;
- Value runtimeName = runtimeValue.GetMemberValue("m_Name");
+ Value runtimeName = runtimeValue.GetFieldValue("m_Name");
if (runtimeName.IsNull) return string.Empty;
return runtimeName.AsString(100);
}
}
- protected virtual void OnNameChanged(ThreadEventArgs e)
- {
- if (NameChanged != null) {
- NameChanged(this, e);
- }
- }
-
- internal void NotifyNameChanged()
- {
- OnNameChanged(new ThreadEventArgs(this));
- }
-
- public Exception CurrentException {
- get {
- if (currentException_DebuggeeState == process.DebuggeeState) {
- return currentException;
- } else {
- return null;
- }
- }
- internal set { currentException = value; }
- }
-
- internal DebuggeeState CurrentException_DebuggeeState {
- get { return currentException_DebuggeeState; }
- set { currentException_DebuggeeState = value; }
- }
-
- public ExceptionType CurrentExceptionType {
- get { return currentExceptionType; }
- internal set { currentExceptionType = value; }
- }
-
- public bool CurrentExceptionIsUnhandled {
- get { return currentExceptionIsUnhandled; }
- internal set { currentExceptionIsUnhandled = value; }
- }
-
/// Tryies to intercept the current exception.
/// The intercepted expression stays available through the CurrentException property.
/// False, if the exception was already intercepted or
@@ -220,9 +165,6 @@ namespace Debugger
}
if (mostRecentUnoptimized == null) return false;
- if (exception == null)
- exception = currentException;
-
try {
// Interception will expire the CorValue so keep permanent reference
exception.MakeValuePermanent();
@@ -345,30 +287,31 @@ namespace Debugger
return stackTrace.ToString();
}
- public StackFrame SelectedStackFrame {
- get {
- if (selectedStackFrame != null && selectedStackFrame.IsInvalid) return null;
- if (process.IsRunning) return null;
- return selectedStackFrame;
- }
- set {
- selectedStackFrame = value;
- }
- }
-
///
/// Returns the most recent stack frame (the one that is currently executing).
/// Returns null if callstack is empty.
///
public StackFrame MostRecentStackFrame {
get {
- foreach(StackFrame stackFrame in Callstack) {
+ foreach(StackFrame stackFrame in this.Callstack) {
return stackFrame;
}
return null;
}
}
+ [Debugger.Tests.Ignore]
+ public StackFrame MostRecentUserStackFrame {
+ get {
+ foreach (StackFrame stackFrame in this.Callstack) {
+ if (!stackFrame.MethodInfo.StepOver) {
+ return stackFrame;
+ }
+ }
+ return null;
+ }
+ }
+
public bool IsInNativeCode {
get {
process.AssertPaused();
@@ -380,21 +323,4 @@ namespace Debugger
}
}
}
-
- [Serializable]
- public class ThreadEventArgs : ProcessEventArgs
- {
- Thread thread;
-
- public Thread Thread {
- get {
- return thread;
- }
- }
-
- public ThreadEventArgs(Thread thread): base(thread.Process)
- {
- this.thread = thread;
- }
- }
}
diff --git a/src/AddIns/Debugger/Debugger.Core/ThreadCollection.cs b/src/AddIns/Debugger/Debugger.Core/ThreadCollection.cs
deleted file mode 100644
index b8bd30ef1c..0000000000
--- a/src/AddIns/Debugger/Debugger.Core/ThreadCollection.cs
+++ /dev/null
@@ -1,42 +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 Debugger.Interop.CorDebug;
-
-namespace Debugger
-{
- public class ThreadCollection: CollectionWithEvents
- {
- public ThreadCollection(NDebugger debugger): base(debugger) {}
-
- Thread selected;
-
- public Thread Selected {
- get { return selected; }
- set { selected = value; }
- }
-
- public Thread Find(Predicate predicate)
- {
- if (predicate == null)
- return null;
-
- foreach (var thread in this)
- {
- if (predicate(thread))
- return thread;
- }
-
- return null;
- }
-
- internal bool Contains(ICorDebugThread corThread)
- {
- foreach(Thread thread in this) {
- if (thread.CorThread == corThread) return true;
- }
- return false;
- }
- }
-}
diff --git a/src/AddIns/Debugger/Debugger.Core/Value.cs b/src/AddIns/Debugger/Debugger.Core/Value.cs
index e104f05c19..64f326c020 100644
--- a/src/AddIns/Debugger/Debugger.Core/Value.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Value.cs
@@ -23,7 +23,7 @@ namespace Debugger
{
AppDomain appDomain;
ICorDebugValue corValue;
- PauseSession corValue_pauseSession;
+ long corValue_pauseSession;
DebugType type;
// Permanently stored as convinience so that it survives Continue
@@ -113,8 +113,7 @@ namespace Debugger
/// Value is valid only until the debuggee is resummed.
public bool IsInvalid {
get {
- return corValue_pauseSession != this.Process.PauseSession &&
- !(corValue is ICorDebugHandleValue);
+ return corValue_pauseSession != this.Process.PauseSession && !(corValue is ICorDebugHandleValue);
}
}
@@ -193,11 +192,11 @@ namespace Debugger
}
// Box value type
- public Value Box()
+ public Value Box(Thread evalThread)
{
byte[] rawValue = this.CorGenericValue.GetRawValue();
// The type must not be a primive type (always true in current design)
- ICorDebugReferenceValue corRefValue = Eval.NewObjectNoConstructor(this.Type).CorReferenceValue;
+ ICorDebugReferenceValue corRefValue = Eval.NewObjectNoConstructor(evalThread, this.Type).CorReferenceValue;
// Make the reference to box permanent
corRefValue = ((ICorDebugHeapValue2)corRefValue.Dereference()).CreateHandle(CorDebugHandleType.HANDLE_STRONG);
// Create new value
@@ -207,8 +206,17 @@ namespace Debugger
return newValue;
}
+ /// If we are sure it is heap value we do not need eval.
[Debugger.Tests.Ignore]
- public Value GetPermanentReference()
+ public Value GetPermanentReferenceOfHeapValue()
+ {
+ if (this.CorValue is ICorDebugReferenceValue) {
+ return GetPermanentReference(null);
+ }
+ throw new DebuggerException("Value is not a heap value");
+ }
+
+ public Value GetPermanentReference(Thread evalThread)
{
if (this.CorValue is ICorDebugHandleValue) {
return this;
@@ -219,12 +227,12 @@ namespace Debugger
if (deRef is ICorDebugHeapValue2) {
return new Value(appDomain, ((ICorDebugHeapValue2)deRef).CreateHandle(CorDebugHandleType.HANDLE_STRONG));
} else {
- // For exampe int* is a refernce not pointing to heap
+ // For exampe int* is a reference not pointing to heap
// TODO: It isn't permanent
return this;
}
} else {
- return this.Box();
+ return this.Box(evalThread);
}
}
@@ -242,13 +250,13 @@ namespace Debugger
}
/// Copy the acutal value from some other Value object
- public void SetValue(Value newValue)
+ public void SetValue(Thread evalThread, Value newValue)
{
ICorDebugValue newCorValue = newValue.CorValue;
if (this.CorValue is ICorDebugReferenceValue) {
if (!(newCorValue is ICorDebugReferenceValue))
- newCorValue = newValue.Box().CorValue;
+ newCorValue = newValue.Box(evalThread).CorValue;
((ICorDebugReferenceValue)this.CorValue).SetValue(((ICorDebugReferenceValue)newCorValue).GetValue());
} else {
this.CorGenericValue.SetRawValue(newValue.CorGenericValue.GetRawValue());
@@ -273,22 +281,24 @@ namespace Debugger
return CorGenericValue.GetValue(this.Type.PrimitiveType);
}
}
- set {
- if (this.Type.FullName == typeof(string).FullName) {
- this.SetValue(Eval.NewString(this.AppDomain, value.ToString()));
- } else {
- if (this.Type.PrimitiveType == null)
- throw new DebuggerException("Value is not a primitive type");
- if (value == null)
- throw new DebuggerException("Can not set primitive value to null");
- object newValue;
- try {
- newValue = Convert.ChangeType(value, this.Type.PrimitiveType);
- } catch {
- throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + this.Type.PrimitiveType.ToString());
- }
- CorGenericValue.SetValue(newValue);
+ }
+
+ public void SetPrimitiveValue(Thread evalThread, object value)
+ {
+ if (this.Type.FullName == typeof(string).FullName) {
+ this.SetValue(evalThread, Eval.NewString(evalThread, value.ToString()));
+ } else {
+ if (this.Type.PrimitiveType == null)
+ throw new DebuggerException("Value is not a primitive type");
+ if (value == null)
+ throw new DebuggerException("Can not set primitive value to null");
+ object newValue;
+ try {
+ newValue = Convert.ChangeType(value, this.Type.PrimitiveType);
+ } catch {
+ throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + this.Type.PrimitiveType.ToString());
}
+ CorGenericValue.SetValue(newValue);
}
}
@@ -370,10 +380,10 @@ namespace Debugger
return CorArrayValue.GetElement(indices);
}
- public void SetArrayElement(int[] elementIndices, Value newVal)
+ public void SetArrayElement(Thread evalThread, int[] elementIndices, Value newVal)
{
Value elem = GetArrayElement(elementIndices);
- elem.SetValue(newVal);
+ elem.SetValue(evalThread, newVal);
}
/// Returns all elements in the array
@@ -409,88 +419,85 @@ namespace Debugger
}
}
- #region Convenience overload methods
-
/// Get a field or property of an object with a given name.
/// Null if not found
- public Value GetMemberValue(string name)
+ public Value GetMemberValue(Thread evalThread, string name)
{
MemberInfo memberInfo = this.Type.GetMember(name, DebugType.BindingFlagsAllInScope, DebugType.IsFieldOrNonIndexedProperty);
if (memberInfo == null)
return null;
- return GetMemberValue(memberInfo);
+ return GetMemberValue(evalThread, memberInfo);
}
/// Get the value of given member.
- public Value GetMemberValue(MemberInfo memberInfo, params Value[] arguments)
+ public Value GetMemberValue(Thread evalThread, MemberInfo memberInfo, params Value[] arguments)
{
- return GetMemberValue(this, memberInfo, arguments);
+ return GetMemberValue(evalThread, this, memberInfo, arguments);
}
- #endregion
-
/// Get the value of given member.
/// null if member is static
- public static Value GetMemberValue(Value objectInstance, MemberInfo memberInfo, params Value[] arguments)
+ public static Value GetMemberValue(Thread evalThread, Value objectInstance, MemberInfo memberInfo, params Value[] arguments)
{
if (memberInfo is FieldInfo) {
if (arguments.Length > 0)
throw new GetValueException("Arguments can not be used for a field");
- return GetFieldValue(objectInstance, (FieldInfo)memberInfo);
+ return GetFieldValue(evalThread, objectInstance, (FieldInfo)memberInfo);
} else if (memberInfo is PropertyInfo) {
- return GetPropertyValue(objectInstance, (PropertyInfo)memberInfo, arguments);
+ return GetPropertyValue(evalThread, objectInstance, (PropertyInfo)memberInfo, arguments);
} else if (memberInfo is MethodInfo) {
- return InvokeMethod(objectInstance, (MethodInfo)memberInfo, arguments);
+ return InvokeMethod(evalThread, objectInstance, (MethodInfo)memberInfo, arguments);
}
throw new DebuggerException("Unknown member type: " + memberInfo.GetType());
}
- #region Convenience overload methods
-
- /// Get the value of given field.
- public Value GetFieldValue(FieldInfo fieldInfo)
+ public static void SetFieldValue(Thread evalThread, Value objectInstance, FieldInfo fieldInfo, Value newValue)
{
- return Value.GetFieldValue(this, fieldInfo);
+ Value val = GetFieldValue(evalThread, objectInstance, fieldInfo);
+ if (!fieldInfo.FieldType.IsAssignableFrom(newValue.Type))
+ throw new GetValueException("Can not assign {0} to {1}", newValue.Type.FullName, fieldInfo.FieldType.FullName);
+ val.SetValue(evalThread, newValue);
}
- #endregion
+ /// Get the value of given instance field.
+ public Value GetFieldValue(string name)
+ {
+ FieldInfo fieldInfo = this.Type.GetMember(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null);
+ if (fieldInfo == null)
+ throw new DebuggerException("Field '{0}' not found", name);
+
+ return new Value(this.AppDomain, GetFieldCorValue(null, this, fieldInfo));
+ }
- public static void SetFieldValue(Value objectInstance, FieldInfo fieldInfo, Value newValue)
+ /// Get the value of given field.
+ public Value GetFieldValue(Thread evalThread, FieldInfo fieldInfo)
{
- Value val = GetFieldValue(objectInstance, fieldInfo);
- if (!fieldInfo.FieldType.IsAssignableFrom(newValue.Type))
- throw new GetValueException("Can not assign {0} to {1}", newValue.Type.FullName, fieldInfo.FieldType.FullName);
- val.SetValue(newValue);
+ return Value.GetFieldValue(evalThread, this, fieldInfo);
}
/// Get the value of given field.
+ /// Thread to use for thread-local storage
/// null if field is static
- public static Value GetFieldValue(Value objectInstance, FieldInfo fieldInfo)
+ public static Value GetFieldValue(Thread evalThread, Value objectInstance, FieldInfo fieldInfo)
{
CheckObject(objectInstance, fieldInfo);
if (fieldInfo.IsStatic && fieldInfo.IsLiteral) {
- return GetLiteralValue((DebugFieldInfo)fieldInfo);
+ return GetLiteralValue(evalThread, (DebugFieldInfo)fieldInfo);
} else {
return new Value(
((DebugFieldInfo)fieldInfo).AppDomain,
- GetFieldCorValue(objectInstance, fieldInfo)
+ GetFieldCorValue(evalThread, objectInstance, fieldInfo)
);
}
}
- static ICorDebugValue GetFieldCorValue(Value objectInstance, FieldInfo fieldInfo)
+ static ICorDebugValue GetFieldCorValue(Thread contextThread, Value objectInstance, FieldInfo fieldInfo)
{
- Process process = ((DebugFieldInfo)fieldInfo).Process;
-
// Current frame is used to resolve context specific static values (eg. ThreadStatic)
ICorDebugFrame curFrame = null;
- if (process.IsPaused &&
- process.SelectedThread != null &&
- process.SelectedThread.MostRecentStackFrame != null &&
- process.SelectedThread.MostRecentStackFrame.CorILFrame != null)
- {
- curFrame = process.SelectedThread.MostRecentStackFrame.CorILFrame;
+ if (contextThread != null && contextThread.MostRecentStackFrame != null && contextThread.MostRecentStackFrame.CorILFrame != null) {
+ curFrame = contextThread.MostRecentStackFrame.CorILFrame;
}
try {
@@ -504,76 +511,54 @@ namespace Debugger
}
}
- static Value GetLiteralValue(DebugFieldInfo fieldInfo)
+ static Value GetLiteralValue(Thread evalThread, DebugFieldInfo fieldInfo)
{
CorElementType corElemType = (CorElementType)fieldInfo.FieldProps.ConstantType;
if (corElemType == CorElementType.CLASS) {
// Only null literals are allowed
- return Eval.CreateValue(fieldInfo.AppDomain, null);
+ return Eval.CreateValue(evalThread, null);
} else if (corElemType == CorElementType.STRING) {
string str = Marshal.PtrToStringUni(fieldInfo.FieldProps.ConstantPtr, (int)fieldInfo.FieldProps.ConstantStringLength);
- return Eval.CreateValue(fieldInfo.AppDomain, str);
+ return Eval.CreateValue(evalThread, str);
} else {
DebugType type = DebugType.CreateFromType(fieldInfo.AppDomain.Mscorlib, DebugType.CorElementTypeToManagedType(corElemType));
if (fieldInfo.FieldType.IsEnum && fieldInfo.FieldType.GetEnumUnderlyingType() == type) {
- Value val = Eval.NewObjectNoConstructor((DebugType)fieldInfo.FieldType);
- Value backingField = val.GetMemberValue("value__");
+ Value val = Eval.NewObjectNoConstructor(evalThread, (DebugType)fieldInfo.FieldType);
+ Value backingField = val.GetMemberValue(evalThread, "value__");
backingField.CorGenericValue.SetValue(fieldInfo.FieldProps.ConstantPtr);
return val;
} else {
- Value val = Eval.NewObjectNoConstructor(type);
+ Value val = Eval.NewObjectNoConstructor(evalThread, type);
val.CorGenericValue.SetValue(fieldInfo.FieldProps.ConstantPtr);
return val;
}
}
}
- #region Convenience overload methods
-
/// Get the value of the property using the get accessor
- public Value GetPropertyValue(PropertyInfo propertyInfo, params Value[] arguments)
+ public Value GetPropertyValue(Thread evalThread, PropertyInfo propertyInfo, params Value[] arguments)
{
- return GetPropertyValue(this, propertyInfo, arguments);
+ return GetPropertyValue(evalThread, this, propertyInfo, arguments);
}
- #endregion
-
/// Get the value of the property using the get accessor
- public static Value GetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, params Value[] arguments)
+ public static Value GetPropertyValue(Thread evalThread, Value objectInstance, PropertyInfo propertyInfo, params Value[] arguments)
{
CheckObject(objectInstance, propertyInfo);
if (propertyInfo.GetGetMethod() == null) throw new GetValueException("Property does not have a get method");
- Value val = Value.InvokeMethod(objectInstance, (DebugMethodInfo)propertyInfo.GetGetMethod(), arguments);
-
- return val;
- }
-
- #region Convenience overload methods
-
- /// Set the value of the property using the set accessor
- public Value SetPropertyValue(PropertyInfo propertyInfo, Value newValue)
- {
- return SetPropertyValue(this, propertyInfo, null, newValue);
+ return Value.InvokeMethod(evalThread, objectInstance, (DebugMethodInfo)propertyInfo.GetGetMethod(), arguments);
}
/// Set the value of the property using the set accessor
- public Value SetPropertyValue(PropertyInfo propertyInfo, Value[] arguments, Value newValue)
+ public Value SetPropertyValue(Thread evalThread, PropertyInfo propertyInfo, Value[] arguments, Value newValue)
{
- return SetPropertyValue(this, propertyInfo, arguments, newValue);
+ return SetPropertyValue(evalThread, this, propertyInfo, arguments, newValue);
}
/// Set the value of the property using the set accessor
- public static Value SetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, Value newValue)
- {
- return SetPropertyValue(objectInstance, propertyInfo, null, newValue);
- }
-
- #endregion
-
- /// Set the value of the property using the set accessor
- public static Value SetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, Value[] arguments, Value newValue)
+ public static Value SetPropertyValue(Thread evalThread, Value objectInstance, PropertyInfo propertyInfo, Value[] arguments, Value newValue)
{
CheckObject(objectInstance, propertyInfo);
@@ -585,25 +570,22 @@ namespace Debugger
allParams[0] = newValue;
arguments.CopyTo(allParams, 1);
- return Value.InvokeMethod(objectInstance, (DebugMethodInfo)propertyInfo.GetSetMethod(), allParams);
+ return Value.InvokeMethod(evalThread, objectInstance, (DebugMethodInfo)propertyInfo.GetSetMethod(), allParams);
}
- #region Convenience overload methods
-
/// Synchronously invoke the method
- public Value InvokeMethod(MethodInfo methodInfo, params Value[] arguments)
+ public Value InvokeMethod(Thread evalThread, MethodInfo methodInfo, params Value[] arguments)
{
- return InvokeMethod(this, methodInfo, arguments);
+ return InvokeMethod(evalThread, this, methodInfo, arguments);
}
- #endregion
-
/// Synchronously invoke the method
- public static Value InvokeMethod(Value objectInstance, MethodInfo methodInfo, params Value[] arguments)
+ public static Value InvokeMethod(Thread evalThread, Value objectInstance, MethodInfo methodInfo, params Value[] arguments)
{
CheckObject(objectInstance, methodInfo);
return Eval.InvokeMethod(
+ evalThread,
(DebugMethodInfo)methodInfo,
methodInfo.IsStatic ? null : objectInstance,
arguments ?? new Value[0]
@@ -611,32 +593,30 @@ namespace Debugger
}
/// Invoke the ToString() method
- public string InvokeToString(int maxLength = int.MaxValue)
+ public string InvokeToString(Thread evalThread, int maxLength = int.MaxValue)
{
+ if (this.IsNull) return AsString(maxLength);
if (this.Type.IsPrimitive) return AsString(maxLength);
if (this.Type.FullName == typeof(string).FullName) return AsString(maxLength);
if (this.Type.IsPointer) return "0x" + this.PointerAddress.ToString("X");
// if (!IsObject) // Can invoke on primitives
DebugMethodInfo methodInfo = (DebugMethodInfo)this.AppDomain.ObjectType.GetMethod("ToString", new DebugType[] {});
- return Eval.InvokeMethod(methodInfo, this, new Value[] {}).AsString(maxLength);
+ return Eval.InvokeMethod(evalThread, methodInfo, this, new Value[] {}).AsString(maxLength);
}
- #region Convenience overload methods
-
/// Asynchronously invoke the method
- public Eval AsyncInvokeMethod(MethodInfo methodInfo, params Value[] arguments)
+ public Eval AsyncInvokeMethod(Thread evalThread, MethodInfo methodInfo, params Value[] arguments)
{
- return AsyncInvokeMethod(this, methodInfo, arguments);
+ return AsyncInvokeMethod(evalThread, this, methodInfo, arguments);
}
- #endregion
-
/// Asynchronously invoke the method
- public static Eval AsyncInvokeMethod(Value objectInstance, MethodInfo methodInfo, params Value[] arguments)
+ public static Eval AsyncInvokeMethod(Thread evalThread, Value objectInstance, MethodInfo methodInfo, params Value[] arguments)
{
CheckObject(objectInstance, methodInfo);
return Eval.AsyncInvokeMethod(
+ evalThread,
(DebugMethodInfo)methodInfo,
methodInfo.IsStatic ? null : objectInstance,
arguments ?? new Value[0]
diff --git a/src/AddIns/Debugger/Debugger.Tests/Debugger.Tests.csproj b/src/AddIns/Debugger/Debugger.Tests/Debugger.Tests.csproj
index 82684e0616..9c117cdddf 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Debugger.Tests.csproj
+++ b/src/AddIns/Debugger/Debugger.Tests/Debugger.Tests.csproj
@@ -77,6 +77,10 @@
{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}
NRefactory
+
+ {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}
+ Debugger.AddIn
+
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}
Debugger.Core
diff --git a/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs b/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs
index 9082f28cef..467695b5fd 100644
--- a/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs
@@ -31,11 +31,9 @@ namespace Debugger.Tests
protected XmlElement snapshotNode;
protected int shapshotID;
- public StackFrame SelectedStackFrame {
- get {
- return process.SelectedStackFrame;
- }
- }
+ public Thread CurrentThread { get; private set; }
+ public StackFrame CurrentStackFrame { get; private set; }
+ public Thread EvalThread { get { return this.CurrentThread; } }
public void Continue()
{
@@ -196,37 +194,40 @@ namespace Debugger.Tests
log = "";
lastLogMessage = null;
- process = debugger.Start(exeFilename, Path.GetDirectoryName(exeFilename), testName);
+ process = debugger.Start(exeFilename, Path.GetDirectoryName(exeFilename), testName, false);
process.LogMessage += delegate(object sender, MessageEventArgs e) {
log += e.Message;
lastLogMessage = e.Message;
LogEvent("LogMessage", e.Message.Replace("\r",@"\r").Replace("\n",@"\n"));
};
- process.Modules.Added += delegate(object sender, CollectionItemEventArgs e) {
- LogEvent("ModuleLoaded", e.Item.Name + (e.Item.HasSymbols ? " (Has symbols)" : " (No symbols)"));
- };
- process.Paused += delegate(object sender, ProcessEventArgs e) {
- LogEvent("DebuggingPaused", e.Process.PauseSession.PausedReason.ToString() + " " + e.Process.SelectedStackFrame.NextStatement.ToString());
+ process.ModuleLoaded += delegate(object sender, ModuleEventArgs e) {
+ LogEvent("ModuleLoaded", e.Module.Name + (e.Module.HasSymbols ? " (Has symbols)" : " (No symbols)"));
};
-// process.DebuggingResumed += delegate(object sender, ProcessEventArgs e) {
-// LogEvent("DebuggingResumed", e.Process.PausedReason.ToString());
-// };
- process.ExceptionThrown += delegate(object sender, ExceptionEventArgs e) {
- StringBuilder msg = new StringBuilder();
- if (process.SelectedThread.InterceptException(e.Exception)) {
- msg.Append(e.Exception.ToString());
+ process.Paused += delegate(object sender, DebuggerEventArgs e) {
+ this.CurrentThread = e.Thread;
+ if (e.Thread != null && e.Thread.IsInValidState) {
+ this.CurrentStackFrame = e.Thread.MostRecentStackFrame;
} else {
- // For example, happens on stack overflow
- msg.Append("Could not intercept: ");
- msg.Append(e.Exception.ToString());
+ this.CurrentStackFrame = null;
+ }
+ if (e.ExceptionThrown != null) {
+ StringBuilder msg = new StringBuilder();
+ if (CurrentThread.InterceptException(e.ExceptionThrown)) {
+ msg.Append(e.ExceptionThrown.ToString());
+ } else {
+ // For example, happens on stack overflow
+ msg.Append("Could not intercept: ");
+ msg.Append(e.ExceptionThrown.ToString());
+ }
+ LogEvent("ExceptionThrown", msg.ToString());
}
- LogEvent("ExceptionThrown", msg.ToString());
+ LogEvent("Paused", CurrentStackFrame != null ? CurrentStackFrame.NextStatement.ToString() : string.Empty);
};
- process.Exited += delegate(object sender, EventArgs e) {
- LogEvent("ProcessExited", null);
+ process.Exited += delegate(object sender, DebuggerEventArgs e) {
+ LogEvent("Exited", null);
};
- LogEvent("ProcessStarted", null);
+ LogEvent("Started", null);
if (wait) {
process.WaitForPause();
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/AppDomain_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/AppDomain_Tests.cs
index 99b3c792c1..9434bc8042 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/AppDomain_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/AppDomain_Tests.cs
@@ -39,12 +39,12 @@ namespace Debugger.Tests {
{
StartTest();
- DebugType type1 = process.SelectedStackFrame.GetLocalVariableValue("one").Type;
- DebugType type1b = process.SelectedStackFrame.GetLocalVariableValue("one").Type;
+ DebugType type1 = this.CurrentStackFrame.GetLocalVariableValue("one").Type;
+ DebugType type1b = this.CurrentStackFrame.GetLocalVariableValue("one").Type;
ObjectDump("SameDomainEqual", type1 == type1b);
process.Continue();
- ObjectDump("AppDomainName", process.SelectedStackFrame.GetLocalVariableValue("appDomainName").AsString());
- DebugType type2 = process.SelectedStackFrame.GetLocalVariableValue("two").Type;
+ ObjectDump("AppDomainName", this.CurrentStackFrame.GetLocalVariableValue("appDomainName").AsString());
+ DebugType type2 = this.CurrentStackFrame.GetLocalVariableValue("two").Type;
ObjectDump("OtherDomainEqual", type1 == type2);
ObjectDump("AppDomainsEqual", type1.AppDomain == type2.AppDomain);
ObjectDump("AppDomainIDsEqual", type1.AppDomain.ID == type2.AppDomain.ID);
@@ -60,19 +60,19 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
AppDomain_Tests.exe (Has symbols)
- Break AppDomain_Tests.cs:13,4-13,40
+ AppDomain_Tests.cs:13,4-13,40
True
mscorlib.dll (No symbols)
AppDomain_Tests.exe (Has symbols)
- Break AppDomain_Tests.cs:26,4-26,40
+ AppDomain_Tests.cs:26,4-26,40
myDomain Id=2
False
False
False
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/Breakpoint_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/Breakpoint_Tests.cs
index 0909840898..366f58621c 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/Breakpoint_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/Breakpoint_Tests.cs
@@ -28,8 +28,8 @@ namespace Debugger.Tests {
[NUnit.Framework.Test]
public void Breakpoint_Tests()
{
- Breakpoint breakpoint1 = debugger.Breakpoints.Add(@"Breakpoint_Tests.cs", 14);
- Breakpoint breakpoint2 = debugger.Breakpoints.Add(@"Breakpoint_Tests.cs", 15);
+ Breakpoint breakpoint1 = debugger.AddBreakpoint(@"Breakpoint_Tests.cs", 14);
+ Breakpoint breakpoint2 = debugger.AddBreakpoint(@"Breakpoint_Tests.cs", 15);
StartTest();
@@ -57,23 +57,23 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
Breakpoint_Tests.exe (Has symbols)
System.dll (No symbols)
- Break Breakpoint_Tests.cs:12,4-12,40
+ Breakpoint_Tests.cs:12,4-12,40
@@ -81,23 +81,23 @@ namespace Debugger.Tests {
System.Configuration.dll (No symbols)
System.Xml.dll (No symbols)
Main 1\r\n
- Breakpoint Breakpoint_Tests.cs:14,4-14,49
+ Breakpoint_Tests.cs:14,4-14,49
Main 2\r\n
- Breakpoint Breakpoint_Tests.cs:16,4-16,49
+ Breakpoint_Tests.cs:16,4-16,49
Main 3\r\n
- Break Breakpoint_Tests.cs:17,4-17,40
-
+ Breakpoint_Tests.cs:17,4-17,40
+
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_DebuggeeKilled.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_DebuggeeKilled.cs
index 74cf7f1c03..57d8a0df02 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_DebuggeeKilled.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_DebuggeeKilled.cs
@@ -42,11 +42,11 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
ControlFlow_DebuggeeKilled.exe (Has symbols)
- Break ControlFlow_DebuggeeKilled.cs:12,4-12,40
-
+ ControlFlow_DebuggeeKilled.cs:12,4-12,40
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_MainThreadExit.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_MainThreadExit.cs
index 7b91fbf995..288d04de36 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_MainThreadExit.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_MainThreadExit.cs
@@ -55,29 +55,26 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
ControlFlow_MainThreadExit.exe (Has symbols)
- Break ControlFlow_MainThreadExit.cs:20,4-20,40
+ ControlFlow_MainThreadExit.cs:20,4-20,40
+ Capacity="4"
+ Count="2">
-
+ RuntimeValue="{System.Threading.Thread}" />
-
- ForcedBreak ControlFlow_MainThreadExit.cs:25,4-25,26
+
+ Capacity="4"
+ Count="2">
-
@@ -100,17 +96,15 @@ namespace Debugger.Tests {
-
+ RuntimeValue="{System.Threading.Thread}" />
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_NoBreak.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_NoBreak.cs
index 04bda9d16c..b7c0b8de19 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_NoBreak.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_NoBreak.cs
@@ -36,10 +36,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
ControlFlow_NoBreak.exe (Has symbols)
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_Stepping.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_Stepping.cs
index d1b99fbe00..1e9c702976 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_Stepping.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_Stepping.cs
@@ -119,69 +119,69 @@ namespace Debugger.Tests {
{
StartTest();
- SourcecodeSegment start = process.SelectedStackFrame.NextStatement;
+ SourcecodeSegment start = this.CurrentStackFrame.NextStatement;
foreach (bool jmcEnabled in new bool[] {true, true, false}) {
ObjectDump("Log", "Starting run with JMC=" + jmcEnabled.ToString());
- process.SelectedStackFrame.SetIP(start.Filename, start.StartLine + 1, start.StartColumn);
+ this.CurrentStackFrame.SetIP(start.Filename, start.StartLine + 1, start.StartColumn, false);
process.Options.EnableJustMyCode = jmcEnabled;
process.Options.StepOverSingleLineProperties = true;
process.Options.StepOverFieldAccessProperties = true;
- process.SelectedStackFrame.StepInto(); // 42.ToString()
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // 42.ToString()
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
if (jmcEnabled) {
- process.SelectedStackFrame.StepInto(); // StepRoot
- Assert.AreEqual("StepRight", process.SelectedStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepOut();
- process.SelectedStackFrame.StepOver(); // Finish the step out
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // StepRoot
+ Assert.AreEqual("StepRight", this.CurrentStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepOut();
+ this.CurrentStackFrame.StepOver(); // Finish the step out
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
} else {
- process.SelectedStackFrame.StepInto(); // StepRoot
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // StepRoot
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
}
- process.SelectedStackFrame.StepInto(); // Generated default constructor
- Assert.AreEqual("Target", process.SelectedStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepOut();
- process.SelectedStackFrame.StepOver(); // Finish the step out
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // Generated default constructor
+ Assert.AreEqual("Target", this.CurrentStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepOut();
+ this.CurrentStackFrame.StepOver(); // Finish the step out
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepInto(); // ShortProperty
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // ShortProperty
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepInto(); // FieldProperty
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // FieldProperty
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepInto(); // CatchExcpetion
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // CatchExcpetion
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
if (jmcEnabled) {
- process.SelectedStackFrame.StepInto(); // ZigZag1
- process.SelectedStackFrame.StepOver();
- process.SelectedStackFrame.StepOver();
- Assert.AreEqual("ZigZag2", process.SelectedStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepInto();
- Assert.AreEqual("ZigZag2", process.SelectedStackFrame.MethodInfo.Name);
- Assert.AreEqual(3, process.SelectedStackFrame.NextStatement.StartColumn);
- process.SelectedStackFrame.StepOut();
- process.SelectedStackFrame.StepOver(); // Finish the step out
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // ZigZag1
+ this.CurrentStackFrame.StepOver();
+ this.CurrentStackFrame.StepOver();
+ Assert.AreEqual("ZigZag2", this.CurrentStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto();
+ Assert.AreEqual("ZigZag2", this.CurrentStackFrame.MethodInfo.Name);
+ Assert.AreEqual(3, this.CurrentStackFrame.NextStatement.StartColumn);
+ this.CurrentStackFrame.StepOut();
+ this.CurrentStackFrame.StepOver(); // Finish the step out
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
} else {
- process.SelectedStackFrame.StepInto(); // ZigZag1
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // ZigZag1
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
}
- process.SelectedStackFrame.StepInto(); // MyEvent
- Assert.AreEqual("Event2", process.SelectedStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepOut();
- Assert.AreEqual("Event4", process.SelectedStackFrame.MethodInfo.Name);
- process.SelectedStackFrame.StepOut();
- process.SelectedStackFrame.StepOver(); // Finish the step out
- Assert.AreEqual("Main", process.SelectedStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepInto(); // MyEvent
+ Assert.AreEqual("Event2", this.CurrentStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepOut();
+ Assert.AreEqual("Event4", this.CurrentStackFrame.MethodInfo.Name);
+ this.CurrentStackFrame.StepOut();
+ this.CurrentStackFrame.StepOver(); // Finish the step out
+ Assert.AreEqual("Main", this.CurrentStackFrame.MethodInfo.Name);
}
// Restore default state
@@ -198,79 +198,76 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
ControlFlow_Stepping.exe (Has symbols)
- Break ControlFlow_Stepping.cs:98,4-98,40
+ ControlFlow_Stepping.cs:98,4-98,40
Starting run with JMC=True
- SetIP ControlFlow_Stepping.cs:99,4-99,37
- StepComplete ControlFlow_Stepping.cs:100,4-100,15
- StepComplete ControlFlow_Stepping.cs:23,27-23,28
- StepComplete ControlFlow_Stepping.cs:100,4-100,15
- StepComplete ControlFlow_Stepping.cs:101,4-101,36
- StepComplete ControlFlow_Stepping.cs:26,25-26,26
- StepComplete ControlFlow_Stepping.cs:101,4-101,36
- StepComplete ControlFlow_Stepping.cs:102,4-102,26
- StepComplete ControlFlow_Stepping.cs:103,4-103,26
- StepComplete ControlFlow_Stepping.cs:104,4-104,21
- StepComplete ControlFlow_Stepping.cs:105,4-105,14
+ ControlFlow_Stepping.cs:100,4-100,15
+ ControlFlow_Stepping.cs:23,27-23,28
+ ControlFlow_Stepping.cs:100,4-100,15
+ ControlFlow_Stepping.cs:101,4-101,36
+ ControlFlow_Stepping.cs:26,25-26,26
+ ControlFlow_Stepping.cs:101,4-101,36
+ ControlFlow_Stepping.cs:102,4-102,26
+ ControlFlow_Stepping.cs:103,4-103,26
+ ControlFlow_Stepping.cs:104,4-104,21
+ ControlFlow_Stepping.cs:105,4-105,14
System.dll (No symbols)
- StepComplete ControlFlow_Stepping.cs:58,3-58,4
- StepComplete ControlFlow_Stepping.cs:59,4-59,46
+ ControlFlow_Stepping.cs:58,3-58,4
+ ControlFlow_Stepping.cs:59,4-59,46
System.Configuration.dll (No symbols)
System.Xml.dll (No symbols)
ZigZag2
- StepComplete ControlFlow_Stepping.cs:60,4-60,14
- StepComplete ControlFlow_Stepping.cs:58,3-58,4
+ ControlFlow_Stepping.cs:60,4-60,14
+ ControlFlow_Stepping.cs:58,3-58,4
ZigZag2
- StepComplete ControlFlow_Stepping.cs:105,4-105,14
- StepComplete ControlFlow_Stepping.cs:106,4-106,35
- StepComplete ControlFlow_Stepping.cs:87,50-87,51
- StepComplete ControlFlow_Stepping.cs:90,50-90,51
- StepComplete ControlFlow_Stepping.cs:106,4-106,35
- StepComplete ControlFlow_Stepping.cs:107,3-107,4
+ ControlFlow_Stepping.cs:105,4-105,14
+ ControlFlow_Stepping.cs:106,4-106,35
+ ControlFlow_Stepping.cs:87,50-87,51
+ ControlFlow_Stepping.cs:90,50-90,51
+ ControlFlow_Stepping.cs:106,4-106,35
+ ControlFlow_Stepping.cs:107,3-107,4
Starting run with JMC=True
- SetIP ControlFlow_Stepping.cs:99,4-99,37
- StepComplete ControlFlow_Stepping.cs:100,4-100,15
- StepComplete ControlFlow_Stepping.cs:23,27-23,28
- StepComplete ControlFlow_Stepping.cs:100,4-100,15
- StepComplete ControlFlow_Stepping.cs:101,4-101,36
- StepComplete ControlFlow_Stepping.cs:26,25-26,26
- StepComplete ControlFlow_Stepping.cs:101,4-101,36
- StepComplete ControlFlow_Stepping.cs:102,4-102,26
- StepComplete ControlFlow_Stepping.cs:103,4-103,26
- StepComplete ControlFlow_Stepping.cs:104,4-104,21
- StepComplete ControlFlow_Stepping.cs:105,4-105,14
- StepComplete ControlFlow_Stepping.cs:58,3-58,4
- StepComplete ControlFlow_Stepping.cs:59,4-59,46
+ ControlFlow_Stepping.cs:100,4-100,15
+ ControlFlow_Stepping.cs:23,27-23,28
+ ControlFlow_Stepping.cs:100,4-100,15
+ ControlFlow_Stepping.cs:101,4-101,36
+ ControlFlow_Stepping.cs:26,25-26,26
+ ControlFlow_Stepping.cs:101,4-101,36
+ ControlFlow_Stepping.cs:102,4-102,26
+ ControlFlow_Stepping.cs:103,4-103,26
+ ControlFlow_Stepping.cs:104,4-104,21
+ ControlFlow_Stepping.cs:105,4-105,14
+ ControlFlow_Stepping.cs:58,3-58,4
+ ControlFlow_Stepping.cs:59,4-59,46
ZigZag2
- StepComplete ControlFlow_Stepping.cs:60,4-60,14
- StepComplete ControlFlow_Stepping.cs:58,3-58,4
+ ControlFlow_Stepping.cs:60,4-60,14
+ ControlFlow_Stepping.cs:58,3-58,4
ZigZag2
- StepComplete ControlFlow_Stepping.cs:105,4-105,14
- StepComplete ControlFlow_Stepping.cs:106,4-106,35
- StepComplete ControlFlow_Stepping.cs:87,50-87,51
- StepComplete ControlFlow_Stepping.cs:90,50-90,51
- StepComplete ControlFlow_Stepping.cs:106,4-106,35
- StepComplete ControlFlow_Stepping.cs:107,3-107,4
+ ControlFlow_Stepping.cs:105,4-105,14
+ ControlFlow_Stepping.cs:106,4-106,35
+ ControlFlow_Stepping.cs:87,50-87,51
+ ControlFlow_Stepping.cs:90,50-90,51
+ ControlFlow_Stepping.cs:106,4-106,35
+ ControlFlow_Stepping.cs:107,3-107,4
Starting run with JMC=False
- SetIP ControlFlow_Stepping.cs:99,4-99,37
- StepComplete ControlFlow_Stepping.cs:100,4-100,15
- StepComplete ControlFlow_Stepping.cs:101,4-101,36
- StepComplete ControlFlow_Stepping.cs:26,25-26,26
- StepComplete ControlFlow_Stepping.cs:101,4-101,36
- StepComplete ControlFlow_Stepping.cs:102,4-102,26
- StepComplete ControlFlow_Stepping.cs:103,4-103,26
- StepComplete ControlFlow_Stepping.cs:104,4-104,21
- StepComplete ControlFlow_Stepping.cs:105,4-105,14
+ ControlFlow_Stepping.cs:100,4-100,15
+ ControlFlow_Stepping.cs:101,4-101,36
+ ControlFlow_Stepping.cs:26,25-26,26
+ ControlFlow_Stepping.cs:101,4-101,36
+ ControlFlow_Stepping.cs:102,4-102,26
+ ControlFlow_Stepping.cs:103,4-103,26
+ ControlFlow_Stepping.cs:104,4-104,21
+ ControlFlow_Stepping.cs:105,4-105,14
ZigZag2
ZigZag2
- StepComplete ControlFlow_Stepping.cs:106,4-106,35
- StepComplete ControlFlow_Stepping.cs:87,50-87,51
- StepComplete ControlFlow_Stepping.cs:90,50-90,51
- StepComplete ControlFlow_Stepping.cs:106,4-106,35
- StepComplete ControlFlow_Stepping.cs:107,3-107,4
-
+ ControlFlow_Stepping.cs:106,4-106,35
+ ControlFlow_Stepping.cs:87,50-87,51
+ ControlFlow_Stepping.cs:90,50-90,51
+ ControlFlow_Stepping.cs:106,4-106,35
+ ControlFlow_Stepping.cs:107,3-107,4
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminatePausedProcess.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminatePausedProcess.cs
index ddf35a769f..cd566ee64c 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminatePausedProcess.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminatePausedProcess.cs
@@ -38,16 +38,16 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
ControlFlow_TerminatePausedProcess.exe (Has symbols)
- Break ControlFlow_TerminatePausedProcess.cs:12,4-12,40
-
-
+ ControlFlow_TerminatePausedProcess.cs:12,4-12,40
+
+
mscorlib.dll (No symbols)
ControlFlow_TerminatePausedProcess.exe (Has symbols)
- Break ControlFlow_TerminatePausedProcess.cs:12,4-12,40
-
+ ControlFlow_TerminatePausedProcess.cs:12,4-12,40
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminateRunningProcess.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminateRunningProcess.cs
index 9feda4d2e1..0707949069 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminateRunningProcess.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ControlFlow_TerminateRunningProcess.cs
@@ -30,11 +30,11 @@ namespace Debugger.Tests {
{
for(int i = 0; i < 2; i++) {
StartTest();
- process.SelectedStackFrame.StepOver();
+ this.CurrentStackFrame.StepOver();
process.Paused += delegate {
Assert.Fail("Should not have received any callbacks after Terminate");
};
- process.SelectedStackFrame.AsyncStepOver();
+ this.CurrentStackFrame.AsyncStepOver();
ObjectDump("Log", "Calling terminate");
process.Terminate();
}
@@ -50,20 +50,20 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
ControlFlow_TerminateRunningProcess.exe (Has symbols)
- Break ControlFlow_TerminateRunningProcess.cs:16,4-16,40
- StepComplete ControlFlow_TerminateRunningProcess.cs:17,4-17,26
+ ControlFlow_TerminateRunningProcess.cs:16,4-16,40
+ ControlFlow_TerminateRunningProcess.cs:17,4-17,26
Calling terminate
-
-
+
+
mscorlib.dll (No symbols)
ControlFlow_TerminateRunningProcess.exe (Has symbols)
- Break ControlFlow_TerminateRunningProcess.cs:16,4-16,40
- StepComplete ControlFlow_TerminateRunningProcess.cs:17,4-17,26
+ ControlFlow_TerminateRunningProcess.cs:16,4-16,40
+ ControlFlow_TerminateRunningProcess.cs:17,4-17,26
Calling terminate
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_CompilerGeneratedClasses.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_CompilerGeneratedClasses.cs
index c958cb2df9..ef103f4b71 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_CompilerGeneratedClasses.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_CompilerGeneratedClasses.cs
@@ -88,10 +88,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
DebugType_CompilerGeneratedClasses.exe (Has symbols)
- Break DebugType_CompilerGeneratedClasses.cs:34,5-34,41
+ DebugType_CompilerGeneratedClasses.cs:34,5-34,41
-
- Break DebugType_CompilerGeneratedClasses.cs:53,6-53,42
+ DebugType_CompilerGeneratedClasses.cs:53,6-53,42
-
- Break DebugType_CompilerGeneratedClasses.cs:50,7-50,43
+ DebugType_CompilerGeneratedClasses.cs:50,7-50,43
-
nestedDelegArg = 402
instanceField = "instance field value"
staticField = "static field value"
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_Tests.cs
index 409265caeb..f96761b388 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/DebugType_Tests.cs
@@ -213,12 +213,11 @@ namespace Debugger.Tests {
{
ObjectDump(
msg,
- SelectedStackFrame.MethodInfo.GetLocalVariables(SelectedStackFrame.IP).Select(v => new LocalVariable() { Name = v.Name, Type = v.LocalType, Value = v.GetValue(process.SelectedStackFrame)})
+ this.CurrentStackFrame.MethodInfo.GetLocalVariables(this.CurrentStackFrame.IP).Select(v => new LocalVariable() { Name = v.Name, Type = v.LocalType, Value = v.GetValue(this.CurrentStackFrame)})
);
}
[NUnit.Framework.Test]
- [NUnit.Framework.Ignore("Broken after Siegfried added the IsGeneric implementation; can't adjust test easily as I'm on .NET 4.5")]
public void DebugType_Tests()
{
if (IsDotnet45Installed())
@@ -232,12 +231,12 @@ namespace Debugger.Tests {
process.Options.StepOverSingleLineProperties = false;
process.Options.StepOverFieldAccessProperties = true;
- ObjectDump("DefinedTypes", process.Modules["DebugType_Tests.exe"].GetNamesOfDefinedTypes());
- ObjectDump("DefinedTypes", process.Modules["DebugType_Tests.exe"].GetDefinedTypes());
+ ObjectDump("DefinedTypes", process.GetModule("DebugType_Tests.exe").GetNamesOfDefinedTypes());
+ ObjectDump("DefinedTypes", process.GetModule("DebugType_Tests.exe").GetDefinedTypes());
- ObjectDump("Members", process.SelectedStackFrame.GetLocalVariableValue("members").Type.GetMembers(DebugType.BindingFlagsAllDeclared));
- ObjectDump("Access-Members", process.SelectedStackFrame.GetLocalVariableValue("access").Type.GetMembers());
- ObjectDump("MyInterfaceImpl-Members", process.SelectedStackFrame.GetLocalVariableValue("myInterfaceImpl").Type.GetMembers());
+ ObjectDump("Members", this.CurrentStackFrame.GetLocalVariableValue("members").Type.GetMembers(DebugType.BindingFlagsAllDeclared));
+ ObjectDump("Access-Members", this.CurrentStackFrame.GetLocalVariableValue("access").Type.GetMembers());
+ ObjectDump("MyInterfaceImpl-Members", this.CurrentStackFrame.GetLocalVariableValue("myInterfaceImpl").Type.GetMembers());
DumpLocalVariables();
EndTest();
@@ -251,10 +250,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
DebugType_Tests.exe (Has symbols)
- Break DebugType_Tests.cs:167,4-167,40
+ DebugType_Tests.cs:167,4-167,40
@@ -688,6 +687,8 @@ namespace Debugger.Tests {
FullName="Int32 Debugger.Tests.DebugType_Tests+MyInterfaceImpl`1[System.Int32].Fun(Debugger.Tests.DebugType_Tests+MyClass a, Debugger.Tests.DebugType_Tests+MyStruct b, System.Object m)"
FullNameWithoutParameterNames="Int32 Debugger.Tests.DebugType_Tests+MyInterfaceImpl`1[System.Int32].Fun(Debugger.Tests.DebugType_Tests+MyClass, Debugger.Tests.DebugType_Tests+MyStruct, System.Object)"
GetLocalVariables="{Debugger.Tests.DebugType_Tests+MyInterfaceImpl`1[System.Int32] this}"
+ IsGenericMethod="True"
+ IsGenericMethodDefinition="True"
Name="Fun"
ReturnType="System.Int32" />
@@ -698,6 +699,8 @@ namespace Debugger.Tests {
FullName="Object[] Debugger.Tests.DebugType_Tests+MyInterfaceImpl`1[System.Int32].Fun2(System.Int32** iPtrPtr, System.Object[,] mdArray, System.Collections.Generic.List`1+Enumerator[System.Object] listEnum)"
FullNameWithoutParameterNames="Object[] Debugger.Tests.DebugType_Tests+MyInterfaceImpl`1[System.Int32].Fun2(System.Int32**, System.Object[,], System.Collections.Generic.List`1+Enumerator[System.Object])"
GetLocalVariables="{Debugger.Tests.DebugType_Tests+MyInterfaceImpl`1[System.Int32] this}"
+ IsGenericMethod="True"
+ IsGenericMethodDefinition="True"
Name="Fun2"
ReturnType="System.Object[]" />
@@ -1679,7 +1682,7 @@ namespace Debugger.Tests {
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/DynamicCode.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/DynamicCode.cs
index 311ce0f98b..68d88ab56f 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/DynamicCode.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/DynamicCode.cs
@@ -56,9 +56,9 @@ namespace Debugger.Tests {
{
StartTest();
- process.SelectedStackFrame.StepOver();
- process.SelectedStackFrame.StepInto();
- Assert.AreEqual("Source.txt", process.SelectedStackFrame.NextStatement.Filename);
+ this.CurrentStackFrame.StepOver();
+ this.CurrentStackFrame.StepInto();
+ Assert.AreEqual("Source.txt", this.CurrentStackFrame.NextStatement.Filename);
EndTest();
}
@@ -71,16 +71,16 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
DynamicCode.exe (Has symbols)
DynamicllyGeneratedAssembly (No symbols)
ISymWrapper.dll (No symbols)
System.dll (No symbols)
- Break DynamicCode.cs:42,4-42,40
- StepComplete DynamicCode.cs:43,4-43,73
- StepComplete Source.txt:1,1-1,100
-
+ DynamicCode.cs:42,4-42,40
+ DynamicCode.cs:43,4-43,73
+ Source.txt:1,1-1,100
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/Exception_Custom.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/Exception_Custom.cs
index afbe5d7973..43fa4167b2 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/Exception_Custom.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/Exception_Custom.cs
@@ -46,12 +46,12 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
Exception_Custom.exe (Has symbols)
Debugger.Tests.MyException: test2 ---> Debugger.Tests.MyException: test1
- ExceptionIntercepted Exception_Custom.cs:23,5-23,39
-
+ Exception_Custom.cs:23,5-23,39
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs
index 2aa62276b7..876fed301f 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs
@@ -205,15 +205,15 @@ namespace Debugger.Tests {
public void ExpressionEvaluator_Tests()
{
StartTest();
- process.SelectedStackFrame.StepOver();
- process.SelectedStackFrame.StepOver(); // Start worker thread
+ this.CurrentStackFrame.StepOver();
+ this.CurrentStackFrame.StepOver(); // Start worker thread
EvalAll(expressionsInput);
// Test member hiding / overloading
- Value myClass = SelectedStackFrame.GetLocalVariableValue("myClass").GetPermanentReference();
- Expression myClassExpr = SelectedStackFrame.MethodInfo.GetLocalVariable(SelectedStackFrame.IP, "myClass").GetExpression();
+ Value myClass = this.CurrentStackFrame.GetLocalVariableValue("myClass").GetPermanentReference(this.EvalThread);
+ Expression myClassExpr = this.CurrentStackFrame.MethodInfo.GetLocalVariable(this.CurrentStackFrame.IP, "myClass").GetExpression();
List expressions = new List();
foreach(MemberInfo memberInfo in myClass.Type.GetFieldsAndNonIndexedProperties(DebugType.BindingFlagsAll)) {
@@ -245,12 +245,12 @@ namespace Debugger.Tests {
// Test type round tripping
- foreach(DebugLocalVariableInfo locVar in process.SelectedStackFrame.MethodInfo.GetLocalVariables()) {
+ foreach(DebugLocalVariableInfo locVar in this.CurrentStackFrame.MethodInfo.GetLocalVariables()) {
if (locVar.Name.StartsWith("complexType")) {
TypeReference complexTypeRef = locVar.LocalType.GetTypeReference();
string code = "typeof(" + complexTypeRef.PrettyPrint() + ")";
TypeOfExpression complexTypeRefRT = (TypeOfExpression)ExpressionEvaluator.Parse(code, SupportedLanguage.CSharp);
- DebugType type = complexTypeRefRT.TypeReference.ResolveType(process.SelectedStackFrame.AppDomain);
+ DebugType type = complexTypeRefRT.TypeReference.ResolveType(this.CurrentStackFrame.AppDomain);
string status = locVar.LocalType.FullName == type.FullName ? "ok" : "fail";
ObjectDumpToString("TypeResulution", string.Format(" {0} = {1} ({2})", code, type.FullName, status));
}
@@ -258,15 +258,15 @@ namespace Debugger.Tests {
// Type equality
- DebugLocalVariableInfo loc = SelectedStackFrame.MethodInfo.GetLocalVariable(SelectedStackFrame.IP, "list");
+ DebugLocalVariableInfo loc = this.CurrentStackFrame.MethodInfo.GetLocalVariable(this.CurrentStackFrame.IP, "list");
Type locType = loc.LocalType;
- Type valType = loc.GetValue(SelectedStackFrame).Type;
+ Type valType = loc.GetValue(this.CurrentStackFrame).Type;
ObjectDump("TypesIdentitcal", object.ReferenceEquals(locType, valType));
ObjectDump("TypesEqual", locType == valType);
- ObjectDump("WorkerThreadMoved", process.SelectedStackFrame.GetThisValue().GetMemberValue("WorkerThreadMoved").AsString());
+ ObjectDump("WorkerThreadMoved", this.CurrentStackFrame.GetThisValue().GetMemberValue(this.EvalThread, "WorkerThreadMoved").AsString());
process.Continue();
- ObjectDump("WorkerThreadMoved", process.SelectedStackFrame.GetThisValue().GetMemberValue("WorkerThreadMoved").AsString());
+ ObjectDump("WorkerThreadMoved", this.CurrentStackFrame.GetThisValue().GetMemberValue(this.EvalThread, "WorkerThreadMoved").AsString());
EndTest();
}
@@ -286,8 +286,8 @@ namespace Debugger.Tests {
restultFmted = null;
} else {
try {
- Value result = ICSharpCode.NRefactory.Visitors.ExpressionEvaluator.Evaluate(expr, SupportedLanguage.CSharp, process.SelectedStackFrame);
- restultFmted = ICSharpCode.NRefactory.Visitors.ExpressionEvaluator.FormatValue(result);
+ Value result = ICSharpCode.NRefactory.Visitors.ExpressionEvaluator.Evaluate(expr, SupportedLanguage.CSharp, this.CurrentStackFrame);
+ restultFmted = ICSharpCode.NRefactory.Visitors.ExpressionEvaluator.FormatValue(this.EvalThread, result);
} catch (GetValueException e) {
restultFmted = e.Message;
}
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/Process_MemoryReadWrite.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/Process_MemoryReadWrite.cs
index e09fa7c808..f7ef425378 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/Process_MemoryReadWrite.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/Process_MemoryReadWrite.cs
@@ -26,8 +26,8 @@ namespace Debugger.Tests {
{
StartTest();
- ulong addrHello = process.SelectedStackFrame.GetLocalVariableValue("hello").Address;
- ulong addrWorld = process.SelectedStackFrame.GetLocalVariableValue("world").Address;
+ ulong addrHello = this.CurrentStackFrame.GetLocalVariableValue("hello").Address;
+ ulong addrWorld = this.CurrentStackFrame.GetLocalVariableValue("world").Address;
addrHello = DeRef(process.ReadMemory(addrHello, 4));
addrWorld = DeRef(process.ReadMemory(addrWorld, 4));
@@ -65,17 +65,17 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
Process_MemoryReadWrite.exe (Has symbols)
System.dll (No symbols)
- Break Process_MemoryReadWrite.cs:14,4-14,40
+ Process_MemoryReadWrite.cs:14,4-14,40
5 0 0 0 48 0 65 0 6C 0 6C 0 6F 0
6 0 0 0 20 0 20 0 20 0 20 0 20 0 21 0
System.Configuration.dll (No symbols)
System.Xml.dll (No symbols)
Hello world!\r\n
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Callstack.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Callstack.cs
index de081d4cb2..7a08d6acac 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Callstack.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Callstack.cs
@@ -33,11 +33,11 @@ namespace Debugger.Tests {
{
StartTest();
- ObjectDump("Callstack", process.SelectedThread.GetCallstack());
- process.SelectedStackFrame.StepOut();
- ObjectDump("Callstack", process.SelectedThread.GetCallstack());
- process.SelectedStackFrame.StepOut();
- ObjectDump("Callstack", process.SelectedThread.GetCallstack());
+ ObjectDump("Callstack", this.CurrentThread.GetCallstack());
+ this.CurrentStackFrame.StepOut();
+ ObjectDump("Callstack", this.CurrentThread.GetCallstack());
+ this.CurrentStackFrame.StepOut();
+ ObjectDump("Callstack", this.CurrentThread.GetCallstack());
EndTest();
}
@@ -50,10 +50,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
StackFrame_Callstack.exe (Has symbols)
- Break StackFrame_Callstack.cs:22,4-22,40
+ StackFrame_Callstack.cs:22,4-22,40
-
- StepComplete StackFrame_Callstack.cs:17,4-17,11
+ StackFrame_Callstack.cs:17,4-17,11
-
- StepComplete StackFrame_Callstack.cs:12,4-12,11
+ StackFrame_Callstack.cs:12,4-12,11
-
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Lifetime.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Lifetime.cs
index bc5636dc40..b6b85829f9 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Lifetime.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Lifetime.cs
@@ -36,21 +36,21 @@ namespace Debugger.Tests {
{
StartTest();
- StackFrame stackFrame = process.SelectedStackFrame;
- ObjectDump("SelectedStackFrame", process.SelectedStackFrame);
+ StackFrame stackFrame = this.CurrentStackFrame;
+ ObjectDump("SelectedStackFrame", this.CurrentStackFrame);
process.Continue(); // Go to the SubFunction
ObjectDump("Old StackFrame", stackFrame);
- ObjectDump("SelectedStackFrame", process.SelectedStackFrame);
+ ObjectDump("SelectedStackFrame", this.CurrentStackFrame);
process.Continue(); // Go back to Function
ObjectDump("Old StackFrame", stackFrame);
- ObjectDump("SelectedStackFrame", process.SelectedStackFrame);
+ ObjectDump("SelectedStackFrame", this.CurrentStackFrame);
process.Continue(); // Setp out of function
- ObjectDump("Main", process.SelectedStackFrame);
+ ObjectDump("Main", this.CurrentStackFrame);
ObjectDump("Old StackFrame", stackFrame);
- ObjectDump("SelectedStackFrame", process.SelectedStackFrame);
+ ObjectDump("SelectedStackFrame", this.CurrentStackFrame);
EndTest();
}
@@ -63,10 +63,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
StackFrame_Lifetime.exe (Has symbols)
- Break StackFrame_Lifetime.cs:18,4-18,40
+ StackFrame_Lifetime.cs:18,4-18,40
- Break StackFrame_Lifetime.cs:25,4-25,40
+ StackFrame_Lifetime.cs:25,4-25,40
- Break StackFrame_Lifetime.cs:20,4-20,40
+ StackFrame_Lifetime.cs:20,4-20,40
- Break StackFrame_Lifetime.cs:13,4-13,40
+ StackFrame_Lifetime.cs:13,4-13,40
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_SetIP.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_SetIP.cs
index 1edc275a26..23f9a15278 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_SetIP.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_SetIP.cs
@@ -26,9 +26,9 @@ namespace Debugger.Tests {
{
StartTest();
- Assert.IsNotNull(process.SelectedStackFrame.CanSetIP("StackFrame_SetIP.cs", 12, 0));
- Assert.IsNull(process.SelectedStackFrame.CanSetIP("StackFrame_SetIP.cs", 100, 0));
- process.SelectedStackFrame.SetIP("StackFrame_SetIP.cs", 12, 0);
+ Assert.IsNotNull(this.CurrentStackFrame.SetIP("StackFrame_SetIP.cs", 12, 0, true));
+ Assert.IsNull(this.CurrentStackFrame.SetIP("StackFrame_SetIP.cs", 100, 0, true));
+ this.CurrentStackFrame.SetIP("StackFrame_SetIP.cs", 12, 0, false);
process.Continue();
Assert.AreEqual("1\r\n1\r\n", log);
@@ -43,18 +43,17 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
StackFrame_SetIP.exe (Has symbols)
System.dll (No symbols)
System.Configuration.dll (No symbols)
System.Xml.dll (No symbols)
1\r\n
- Break StackFrame_SetIP.cs:13,4-13,40
- SetIP StackFrame_SetIP.cs:12,4-12,44
+ StackFrame_SetIP.cs:13,4-13,40
1\r\n
- Break StackFrame_SetIP.cs:13,4-13,40
-
+ StackFrame_SetIP.cs:13,4-13,40
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Tests.cs
index bbd7013d2a..f2f3d84764 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_Tests.cs
@@ -54,10 +54,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
StackFrame_Tests.exe (Has symbols)
- Break StackFrame_Tests.cs:13,5-13,41
+ StackFrame_Tests.cs:13,5-13,41
-
- Break StackFrame_Tests.cs:16,5-16,41
+ StackFrame_Tests.cs:16,5-16,41
-
- Break StackFrame_Tests.cs:19,4-19,40
+ StackFrame_Tests.cs:19,4-19,40
-
- Break StackFrame_Tests.cs:23,4-23,40
+ StackFrame_Tests.cs:23,4-23,40
-
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_VariablesLifetime.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_VariablesLifetime.cs
index 720052911f..5041ce0a07 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_VariablesLifetime.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/StackFrame_VariablesLifetime.cs
@@ -46,15 +46,15 @@ namespace Debugger.Tests {
StartTest(); // 1 - Enter program
- argument = process.SelectedStackFrame.GetArgumentValue(0);
- local = process.SelectedStackFrame.GetLocalVariableValue("local");
- @class = process.SelectedStackFrame.GetThisValue().GetMemberValue("class");
+ argument = this.CurrentStackFrame.GetArgumentValue(0);
+ local = this.CurrentStackFrame.GetLocalVariableValue("local");
+ @class = this.CurrentStackFrame.GetThisValue().GetMemberValue(this.EvalThread, "class");
ObjectDump("argument", argument);
ObjectDump("local", local);
ObjectDump("@class", @class);
process.Continue(); // 2 - Go to the SubFunction
- localInSubFunction = process.SelectedStackFrame.GetLocalVariableValue("localInSubFunction");
+ localInSubFunction = this.CurrentStackFrame.GetLocalVariableValue("localInSubFunction");
ObjectDump("argument", argument);
ObjectDump("local", local);
ObjectDump("@class", @class);
@@ -71,7 +71,7 @@ namespace Debugger.Tests {
ObjectDump("local", local);
ObjectDump("@class", @class);
ObjectDump("localInSubFunction", @localInSubFunction);
- localInSubFunction = process.SelectedStackFrame.GetLocalVariableValue("localInSubFunction");
+ localInSubFunction = this.CurrentStackFrame.GetLocalVariableValue("localInSubFunction");
ObjectDump("localInSubFunction(new)", @localInSubFunction);
process.Continue(); // 5 - Setp out of both functions
@@ -91,10 +91,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
StackFrame_VariablesLifetime.exe (Has symbols)
- Break StackFrame_VariablesLifetime.cs:21,4-21,40
+ StackFrame_VariablesLifetime.cs:21,4-21,40
- Break StackFrame_VariablesLifetime.cs:30,4-30,40
+ StackFrame_VariablesLifetime.cs:30,4-30,40
- Break StackFrame_VariablesLifetime.cs:23,4-23,40
+ StackFrame_VariablesLifetime.cs:23,4-23,40
- Break StackFrame_VariablesLifetime.cs:30,4-30,40
+ StackFrame_VariablesLifetime.cs:30,4-30,40
- Break StackFrame_VariablesLifetime.cs:15,4-15,40
+ StackFrame_VariablesLifetime.cs:15,4-15,40
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/Thread_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/Thread_Tests.cs
index 09b28a4390..c8af696246 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/Thread_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/Thread_Tests.cs
@@ -9,6 +9,7 @@ namespace Debugger.Tests
{
public static void Main()
{
+ System.Diagnostics.Debugger.Break();
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.AboveNormal;
System.Diagnostics.Debugger.Break();
System.Threading.Thread.CurrentThread.Name = "ThreadName";
@@ -24,21 +25,14 @@ namespace Debugger.Tests {
[NUnit.Framework.Test]
public void Thread_Tests()
{
- debugger.Processes.Added += debugger_ProcessStarted;
StartTest();
- debugger.Processes.Added -= debugger_ProcessStarted;
- ObjectDump("Thread", process.SelectedThread);
+ ObjectDump("Thread", this.CurrentThread);
+ process.Continue();
+ ObjectDump("Thread", this.CurrentThread);
process.Continue();
- ObjectDump("Thread", process.SelectedThread);
+ ObjectDump("Thread", this.CurrentThread);
EndTest();
}
-
- void debugger_ProcessStarted(object sender, CollectionItemEventArgs e)
- {
- e.Item.Threads.Added += delegate(object sender2, CollectionItemEventArgs f) {
- ObjectDump("ThreadStartedEvent", f.Item);
- };
- }
}
}
#endif
@@ -48,58 +42,43 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
-
+ Thread_Tests.exe (Has symbols)
+ Thread_Tests.cs:12,4-12,40
+
-
- Thread_Tests.exe (Has symbols)
- Break Thread_Tests.cs:13,4-13,40
+ RuntimeValue="{System.Threading.Thread}" />
+
+ Thread_Tests.cs:14,4-14,40
+ RuntimeValue="{System.Threading.Thread}" />
- Break Thread_Tests.cs:15,4-15,40
+ Thread_Tests.cs:16,4-16,40
+ RuntimeValue="{System.Threading.Thread}" />
-
-
-
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/Value_Tests.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/Value_Tests.cs
index 6eebf3999c..2021910972 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/Value_Tests.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/Value_Tests.cs
@@ -40,11 +40,11 @@ namespace Debugger.Tests {
DumpLocalVariables();
- Value array = process.SelectedStackFrame.GetLocalVariableValue("array").GetPermanentReference();
- ObjectDump("array.Length", array.GetMemberValue("Length"));
+ Value array = this.CurrentStackFrame.GetLocalVariableValue("array").GetPermanentReference(this.EvalThread);
+ ObjectDump("array.Length", array.GetMemberValue(this.EvalThread, "Length"));
ObjectDump("array", array);
- Value lbArray = process.SelectedStackFrame.GetLocalVariableValue("lbArray").GetPermanentReference();
+ Value lbArray = this.CurrentStackFrame.GetLocalVariableValue("lbArray").GetPermanentReference(this.EvalThread);
ObjectDump("lbArray", lbArray);
ObjectDump("lbArray-10-20", lbArray.GetArrayElement(new int[] {10, 20}));
@@ -59,10 +59,10 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
Value_Tests.exe (Has symbols)
- Break Value_Tests.cs:27,4-27,40
+ Value_Tests.cs:27,4-27,40
-
-
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/Debugger/Debugger.Tests/Tests/_HelloWorldTest.cs b/src/AddIns/Debugger/Debugger.Tests/Tests/_HelloWorldTest.cs
index d32fa7f838..f667725372 100644
--- a/src/AddIns/Debugger/Debugger.Tests/Tests/_HelloWorldTest.cs
+++ b/src/AddIns/Debugger/Debugger.Tests/Tests/_HelloWorldTest.cs
@@ -36,15 +36,15 @@ namespace Debugger.Tests {
-
+
mscorlib.dll (No symbols)
_HelloWorldTest.exe (Has symbols)
System.dll (No symbols)
System.Configuration.dll (No symbols)
System.Xml.dll (No symbols)
Hello world!\r\n
- Break _HelloWorldTest.cs:14,4-14,40
-
+ _HelloWorldTest.cs:14,4-14,40
+
#endif // EXPECTED_OUTPUT
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
index f3cad8d692..8a95352026 100755
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
@@ -246,7 +246,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
#region Tooltip
ToolTip toolTip;
- Popup popup;
+ Popup popupToolTip;
void TextEditorMouseHover(object sender, MouseEventArgs e)
{
@@ -287,26 +287,19 @@ namespace ICSharpCode.AvalonEdit.AddIn
ToolTipRequestService.RequestToolTip(args);
}
+ if (!TryCloseExistingPopup(false)) {
+ return;
+ }
+
if (args.ContentToShow != null) {
- var contentToShowITooltip = args.ContentToShow as ITooltip;
+ popupToolTip = args.ContentToShow as Popup;
- if (contentToShowITooltip != null && contentToShowITooltip.ShowAsPopup) {
- if (!(args.ContentToShow is UIElement)) {
- throw new NotSupportedException("Content to show in Popup must be UIElement: " + args.ContentToShow);
- }
- if (popup == null) {
- popup = CreatePopup();
- }
- // if popup was only first level, hovering somewhere else closes it
- if (TryCloseExistingPopup(false)) {
-
- // when popup content decides to close, close the popup
- contentToShowITooltip.Closed += (closedSender, closedArgs) => { popup.IsOpen = false; };
- popup.Child = (UIElement)args.ContentToShow;
- //ICSharpCode.SharpDevelop.Debugging.DebuggerService.CurrentDebugger.IsProcessRunningChanged
- SetPopupPosition(popup, e);
- popup.IsOpen = true;
- }
+ if (popupToolTip != null) {
+ var popupPosition = GetPopupPosition(e);
+ popupToolTip.HorizontalOffset = popupPosition.X;
+ popupToolTip.VerticalOffset = popupPosition.Y;
+ popupToolTip.IsOpen = true;
+ popupToolTip.StaysOpen = true; // We will close it ourselves
e.Handled = true;
} else {
if (toolTip == null) {
@@ -328,35 +321,19 @@ namespace ICSharpCode.AvalonEdit.AddIn
toolTip.IsOpen = true;
e.Handled = true;
}
- } else {
- // close popup if mouse hovered over empty area
- if (popup != null) {
- e.Handled = true;
- }
- TryCloseExistingPopup(false);
}
}
- bool TryCloseExistingPopup(bool hard)
+ bool TryCloseExistingPopup(bool mouseClick)
{
- bool canClose = true;
- if (popup != null) {
- var popupContentITooltip = popup.Child as ITooltip;
- if (popupContentITooltip != null) {
- canClose = popupContentITooltip.Close(hard);
- }
- if (canClose) {
- popup.IsOpen = false;
+ if (popupToolTip != null) {
+ if (popupToolTip.IsOpen && !mouseClick && popupToolTip is ITooltip && !((ITooltip)popupToolTip).CloseOnHoverEnd) {
+ return false; // Popup does not want to be closed yet
}
+ popupToolTip.IsOpen = false;
+ popupToolTip = null;
}
- return canClose;
- }
-
- void SetPopupPosition(Popup popup, MouseEventArgs mouseArgs)
- {
- var popupPosition = GetPopupPosition(mouseArgs);
- popup.HorizontalOffset = popupPosition.X;
- popup.VerticalOffset = popupPosition.Y;
+ return true;
}
/// Returns Popup position based on mouse position, in device independent units
@@ -379,17 +356,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
return positionInPixels.TransformFromDevice(this);
}
- Popup CreatePopup()
- {
- popup = new Popup();
- popup.Closed += PopupClosed;
- popup.AllowsTransparency = true;
- popup.PlacementTarget = this; // required for property inheritance
- popup.Placement = PlacementMode.Absolute;
- popup.StaysOpen = true;
- return popup;
- }
-
void TextEditorMouseHoverStopped(object sender, MouseEventArgs e)
{
if (toolTip != null) {
@@ -400,7 +366,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
void TextEditorMouseLeave(object sender, MouseEventArgs e)
{
- if (popup != null && !popup.IsMouseOver) {
+ if (popupToolTip != null && !popupToolTip.IsMouseOver) {
// do not close popup if mouse moved from editor to popup
TryCloseExistingPopup(false);
}
@@ -411,11 +377,6 @@ namespace ICSharpCode.AvalonEdit.AddIn
toolTip = null;
}
- void PopupClosed(object sender, EventArgs e)
- {
- popup = null;
- }
-
#region GetTooltipTextForCollapsedSection
string GetTooltipTextForCollapsedSection(FoldingSection foldingSection)
{
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs
index 97ecfdeaef..47268c4c23 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CustomizableHighlightingColorizer.cs
@@ -31,6 +31,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
public const string LinkText = "Link text";
public const string BreakpointMarker = "Breakpoint";
public const string InstructionPointerMarker = "Current statement";
+ public const string ColumnRuler = "Column ruler";
public static void ApplyCustomizationsToDefaultElements(TextEditor textEditor, IEnumerable customizations)
{
@@ -43,7 +44,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
textEditor.TextArea.TextView.ClearValue(TextView.NonPrintableCharacterBrushProperty);
textEditor.TextArea.TextView.ClearValue(TextView.LinkTextForegroundBrushProperty);
textEditor.TextArea.TextView.ClearValue(TextView.LinkTextBackgroundBrushProperty);
- textEditor.TextArea.TextView.ClearValue(TextView.ColumnRulerBrushProperty);
+ textEditor.TextArea.TextView.ClearValue(TextView.ColumnRulerPenProperty);
// 'assigned' flags are used so that the first matching customization wins.
// This is necessary because more specific customizations come first in the list
@@ -110,12 +111,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (color.Background != null)
textEditor.TextArea.TextView.LinkTextBackgroundBrush = CreateFrozenBrush(color.Background.Value);
break;
- case ColumnRulerRenderer.Name:
+ case ColumnRuler:
if (assignedColumnRulerColor)
continue;
assignedColumnRulerColor = true;
if (color.Foreground != null)
- textEditor.TextArea.TextView.ColumnRulerBrush = CreateFrozenBrush(color.Foreground.Value);
+ textEditor.TextArea.TextView.ColumnRulerPen = CreateFrozenPen(color.Foreground.Value);
break;
}
}
@@ -347,5 +348,12 @@ namespace ICSharpCode.AvalonEdit.AddIn
brush.Freeze();
return brush;
}
+
+ static Pen CreateFrozenPen(Color color)
+ {
+ Pen pen = new Pen(CreateFrozenBrush(color), 1);
+ pen.Freeze();
+ return pen;
+ }
}
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
index b2f7dad566..4a46f0fe43 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs
@@ -431,14 +431,14 @@ namespace ICSharpCode.AvalonEdit.AddIn.Options
items.Add(currentStatementMarker);
IHighlightingItem columnRuler = new SimpleHighlightingItem(
- ColumnRulerRenderer.Name,
+ CustomizableHighlightingColorizer.ColumnRuler,
ta => {
ta.Document.Text = "some line with a lot of text";
ta.TextView.Options.ColumnRulerPosition = 15;
ta.TextView.Options.ShowColumnRuler = true;
})
{
- Foreground = ColumnRulerRenderer.DefaultForeground
+ Foreground = Colors.LightGray
};
columnRuler = new CustomizedHighlightingItem(customizationList, columnRuler, language, canSetFont: false, canSetBackground: false);
columnRuler.PropertyChanged += item_PropertyChanged;
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs
index 1dd2047a18..e1c0bb1484 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/XmlDoc/XmlDocTooltipProvider.cs
@@ -4,6 +4,7 @@
using System;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.AddIn.Options;
@@ -34,7 +35,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
}
}
- sealed class FlowDocumentTooltip : Border, ITooltip
+ sealed class FlowDocumentTooltip : Popup, ITooltip
{
FlowDocumentScrollViewer viewer;
@@ -42,26 +43,23 @@ namespace ICSharpCode.AvalonEdit.AddIn.XmlDoc
{
viewer = new FlowDocumentScrollViewer();
viewer.Document = document;
- this.Child = viewer;
-
- this.Background = SystemColors.InfoBrush;
+ Border border = new Border {
+ Background = SystemColors.InfoBrush,
+ BorderBrush = SystemColors.InfoTextBrush,
+ BorderThickness = new Thickness(1),
+ MaxHeight = 400,
+ Child = viewer
+ };
+ this.Child = border;
viewer.Foreground = SystemColors.InfoTextBrush;
- this.BorderBrush = SystemColors.InfoTextBrush;
- this.BorderThickness = new Thickness(1);
- this.MaxHeight = 400;
document.FontSize = CodeEditorOptions.Instance.FontSize;
}
public event RoutedEventHandler Closed { add {} remove {} }
- public bool ShowAsPopup {
+ public bool CloseOnHoverEnd {
get { return true; }
}
-
- public bool Close(bool mouseClick)
- {
- return true;
- }
}
object CreateTooltip(IType type)
diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs
index aab1ac03d0..e5c89b553b 100644
--- a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs
+++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs
@@ -76,7 +76,7 @@ namespace ICSharpCode.ILSpyAddIn.ViewContent
#region Popup
ToolTip toolTip;
- Popup popup;
+ Popup popupToolTip;
void TextEditorMouseHover(object sender, MouseEventArgs e)
{
@@ -92,24 +92,19 @@ namespace ICSharpCode.ILSpyAddIn.ViewContent
ToolTipRequestService.RequestToolTip(args);
}
+ if (!TryCloseExistingPopup(false)) {
+ return;
+ }
+
if (args.ContentToShow != null) {
- var contentToShowITooltip = args.ContentToShow as ITooltip;
+ popupToolTip = args.ContentToShow as Popup;
- if (contentToShowITooltip != null && contentToShowITooltip.ShowAsPopup) {
- if (!(args.ContentToShow is UIElement)) {
- throw new NotSupportedException("Content to show in Popup must be UIElement: " + args.ContentToShow);
- }
- if (popup == null) {
- popup = CreatePopup();
- }
- if (TryCloseExistingPopup(false)) {
- // when popup content decides to close, close the popup
- contentToShowITooltip.Closed += (closedSender, closedArgs) => { popup.IsOpen = false; };
- popup.Child = (UIElement)args.ContentToShow;
- //ICSharpCode.SharpDevelop.Debugging.DebuggerService.CurrentDebugger.IsProcessRunningChanged
- SetPopupPosition(popup, e);
- popup.IsOpen = true;
- }
+ if (popupToolTip != null) {
+ var popupPosition = GetPopupPosition(e);
+ popupToolTip.HorizontalOffset = popupPosition.X;
+ popupToolTip.VerticalOffset = popupPosition.Y;
+ popupToolTip.IsOpen = true;
+ popupToolTip.StaysOpen = true; // We will close it ourselves
e.Handled = true;
} else {
if (toolTip == null) {
@@ -131,35 +126,19 @@ namespace ICSharpCode.ILSpyAddIn.ViewContent
toolTip.IsOpen = true;
e.Handled = true;
}
- } else {
- // close popup if mouse hovered over empty area
- if (popup != null) {
- e.Handled = true;
- }
- TryCloseExistingPopup(false);
}
}
bool TryCloseExistingPopup(bool mouseClick)
{
- bool canClose = true;
- if (popup != null) {
- var popupContentITooltip = popup.Child as ITooltip;
- if (popupContentITooltip != null) {
- canClose = popupContentITooltip.Close(mouseClick);
- }
- if (canClose) {
- popup.IsOpen = false;
+ if (popupToolTip != null) {
+ if (popupToolTip.IsOpen && !mouseClick && popupToolTip is ITooltip && !((ITooltip)popupToolTip).CloseOnHoverEnd) {
+ return false; // Popup does not want to be closed yet
}
+ popupToolTip.IsOpen = false;
+ popupToolTip = null;
}
- return canClose;
- }
-
- void SetPopupPosition(Popup popup, MouseEventArgs mouseArgs)
- {
- var popupPosition = GetPopupPosition(mouseArgs);
- popup.HorizontalOffset = popupPosition.X;
- popup.VerticalOffset = popupPosition.Y;
+ return true;
}
/// Returns Popup position based on mouse position, in device independent units
@@ -182,17 +161,6 @@ namespace ICSharpCode.ILSpyAddIn.ViewContent
return positionInPixels.TransformFromDevice(this);
}
- Popup CreatePopup()
- {
- popup = new Popup();
- popup.Closed += (s, e) => popup = null;
- popup.AllowsTransparency = true;
- popup.PlacementTarget = this; // required for property inheritance
- popup.Placement = PlacementMode.Absolute;
- popup.StaysOpen = true;
- return popup;
- }
-
void TextEditorMouseHoverStopped(object sender, MouseEventArgs e)
{
if (toolTip != null) {
@@ -205,7 +173,7 @@ namespace ICSharpCode.ILSpyAddIn.ViewContent
void TextEditorMouseLeave(object sender, MouseEventArgs e)
{
- if (popup != null && !popup.IsMouseOver) {
+ if (popupToolTip != null && !popupToolTip.IsMouseOver) {
// do not close popup if mouse moved from editor to popup
TryCloseExistingPopup(false);
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ColumnRulerRenderer.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ColumnRulerRenderer.cs
index f809b57de4..bcf5772d76 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ColumnRulerRenderer.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/ColumnRulerRenderer.cs
@@ -8,18 +8,17 @@ using System.Windows.Media;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Utils;
-namespace ICSharpCode.AvalonEdit
+namespace ICSharpCode.AvalonEdit.Rendering
{
///
/// Renders a ruler at a certain column.
///
- public class ColumnRulerRenderer : IBackgroundRenderer
+ sealed class ColumnRulerRenderer : IBackgroundRenderer
{
Pen pen;
int column;
TextView textView;
- public const string Name = "Column ruler";
public static readonly Color DefaultForeground = Colors.LightGray;
public ColumnRulerRenderer(TextView textView)
@@ -37,15 +36,14 @@ namespace ICSharpCode.AvalonEdit
get { return KnownLayer.Background; }
}
- public void SetRuler(int column, Brush brush)
+ public void SetRuler(int column, Pen pen)
{
if (this.column != column) {
this.column = column;
textView.InvalidateLayer(this.Layer);
}
- if (pen.Brush != brush) {
- this.pen = new Pen(brush, 1);
- this.pen.Freeze();
+ if (this.pen != pen) {
+ this.pen = pen;
textView.InvalidateLayer(this.Layer);
}
}
diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
index 5355858c57..e8c19f53cf 100644
--- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
+++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
@@ -54,7 +54,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
backgroundRenderers = new ObserveAddRemoveCollection(BackgroundRenderer_Added, BackgroundRenderer_Removed);
columnRulerRenderer = new ColumnRulerRenderer(this);
this.Options = new TextEditorOptions();
- this.columnRulerRenderer.SetRuler(Options.ColumnRulerPosition, ColumnRulerBrush);
+ this.columnRulerRenderer.SetRuler(Options.ColumnRulerPosition, ColumnRulerPen);
Debug.Assert(singleCharacterElementGenerator != null); // assert that the option change created the builtin element generators
@@ -204,13 +204,10 @@ namespace ICSharpCode.AvalonEdit.Rendering
OptionChanged(this, e);
}
- // PropertyName == null means all properties are changed
- if (e.PropertyName == null || e.PropertyName == "ColumnRulerPosition" || e.PropertyName == "ShowColumnRuler") {
- if (Options.ShowColumnRuler)
- columnRulerRenderer.SetRuler(Options.ColumnRulerPosition, ColumnRulerBrush);
- else
- columnRulerRenderer.SetRuler(-1, ColumnRulerBrush);
- }
+ if (Options.ShowColumnRuler)
+ columnRulerRenderer.SetRuler(Options.ColumnRulerPosition, ColumnRulerPen);
+ else
+ columnRulerRenderer.SetRuler(-1, ColumnRulerPen);
UpdateBuiltinElementGeneratorsFromOptions();
Redraw();
@@ -1951,24 +1948,33 @@ namespace ICSharpCode.AvalonEdit.Rendering
InvalidateDefaultTextMetrics();
Redraw();
}
+ if (e.Property == ColumnRulerPenProperty) {
+ columnRulerRenderer.SetRuler(this.Options.ColumnRulerPosition, this.ColumnRulerPen);
+ }
}
- public static readonly DependencyProperty ColumnRulerBrushProperty =
- DependencyProperty.Register("ColumnRulerBrush", typeof(Brush), typeof(TextView),
- new FrameworkPropertyMetadata(Brushes.LightGray, OnUpdateBrushes));
-
- public Brush ColumnRulerBrush {
- get { return (Brush)GetValue(ColumnRulerBrushProperty); }
- set { SetValue(ColumnRulerBrushProperty, value); }
- }
+ ///
+ /// The pen used to draw the column ruler.
+ ///
+ ///
+ public static readonly DependencyProperty ColumnRulerPenProperty =
+ DependencyProperty.Register("ColumnRulerBrush", typeof(Pen), typeof(TextView),
+ new FrameworkPropertyMetadata(CreateFrozenPen(Brushes.LightGray)));
- public static void OnUpdateBrushes(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ static Pen CreateFrozenPen(SolidColorBrush brush)
{
- TextView view = d as TextView;
- if (view == null) return;
- if (e.Property == ColumnRulerBrushProperty)
- view.columnRulerRenderer.SetRuler(view.Options.ColumnRulerPosition, (Brush)e.NewValue);
+ Pen pen = new Pen(brush, 1);
+ pen.Freeze();
+ return pen;
}
+ ///
+ /// Gets/Sets the pen used to draw the column ruler.
+ ///
+ ///
+ public Pen ColumnRulerPen {
+ get { return (Pen)GetValue(ColumnRulerPenProperty); }
+ set { SetValue(ColumnRulerPenProperty, value); }
+ }
}
}
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
index b8bfada506..caf3d4c544 100755
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
@@ -1142,12 +1142,12 @@
+ class = "ICSharpCode.SharpDevelop.Bookmarks.DeleteMark"/>
+ class = "ICSharpCode.SharpDevelop.Bookmarks.DeleteAllMarks"/>
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index f7e840c8fa..bab5fa831b 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -94,9 +94,6 @@
Src\Project\MSBuildEngine\ExtendedBinaryReader.cs
-
- ListViewPad.xaml
-
@@ -372,10 +369,6 @@
-
-
-
-
@@ -661,8 +654,6 @@
-
-
@@ -815,7 +806,7 @@
-
+
@@ -851,13 +842,11 @@
-
-
diff --git a/src/Main/Base/Project/Src/Bookmarks/BookmarkBase.cs b/src/Main/Base/Project/Src/Bookmarks/BookmarkBase.cs
index 97044671de..6b650d8951 100644
--- a/src/Main/Base/Project/Src/Bookmarks/BookmarkBase.cs
+++ b/src/Main/Base/Project/Src/Bookmarks/BookmarkBase.cs
@@ -3,8 +3,11 @@
using System;
using System.Windows.Input;
+using System.Windows.Media;
+
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.SharpDevelop.Bookmarks
{
@@ -155,6 +158,10 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
get { return DefaultBookmarkImage; }
}
+ public ImageSource ImageSource {
+ get { return this.Image != null ? this.Image.ImageSource : null; }
+ }
+
public virtual void MouseDown(MouseButtonEventArgs e)
{
}
diff --git a/src/Main/Base/Project/Src/Bookmarks/BookmarkConverter.cs b/src/Main/Base/Project/Src/Bookmarks/BookmarkConverter.cs
index 1d65aad0b3..ada0bb7036 100644
--- a/src/Main/Base/Project/Src/Bookmarks/BookmarkConverter.cs
+++ b/src/Main/Base/Project/Src/Bookmarks/BookmarkConverter.cs
@@ -63,24 +63,6 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
bbm.Condition = script;
bookmark = bbm;
break;
- case "PinBookmark":
- var pin = new PinBookmark(fileName, new TextLocation(lineNumber, columnNumber));
- pin.Comment = v[4];
- pin.PinPosition =
- new Point
- {
- X = double.Parse(v[5], culture),
- Y = double.Parse(v[6], culture)
- };
-
- // pop-up nodes
- pin.SavedNodes = new System.Collections.Generic.List>();
- for (int i = 7; i < v.Length; i+=3) {
- pin.SavedNodes.Add(new Tuple(v[i], v[i+1], v[i+2]));
- }
-
- bookmark = pin;
- break;
default:
bookmark = new Bookmark(fileName, new TextLocation(lineNumber, columnNumber));
break;
@@ -101,10 +83,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
} else if (bookmark is Debugging.BreakpointBookmark) {
b.Append("Breakpoint");
} else {
- if (bookmark is PinBookmark)
- b.Append("PinBookmark");
- else
- b.Append("Bookmark");
+ b.Append("Bookmark");
}
b.Append('|');
b.Append(bookmark.FileName);
@@ -135,27 +114,6 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
b.Append(bbm.Condition);
}
- if (bookmark is PinBookmark) {
- var pin = (PinBookmark)bookmark;
- b.Append('|');
- b.Append(pin.Comment ?? string.Empty);
-
- // popup position
- b.Append('|');
- b.Append(pin.PinPosition.Value.X);
- b.Append('|');
- b.Append(pin.PinPosition.Value.Y);
-
- //popup nodes
- foreach(var node in pin.Nodes) {
- b.Append('|');
- b.Append(node.ImageName);
- b.Append('|');
- b.Append(node.FullName);
- b.Append('|');
- b.Append(node.Text);
- }
- }
return b.ToString();
} else {
return base.ConvertTo(context, culture, value, destinationType);
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPad.cs b/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPad.cs
index 333b05a8d9..491cb932f2 100644
--- a/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPad.cs
+++ b/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPad.cs
@@ -3,12 +3,11 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
-
using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
-using ICSharpCode.SharpDevelop.Bookmarks.Pad.Controls;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Gui;
@@ -16,108 +15,57 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
{
public sealed class BookmarkPad : BookmarkPadBase
{
- static BookmarkPad instance;
-
- public static BookmarkPad Instance {
- get {
- if (instance == null) {
- WorkbenchSingleton.Workbench.GetPad(typeof(BookmarkPad)).CreatePad();
- }
- return instance;
- }
- }
-
- protected override ToolBar CreateToolBar()
+ public BookmarkPad()
{
- ToolBar toolbar = ToolBarService.CreateToolBar(myPanel, this, "/SharpDevelop/Pads/BookmarkPad/Toolbar");
- toolbar.SetValue(Grid.RowProperty, 0);
- return toolbar;
+ ToolBar toolbar = ToolBarService.CreateToolBar((UIElement)this.Control, this, "/SharpDevelop/Pads/BookmarkPad/Toolbar");
+ this.control.Children.Add(toolbar);
}
- protected override void CreateColumns() { }
-
- public BookmarkPad()
+ protected override bool ShowBookmarkInThisPad(SDBookmark bookmark)
{
- instance = this;
- myPanel.Children.Add(CreateToolBar());
- listView.HideColumns(2, 0);
+ return bookmark.IsVisibleInBookmarkPad && !(bookmark is BreakpointBookmark);
}
}
public abstract class BookmarkPadBase : AbstractPadContent
{
- protected Grid myPanel = new Grid();
- protected ListViewPad listView = new ListViewPad();
+ protected BookmarkPadContent control;
public override object Control {
- get {
- return myPanel;
- }
+ get { return this.control; }
}
- public ListViewPadItemModel CurrentItem {
- get {
- return listView.CurrentItem;
- }
+ public ListView ListView {
+ get { return this.control.listView; }
}
- protected abstract ToolBar CreateToolBar();
+ public ItemCollection Items {
+ get { return this.control.listView.Items; }
+ }
- protected abstract void CreateColumns();
+ public SDBookmark SelectedItem {
+ get { return (SDBookmark)this.control.listView.SelectedItem; }
+ }
protected BookmarkPadBase()
{
- myPanel.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
- myPanel.RowDefinitions.Add(new RowDefinition());
- listView.SetValue(Grid.RowProperty, 1);
- myPanel.Children.Add(listView);
+ this.control = new BookmarkPadContent();
+ this.control.InitializeComponent();
BookmarkManager.Added += BookmarkManagerAdded;
BookmarkManager.Removed += BookmarkManagerRemoved;
- foreach (SDBookmark mark in BookmarkManager.Bookmarks) {
- AddMark(mark);
- }
-
- listView.ItemActivated += new EventHandler(OnItemActivated);
- }
-
- public IEnumerable AllItems {
- get {
- foreach (var item in listView.ItemCollection) {
- yield return item;
+ foreach (SDBookmark bookmark in BookmarkManager.Bookmarks) {
+ if (ShowBookmarkInThisPad(bookmark)) {
+ this.Items.Add(bookmark);
}
}
- }
-
- public ListViewPadItemModel NextItem {
- get {
- return this.listView.NextItem;
- }
- }
-
- public ListViewPadItemModel PreviousItem {
- get {
- return this.listView.PreviousItem;
- }
- }
-
- public void EnableDisableAll()
- {
- bool isOneChecked = false;
- foreach (var node in AllItems) {
- if (node.IsChecked) {
- isOneChecked = true;
- break;
- }
- }
- foreach (var node in AllItems)
- node.IsChecked = !isOneChecked;
- }
-
- public void SelectItem(ListViewPadItemModel model)
- {
- listView.CurrentItem = model;
+
+ this.control.listView.MouseDoubleClick += delegate {
+ SDBookmark bm = this.control.listView.SelectedItem as SDBookmark;
+ if (bm != null)
+ OnItemActivated(bm);
+ };
}
public override void Dispose()
@@ -126,60 +74,23 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
BookmarkManager.Removed -= BookmarkManagerRemoved;
}
- void AddMark(SDBookmark mark)
- {
- if (!ShowBookmarkInThisPad(mark))
- return;
-
- var model = new ListViewPadItemModel(mark);
- model.PropertyChanged += OnModelPropertyChanged;
- listView.Add(model);
- }
+ protected abstract bool ShowBookmarkInThisPad(SDBookmark mark);
- protected virtual bool ShowBookmarkInThisPad(SDBookmark mark)
+ protected virtual void OnItemActivated(SDBookmark bm)
{
- 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);
- }
- }
+ FileService.JumpToFilePosition(bm.FileName, bm.LineNumber, 1);
}
void BookmarkManagerAdded(object sender, BookmarkEventArgs e)
- {
- AddMark(e.Bookmark);
- }
-
- void BookmarkManagerRemoved(object sender, BookmarkEventArgs e)
{
if (ShowBookmarkInThisPad(e.Bookmark)) {
- var model = listView.Remove(e.Bookmark);
- if (model != null)
- model.PropertyChanged -= OnModelPropertyChanged;
+ this.Items.Add(e.Bookmark);
}
}
- void OnModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ void BookmarkManagerRemoved(object sender, BookmarkEventArgs e)
{
- var model = sender as ListViewPadItemModel;
- if (e.PropertyName == "IsChecked") {
- if (model.Mark is BreakpointBookmark) {
- var bpm = model.Mark as BreakpointBookmark;
- bpm.IsEnabled = model.IsChecked;
- if (model.IsChecked) {
- model.Image = string.IsNullOrEmpty(model.Condition) ? BreakpointBookmark.BreakpointImage.ImageSource : BreakpointBookmark.BreakpointConditionalImage.ImageSource;
- } else {
- model.Image = BreakpointBookmark.DisabledBreakpointImage.ImageSource;
- }
- }
- }
+ this.Items.Remove(e.Bookmark);
}
}
}
\ No newline at end of file
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadContent.xaml b/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadContent.xaml
new file mode 100644
index 0000000000..b29cd843b6
--- /dev/null
+++ b/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadContent.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadToolbarCommands.cs b/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadToolbarCommands.cs
index a665d2f839..6b00672959 100644
--- a/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadToolbarCommands.cs
+++ b/src/Main/Base/Project/Src/Bookmarks/Pad/BookmarkPadToolbarCommands.cs
@@ -7,116 +7,65 @@ using System.Linq;
using System.Windows.Forms;
using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Bookmarks.Pad.Controls;
using ICSharpCode.SharpDevelop.Debugging;
namespace ICSharpCode.SharpDevelop.Bookmarks
{
- #region Goto Commands
- public abstract class NextPrevBookmarkPadCommand : AbstractMenuCommand
- {
- public void Run(ListViewPadItemModel item)
- {
- var bookmarkBase = (BookmarkPadBase)Owner;
-
- if (item == null) return;
-
- // get current mark
- var mark = item.Mark as SDBookmark;
- int line = mark.LineNumber;
- var fileName = mark.FileName;
-
- SDBookmark bookmark;
- if (item.Mark is BreakpointBookmark) {
- var bookmarks = DebuggerService.Breakpoints;
- bookmark = bookmarks.FirstOrDefault(b => b.LineNumber == line && b.FileName == fileName);
- if (bookmark == null && bookmarks.Count > 0) {
- bookmark = bookmarks[0]; // jump around to first bookmark
- }
- }
- else {
- var bookmarks = BookmarkManager.Bookmarks;
- bookmark = bookmarks.FirstOrDefault(b => b.LineNumber == line && b.FileName == fileName);
- if (bookmark == null && bookmarks.Count > 0) {
- bookmark = bookmarks[0]; // jump around to first bookmark
- }
- }
-
- if (bookmark != null) {
- FileService.JumpToFilePosition(bookmark.FileName, bookmark.LineNumber, bookmark.ColumnNumber);
- }
-
- // select in tree
- bookmarkBase.SelectItem(item);
- }
- }
-
- public sealed class NextBookmarkPadCommand : NextPrevBookmarkPadCommand
+ public sealed class NextBookmarkPadCommand : AbstractMenuCommand
{
public override void Run()
{
- var bookmarkBase = (BookmarkPadBase)Owner;
- var nextItem = bookmarkBase.NextItem;
-
- Run(nextItem);
+ BookmarkPadBase pad = (BookmarkPadBase)this.Owner;
+ if (pad.ListView.Items.Count > 0) {
+ pad.ListView.SelectedIndex = (pad.ListView.SelectedIndex + 1) % pad.ListView.Items.Count;
+ FileService.JumpToFilePosition(pad.SelectedItem.FileName, pad.SelectedItem.LineNumber, pad.SelectedItem.ColumnNumber);
+ }
}
}
- public sealed class PrevBookmarkPadCommand : NextPrevBookmarkPadCommand
+ public sealed class PrevBookmarkPadCommand : AbstractMenuCommand
{
public override void Run()
{
- var bookmarkBase = (BookmarkPadBase)Owner;
- var prevItem = bookmarkBase.PreviousItem;
-
- Run(prevItem);
- }
- }
- #endregion Goto Commands
-
- #region Delete BookMark(s) commands
-
- public abstract class AbstractDeleteMarkClass : AbstractMenuCommand
- {
- protected void deleteBookMark (SDBookmark bookmark) {
- if (bookmark == null) return;
- if (bookmark is BreakpointBookmark) return;
- ICSharpCode.SharpDevelop.Bookmarks.BookmarkManager.RemoveMark(bookmark);
+ BookmarkPadBase pad = (BookmarkPadBase)this.Owner;
+ if (pad.ListView.Items.Count > 0) {
+ pad.ListView.SelectedIndex = (pad.ListView.SelectedIndex - 1 + pad.ListView.Items.Count) % pad.ListView.Items.Count;
+ FileService.JumpToFilePosition(pad.SelectedItem.FileName, pad.SelectedItem.LineNumber, pad.SelectedItem.ColumnNumber);
+ }
}
}
- ///
- /// Deletes all s in the BookMarkPad.
- ///
- public class DeleteAllMarks : AbstractDeleteMarkClass
+ public class DeleteAllMarks : AbstractMenuCommand
{
public override void Run()
{
- BookmarkManager.RemoveAll(b => !(b is BreakpointBookmark));
+ BookmarkPadBase pad = (BookmarkPadBase)this.Owner;
+ foreach(SDBookmark bm in pad.Items.OfType().ToList()) {
+ BookmarkManager.RemoveMark(bm);
+ }
}
}
- ///
- /// Deletes the currently selected or
- ///
- public class DeleteMark : AbstractDeleteMarkClass
+ public class DeleteMark : AbstractMenuCommand
{
public override void Run()
{
- var node = ((BookmarkPadBase)Owner).CurrentItem;
- if (node == null) return;
-
- deleteBookMark(node.Mark as SDBookmark);
+ BookmarkPadBase pad = (BookmarkPadBase)this.Owner;
+ if (pad.SelectedItem != null) {
+ BookmarkManager.RemoveMark(pad.SelectedItem);
+ }
}
}
- #endregion Delete BookMark(s) commands
-
public class EnableDisableAll : AbstractMenuCommand
{
public override void Run()
{
- ((BookmarkPadBase)Owner).EnableDisableAll();
+ BookmarkPadBase pad = (BookmarkPadBase)this.Owner;
+ bool anyEnabled = pad.Items.OfType().Any(bp => bp.IsEnabled);
+ foreach (var bp in pad.Items.OfType()) {
+ bp.IsEnabled = !anyEnabled;
+ }
}
}
}
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/Controls/ListViewPad.xaml b/src/Main/Base/Project/Src/Bookmarks/Pad/Controls/ListViewPad.xaml
deleted file mode 100644
index dbc714cc73..0000000000
--- a/src/Main/Base/Project/Src/Bookmarks/Pad/Controls/ListViewPad.xaml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/Controls/ListViewPad.xaml.cs b/src/Main/Base/Project/Src/Bookmarks/Pad/Controls/ListViewPad.xaml.cs
deleted file mode 100644
index 4876bbbf7d..0000000000
--- a/src/Main/Base/Project/Src/Bookmarks/Pad/Controls/ListViewPad.xaml.cs
+++ /dev/null
@@ -1,241 +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.ObjectModel;
-using System.ComponentModel;
-using System.IO;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using System.Windows.Media;
-
-using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace ICSharpCode.SharpDevelop.Bookmarks.Pad.Controls
-{
- ///
- /// ListViewPad inside WPF pads.
- ///
- public sealed partial class ListViewPad : UserControl
- {
- ObservableCollection itemCollection = new ObservableCollection();
-
- public ObservableCollection ItemCollection {
- get { return itemCollection; }
- }
-
- public event EventHandler ItemActivated;
-
- public ListViewPad()
- {
- InitializeComponent();
-
- this.MyListView.PreviewMouseDoubleClick += new MouseButtonEventHandler(ListViewPad_PreviewMouseDoubleClick);
- this.MyListView.KeyDown += new KeyEventHandler(ListViewPad_KeyDown);
- }
-
- public ListViewPadItemModel CurrentItem {
- get {
- if (MyListView.SelectedItem == null && MyListView.Items.Count > 0)
- this.MyListView.SelectedItem = MyListView.Items[0];
-
- return MyListView.SelectedItem as ListViewPadItemModel;
- }
- set {
- if (value == null) return;
-
- this.MyListView.SelectedItem = value;
- }
- }
-
- public ListViewPadItemModel NextItem {
- get {
- bool found = false;
- foreach (var line in ItemCollection) {
- if (found)
- return line;
- if (line == CurrentItem)
- found = true;
- }
-
- return null;
- }
- }
-
- public ListViewPadItemModel PreviousItem {
- get {
- bool found = false;
- ListViewPadItemModel prev = null;
- foreach (var line in ItemCollection) {
- if (found)
- return prev;
- if (line == CurrentItem) {
- found = true;
- }
- else {
- prev = line;
- }
- }
-
- return prev;
- }
- }
-
- public void Add(ListViewPadItemModel item)
- {
- if (item == null) return;
- ItemCollection.Add(item);
- }
-
- public ListViewPadItemModel Remove(SDBookmark bookmark)
- {
- if (bookmark is CurrentLineBookmark)
- return null;
-
- foreach (var model in itemCollection) {
- SDBookmark currentBookmark = model.Mark as SDBookmark;
-
- if (bookmark.FileName == currentBookmark.FileName &&
- bookmark.LineNumber == currentBookmark.LineNumber) {
- ItemCollection.Remove(model);
- return model;
- }
- }
-
- return null;
- }
-
- public void AddColumn(string header, DataTemplate cellTemplate)
- {
- GridViewColumn column = new GridViewColumn();
- column.Header = header;
- column.CellTemplate = cellTemplate;
- ((GridView)this.MyListView.View).Columns.Add(column);
- }
-
- ///
- /// Indexes from end to start.
- ///
- ///
- public void HideColumns(params int[] columnIndexes)
- {
- foreach(int i in columnIndexes)
- ((GridView)MyListView.View).Columns.RemoveAt(i);
- }
-
- private void ListViewPad_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
- {
- var handler = ItemActivated;
-
- if (handler != null)
- ItemActivated(this, EventArgs.Empty);
- }
-
- private void ListViewPad_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Escape) {
- this.MyListView.UnselectAll();
- e.Handled = true;
- }
- }
- }
-
- public sealed class ListViewPadItemModel : INotifyPropertyChanged
- {
- bool isChecked;
- object tag;
- string language;
- string condition;
- ImageSource imageSource;
-
- public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
-
- public ListViewPadItemModel(SDBookmark mark)
- {
- if (mark is BreakpointBookmark) {
- isChecked = ((BreakpointBookmark)mark).IsEnabled;
- condition = ((BreakpointBookmark)mark).Condition;
- language = ((BreakpointBookmark)mark).ScriptLanguage;
- }
-
- imageSource = mark.Image.ImageSource;
-
- Location = GetLocation(mark);
- Mark = mark;
- tag = this;
- }
-
- public bool IsChecked {
- get {
- return isChecked;
- }
- set {
- if (value != isChecked)
- {
- isChecked = value;
- NotifyPropertyChanged("IsChecked");
- }
- }
- }
-
- public SDBookmark Mark {
- get; set;
- }
-
- public ImageSource Image {
- get { return imageSource; }
- set {
- imageSource = value;
- NotifyPropertyChanged("Image");
- }
- }
-
- public string Location {
- get; private set;
- }
-
- public string Language {
- get { return language; }
- set {
- language = value;
- NotifyPropertyChanged("Language");
- }
- }
-
- public string Condition {
- get { return condition; }
- set {
- condition = value;
- NotifyPropertyChanged("Condition");
- }
- }
-
- public object Tag {
- get { return tag;}
- set {
- tag = value;
- NotifyPropertyChanged("Tag");
- }
- }
-
- public override string ToString()
- {
- return Location;
- }
-
- private string GetLocation(SDBookmark bookmark)
- {
- return string.Format(StringParser.Parse("${res:MainWindow.Windows.BookmarkPad.LineText}"),
- Path.GetFileName(bookmark.FileName), bookmark.LineNumber);
- }
-
- private void NotifyPropertyChanged(string property)
- {
- if (PropertyChanged != null) {
- PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(property));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs b/src/Main/Base/Project/Src/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs
deleted file mode 100644
index d30b5ed142..0000000000
--- a/src/Main/Base/Project/Src/Bookmarks/Pad/Nodes/BookmarkFolderNode.cs
+++ /dev/null
@@ -1,127 +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.Drawing;
-using System.IO;
-using System.Windows.Forms;
-
-using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Gui;
-
-namespace ICSharpCode.SharpDevelop.Bookmarks
-{
- ///
- /// Description of SearchFolderNode.
- ///
- public class BookmarkFolderNode : ExtFolderNode
- {
- List marks = new List();
- string fileName;
- string fileNameText;
- string occurences;
- Image icon;
-
- public List Marks {
- get {
- return marks;
- }
- }
-
- public BookmarkFolderNode(string fileName)
- {
- drawDefault = false;
- this.fileName = fileName;
- fileNameText = Path.GetFileName(fileName) + StringParser.Parse(" ${res:MainWindow.Windows.SearchResultPanel.In} ") + Path.GetDirectoryName(fileName);
- icon = IconService.GetBitmap(IconService.GetImageForFile(fileName));
- Nodes.Add(new TreeNode());
- }
-
- public void SetText()
- {
- if (marks.Count == 1) {
- occurences = " (1 bookmark)";
- } else {
- occurences = " (" + marks.Count + " bookmarks)";
- }
- this.Text = fileNameText + occurences;
- }
-
- protected override int MeasureItemWidth(DrawTreeNodeEventArgs e)
- {
- Graphics g = e.Graphics;
- int x = MeasureTextWidth(g, fileNameText, RegularBigFont);
- x += MeasureTextWidth(g, occurences, ItalicBigFont);
- if (icon != null) {
- x += icon.Width;
- }
- return x + 3;
- }
- protected override void DrawForeground(DrawTreeNodeEventArgs e)
- {
- Graphics g = e.Graphics;
- float x = e.Bounds.X;
- if (icon != null) {
- g.DrawImage(icon, x, e.Bounds.Y, icon.Width, icon.Height);
- x += icon.Width + 2;
- }
- DrawText(e, fileNameText, SystemBrushes.WindowText, RegularBigFont, ref x);
- DrawText(e, occurences, SystemBrushes.GrayText, ItalicBigFont, ref x);
- }
-
- public void AddMark(SDBookmark mark)
- {
- int index = -1;
- for (int i = 0; i < marks.Count; ++i) {
- if (mark.LineNumber < marks[i].LineNumber) {
- index = i;
- break;
- }
- }
- if (index < 0)
- marks.Add(mark);
- else
- marks.Insert(index, mark);
-
- if (isInitialized) {
- BookmarkNode newNode = new BookmarkNode(mark);
- if (index < 0)
- Nodes.Add(newNode);
- else
- Nodes.Insert(index, newNode);
- newNode.EnsureVisible();
- }
- SetText();
- }
-
- public void RemoveMark(SDBookmark mark)
- {
- marks.Remove(mark);
- if (isInitialized) {
- for (int i = 0; i < Nodes.Count; ++i) {
- if (((BookmarkNode)Nodes[i]).Bookmark == mark) {
- Nodes.RemoveAt(i);
- break;
- }
- }
- }
- SetText();
- }
-
- protected override void Initialize()
- {
- Nodes.Clear();
- if (marks.Count > 0) {
-// IDocument document = marks[0].Document;
-// if (document != null && document.HighlightingStrategy == null) {
-// document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategyForFile(fileName);
-// }
- foreach (SDBookmark mark in marks) {
- TreeNode newResult = new BookmarkNode(mark);
- Nodes.Add(newResult);
- }
- }
- }
- }
-}
diff --git a/src/Main/Base/Project/Src/Bookmarks/Pad/Nodes/BookmarkNode.cs b/src/Main/Base/Project/Src/Bookmarks/Pad/Nodes/BookmarkNode.cs
deleted file mode 100644
index 746a95120f..0000000000
--- a/src/Main/Base/Project/Src/Bookmarks/Pad/Nodes/BookmarkNode.cs
+++ /dev/null
@@ -1,146 +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.Drawing;
-using System.Windows.Forms;
-
-using ICSharpCode.SharpDevelop.Gui;
-
-namespace ICSharpCode.SharpDevelop.Bookmarks
-{
- ///
- /// ExtTreeNode representing a bookmark.
- ///
- public class BookmarkNode : ExtTreeNode
- {
- SDBookmark bookmark;
- //LineSegment line;
-
- SizeF spaceSize;
- static StringFormat sf = (StringFormat)System.Drawing.StringFormat.GenericTypographic.Clone();
-
- string positionText;
-
- public SDBookmark Bookmark {
- get {
- return bookmark;
- }
- }
-
- public BookmarkNode(SDBookmark bookmark)
- {
- drawDefault = false;
- this.bookmark = bookmark;
- Tag = bookmark;
-// Checked = bookmark.IsEnabled;
- positionText = "(" + (bookmark.LineNumber) + ") ";
-
- bookmark.DocumentChanged += BookmarkDocumentChanged;
- bookmark.LineNumberChanged += BookmarkLineNumberChanged;
- if (bookmark.Document != null) {
- BookmarkDocumentChanged(null, null);
- } else {
- Text = positionText;
- }
- }
-
- public override void CheckedChanged()
- {
-// bookmark.IsEnabled = Checked;
- }
-
- void BookmarkDocumentChanged(object sender, EventArgs e)
- {
- if (bookmark.Document != null) {
-// line = bookmark.Document.GetLineSegment(Math.Min(bookmark.LineNumber, bookmark.Document.TotalNumberOfLines));
-// Text = positionText + bookmark.Document.GetText(line);
- }
- }
-
- void BookmarkLineNumberChanged(object sender, EventArgs e)
- {
- positionText = "(" + (bookmark.LineNumber) + ") ";
- BookmarkDocumentChanged(sender, e);
- }
-
- protected override int MeasureItemWidth(DrawTreeNodeEventArgs e)
- {
- Graphics g = e.Graphics;
- int x = MeasureTextWidth(g, positionText, BoldMonospacedFont);
-// if (line != null && !line.IsDeleted) {
-// x += MeasureTextWidth(g, bookmark.Document.GetText(line).Replace("\t", " "), BoldMonospacedFont);
-// }
- return x;
- }
-
- protected override void DrawForeground(DrawTreeNodeEventArgs e)
- {
- Graphics g = e.Graphics;
- float x = e.Bounds.X;
- DrawText(e, positionText, SystemBrushes.WindowText, RegularBigFont, ref x);
-
- spaceSize = g.MeasureString("-", RegularBigFont, new PointF(0, 0), StringFormat.GenericTypographic);
-
-// if (line != null && !line.IsDeleted) {
-// DrawLine(g, line, e.Bounds.Y, x, e.State);
-// }
- }
-
- public override void ActivateItem()
- {
- FileService.JumpToFilePosition(bookmark.FileName, bookmark.LineNumber, 1);
- }
-
- /*
- float DrawDocumentWord(Graphics g, string word, PointF position, Font font, Color foreColor)
- {
- if (word == null || word.Length == 0) {
- return 0f;
- }
- SizeF wordSize = g.MeasureString(word, font, 32768, sf);
-
- g.DrawString(word,
- font,
- BrushRegistry.GetBrush(foreColor),
- position,
- sf);
- return wordSize.Width;
- }
-
- void DrawLine(Graphics g, LineSegment line, float yPos, float xPos, TreeNodeStates state)
- {
- int logicalX = 0;
- if (line.Words != null) {
- foreach (TextWord word in line.Words) {
- switch (word.Type) {
- case TextWordType.Space:
- xPos += spaceSize.Width;
- logicalX++;
- break;
- case TextWordType.Tab:
- xPos += spaceSize.Width * 4;
- logicalX++;
- break;
- case TextWordType.Word:
- xPos += DrawDocumentWord(g,
- word.Word,
- new PointF(xPos, yPos),
- word.Bold ? BoldMonospacedFont : RegularMonospacedFont,
- GetTextColor(state, word.Color)
- );
- logicalX += word.Word.Length;
- break;
- }
- }
- } else {
-// DrawDocumentWord(g,
-// bookmark.Document.GetText(line),
-// new PointF(xPos, yPos),
-// RegularMonospacedFont,
-// GetTextColor(state, Color.Black)
-// );
- }
- }*/
- }
-}
diff --git a/src/Main/Base/Project/Src/Bookmarks/SDBookmark.cs b/src/Main/Base/Project/Src/Bookmarks/SDBookmark.cs
index 189d83d794..94a55a05b4 100644
--- a/src/Main/Base/Project/Src/Bookmarks/SDBookmark.cs
+++ b/src/Main/Base/Project/Src/Bookmarks/SDBookmark.cs
@@ -3,6 +3,7 @@
using System;
using System.ComponentModel;
+using System.IO;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
@@ -33,6 +34,10 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
}
}
+ public string FileNameAndLineNumber {
+ get { return string.Format(StringParser.Parse("${res:MainWindow.Windows.BookmarkPad.LineText}"), Path.GetFileName(this.FileName), this.LineNumber); }
+ }
+
public event EventHandler FileNameChanged;
protected virtual void OnFileNameChanged(EventArgs e)
diff --git a/src/Main/Base/Project/Src/Commands/DebugCommands.cs b/src/Main/Base/Project/Src/Commands/DebugCommands.cs
index acca2c1cff..a17029e0bf 100644
--- a/src/Main/Base/Project/Src/Commands/DebugCommands.cs
+++ b/src/Main/Base/Project/Src/Commands/DebugCommands.cs
@@ -7,7 +7,6 @@ using System.Linq;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Bookmarks;
-using ICSharpCode.SharpDevelop.Bookmarks.Pad.Controls;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
@@ -139,31 +138,6 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
}
}
- public class RemoveAllBreakpointsCommand : AbstractMenuCommand
- {
- public override void Run()
- {
- BookmarkManager.RemoveAll(b => b is BreakpointBookmark);
- }
- }
-
- public class DeleteBreakpointCommand : AbstractMenuCommand
- {
- public override void Run()
- {
- if (Owner == null || !(Owner is BookmarkPadBase)) return;
-
- var bookmarkBase = (BookmarkPadBase)Owner;
- var item = bookmarkBase.CurrentItem;
-
- if (item == null) return;
-
- if (item.Mark is BreakpointBookmark) {
- BookmarkManager.RemoveMark(item.Mark);
- }
- }
- }
-
public class AttachToProcessCommand : AbstractMenuCommand
{
public override void Run()
diff --git a/src/Main/Base/Project/Src/Editor/ITooltip.cs b/src/Main/Base/Project/Src/Editor/ITooltip.cs
index def96396f1..5e338ff1d5 100644
--- a/src/Main/Base/Project/Src/Editor/ITooltip.cs
+++ b/src/Main/Base/Project/Src/Editor/ITooltip.cs
@@ -6,30 +6,9 @@ using System.Windows;
namespace ICSharpCode.SharpDevelop.Editor
{
- ///
- /// Content of text editor tooltip (used as ),
- /// specifying whether it should be displayed in a WPF Popup.
- ///
public interface ITooltip
{
- ///
- /// 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.
- ///
- bool ShowAsPopup { get; }
-
- ///
- /// Closes this tooltip.
- ///
- /// True if close request is raised
- /// because of mouse click on some SharpDevelop GUI element.
- /// True if Close succeeded (that is, can close). False otherwise.
- bool Close(bool mouseClick);
-
- ///
- /// Occurs when this tooltip decides to close.
- ///
- event RoutedEventHandler Closed;
+ /// Should the tooltip close when the mouse moves away?
+ bool CloseOnHoverEnd { get; }
}
}
diff --git a/src/Main/Base/Project/Src/Project/Solution/Solution.cs b/src/Main/Base/Project/Src/Project/Solution/Solution.cs
index 7fcac06c00..a71adc0474 100644
--- a/src/Main/Base/Project/Src/Project/Solution/Solution.cs
+++ b/src/Main/Base/Project/Src/Project/Solution/Solution.cs
@@ -404,7 +404,7 @@ namespace ICSharpCode.SharpDevelop.Project
} else if (versionNumber == SolutionVersionVS11) {
sw.WriteLine("# Visual Studio 11");
}
- sw.WriteLine("# SharpDevelop " + RevisionClass.FullVersion);
+ sw.WriteLine("# SharpDevelop " + RevisionClass.Major + "." + RevisionClass.Minor);
sw.Write(projectSection.ToString());
sw.Write(globalSection.ToString());
diff --git a/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs
index 5adc72d02c..80ccd3807d 100644
--- a/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs
+++ b/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs
@@ -29,6 +29,8 @@ namespace ICSharpCode.SharpDevelop.Debugging
string condition;
string scriptLanguage;
+ public event EventHandler ConditionChanged;
+
public string ScriptLanguage {
get { return scriptLanguage; }
set { scriptLanguage = value; }
@@ -36,7 +38,15 @@ namespace ICSharpCode.SharpDevelop.Debugging
public string Condition {
get { return condition; }
- set { condition = value; }
+ set {
+ if (condition != value) {
+ condition = value;
+ this.Action = string.IsNullOrEmpty(condition) ? BreakpointAction.Break : BreakpointAction.Condition;
+ if (ConditionChanged != null)
+ ConditionChanged(this, EventArgs.Empty);
+ Redraw();
+ }
+ }
}
public BreakpointAction Action {
@@ -51,6 +61,8 @@ namespace ICSharpCode.SharpDevelop.Debugging
}
}
+ public object InternalBreakpointObject { get; set; }
+
public virtual bool IsHealthy {
get {
return isHealthy;
diff --git a/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs
index a3e53649da..fb83cacdf1 100644
--- a/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs
+++ b/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs
@@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
// because Drag'N'Drop operation has finished
WorkbenchSingleton.SafeThreadAsyncCall(
delegate {
- DebuggerService.CurrentDebugger.SetInstructionPointer(this.FileName, lineNumber, 1);
+ DebuggerService.CurrentDebugger.SetInstructionPointer(this.FileName, lineNumber, 1, false);
});
}
}
diff --git a/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs b/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs
index fddeb79656..da96bba580 100644
--- a/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs
+++ b/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs
@@ -125,12 +125,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
{
}
- public bool CanSetInstructionPointer(string filename, int line, int column)
- {
- return false;
- }
-
- public bool SetInstructionPointer(string filename, int line, int column)
+ public bool SetInstructionPointer(string filename, int line, int column, bool dryRun)
{
return false;
}
diff --git a/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs b/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs
index 2f50e683b7..7c2a5a3c16 100644
--- a/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs
+++ b/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs
@@ -78,17 +78,11 @@ namespace ICSharpCode.SharpDevelop.Debugging
void Detach();
- ///
- /// Queries the debugger whether it is possible to set the instruction pointer to a given position.
- ///
- /// True if possible. False otherwise
- bool CanSetInstructionPointer(string filename, int line, int column);
-
///
/// Set the instruction pointer to a given position.
///
/// True if successful. False otherwise
- bool SetInstructionPointer(string filename, int line, int column);
+ bool SetInstructionPointer(string filename, int line, int column, bool dryRun);
///
/// Ocurrs when the debugger is starting.
diff --git a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/IPinDebuggerControl.cs b/src/Main/Base/Project/Src/Services/Debugger/Tooltips/IPinDebuggerControl.cs
deleted file mode 100644
index 835aaa0e25..0000000000
--- a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/IPinDebuggerControl.cs
+++ /dev/null
@@ -1,20 +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.Windows;
-
-using ICSharpCode.SharpDevelop.Bookmarks;
-
-namespace ICSharpCode.SharpDevelop.Debugging
-{
- public interface IPinDebuggerControl
- {
- void Open();
- void Close();
- PinBookmark Mark { get; set; }
- IEnumerable ItemsSource { set; }
- Point Location { get; set; }
- }
-}
diff --git a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/ITreeNode.cs b/src/Main/Base/Project/Src/Services/Debugger/Tooltips/ITreeNode.cs
deleted file mode 100644
index 59762e5870..0000000000
--- a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/ITreeNode.cs
+++ /dev/null
@@ -1,41 +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.Windows.Media;
-
-namespace ICSharpCode.SharpDevelop.Debugging
-{
- ///
- /// Node that can be bound to .
- ///
- public interface ITreeNode : IComparable
- {
- string Name { get; }
-
- string FullName { get; }
-
- string ImageName { get; }
-
- string Text { get; }
-
- bool CanSetText { get; }
-
- string Type { get; }
-
- ImageSource ImageSource { get; }
-
- IEnumerable ChildNodes { get; }
-
- bool HasChildNodes { get; }
-
- IEnumerable VisualizerCommands { get; }
-
- bool HasVisualizerCommands { get; }
-
- bool IsPinned { get; set; }
-
- bool SetText(string newValue);
- }
-}
diff --git a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/PinBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/Tooltips/PinBookmark.cs
deleted file mode 100644
index ac940c25eb..0000000000
--- a/src/Main/Base/Project/Src/Services/Debugger/Tooltips/PinBookmark.cs
+++ /dev/null
@@ -1,98 +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.Windows;
-using ICSharpCode.Core;
-using ICSharpCode.NRefactory;
-using ICSharpCode.SharpDevelop.Debugging;
-
-namespace ICSharpCode.SharpDevelop.Bookmarks
-{
- public class PinBookmark : SDBookmark
- {
- string tooltip;
-
- public IPinDebuggerControl Popup { get; set; }
-
- public static readonly IImage PinImage = new ResourceServiceImage("Bookmarks.Pin");
-
- public PinBookmark(FileName fileName, TextLocation location) : base(fileName, location)
- {
- Nodes = new ObservableCollection();
- IsVisibleInBookmarkPad = false;
- }
-
- ///
- /// Pin's position relative to the layer BUT ABSOLUTE TO THE SCREEN.
- ///
- public Nullable PinPosition { get; set; }
-
- ///
- /// Nodes inside the pin control.
- ///
- public ObservableCollection Nodes { get; set; }
-
- ///
- /// Image, Name, Text
- ///
- public List> SavedNodes { get; set; }
-
- public string Comment { get; set; }
-
- public override IImage Image {
- get {
- return PinImage;
- }
- }
-
- public string Tooltip {
- get { return tooltip; }
- set { tooltip = value; }
- }
-
- public override bool CanDragDrop {
- get { return true; }
- }
-
- public override void Drop(int lineNumber)
- {
- this.Location = new TextLocation(lineNumber, ColumnNumber);
- }
- }
-
- public static class PinBookmarkExtensions
- {
- public static bool ContainsNode(this PinBookmark mark, ITreeNode node)
- {
- if (mark == null)
- throw new ArgumentNullException("mark is null");
- if (node == null)
- throw new ArgumentNullException("Node is null");
-
- foreach (var currentNode in mark.Nodes) {
- if (node.FullName == currentNode.FullName)
- return true;
- }
-
- return false;
- }
-
- public static void RemoveNode(this PinBookmark mark, ITreeNode node)
- {
- if (mark == null)
- throw new ArgumentNullException("mark is null");
- if (node == null)
- throw new ArgumentNullException("Node is null");
-
- foreach (var currentNode in mark.Nodes) {
- if (node.FullName == currentNode.FullName) {
- mark.Nodes.Remove(currentNode);
- return;
- }
- }
- }
- }
-}