diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs index ca4d01dfc9..bfed635c37 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/CallStackPad.cs @@ -117,7 +117,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads } if (showArgumentValues) { try { - argValue = f.GetArgumentVariable(i).ValueProxy.AsString; + argValue = f.GetArgument(i).AsString; } catch { } } if (parameterName != null && argValue != null) { diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs index c23446584d..317b42bf1b 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs @@ -97,24 +97,24 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads localVarList.EndUpdate(); } - delegate void AddVariableMethod(Variable variable); + //delegate void AddVariableMethod(NamedValue val); - public static void AddVariableCollectionToTree(VariableCollection varCollection, TreeListViewItemCollection tree) + public static void AddVariableCollectionToTree(NamedValueCollection collection, TreeListViewItemCollection tree) { - foreach(VariableCollection sub in varCollection.SubCollections) { - VariableCollection subCollection = sub; - TreeListViewItem subMenu = new TreeListViewItem("<" + subCollection.Name + ">", 0); - subMenu.SubItems.Add(subCollection.Value); - tree.Add(subMenu); - TreeListViewItem.TreeListViewItemHanlder populate = null; - populate = delegate { - AddVariableCollectionToTree(subCollection, subMenu.Items); - subMenu.AfterExpand -= populate; - }; - subMenu.AfterExpand += populate; - } - foreach(Variable variable in varCollection.Items) { - tree.Add(new TreeListViewDebuggerItem(variable)); +// foreach(VariableCollection sub in varCollection.SubCollections) { +// VariableCollection subCollection = sub; +// TreeListViewItem subMenu = new TreeListViewItem("<" + subCollection.Name + ">", 0); +// subMenu.SubItems.Add(subCollection.Value); +// tree.Add(subMenu); +// TreeListViewItem.TreeListViewItemHanlder populate = null; +// populate = delegate { +// AddVariableCollectionToTree(subCollection, subMenu.Items); +// subMenu.AfterExpand -= populate; +// }; +// subMenu.AfterExpand += populate; +// } + foreach(NamedValue val in collection) { + tree.Add(new TreeListViewDebuggerItem(val)); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs index 58aff74b4e..88a243898e 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/TreeListViewDebuggerItem.cs @@ -15,13 +15,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads { public class TreeListViewDebuggerItem: TreeListViewItem { - Variable variable; + NamedValue val; bool populated = false; bool dirty = true; - public Variable Variable { + public NamedValue Value { get { - return variable; + return val; } } @@ -51,12 +51,12 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads } } - public TreeListViewDebuggerItem(Variable variable) + public TreeListViewDebuggerItem(NamedValue val) { - this.variable = variable; + this.val = val; - variable.Changed += delegate { dirty = true; Update(); }; - variable.Expired += delegate { this.Remove(); }; + val.Changed += delegate { dirty = true; Update(); }; + val.Expired += delegate { this.Remove(); }; SubItems.Add(""); SubItems.Add(""); @@ -71,18 +71,18 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads if (this.TreeListView != null) { ((DebuggerTreeListView)this.TreeListView).DelayRefresh(); - Highlight = (Variable.ValueProxy.AsString != SubItems[1].Text); + Highlight = (val.AsString != SubItems[1].Text); } - this.SubItems[0].Text = Variable.Name; - this.SubItems[1].Text = Variable.ValueProxy.AsString; - this.SubItems[2].Text = Variable.ValueProxy.Type; + this.SubItems[0].Text = val.Name; + this.SubItems[1].Text = val.AsString; + this.SubItems[2].Text = val.IsNull ? String.Empty : val.Type.Name; - this.ImageIndex = DebuggerIcons.GetImageListIndex(variable); + this.ImageIndex = DebuggerIcons.GetImageListIndex(val); if (!IsExpanded) { // Show plus sign - if (variable.ValueProxy.MayHaveSubVariables && Items.Count == 0) { + if ((val.IsObject || val.IsArray) && Items.Count == 0) { TreeListViewItem dummy = new TreeListViewItem(); this.AfterExpand += delegate { dummy.Remove(); }; Items.Add(dummy); @@ -96,9 +96,14 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads { if (!populated) { Items.Clear(); - // Do not sort names of array items - this.Items.SortOrder = variable.ValueProxy is ArrayValue ? SortOrder.None : SortOrder.Ascending; - LocalVarPad.AddVariableCollectionToTree(variable.ValueProxy.SubVariables, this.Items); + if (val.IsArray) { + // Do not sort names of array items + this.Items.SortOrder = SortOrder.None; + LocalVarPad.AddVariableCollectionToTree(val.GetArrayElements(), this.Items); + } else if (val.IsObject) { + this.Items.SortOrder = SortOrder.Ascending; + LocalVarPad.AddVariableCollectionToTree(val.GetMembers(), this.Items); + } populated = true; } } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerIcons.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerIcons.cs index 41d4881dba..a0f5930666 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerIcons.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DebuggerIcons.cs @@ -34,14 +34,14 @@ namespace Debugger imageList.Images.Add(IconService.GetBitmap("Icons.16x16.Property")); } - public static Image GetImage(Variable variable) + public static Image GetImage(Value val) { - return imageList.Images[GetImageListIndex(variable)]; + return imageList.Images[GetImageListIndex(val)]; } - public static int GetImageListIndex(Variable variable) + public static int GetImageListIndex(Value val) { - if (variable.ValueProxy is ObjectValue) { + if (val.IsObject) { return 0; // Class } else { return 1; // Field diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs index 0dca2c514f..31a13da551 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs @@ -25,17 +25,17 @@ namespace ICSharpCode.SharpDevelop.Services // 2 = text // 3 = value - Variable variable; + NamedValue val; Image image; bool populated = false; bool dirty = true; - public Variable Variable { + public NamedValue Value { get { - return variable; + return val; } set { - variable = value; + val = value; } } @@ -52,18 +52,18 @@ namespace ICSharpCode.SharpDevelop.Services { } - public DynamicTreeDebuggerRow(Variable variable) + public DynamicTreeDebuggerRow(NamedValue val) { - if (variable == null) throw new ArgumentNullException("variable"); + if (val == null) throw new ArgumentNullException("val"); - this.variable = variable; + this.val = val; this.Shown += delegate { - this.variable.Changed += Update; + this.val.Changed += Update; dirty = true; DoInPausedState( delegate { Update(); } ); }; this.Hidden += delegate { - this.variable.Changed -= Update; + this.val.Changed -= Update; }; DebuggerGridControl.AddColumns(this.ChildColumns); @@ -85,25 +85,22 @@ namespace ICSharpCode.SharpDevelop.Services { if (!dirty) return; - image = DebuggerIcons.GetImage(variable); + image = DebuggerIcons.GetImage(val); this[1].Text = ""; // Icon - this[2].Text = variable.Name; - if (ShowValuesInHexadecimal && variable.ValueProxy is PrimitiveValue && variable.ValueProxy.TheValue.IsInteger) { - this[3].Text = String.Format("0x{0:X}", (variable.ValueProxy as PrimitiveValue).Primitive); + this[2].Text = val.Name; + if (ShowValuesInHexadecimal && val.IsPrimitive && val.IsInteger) { + this[3].Text = String.Format("0x{0:X}", val.PrimitiveValue); } else { - this[3].Text = variable.ValueProxy.AsString; + this[3].Text = val.AsString; } - this[3].AllowLabelEdit = variable.ValueProxy is PrimitiveValue && - variable.ValueProxy.ManagedType != typeof(string) && - !ShowValuesInHexadecimal; - ObjectValue objValue = variable.ValueProxy as ObjectValue; - if (objValue != null) { - objValue.ToStringText.Changed -= Update; - objValue.ToStringText.Changed += Update; - this[3].Text = objValue.ToStringText.ValueProxy.AsString; + this[3].AllowLabelEdit = val.IsInteger && !ShowValuesInHexadecimal; + if (val.IsObject) { + val.ObjectToString.Changed -= Update; + val.ObjectToString.Changed += Update; + this[3].Text = val.ObjectToString.AsString; } - this.ShowPlus = variable.ValueProxy.MayHaveSubVariables; + this.ShowPlus = val.IsObject || val.IsArray; this.ShowMinusWhileExpanded = true; dirty = false; @@ -118,13 +115,12 @@ namespace ICSharpCode.SharpDevelop.Services void OnLabelEdited(object sender, DynamicListEventArgs e) { - PrimitiveValue val = (PrimitiveValue)variable.ValueProxy; string newValue = ((DynamicListItem)sender).Text; try { - val.Primitive = newValue; + val.PrimitiveValue = newValue; } catch (NotSupportedException) { string format = ResourceService.GetString("MainWindow.Windows.Debug.LocalVariables.CannotSetValue.BadFormat"); - string msg = String.Format(format, newValue, val.ManagedType.ToString()); + string msg = String.Format(format, newValue, val.Type.ManagedType.ToString()); MessageService.ShowMessage(msg ,"${res:MainWindow.Windows.Debug.LocalVariables.CannotSetValue.Title}"); } catch (COMException) { // COMException (0x80131330): Cannot perfrom SetValue on non-leaf frames. @@ -177,48 +173,49 @@ namespace ICSharpCode.SharpDevelop.Services void DoInPausedState(MethodInvoker action) { - if (Variable.Process.IsPaused) { + if (val.Process.IsPaused) { action(); } else { EventHandler onDebuggingPaused = null; onDebuggingPaused = delegate { action(); - Variable.Process.DebuggingPaused -= onDebuggingPaused; + val.Process.DebuggingPaused -= onDebuggingPaused; }; - Variable.Process.DebuggingPaused += onDebuggingPaused; + val.Process.DebuggingPaused += onDebuggingPaused; } } void Populate() { - Fill(this, Variable.ValueProxy.SubVariables); + if (val.IsArray) Fill(this, val.GetArrayElements()); + if (val.IsObject) Fill(this, val.GetMembers()); populated = true; } - static void Fill(DynamicTreeRow row, VariableCollection collection) + static void Fill(DynamicTreeRow row, NamedValueCollection collection) { row.ChildRows.Clear(); - foreach(VariableCollection sub in collection.SubCollections) { - VariableCollection subCollection = sub; - - DynamicTreeRow subMenu = new DynamicTreeRow(); - DebuggerGridControl.AddColumns(subMenu.ChildColumns); - subMenu[2].Text = subCollection.Name; - subMenu[3].Text = subCollection.Value; - subMenu.ShowMinusWhileExpanded = true; - subMenu.ShowPlus = !subCollection.IsEmpty; - - EventHandler populate = null; - populate = delegate { - Fill(subMenu, subCollection); - subMenu.Expanding -= populate; - }; - subMenu.Expanding += populate; - - row.ChildRows.Add(subMenu); - } - foreach(Variable variable in collection.Items) { - row.ChildRows.Add(new DynamicTreeDebuggerRow(variable)); +// foreach(VariableCollection sub in collection.SubCollections) { +// VariableCollection subCollection = sub; +// +// DynamicTreeRow subMenu = new DynamicTreeRow(); +// DebuggerGridControl.AddColumns(subMenu.ChildColumns); +// subMenu[2].Text = subCollection.Name; +// subMenu[3].Text = subCollection.Value; +// subMenu.ShowMinusWhileExpanded = true; +// subMenu.ShowPlus = !subCollection.IsEmpty; +// +// EventHandler populate = null; +// populate = delegate { +// Fill(subMenu, subCollection); +// subMenu.Expanding -= populate; +// }; +// subMenu.Expanding += populate; +// +// row.ChildRows.Add(subMenu); +// } + foreach(NamedValue val in collection) { + row.ChildRows.Add(new DynamicTreeDebuggerRow(val)); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs index fb4dd66e39..a844fb86e9 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/WindowsDebugger.cs @@ -211,11 +211,11 @@ namespace ICSharpCode.SharpDevelop.Services /// Gets variable of given name. /// Returns null if unsuccessful. /// - public Variable GetVariableFromName(string variableName) + public NamedValue GetVariableFromName(string variableName) { if (debuggedProcess == null || debuggedProcess.IsRunning) return null; - VariableCollection collection = debuggedProcess.LocalVariables; + NamedValueCollection collection = debuggedProcess.LocalVariables; if (collection == null) return null; @@ -233,12 +233,12 @@ namespace ICSharpCode.SharpDevelop.Services /// public string GetValueAsString(string variableName) { - Variable variable = GetVariableFromName(variableName); + NamedValue val = GetVariableFromName(variableName); - if (variable == null) { + if (val == null) { return null; } else { - return variable.ValueProxy.AsString; + return val.AsString; } } @@ -248,12 +248,12 @@ namespace ICSharpCode.SharpDevelop.Services /// public DebuggerGridControl GetTooltipControl(string variableName) { - Variable variable = GetVariableFromName(variableName.Trim()); + NamedValue val = GetVariableFromName(variableName.Trim()); - if (variable == null) { + if (val == null) { return null; } else { - return new DebuggerGridControl(new DynamicTreeDebuggerRow(variable)); + return new DebuggerGridControl(new DynamicTreeDebuggerRow(val)); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.BooInterpreter/Project/Src/DebugeeInterpreterContext.cs b/src/AddIns/Misc/Debugger/Debugger.BooInterpreter/Project/Src/DebugeeInterpreterContext.cs index 398df7763b..d8157bc3ae 100644 --- a/src/AddIns/Misc/Debugger/Debugger.BooInterpreter/Project/Src/DebugeeInterpreterContext.cs +++ b/src/AddIns/Misc/Debugger/Debugger.BooInterpreter/Project/Src/DebugeeInterpreterContext.cs @@ -67,8 +67,8 @@ namespace Debugger // Debugger.BooInterpreter.dll assembly = LoadAssembly(typeof(DebugeeInteractiveInterpreter).Assembly.Location); Value interpreterType = Eval.NewString(process, typeof(DebugeeInteractiveInterpreter).FullName); - interpreter = Eval.CallFunction(process, typeof(Assembly), "CreateInstance", assembly, new Value[] {interpreterType}); - interpreter_localVariable = interpreter.ValueProxy.SubVariables["localVariable"].Value; + interpreter = Eval.InvokeMethod(process, typeof(Assembly), "CreateInstance", assembly, new Value[] {interpreterType}); + interpreter_localVariable = interpreter.GetMember("localVariable"); RunCommand( "import System\n" + "import System.IO\n" + @@ -82,7 +82,7 @@ namespace Debugger Value LoadAssembly(string path) { Value assemblyPath = Eval.NewString(process, path); - Value assembly = Eval.CallFunction(process, typeof(Assembly), "LoadFrom", null, new Value[] {assemblyPath}); + Value assembly = Eval.InvokeMethod(process, typeof(Assembly), "LoadFrom", null, new Value[] {assemblyPath}); return assembly; } @@ -90,7 +90,7 @@ namespace Debugger { if (CanLoadInterpreter) { Value cmd = Eval.NewString(process, code); - Eval.CallFunction(process, typeof(InteractiveInterpreter), "LoopEval", interpreter, new Value[] {cmd}); + Eval.InvokeMethod(process, typeof(InteractiveInterpreter), "LoopEval", interpreter, new Value[] {cmd}); } } @@ -103,7 +103,7 @@ namespace Debugger { if (CanLoadInterpreter) { Value cmd = Eval.NewString(process, code); - Eval.CallFunction(process, typeof(AbstractInterpreter), "SuggestCodeCompletion", interpreter, new Value[] {cmd}); + Eval.InvokeMethod(process, typeof(AbstractInterpreter), "SuggestCodeCompletion", interpreter, new Value[] {cmd}); return null; } else { return null; @@ -129,7 +129,7 @@ namespace Debugger void BeforeGetValue(string name) { - Variable localVar; + NamedValue localVar; try { localVar = process.LocalVariables[name]; } catch (DebuggerException) { @@ -140,7 +140,7 @@ namespace Debugger Stepper stepOut = new Stepper(process.SelectedThread.LastFunction, "Boo interperter"); stepOut.StepComplete += delegate { process.Debugger.MTA2STA.AsyncCall(delegate { - if (!interpreter_localVariable.SetValue(localVar.Value)) { + if (!interpreter_localVariable.SetValue(localVar)) { PrintLine("Getting of local variable " + name + " failed"); } process.Continue(); @@ -151,14 +151,14 @@ namespace Debugger void BeforeSetValue(string name) { - Variable localVar; + NamedValue localVar; try { localVar = process.LocalVariables[name]; } catch (DebuggerException) { return; } PrintLine("Setting local variable " + name); - localVar.Value.SetValue(interpreter_localVariable); + localVar.SetValue(interpreter_localVariable); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj index 08b7fdf96e..7a6799b2b9 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj @@ -18,21 +18,19 @@ 4096 4 false + ..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\ + True true Full - ..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\ DEBUG;TRACE - True False PdbOnly true - ..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\ TRACE - true 108 false @@ -171,18 +169,6 @@ - - - - - - - - - - - - @@ -363,22 +349,39 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -391,6 +394,11 @@ + + + + + diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exceptions.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exceptions.cs index a2540d9782..30096d1fd2 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exceptions.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Exceptions.cs @@ -15,6 +15,4 @@ namespace Debugger public DebuggerException(string message): base(message) {} public DebuggerException(string message, System.Exception inner): base(message, inner) {} } - - public class BadSignatureException: DebuggerException {} } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs index 0079cc3be4..49893a8515 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/MTA2STA.cs @@ -12,7 +12,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; -namespace Debugger +namespace Debugger.Interop { public delegate T MethodInvokerWithReturnValue(); @@ -204,7 +204,7 @@ namespace Debugger /// Return value of the called function public static object InvokeMethod(object targetObject, string functionName, object[] functionParameters) { - MethodInfo method; + System.Reflection.MethodInfo method; if (targetObject is Type) { method = ((Type)targetObject).GetMethod(functionName); } else { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallbackProxy.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallbackProxy.cs index 1f340d995c..dc9e6d6877 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallbackProxy.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallbackProxy.cs @@ -7,6 +7,8 @@ using System; using System.Windows.Forms; + +using Debugger.Interop; using Debugger.Wrappers.CorDebug; // Regular expresion: diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs index 95882aa024..a9ebf35b07 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs @@ -9,6 +9,7 @@ using System; using System.Text; using System.Threading; +using Debugger.Interop; using Debugger.Wrappers.CorDebug; namespace Debugger diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NamespaceDoc.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NamespaceDoc.cs new file mode 100644 index 0000000000..c583c15f5b --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NamespaceDoc.cs @@ -0,0 +1,23 @@ +// +// +// +// +// $Revision: 1965 $ +// + +using System; +using System.Text; +using System.Threading; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// This library provides features for debugging managed applications. + /// + class NamespaceDoc + { + + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs index 3e3d9e12f3..959ecbbd86 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; namespace Debugger { - public static class Util + static class Util { public static List MergeLists(T a, IEnumerable b) { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/ClassFieldAttribute.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/ClassFieldAttribute.cs index 4374e6a125..f58204a9bc 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/ClassFieldAttribute.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/ClassFieldAttribute.cs @@ -5,9 +5,10 @@ // $Revision$ // -namespace Debugger +namespace Debugger.Wrappers.MetaData { - [System.Flags()] enum ClassFieldAttribute: uint + [System.Flags()] + enum ClassFieldAttribute: uint { // member access mask - Use this mask to retrieve accessibility information. fdFieldAccessMask = 0x0007, diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorCallingConvention.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorCallingConvention.cs index 94b568a082..d2b7270c22 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorCallingConvention.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorCallingConvention.cs @@ -5,7 +5,7 @@ // $Revision$ // -namespace Debugger +namespace Debugger.Wrappers.MetaData { enum CorCallingConvention: uint { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorElementType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorElementType.cs index 360133c199..22b8393981 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorElementType.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorElementType.cs @@ -5,7 +5,7 @@ // $Revision$ // -namespace Debugger +namespace Debugger.Wrappers.CorDebug { enum CorElementType: uint { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorMethodAttr.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorMethodAttr.cs index 3a16f920e8..749bf6b669 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorMethodAttr.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorMethodAttr.cs @@ -5,7 +5,7 @@ // $Revision$ // -namespace Debugger +namespace Debugger.Wrappers.MetaData { enum CorMethodAttr: uint { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorTokenType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorTokenType.cs index 96d8d7f016..0b3be782b1 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorTokenType.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop enums/CorTokenType.cs @@ -5,7 +5,7 @@ // $Revision$ // -namespace Debugger +namespace Debugger.Wrappers.MetaData { enum CorTokenType: uint { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugClass2.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugClass2.cs index b52519101a..11ae7a7873 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugClass2.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugClass2.cs @@ -17,7 +17,7 @@ namespace Debugger.Interop.CorDebug public interface ICorDebugClass2 { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] - void GetParameterizedType([In] uint elementType, [In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugType ppTypeArgs, [MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); + void GetParameterizedType([In] uint elementType, [In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] ppTypeArgs, [MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] void SetJMCStatus([In] int bIsJustMyCode); } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs index 5a7061235e..2979104d36 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Modules/Module.cs @@ -116,12 +116,6 @@ namespace Debugger } } - internal ICorDebugFunction GetMethod(string type, string name, int paramCount) - { - uint token = MetaData.GetMethod(type, name, paramCount).Token; - return corModule.GetFunctionFromToken(token); - } - internal Module(Process process, ICorDebugModule pModule) { this.process = process; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs index 304a97bb82..caf9ec19cd 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs @@ -15,8 +15,6 @@ namespace Debugger Process process; Thread thread; ICorDebugValue corValue; - ValueProxy runtimeValue; - ObjectValueClass runtimeValueException; ExceptionType exceptionType; SourcecodeSegment location; DateTime creationTime; @@ -37,12 +35,11 @@ namespace Debugger this.thread = thread; corValue = thread.CorThread.CurrentException; exceptionType = thread.CurrentExceptionType; - runtimeValue = new Value(process, - new IExpirable[] {process.PauseSession}, - new IMutable[] {}, - delegate { return corValue; } ).ValueProxy; - runtimeValueException = ((ObjectValue)runtimeValue).GetClass("System.Exception"); - message = runtimeValueException.SubVariables["_message"].ValueProxy.AsString; + Value runtimeValue = new Value(process, + new IExpirable[] {process.PauseSession}, + new IMutable[] {}, + delegate { return corValue; } ); + message = runtimeValue.GetMember("_message").AsString; if (thread.LastFunctionWithLoadedSymbols != null) { location = thread.LastFunctionWithLoadedSymbols.NextStatement; @@ -65,7 +62,7 @@ namespace Debugger callstackItems++; } - type = runtimeValue.Type; + type = runtimeValue.Type.Name; } public string Type { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs index 976abc006b..f73d387789 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs @@ -15,6 +15,10 @@ using Debugger.Wrappers.MetaData; namespace Debugger { + /// + /// A function (or also a method or frame) which is being executed on + /// some thread. Use to obtain arguments or local variables. + /// public class Function: RemotingObjectBase, IExpirable { Process process; @@ -32,68 +36,74 @@ namespace Debugger MethodProps methodProps; + /// The process in which this function is executed public Process Process { get { return process; } } + /// The name of the function (eg "ToString") public string Name { get { return methodProps.Name; } } + /// Metadata token of the function public uint Token { get { return methodProps.Token; } } + /// A module in which the function is defined public Module Module { get { return module; } } + /// A thread in which the function is executed public Thread Thread { get { return thread; } } - + + /// True if the function is static public bool IsStatic { get { return methodProps.IsStatic; } } + /// True if the function has symbols defined. + /// (That is has accesss to the .pdb file) public bool HasSymbols { get { return GetSegmentForOffet(0) != null; } } - - internal ICorDebugClass ContaingClass { + + /// The class that defines this function + internal ICorDebugClass ContaingClass { // TODO: Use DebugType get { return corFunction.Class; } } - /// - /// True if function stepped out and is not longer valid. - /// + /// True if function stepped out and is not longer valid. public bool HasExpired { get { return steppedOut || Module.Unloaded; } } - /// - /// Occurs when function expires and is no longer usable - /// + /// Occurs when function expires and is no longer usable public event EventHandler Expired; + /// Is called when function expires and is no longer usable internal protected virtual void OnExpired(EventArgs e) { if (!steppedOut) { @@ -124,6 +134,7 @@ namespace Debugger process.TraceMessage("Function " + this.ToString() + " created"); } + /// Returns diagnostic description of the frame public override string ToString() { return methodProps.Name + "(" + frameID.ToString() + ")"; @@ -174,16 +185,19 @@ namespace Debugger } } + /// Step into next instruction public void StepInto() { Step(true); - } - + } + + /// Step over next instruction public void StepOver() { Step(false); } - + + /// Step out of the function public void StepOut() { new Stepper(this, "Function step out").StepOut(); @@ -313,11 +327,19 @@ namespace Debugger return null; } + /// + /// 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); @@ -353,31 +375,40 @@ namespace Debugger } } - public VariableCollection Variables { + /// + /// Gets all variables in the lexical scope of the function. + /// That is, arguments, local variables and varables of the containing class. + /// + public NamedValueCollection Variables { get { - return new VariableCollection(GetVariables()); + return new NamedValueCollection(GetVariables()); } } - IEnumerable GetVariables() + IEnumerable GetVariables() { if (!IsStatic) { - yield return new Variable("this", ThisValue); + yield return ThisValue; } - foreach(Variable var in ArgumentVariables) { - yield return var; + foreach(NamedValue namedValue in Arguments) { + yield return namedValue; } - foreach(Variable var in LocalVariables) { - yield return var; + foreach(NamedValue namedValue in LocalVariables) { + yield return namedValue; } - foreach(Variable var in ContaingClassVariables) { - yield return var; + foreach(NamedValue namedValue in ContaingClassVariables) { + yield return namedValue; } } - public Value ThisValue { + /// + /// Gets the instance of the class asociated with the current frame. + /// That is, 'this' in C#. + /// + public NamedValue ThisValue { get { - return new Value( + return new NamedValue( + "this", process, new IExpirable[] {this}, new IMutable[] {}, @@ -400,17 +431,22 @@ namespace Debugger } } - public IEnumerable ContaingClassVariables { + /// + /// Gets all accessible members of the class that defines this function. + /// + public NamedValueCollection ContaingClassVariables { get { // TODO: Should work for static if (!IsStatic) { - foreach(Variable var in ThisValue.ValueProxy.SubVariables) { - yield return var; - } + return ThisValue.GetMembers(); + } else { + return NamedValueCollection.Empty; } } } + /// Gets the name of given parameter + /// Zero-based index public string GetParameterName(int index) { // index = 0 is return parameter @@ -421,6 +457,7 @@ namespace Debugger } } + /// Total number of arguments (excluding implicit 'this' argument) public int ArgumentCount { get { ICorDebugValueEnum argumentEnum = CorILFrame.EnumerateArguments(); @@ -432,17 +469,17 @@ namespace Debugger } } - public MethodArgument GetArgumentVariable(int index) + /// Gets argument with a given index + /// Zero-based index + public MethodArgument GetArgument(int index) { return new MethodArgument( GetParameterName(index), index, - new Value( - process, - new IExpirable[] {this}, - new IMutable[] {process.DebugeeState}, - delegate { return GetArgumentCorValue(index); } - ) + process, + new IExpirable[] {this}, + new IMutable[] {process.DebugeeState}, + delegate { return GetArgumentCorValue(index); } ); } @@ -459,14 +496,22 @@ namespace Debugger } } - public IEnumerable ArgumentVariables { + /// Gets all arguments of the function. + public NamedValueCollection Arguments { + get { + return new NamedValueCollection(ArgumentsEnum); + } + } + + IEnumerable ArgumentsEnum { get { for (int i = 0; i < ArgumentCount; i++) { - yield return GetArgumentVariable(i); + yield return GetArgument(i); } } } + /// Gets all local variables of the function. public IEnumerable LocalVariables { get { if (symMethod != null) { // TODO: Is this needed? @@ -496,12 +541,10 @@ namespace Debugger { return new LocalVariable( symVar.Name, - new Value( - process, - new IExpirable[] {this}, - new IMutable[] {process.DebugeeState}, - delegate { return GetCorValueOfLocalVariable(symVar); } - ) + process, + new IExpirable[] {this}, + new IMutable[] {process.DebugeeState}, + delegate { return GetCorValueOfLocalVariable(symVar); } ); } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs index 6883abaa2e..59cd0e4b99 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs @@ -6,6 +6,8 @@ // using System; +using System.Collections.Generic; + using Debugger.Wrappers.CorDebug; namespace Debugger @@ -20,6 +22,8 @@ namespace Debugger Thread selectedThread; PauseSession pauseSession; + Dictionary debugTypeCache = new Dictionary(); + bool hasExpired = false; public event EventHandler Expired; @@ -239,14 +243,24 @@ namespace Debugger } } - public VariableCollection LocalVariables { + public NamedValueCollection LocalVariables { get { if (SelectedFunction == null || IsRunning) { - return VariableCollection.Empty; + return NamedValueCollection.Empty; } else { return SelectedFunction.Variables; } } } + + internal DebugType GetDebugType(ICorDebugType corType) + { + DebugType type; + if (!debugTypeCache.TryGetValue(corType.WrappedObject, out type)) { + type = new DebugType(this, corType); + debugTypeCache.Add(corType.WrappedObject, type); + } + return type; + } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs index f65083117c..7ebf9d7e88 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs @@ -149,9 +149,9 @@ namespace Debugger if (!HasBeenLoaded) return lastPriority; if (process.IsRunning) return lastPriority; - ValueProxy runTimeValue = RuntimeValue.ValueProxy; - if (runTimeValue is NullValue) return ThreadPriority.Normal; - lastPriority = (ThreadPriority)(int)(runTimeValue["m_Priority"].ValueProxy as PrimitiveValue).Primitive; + Value runTimeValue = RuntimeValue; + if (runTimeValue.IsNull) return ThreadPriority.Normal; + lastPriority = (ThreadPriority)(int)runTimeValue.GetMember("m_Priority").PrimitiveValue; return lastPriority; } } @@ -174,10 +174,10 @@ namespace Debugger get { if (!HasBeenLoaded) return lastName; if (process.IsRunning) return lastName; - ValueProxy runtimeVar = RuntimeValue.ValueProxy; - if (runtimeVar is NullValue) return lastName; - ValueProxy runtimeName = runtimeVar["m_Name"].ValueProxy; - if (runtimeName is NullValue) return string.Empty; + Value runtimeValue = RuntimeValue; + if (runtimeValue.IsNull) return lastName; + Value runtimeName = runtimeValue.GetMember("m_Name"); + if (runtimeName.IsNull) return string.Empty; lastName = runtimeName.AsString.ToString(); return lastName; } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayElement.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayElement.cs deleted file mode 100644 index 59f1484e1a..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayElement.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; - -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - public class ArrayElement: Variable - { - uint[] indicies; - - public uint[] Indicies { - get { return indicies; } - } - - public ArrayElement(string name, uint[] indicies, Value @value) - :base (name, @value) - { - this.indicies = indicies; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs deleted file mode 100644 index 449ddb2d55..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs +++ /dev/null @@ -1,166 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; -using Debugger.Wrappers.CorDebug; - -//TODO: Support for lower bound - -namespace Debugger -{ - public class ArrayValue: ValueProxy - { - uint[] dimensions; - - uint lenght; - CorElementType corElementType; - readonly uint rank; - - protected ICorDebugArrayValue CorArrayValue { - get { - return TheValue.CorValue.CastTo(); - } - } - - public uint Lenght { - get { - return lenght; - } - } - - public string ElementsType { - get { - return Value.CorTypeToString(corElementType); - } - } - - public uint Rank { - get { - return rank; - } - } - - public override string AsString { - get { - string txt = "{" + ElementsType + "["; - for (int i = 0; i < rank; i++) { - txt += dimensions[i].ToString() + ","; - } - txt = txt.TrimEnd(new char[] {','}) + "]}"; - return txt; - } - } - - - internal unsafe ArrayValue(Value @value):base(@value) - { - corElementType = (CorElementType)CorArrayValue.ElementType; - - rank = CorArrayValue.Rank; - lenght = CorArrayValue.Count; - - dimensions = new uint[rank]; - fixed (void* pDimensions = dimensions) { - CorArrayValue.GetDimensions(rank, new IntPtr(pDimensions)); - } - } - - bool IsCorValueCompatible { - get { - ArrayValue freshValue = TheValue.ValueProxy as ArrayValue; - return freshValue != null && - freshValue.ElementsType == this.ElementsType && - freshValue.Lenght == this.Lenght && - freshValue.Rank == this.Rank; - } - } - - public Variable this[uint index] { - get { - return this[new uint[] {index}]; - } - } - - public Variable this[uint index1, uint index2] { - get { - return this[new uint[] {index1, index2}]; - } - } - - public Variable this[uint index1, uint index2, uint index3] { - get { - return this[new uint[] {index1, index2, index3}]; - } - } - - public Variable this[uint[] indices] { - get { - return GetItem(indices); - } - } - - Variable GetItem(uint[] itemIndices) - { - uint[] indices = (uint[])itemIndices.Clone(); - - if (indices.Length != rank) throw new DebuggerException("Given indicies does not match array size."); - - string elementName = "["; - for (int i = 0; i < indices.Length; i++) - elementName += indices[i].ToString() + ","; - elementName = elementName.TrimEnd(new char[] {','}) + "]"; - - return new ArrayElement( - elementName, - indices, - new Value( - TheValue.Process, - new IExpirable[] {this.TheValue}, - new IMutable[] {this.TheValue}, - delegate { return GetCorValueOfItem(indices); } - ) - ); - } - - unsafe ICorDebugValue GetCorValueOfItem(uint[] indices) - { - if (!IsCorValueCompatible) throw new CannotGetValueException("Value is not the same array"); - fixed (void* pIndices = indices) { - return CorArrayValue.GetElement(rank, new IntPtr(pIndices)); - } - } - - protected override bool GetMayHaveSubVariables() - { - return true; - } - - protected override VariableCollection GetSubVariables() - { - return new VariableCollection(GetSubVariablesEnum()); - } - - IEnumerable GetSubVariablesEnum() - { - uint[] indices = new uint[rank]; - - while(true) { // Go thought all combinations - for (uint i = rank - 1; i >= 1; i--) - if (indices[i] >= dimensions[i]) { - indices[i] = 0; - indices[i-1]++; - } - if (indices[0] >= dimensions[0]) break; // We are done - - yield return GetItem(indices); - - indices[rank - 1]++; - } - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/CallFunctionEval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/CallFunctionEval.cs deleted file mode 100644 index 76b7211c09..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/CallFunctionEval.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - class CallFunctionEval: Eval - { - ICorDebugFunction corFunction; - Value thisValue; - Value[] args; - - public CallFunctionEval(Process process, - IExpirable[] expireDependencies, - IMutable[] mutateDependencies, - ICorDebugFunction corFunction, - Value thisValue, - Value[] args) - :base(process, expireDependencies, mutateDependencies) - { - this.corFunction = corFunction; - this.thisValue = thisValue; - this.args = args; - } - - protected override void StartEvaluation() - { - List corArgs = new List(); - try { - if (thisValue != null) { - ValueProxy val = thisValue.ValueProxy; - if (!(val is ObjectValue)) { - throw new EvalSetupException("Can not evaluate on a value which is not an object"); - } - if (!((ObjectValue)val).IsInClassHierarchy(corFunction.Class)) { - throw new EvalSetupException("Can not evaluate because the object does not contain specified function"); - } - corArgs.Add(thisValue.SoftReference); - } - foreach(Value arg in args) { - corArgs.Add(arg.SoftReference); - } - } catch (CannotGetValueException e) { - throw new EvalSetupException(e.Message); - } - - corEval.CallFunction(corFunction, (uint)corArgs.Count, corArgs.ToArray()); - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs index 2dfbdcf490..0fe3129f1f 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs @@ -6,6 +6,7 @@ // using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using Debugger.Wrappers.CorDebug; @@ -16,143 +17,198 @@ namespace Debugger /// /// This class holds information about function evaluation. /// - public abstract partial class Eval: Value + public class Eval: RemotingObjectBase { - protected class EvalSetupException: System.Exception + delegate void EvaluationInvoker(ICorDebugEval corEval); + + class EvalSetupException: System.Exception { public EvalSetupException(string msg):base(msg) { } } - protected ICorDebugEval corEval; - EvalState currentState = EvalState.WaitingForRequest; - string currentErrorMsg; + Process process; + Value val; + string description; + EvaluationInvoker evaluationInvoker; + + EvalState state = EvalState.WaitingForRequest; + ICorDebugEval corEval; + string errorMsg; + ICorDebugValue result; + + public Process Process { + get { + return process; + } + } + + public Value Result { + get { + return val; + } + } - string description = String.Empty; + public string Description { + get { + return description; + } + } public EvalState State { get { - return currentState; + return state; } } public bool Evaluated { get { - return currentState == EvalState.EvaluatedSuccessfully || - currentState == EvalState.EvaluatedException || - currentState == EvalState.EvaluatedNoResult || - currentState == EvalState.EvaluatedError; + return state == EvalState.EvaluatedSuccessfully || + state == EvalState.EvaluatedException || + state == EvalState.EvaluatedNoResult || + state == EvalState.EvaluatedError; } } - internal ICorDebugEval CorEval { - get { - return corEval; + Eval(Process process, + string description, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + EvaluationInvoker evaluationInvoker) + { + this.process = process; + this.description = description; + this.val = new Value(process, + expireDependencies, + mutateDependencies, + delegate { return GetCorValue(); }); + this.val.Changed += delegate { SetState(EvalState.WaitingForRequest, null, null); }; + this.evaluationInvoker = evaluationInvoker; + } + + internal bool IsCorEval(ICorDebugEval corEval) + { + return this.corEval == corEval; + } + + public ICorDebugValue GetCorValue() + { + switch(this.State) { + case EvalState.WaitingForRequest: RequestEvaluation(); goto case EvalState.EvaluationScheduled; + case EvalState.EvaluationScheduled: throw new CannotGetValueException("Evaluation pending"); + case EvalState.Evaluating: throw new CannotGetValueException("Evaluating..."); + case EvalState.EvaluatedSuccessfully: return result; + case EvalState.EvaluatedException: return result; + case EvalState.EvaluatedNoResult: throw new CannotGetValueException("No return value"); + case EvalState.EvaluatedError: throw new CannotGetValueException(errorMsg); + default: throw new DebuggerException("Unknown state"); } } - public string Description { - get { return description; } - set { description = value; } + void SetState(EvalState state, string errorMsg, ICorDebugValue result) + { + this.state = state; + this.errorMsg = errorMsg; + this.result = result; } - protected Eval(Process process, - IExpirable[] expireDependencies, - IMutable[] mutateDependencies) - :base(process, expireDependencies, mutateDependencies, null) + void ChangeState(EvalState state, string errorMsg, ICorDebugValue result) { + SetState(state, errorMsg, result); + this.Result.NotifyChange(); } - protected override void ClearCurrentValue() + /// Synchronously calls a function and returns its return value + public static Value InvokeMethod(Process process, System.Type type, string name, Value thisValue, Value[] args) { - currentState = EvalState.WaitingForRequest; - currentErrorMsg = null; - base.ClearCurrentValue(); + return InvokeMethod(MethodInfo.GetFromName(process, type, name, args.Length), thisValue, args); } - public void SetState(EvalState currentState, string currentErrorMsg, ICorDebugValue currentCorValue) + /// Synchronously calls a function and returns its return value + public static Value InvokeMethod(MethodInfo method, Value thisValue, Value[] args) { - ClearCurrentValue(); - this.currentState = currentState; - this.currentErrorMsg = currentErrorMsg; - this.currentCorValue = currentCorValue; - this.currentCorValuePauseSession = process.PauseSession; - OnChanged(new EvalEventArgs(this)); + return AsyncInvokeMethod(method, thisValue, args).EvaluateNow(); } - /// - /// Synchronously calls a function and returns its return value - /// - public static Value CallFunction(Process process, Type type, string functionName, Value thisValue, Value[] args) + public static Eval AsyncInvokeMethod(MethodInfo method, Value thisValue, Value[] args) { - string moduleName = System.IO.Path.GetFileName(type.Assembly.Location); - Module module = process.GetModule(moduleName); - string containgType = type.FullName; - ICorDebugFunction corFunction = module.GetMethod(containgType, functionName, args.Length); - Eval eval = new CallFunctionEval( - process, - new IExpirable[] {}, +// string moduleName = System.IO.Path.GetFileName(type.Assembly.Location); +// Module module = process.GetModule(moduleName); +// string containgType = type.FullName; +// ICorDebugFunction corFunction = module.GetMethod(containgType, functionName, args.Length); + return new Eval( + method.Process, + "Function call: " + method.DeclaringType.Name + "." + method.Name, + new IExpirable[] {}, // TODO new IMutable[] {}, - corFunction, - thisValue, - args + delegate(ICorDebugEval corEval) { StartMethodInvoke(corEval, method, thisValue, args); } ); - eval.Description = "Function call: " + containgType + "." + functionName; - return eval.EvaluateNow(); } - /// - /// Synchronously creates a new string - /// + static void StartMethodInvoke(ICorDebugEval corEval, MethodInfo method, Value thisValue, Value[] args) + { + List corArgs = new List(); + args = args ?? new Value[0]; + try { + if (thisValue != null) { + if (!(thisValue.IsObject)) { + throw new EvalSetupException("Can not evaluate on a value which is not an object"); + } + if (!method.DeclaringType.IsInstanceOfType(thisValue)) { + throw new EvalSetupException("Can not evaluate because the object is not of proper type"); + } + corArgs.Add(thisValue.SoftReference); + } + foreach(Value arg in args) { + corArgs.Add(arg.SoftReference); + } + } catch (CannotGetValueException e) { + throw new EvalSetupException(e.Message); + } + + corEval.CallFunction(method.CorFunction, (uint)corArgs.Count, corArgs.ToArray()); + } + public static Value NewString(Process process, string textToCreate) { - Eval eval = new NewStringEval( + return AsyncNewString(process, textToCreate).EvaluateNow(); + } + + public static Eval AsyncNewString(Process process, string textToCreate) + { + return new Eval( process, + "New string: " + textToCreate, new IExpirable[] {}, new IMutable[] {}, - textToCreate + delegate(ICorDebugEval corEval) { corEval.NewString(textToCreate); } ); - eval.Description = "New string: " + textToCreate; - return eval.EvaluateNow(); } - /// - /// Synchronously creates a new object - /// public static Value NewObject(Process process, ICorDebugClass classToCreate) { - Eval eval = new NewObjectEval( + return AsyncNewObject(process, classToCreate).EvaluateNow(); + } + + public static Eval AsyncNewObject(Process process, ICorDebugClass classToCreate) + { + return new Eval( process, + "New object: " + classToCreate.Token, new IExpirable[] {}, new IMutable[] {}, - classToCreate + delegate(ICorDebugEval corEval) { corEval.NewObjectNoConstructor(classToCreate); } ); - eval.Description = "New object: " + classToCreate.Token; - return eval.EvaluateNow(); } - protected override ICorDebugValue RawCorValue { - get { - switch(this.State) { - case EvalState.WaitingForRequest: ScheduleEvaluation(); goto case EvalState.EvaluationScheduled; - case EvalState.EvaluationScheduled: throw new CannotGetValueException("Evaluation pending"); - case EvalState.Evaluating: throw new CannotGetValueException("Evaluating..."); - case EvalState.EvaluatedSuccessfully: return currentCorValue; - case EvalState.EvaluatedException: return currentCorValue; - case EvalState.EvaluatedNoResult: throw new CannotGetValueException("No return value"); - case EvalState.EvaluatedError: throw new CannotGetValueException(currentErrorMsg); - default: throw new DebuggerException("Unknown state"); - } - } - } - public void ScheduleEvaluation() + public void RequestEvaluation() { if (Evaluated || State == EvalState.WaitingForRequest) { process.ScheduleEval(this); process.Debugger.MTA2STA.AsyncCall(delegate { process.StartEvaluation(); }); - SetState(EvalState.EvaluationScheduled, null, null); + ChangeState(EvalState.EvaluationScheduled, null, null); } } @@ -173,7 +229,7 @@ namespace Debugger corEval = targetThread.CorThread.CreateEval(); try { - StartEvaluation(); + evaluationInvoker(corEval); } catch (COMException e) { if ((uint)e.ErrorCode == 0x80131C26) { throw new EvalSetupException("Can not evaluate in optimized code"); @@ -187,24 +243,22 @@ namespace Debugger } } - SetState(EvalState.Evaluating, null, null); + ChangeState(EvalState.Evaluating, null, null); return true; } catch (EvalSetupException e) { - SetState(EvalState.EvaluatedError, e.Message, null); + ChangeState(EvalState.EvaluatedError, e.Message, null); return false; } } - protected abstract void StartEvaluation(); - public Value EvaluateNow() { while (State == EvalState.WaitingForRequest) { - ScheduleEvaluation(); + RequestEvaluation(); process.WaitForPause(); process.WaitForPause(); } - return this; + return this.Result; } internal void NotifyEvaluationComplete(bool successful) @@ -212,12 +266,12 @@ namespace Debugger // Eval result should be ICorDebugHandleValue so it should survive Continue() if (corEval.Result == null) { - SetState(EvalState.EvaluatedNoResult, null, null); + ChangeState(EvalState.EvaluatedNoResult, null, null); } else { if (successful) { - SetState(EvalState.EvaluatedSuccessfully, null, corEval.Result); + ChangeState(EvalState.EvaluatedSuccessfully, null, corEval.Result); } else { - SetState(EvalState.EvaluatedException, null, corEval.Result); + ChangeState(EvalState.EvaluatedException, null, corEval.Result); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs index e587925479..a760dfe3f5 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs @@ -9,17 +9,22 @@ using System; namespace Debugger { + /// + /// Provides data related to evalution events + /// [Serializable] public class EvalEventArgs : ProcessEventArgs { Eval eval; + /// The evaluation that caused the event public Eval Eval { get { return eval; } } + /// Initializes a new instance of the class public EvalEventArgs(Eval eval): base(eval.Process) { this.eval = eval; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NewObjectEval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NewObjectEval.cs deleted file mode 100644 index 0944235a1a..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NewObjectEval.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - class NewObjectEval: Eval - { - ICorDebugClass classToCreate; - - public NewObjectEval(Process process, - IExpirable[] expireDependencies, - IMutable[] mutateDependencies, - ICorDebugClass classToCreate) - :base(process, expireDependencies, mutateDependencies) - { - this.classToCreate = classToCreate; - } - - protected override void StartEvaluation() - { - corEval.NewObjectNoConstructor(classToCreate); - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NewStringEval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NewStringEval.cs deleted file mode 100644 index 02dc278198..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NewStringEval.cs +++ /dev/null @@ -1,30 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; - -namespace Debugger -{ - class NewStringEval: Eval - { - string textToCreate; - - public NewStringEval(Process process, - IExpirable[] expireDependencies, - IMutable[] mutateDependencies, - string textToCreate) - :base(process, expireDependencies, mutateDependencies) - { - this.textToCreate = textToCreate; - } - - protected override void StartEvaluation() - { - corEval.NewString(textToCreate); - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Process-Evals.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Process-Evals.cs index 185d278999..42aaa65419 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Process-Evals.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Process-Evals.cs @@ -25,7 +25,7 @@ namespace Debugger internal Eval GetEval(ICorDebugEval corEval) { - return activeEvals.Find(delegate (Eval eval) {return eval.CorEval == corEval;}); + return activeEvals.Find(delegate (Eval eval) {return eval.IsCorEval(corEval);}); } /// diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/MethodArgument.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/MethodArgument.cs deleted file mode 100644 index dc558da5cd..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/MethodArgument.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; - -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - public class MethodArgument: Variable - { - int index; - - public int Index { - get { - return index; - } - } - - public MethodArgument(string name, int index, Value @value) - :base (name, @value) - { - this.index = index; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs deleted file mode 100644 index e0fb81ad0d..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; - -namespace Debugger -{ - public class NullValue: ValueProxy - { - public override string AsString { - get { - return ""; - } - } - - public override string Type { - get { - switch (TheValue.CorType) { - case CorElementType.SZARRAY: - case CorElementType.ARRAY: return typeof(System.Array).ToString(); - case CorElementType.OBJECT: return typeof(System.Object).ToString(); - case CorElementType.STRING: return typeof(System.String).ToString(); - case CorElementType.CLASS: return ""; - default: return string.Empty; - } - } - } - - internal unsafe NullValue(Value @value):base(@value) - { - - } - - protected override bool GetMayHaveSubVariables() - { - return false; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectMember.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectMember.cs deleted file mode 100644 index 21db7cd50c..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectMember.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; - -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - /// - /// Provides information about a member of a given object. - /// In particular, it allows to access the value. - /// - public class ObjectMember: Variable - { - [Flags] - public enum Flags { Default = Public, None = 0, Public = 1, Static = 2, PublicStatic = Public | Static}; - - Flags memberFlags; - - public Flags MemberFlags { - get { - return memberFlags; - } - } - - public bool IsStatic { - get { - return (memberFlags & Flags.Static) != 0; - } - } - - public bool IsPublic { - get { - return (memberFlags & Flags.Public) != 0; - } - } - - public ObjectMember(string name, Flags flags, Value @value) - :base (name, @value) - { - this.memberFlags = flags; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs deleted file mode 100644 index 9b1e4f9e7c..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - public class ObjectValue: ValueProxy - { - ObjectValueClass topClass; - Value toStringText; - - public override string AsString { - get { - return "{" + Type + "}"; - } - } - - public Value ToStringText { - get { - return toStringText; - } - } - - public override string Type { - get { - return topClass.Type; - } - } - - public ObjectValueClass TopClass { - get { - return topClass; - } - } - - public IEnumerable Classes { - get { - ObjectValueClass currentClass = topClass; - do { - yield return currentClass; - currentClass = currentClass.BaseClass; - } while (currentClass != null); - } - } - - public ObjectValueClass GetClass(string type) - { - foreach(ObjectValueClass cls in Classes) { - if (cls.Type == type) return cls; - } - return null; - } - - internal bool IsInClassHierarchy(ICorDebugClass corClass) - { - foreach(ObjectValueClass cls in Classes) { - if (cls.CorClass == corClass) return true; - } - return false; - } - - internal ObjectValue(Value @value):base(@value) - { - topClass = new ObjectValueClass(this, TheValue.CorValue.As().Class); - Module module = GetClass("System.Object").Module; - ICorDebugFunction corFunction = module.GetMethod("System.Object", "ToString", 0); - toStringText = new CallFunctionEval(TheValue.Process, - new IExpirable[] {this.TheValue}, - new IMutable[] {this.TheValue}, - corFunction, - TheValue, - new Value[] {}); - } - - internal bool IsCorValueCompatible { - get { - ObjectValue freshValue = TheValue.ValueProxy as ObjectValue; - return freshValue != null && - topClass.Module == freshValue.TopClass.Module && - topClass.ClassToken == freshValue.TopClass.ClassToken; - } - } - - protected override bool GetMayHaveSubVariables() - { - return true; - } - - protected override VariableCollection GetSubVariables() - { - return topClass.SubVariables; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValueClass.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValueClass.cs deleted file mode 100644 index e91248abf5..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValueClass.cs +++ /dev/null @@ -1,232 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; -using Debugger.Wrappers.CorDebug; -using Debugger.Wrappers.MetaData; - -namespace Debugger -{ - public class ObjectValueClass: RemotingObjectBase - { - Process process; - - ObjectValue objectValue; - - Module module; - ICorDebugClass corClass; - TypeDefProps classProps; - - ICorDebugObjectValue CorObjectValue { - get { - return objectValue.TheValue.CorValue.As(); - } - } - - bool IsCorValueCompatible { - get { - return objectValue.IsCorValueCompatible; - } - } - - public Module Module { - get { - return module; - } - } - - public string Type { - get{ - return classProps.Name; - } - } - - internal ICorDebugClass CorClass { - get { - return corClass; - } - } - - public uint ClassToken { - get { - return classProps.Token; - } - } - - public ObjectValueClass(ObjectValue objectValue, ICorDebugClass corClass) - { - this.process = objectValue.TheValue.Process; - this.objectValue = objectValue; - this.module = process.GetModule(corClass.Module); - this.corClass = corClass; - this.classProps = Module.MetaData.GetTypeDefProps(corClass.Token); - } - - public VariableCollection SubVariables { - get { - return new VariableCollection("Base class", - "{" + Type + "}", - SubCollections, - GetSubVariables(ObjectMember.Flags.Public, ObjectMember.Flags.PublicStatic)); - } - } - - IEnumerable SubCollections { - get { - ObjectValueClass baseClass = BaseClass; - VariableCollection privateStatic = new VariableCollection("Private static members", - String.Empty, - new VariableCollection[0], - GetSubVariables(ObjectMember.Flags.Static, ObjectMember.Flags.PublicStatic)); - VariableCollection privateInstance = new VariableCollection("Private members", - String.Empty, - privateStatic.IsEmpty? new VariableCollection[0] : new VariableCollection[] {privateStatic}, - GetSubVariables(ObjectMember.Flags.None, ObjectMember.Flags.PublicStatic)); - VariableCollection publicStatic = new VariableCollection("Static members", - String.Empty, - new VariableCollection[0], - GetSubVariables(ObjectMember.Flags.PublicStatic, ObjectMember.Flags.PublicStatic)); - if (baseClass != null) { - yield return baseClass.SubVariables; - } - if (!privateInstance.IsEmpty) { - yield return privateInstance; - } - if (!publicStatic.IsEmpty) { - yield return publicStatic; - } - } - } - - IEnumerable GetSubVariables(ObjectMember.Flags requiredFlags, ObjectMember.Flags mask) { - foreach(ObjectMember var in GetFieldVariables()) { - if ((var.MemberFlags & mask) == requiredFlags) { - yield return var; - } - } - - foreach(ObjectMember var in GetPropertyVariables()) { - if ((var.MemberFlags & mask) == requiredFlags) { - yield return var; - } - } - } - - public ObjectValueClass BaseClass { - get { - ICorDebugClass superClass = GetSuperClass(process, corClass); - if (superClass != null) { - return new ObjectValueClass(objectValue, superClass); - } else { - return null; - } - } - } - - public IEnumerable GetFieldVariables() - { - foreach(FieldProps f in Module.MetaData.EnumFields(ClassToken)) { - FieldProps field = f; // One per scope/delegate - if (field.IsStatic && field.IsLiteral) continue; // Skip field - yield return new ObjectMember( - field.Name, - (field.IsStatic ? ObjectMember.Flags.Static : ObjectMember.Flags.None) | - (field.IsPublic ? ObjectMember.Flags.Public : ObjectMember.Flags.None), - new Value( - process, - new IExpirable[] {this.objectValue.TheValue}, - new IMutable[] {this.objectValue.TheValue}, - delegate { return GetCorValueOfField(field); } - ) - ); - } - } - - ICorDebugValue GetCorValueOfField(FieldProps field) - { - if (!IsCorValueCompatible) throw new CannotGetValueException("Object type changed"); - - // Current frame is used to resolve context specific static values (eg. ThreadStatic) - ICorDebugFrame curFrame = null; - if (process.IsPaused && process.SelectedThread != null && process.SelectedThread.LastFunction != null && process.SelectedThread.LastFunction.CorILFrame != null) { - curFrame = process.SelectedThread.LastFunction.CorILFrame.CastTo(); - } - - try { - if (field.IsStatic) { - return corClass.GetStaticFieldValue(field.Token, curFrame); - } else { - return CorObjectValue.GetFieldValue(corClass, field.Token); - } - } catch { - throw new CannotGetValueException("Can not get value of field"); - } - } - - IEnumerable Methods { - get { - return this.Module.MetaData.EnumMethods(this.ClassToken); - } - } - - public IEnumerable GetPropertyVariables() - { - foreach(MethodProps m in Methods) { - MethodProps method = m; // One per scope/delegate - if (method.HasSpecialName && method.Name.StartsWith("get_") && method.Name != "get_Item") { - ObjectMember.Flags flags = (method.IsStatic ? ObjectMember.Flags.Static : ObjectMember.Flags.None) | - (method.IsPublic ? ObjectMember.Flags.Public : ObjectMember.Flags.None); - yield return new ObjectMember( - method.Name.Remove(0, 4), - flags, - new CallFunctionEval( - process, - new IExpirable[] {this.objectValue.TheValue}, - new IMutable[] {process.DebugeeState}, - Module.CorModule.GetFunctionFromToken(method.Token), - method.IsStatic ? null : this.objectValue.TheValue, // this - new Value[] {} - ) - ); // args - } - } - } - - protected static ICorDebugClass GetSuperClass(Process process, ICorDebugClass currClass) - { - Module currModule = process.GetModule(currClass.Module); - uint superToken = currModule.MetaData.GetTypeDefProps(currClass.Token).SuperClassToken; - - // It has no base class - if ((superToken & 0x00FFFFFF) == 0x00000000) return null; - - // TypeDef - Localy defined - if ((superToken & 0xFF000000) == 0x02000000) { - return currModule.CorModule.GetClassFromToken(superToken); - } - - // TypeRef - Referencing to external assembly - if ((superToken & 0xFF000000) == 0x01000000) { - string fullTypeName = currModule.MetaData.GetTypeRefProps(superToken).Name; - - foreach (Module superModule in process.Modules) { - // TODO: Does not work for nested - // TODO: preservesig - try { - uint token = superModule.MetaData.FindTypeDefByName(fullTypeName, 0).Token; - return superModule.CorModule.GetClassFromToken(token); - } catch { - continue; - } - } - } - - throw new DebuggerException("Superclass not found"); - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs deleted file mode 100644 index a5cc79698b..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.ComponentModel; -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - public class PrimitiveValue: ValueProxy - { - public override string AsString { - get { - if (Primitive != null) { - return Primitive.ToString(); - } else { - return String.Empty; - } - } - } - - public object Primitive { - get { - if (TheValue.CorType == CorElementType.STRING) { - return (TheValue.CorValue.CastTo()).String; - } else { - return (TheValue.CorValue.CastTo()).Value; - } - } - set { - object newValue; - TypeConverter converter = TypeDescriptor.GetConverter(ManagedType); - try { - newValue = converter.ConvertFrom(value); - } catch { - throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + ManagedType.ToString()); - } - - if (TheValue.CorType == CorElementType.STRING) { - throw new NotSupportedException(); - } else { - (TheValue.CorValue.CastTo()).Value = newValue; - } - TheValue.NotifyChange(); - } - } - - internal PrimitiveValue(Value @value):base(@value) - { - } - - protected override bool GetMayHaveSubVariables() - { - return false; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/SignatureStream.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/SignatureStream.cs deleted file mode 100644 index caff30728e..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/SignatureStream.cs +++ /dev/null @@ -1,296 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Runtime.InteropServices; - -namespace Debugger { - - unsafe class SignatureStream { - byte[] signature; - int currentPos; - - public SignatureStream (byte[] signature) - { - this.signature = signature; - currentPos = 0; - } - - public SignatureStream (IntPtr pSigBlob, uint sigBlobSize) - { - signature = new Byte[sigBlobSize]; - Marshal.Copy(pSigBlob, signature, 0, (int)sigBlobSize); - currentPos = 0; - } - - public bool EndOfStream { - get { - return currentPos >= signature.Length; - } - } - - byte PeekByte { - get { - if (EndOfStream) throw new BadSignatureException(); - return signature[currentPos]; - } - } - - byte ReadByte { - get { - byte value = PeekByte; - currentPos++; - return value; - } - } - - - uint ReadData(out int compressedSize) - { - if ((PeekByte & 0x80) == 0x00) { - compressedSize = 1; - return ReadByte; - } - if ((PeekByte & 0xC0) == 0x80) { - compressedSize = 2; - return (uint)( - (ReadByte & 0x3F) * 0x100 + - ReadByte - ); - } - if ((PeekByte & 0xE0) == 0xC0) { - compressedSize = 4; - return (uint)( - (ReadByte & 0x1F) * 0x1000000 + - ReadByte * 0x10000 + - ReadByte * 0x100 + - ReadByte - ); - } - throw new BadSignatureException(); - } - - - public uint PeekData() - { - int oldPos = currentPos; - uint res = ReadData(); - currentPos = oldPos; - return res; - } - - public uint ReadData() - { - int compressedSize; - return ReadData(out compressedSize); - } - - - CorTokenType[] encodeTokenType = new CorTokenType[] {CorTokenType.mdtTypeDef, CorTokenType.mdtTypeRef, CorTokenType.mdtTypeSpec, CorTokenType.mdtBaseType}; - - public uint PeekToken() - { - int oldPos = currentPos; - uint res = ReadToken(); - currentPos = oldPos; - return res; - } - - public uint ReadToken() - { - uint data; - uint tokenType; - - data = ReadData(); - tokenType = (uint)encodeTokenType[data & 0x3]; - return (data >> 2) | tokenType; - } - - - public uint PeekSignedInt() - { - int oldPos = currentPos; - uint res = ReadSignedInt(); - currentPos = oldPos; - return res; - } - - public uint ReadSignedInt() - { - int compressedSize; - bool signed; - uint data; - - data = ReadData(out compressedSize); - signed = (data & 0x1) == 1; - data = data >> 1; - if (signed) { - switch (compressedSize) { - case 1: - data |= 0xffffffc0; - break; - case 2: - data |= 0xffffe000; - break; - case 4: - data |= 0xf0000000; - break; - default: - throw new BadSignatureException(); - } - } - return data; - } - - - public uint PeekCallingConv() - { - int oldPos = currentPos; - uint res = ReadCallingConv(); - currentPos = oldPos; - return res; - } - - public uint ReadCallingConv() - { - return ReadData(); - } - - - public CorElementType PeekElementType() - { - int oldPos = currentPos; - CorElementType res = ReadElementType(); - currentPos = oldPos; - return res; - } - - public CorElementType ReadElementType() - { - return (CorElementType)ReadData(); - } - - - - public void ReadCustomMod() - { - while (PeekElementType() == CorElementType.CMOD_OPT || - PeekElementType() == CorElementType.CMOD_REQD) { - ReadElementType(); - ReadToken(); - } - } - - public string ReadType() - { - CorElementType type = ReadElementType(); - switch(type) - { - case CorElementType.BOOLEAN: - case CorElementType.CHAR: - case CorElementType.I1: - case CorElementType.U1: - case CorElementType.I2: - case CorElementType.U2: - case CorElementType.I4: - case CorElementType.U4: - case CorElementType.I8: - case CorElementType.U8: - case CorElementType.R4: - case CorElementType.R8: - case CorElementType.I: - case CorElementType.U: - case CorElementType.STRING: - case CorElementType.OBJECT: - return type.ToString(); - - case CorElementType.VALUETYPE: - case CorElementType.CLASS: - ReadToken(); - return type.ToString(); - - case CorElementType.PTR: - ReadCustomMod(); - if (PeekElementType() == CorElementType.VOID) { - ReadElementType(); - break; - } else { - return "Pointer:" + ReadType(); - } - - case CorElementType.FNPTR: - ReadFunction(); - break; - - case CorElementType.ARRAY: - ReadType(); - ReadArrayShape(); - break; - - case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array - ReadCustomMod(); - ReadType(); - break; - - default: - throw new BadSignatureException(); - } - return ""; - } - - public void ReadArrayShape() - { - ReadData(); //rank - uint numSizes = ReadData(); - for (int i = 0; i < numSizes; i++) { - ReadData(); //size - } - if (numSizes > 0) { - uint numLoBounds = ReadData(); - for (int i = 0; i < numLoBounds; i++) { - ReadData(); //LoBound - } - } - } - - public void ReadFunction() - { - uint callConv = ReadCallingConv(); - uint paramCount = ReadData(); - - // Read return type - switch (ReadElementType()) { - case CorElementType.BYREF: - ReadType(); - break; - case CorElementType.TYPEDBYREF: - break; - case CorElementType.VOID: - break; - default: - throw new BadSignatureException(); - } - - // Read params - for (int i = 0; i < paramCount; i++) { - ReadCustomMod(); - switch (PeekElementType()) { - case CorElementType.BYREF: - ReadElementType(); - ReadType(); - break; - case CorElementType.TYPEDBYREF: - ReadElementType(); - break; - default: - ReadType(); - break; - } - } - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/BindingFlags.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/BindingFlags.cs new file mode 100644 index 0000000000..71866dd52c --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/BindingFlags.cs @@ -0,0 +1,32 @@ +// +// +// +// +// $Revision: 2023 $ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + /// + /// Binding flags specify which members should be returned. + /// Use 'or' operation to combine flags. + /// + [Flags] + public enum BindingFlags { + /// Return instance (ie non-static members) members + Instance, + /// Return static members + Static, + /// Return public members + Public, + /// Return members which are not public + NonPublic, + /// Return all members + All = Instance | Static | Public | NonPublic + }; +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType-Helpers.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType-Helpers.cs new file mode 100644 index 0000000000..7164dfba7f --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType-Helpers.cs @@ -0,0 +1,102 @@ +// +// +// +// +// $Revision: 2023 $ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + public partial class DebugType + { + IList FilterMemberInfo(List input, BindingFlags bindingFlags) where T:MemberInfo + { + List filtered = new List(); + foreach(T memberInfo in input) { + if (memberInfo.IsStatic && ((bindingFlags & BindingFlags.Static) != 0) || + !memberInfo.IsStatic && ((bindingFlags & BindingFlags.Instance) != 0)) { + + if (memberInfo.IsPrivate && ((bindingFlags & BindingFlags.NonPublic) != 0) || + memberInfo.IsPublic && ((bindingFlags & BindingFlags.Public) != 0)) { + + filtered.Add(memberInfo); + } + } + } + return filtered.AsReadOnly(); + } + + /// + /// Returns simple managed type coresponding to the debug type. + /// Any class yields System.Object + /// + public System.Type ManagedType { + get { + switch(this.corElementType) { + case CorElementType.BOOLEAN: return typeof(System.Boolean); + case CorElementType.CHAR: return typeof(System.Char); + case CorElementType.I1: return typeof(System.SByte); + case CorElementType.U1: return typeof(System.Byte); + case CorElementType.I2: return typeof(System.Int16); + case CorElementType.U2: return typeof(System.UInt16); + case CorElementType.I4: return typeof(System.Int32); + case CorElementType.U4: return typeof(System.UInt32); + case CorElementType.I8: return typeof(System.Int64); + case CorElementType.U8: return typeof(System.UInt64); + case CorElementType.R4: return typeof(System.Single); + case CorElementType.R8: return typeof(System.Double); + case CorElementType.I: return typeof(int); + case CorElementType.U: return typeof(uint); + case CorElementType.SZARRAY: + case CorElementType.ARRAY: return typeof(System.Array); + case CorElementType.OBJECT: return typeof(System.Object); + case CorElementType.STRING: return typeof(System.String); + default: return null; + } + } + } + + /* + * Find the super class manually - unused since we have ICorDebugType.GetBase() in .NET 2.0 + * + protected static ICorDebugClass GetSuperClass(Process process, ICorDebugClass currClass) + { + Module currModule = process.GetModule(currClass.Module); + uint superToken = currModule.MetaData.GetTypeDefProps(currClass.Token).SuperClassToken; + + // It has no base class + if ((superToken & 0x00FFFFFF) == 0x00000000) return null; + + // TypeDef - Localy defined + if ((superToken & 0xFF000000) == 0x02000000) { + return currModule.CorModule.GetClassFromToken(superToken); + } + + // TypeRef - Referencing to external assembly + if ((superToken & 0xFF000000) == 0x01000000) { + string fullTypeName = currModule.MetaData.GetTypeRefProps(superToken).Name; + + foreach (Module superModule in process.Modules) { + // TODO: Does not work for nested + // TODO: preservesig + try { + uint token = superModule.MetaData.FindTypeDefByName(fullTypeName, 0).Token; + return superModule.CorModule.GetClassFromToken(token); + } catch { + continue; + } + } + } + + // TODO: Can also be TypeSpec = 0x1b000000 + + throw new DebuggerException("Superclass not found"); + } + */ + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs new file mode 100644 index 0000000000..7ce3b16b0f --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs @@ -0,0 +1,340 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + /// + /// Represents a type in a debugee. That is, a class, array, value type or a primitive type. + /// This class mimics the class. + /// + public partial class DebugType: RemotingObjectBase + { + Process process; + ICorDebugType corType; + CorElementType corElementType; + + // Class/ValueType specific data + ICorDebugClass corClass; + Module module; + TypeDefProps classProps; + + // Cache + List fields; + List methods; + List properties; + + void AssertClassOrValueType() + { + if(!IsClass && !IsValueType) { + throw new DebuggerException("The type is not a class or value type."); + } + } + + /// Gets the process in which the type was loaded + public Process Process { + get { + return process; + } + } + + internal ICorDebugType CorType { + get { + return corType; + } + } + + /// + /// Gets the module in which the class or value type is defined. + /// Only applicable to class or value type! + /// + public Module Module { + get { + AssertClassOrValueType(); + return module; + } + } + + /// + /// Gets the metadata token of the class or value type. + /// Only applicable to class or value type! + /// + public uint MetadataToken { + get { + AssertClassOrValueType(); + return classProps.Token; + } + } + + /// Returns a string describing the type + public string Name { + get { + // TODO: Improve + if(IsClass || IsValueType) { + return classProps.Name; + } else { + System.Type managedType = this.ManagedType; + if (managedType != null) { + return managedType.ToString(); + } else { + return ""; + } + } + } + } + + /// Gets a value indicating whether the type is an array + public bool IsArray { + get { + return this.corElementType == CorElementType.ARRAY || + this.corElementType == CorElementType.SZARRAY; + } + } + + /// Gets a value indicating whether the type is a class + public bool IsClass { + get { + return this.corElementType == CorElementType.CLASS || + this.corElementType == CorElementType.OBJECT; + } + } + + /// Gets a value indicating whether the type is a value type (that is, a structre in C#) + public bool IsValueType { + get { + return this.corElementType == CorElementType.VALUETYPE; + } + } + + /// Gets a value indicating whether the type is a primitive type + public bool IsPrimitive { + get { + return this.corElementType == CorElementType.BOOLEAN || + this.corElementType == CorElementType.CHAR || + this.corElementType == CorElementType.I1 || + this.corElementType == CorElementType.U1 || + this.corElementType == CorElementType.I2 || + this.corElementType == CorElementType.U2 || + this.corElementType == CorElementType.I4 || + this.corElementType == CorElementType.U4 || + this.corElementType == CorElementType.I8 || + this.corElementType == CorElementType.U8 || + this.corElementType == CorElementType.R4 || + this.corElementType == CorElementType.R8 || + this.corElementType == CorElementType.I || + this.corElementType == CorElementType.U || + this.corElementType == CorElementType.STRING; + } + } + + /// Gets a value indicating whether the type is an integer type + public bool IsInteger { + get { + return this.corElementType == CorElementType.I1 || + this.corElementType == CorElementType.U1 || + this.corElementType == CorElementType.I2 || + this.corElementType == CorElementType.U2 || + this.corElementType == CorElementType.I4 || + this.corElementType == CorElementType.U4 || + this.corElementType == CorElementType.I8 || + this.corElementType == CorElementType.U8 || + this.corElementType == CorElementType.I || + this.corElementType == CorElementType.U; + } + } + + /// + /// Gets the type from which this type inherits. + /// + /// Returns null if the current type is . + /// + /// + public DebugType BaseType { + get { + ICorDebugType baseType = corType.Base; + if (baseType != null) { + return new DebugType(process, baseType); + } else { + return null; + } + } + } + + internal DebugType(Process process, ICorDebugType corType) + { + if (corType == null) throw new ArgumentNullException("corType"); + + this.process = process; + this.corType = corType; + this.corElementType = (CorElementType)corType.Type; + + if (this.IsClass || this.IsValueType) { + this.corClass = corType.Class; + this.module = process.GetModule(corClass.Module); + this.classProps = module.MetaData.GetTypeDefProps(corClass.Token); + } + + process.TraceMessage("Created type " + this.Name); + } + + /// + /// Obtains instance of DebugType using process cache + /// + static internal DebugType Create(Process process, ICorDebugType corType) + { + return process.GetDebugType(corType); + } + + /// Determines whether the current type is sublass of + /// the the given type. That is, it derives from the given type. + /// Returns false if the given type is same as the current type + public bool IsSubclassOf(DebugType superType) + { + DebugType type = this.BaseType; + while (type != null) { + if (this.Equals(type)) return true; + type = type.BaseType; + } + return false; + } + + /// Determines whether the given object is instance of the + /// current type or can be implicitly cast to it + public bool IsInstanceOfType(Value objectInstance) + { + return this.Equals(objectInstance.Type) || + this.IsSubclassOf(objectInstance.Type); + } + + List GetAllFields() + { + AssertClassOrValueType(); + + // Build cache + if (fields == null) { + process.TraceMessage("Loading fields for type " + this.Name); + fields = new List(); + foreach(FieldProps field in module.MetaData.EnumFields(this.MetadataToken)) { + // TODO: Why? + if (field.IsStatic && field.IsLiteral) continue; // Skip static literals + fields.Add(new FieldInfo(this, field)); + }; + } + return fields; + } + + List GetAllMethods() + { + AssertClassOrValueType(); + + // Build cache + if (methods == null) { + process.TraceMessage("Loading methods for type " + this.Name); + methods = new List(); + foreach(MethodProps m in module.MetaData.EnumMethods(this.MetadataToken)) { + methods.Add(new MethodInfo(this, m)); + } + } + return methods; + } + + // TODO: Handle indexers ("get_Item") in other code + List GetAllProperties() + { + AssertClassOrValueType(); + + // Build cache + if (properties == null) { + process.TraceMessage("Loading properties for type " + this.Name); + properties = new List(); + // Collect data + Dictionary methods = new Dictionary(); + Dictionary names = new Dictionary(); + foreach(MethodInfo method in GetAllMethods()) { + if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))) { + methods.Add(method.Name, method); + names.Add(method.Name.Remove(0,4), null); + } + } + // Pair up getters and setters + foreach(KeyValuePair kvp in names) { + MethodInfo getter = null; + MethodInfo setter = null; + methods.TryGetValue("get_" + kvp.Key, out getter); + methods.TryGetValue("set_" + kvp.Key, out setter); + properties.Add(new PropertyInfo(this, getter, setter)); + } + } + return properties; + } + + /// Return all public fields. + public IList GetFields() + { + return GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); + } + + /// Return all fields satisfing binding flags. + public IList GetFields(BindingFlags bindingFlags) + { + if (IsClass || IsValueType) { + return FilterMemberInfo(GetAllFields(), bindingFlags); + } else { + return new List(); + } + } + + /// Return all public methods. + public IList GetMethods() + { + return GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); + } + + /// Return all methods satisfing binding flags. + public IList GetMethods(BindingFlags bindingFlags) + { + if (IsClass || IsValueType) { + return FilterMemberInfo(GetAllMethods(), bindingFlags); + } else { + return new List(); + } + } + + /// Return all public properties. + public IList GetProperties() + { + return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); + } + + /// Return all properties satisfing binding flags. + public IList GetProperties(BindingFlags bindingFlags) + { + if (IsClass || IsValueType) { + return FilterMemberInfo(GetAllProperties(), bindingFlags); + } else { + return new List(); + } + } + + /// Compares two types + public override bool Equals(object obj) + { + return obj is DebugType && + ((DebugType)obj).CorType == this.CorType; + } + + /// Get hash code of the object + public override int GetHashCode() + { + return base.GetHashCode(); + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/FieldInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/FieldInfo.cs new file mode 100644 index 0000000000..4d012f15df --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/FieldInfo.cs @@ -0,0 +1,109 @@ +// +// +// +// +// $Revision: 2023 $ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + /// + /// Provides information about a field of some class. + /// + public class FieldInfo: MemberInfo + { + FieldProps fieldProps; + + /// Gets a value indicating whether this field is literal field + public bool IsLiteral { + get { + return fieldProps.IsLiteral; + } + } + + /// Gets a value indicating whether this field is private + public override bool IsPrivate { + get { + return !fieldProps.IsPublic; + } + } + + /// Gets a value indicating whether this field is public + public override bool IsPublic { + get { + return fieldProps.IsPublic; + } + } + + /// Gets a value indicating whether this field is static + public override bool IsStatic { + get { + return fieldProps.IsStatic; + } + } + + /// Gets the metadata token associated with this field + public override uint MetadataToken { + get { + return fieldProps.Token; + } + } + + /// Gets the name of this field + public override string Name { + get { + return fieldProps.Name; + } + } + + internal FieldInfo(DebugType declaringType, FieldProps fieldProps):base (declaringType) + { + this.fieldProps = fieldProps; + } + + /// + /// Given an object of correct type, get the value of this field + /// + public MemberValue GetValue(Value objectInstance) { + return new MemberValue( + this, + this.Process, + new IExpirable[] {objectInstance}, + new IMutable[] {objectInstance}, + delegate { return GetCorValue(objectInstance); } + ); + } + + ICorDebugValue GetCorValue(Value objectInstance) + { + if (!DeclaringType.IsInstanceOfType(objectInstance)) { + throw new CannotGetValueException("Object is not of type " + DeclaringType.Name); + } + + // Current frame is used to resolve context specific static values (eg. ThreadStatic) + ICorDebugFrame curFrame = null; + if (this.Process.IsPaused && + this.Process.SelectedThread != null && + this.Process.SelectedThread.LastFunction != null && + this.Process.SelectedThread.LastFunction.CorILFrame != null) { + + curFrame = this.Process.SelectedThread.LastFunction.CorILFrame.CastTo(); + } + + try { + if (this.IsStatic) { + return DeclaringType.CorType.GetStaticFieldValue(MetadataToken, curFrame); + } else { + return objectInstance.CorObjectValue.GetFieldValue(DeclaringType.CorType.Class, MetadataToken); + } + } catch { + throw new CannotGetValueException("Can not get value of field"); + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/MemberInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/MemberInfo.cs new file mode 100644 index 0000000000..d46b8d4d30 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/MemberInfo.cs @@ -0,0 +1,64 @@ +// +// +// +// +// $Revision: 2023 $ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + /// + /// Provides information about a member of some class + /// (eg. a field or a method). + /// + public abstract class MemberInfo: RemotingObjectBase + { + DebugType declaringType; + + /// Gets the process in which the type was loaded + public Process Process { + get { + return declaringType.Process; + } + } + + /// Gets the type that declares this member element + public DebugType DeclaringType { + get { + return declaringType; + } + } + + /// Gets a value indicating whether this member is private + public abstract bool IsPrivate { get; } + + /// Gets a value indicating whether this member is public + public abstract bool IsPublic { get; } + + /// Gets a value indicating whether this member is static + public abstract bool IsStatic { get; } + + /// Gets the metadata token associated with this member + public abstract uint MetadataToken { get; } + + /// Gets the name of this member + public abstract string Name { get; } + + /// Gets the module in which this member is defined + public Module Module { + get { + return declaringType.Module; + } + } + + internal MemberInfo(DebugType declaringType) + { + this.declaringType = declaringType; + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/MethodInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/MethodInfo.cs new file mode 100644 index 0000000000..13b2234336 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/MethodInfo.cs @@ -0,0 +1,126 @@ +// +// +// +// +// $Revision: 2023 $ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + /// + /// Provides information about a method in a class + /// + public class MethodInfo: MemberInfo + { + MethodProps methodProps; + + /// Gets a value indicating whether this method is private + public override bool IsPrivate { + get { + return !methodProps.IsPublic; + } + } + + /// Gets a value indicating whether this method is public + public override bool IsPublic { + get { + return methodProps.IsPublic; + } + } + + /// Gets a value indicating whether the name of this method + /// is marked as specail. + /// For example, property accessors are marked as special + public bool IsSpecialName { + get { + return methodProps.HasSpecialName; + } + } + + /// Gets a value indicating whether this method is static + public override bool IsStatic { + get { + return methodProps.IsStatic; + } + } + + /// Gets the metadata token associated with this method + public override uint MetadataToken { + get { + return methodProps.Token; + } + } + + /// Gets the name of this method + public override string Name { + get { + return methodProps.Name; + } + } + + internal ICorDebugFunction CorFunction { + get { + return this.Module.CorModule.GetFunctionFromToken(this.MetadataToken); + } + } + + internal MethodInfo(DebugType declaringType, MethodProps methodProps):base (declaringType) + { + this.methodProps = methodProps; + } + + /// + /// Get a method from a managed type, method name and argument count + /// + public static MethodInfo GetFromName(Process process, System.Type type, string name, int paramCount) + { + if (type.IsNested) throw new DebuggerException("Not implemented for nested types"); + if (type.IsGenericType) throw new DebuggerException("Not implemented for generic types"); + if (type.IsGenericParameter) throw new DebuggerException("Type can not be generic parameter"); + + foreach(Module module in process.Modules) { + TypeDefProps typeDefProps = module.MetaData.FindTypeDefByName(type.FullName, 0 /* enclosing class for nested */); + foreach(MethodProps methodProps in module.MetaData.EnumMethodsWithName(typeDefProps.Token, name)) { + if (module.MetaData.GetParamCount(methodProps.Token) == paramCount) { + ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(methodProps.Token); + ICorDebugClass2 corClass = corFunction.Class.As(); + ICorDebugType corType = corClass.GetParameterizedType(type.IsValueType ? (uint)CorElementType.VALUETYPE : (uint)CorElementType.CLASS, + 0, + new ICorDebugType[] {}); + return new MethodInfo(DebugType.Create(process, corType), methodProps); + } + } + } + throw new DebuggerException("Not found"); + } + + /// + /// Synchronously invoke the method of an a given object + /// + public Value Invoke(Value objectInstance, Value[] arguments) + { + return Eval.InvokeMethod( + this, + this.IsStatic ? null : objectInstance, + arguments ?? new Value[0] + ); + } + + /// + /// Asynchronously invoke the method of an a given object + /// + public Eval AsyncInvoke(Value objectInstance, Value[] arguments) + { + return Eval.AsyncInvokeMethod( + this, + this.IsStatic ? null : objectInstance, + arguments ?? new Value[0] + ); + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/PropertyInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/PropertyInfo.cs new file mode 100644 index 0000000000..c3ca212f8c --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/PropertyInfo.cs @@ -0,0 +1,120 @@ +// +// +// +// +// $Revision: 2023 $ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; +using Debugger.Wrappers.MetaData; + +namespace Debugger +{ + /// + /// Provides information about a property in a class + /// + public class PropertyInfo: MemberInfo + { + MethodInfo getMethod; + MethodInfo setMethod; + + /// Gets a value indicating whether this property is private + public override bool IsPrivate { + get { + return !(getMethod ?? setMethod).IsPublic; + } + } + + /// Gets a value indicating whether this property is public + public override bool IsPublic { + get { + return (getMethod ?? setMethod).IsPublic; + } + } + + /// Gets a value indicating whether this property is static + public override bool IsStatic { + get { + return (getMethod ?? setMethod).IsStatic; + } + } + + /// Gets the metadata token associated with getter (or setter) + /// of this property + public override uint MetadataToken { + get { + return (getMethod ?? setMethod).MetadataToken; + } + } + + /// Gets the name of this property + public override string Name { + get { + return (getMethod ?? setMethod).Name.Remove(0,4); + } + } + + internal PropertyInfo(DebugType declaringType, MethodInfo getMethod, MethodInfo setMethod): base(declaringType) + { + if (getMethod == null && setMethod == null) throw new ArgumentNullException("Both getter and setter can not be null."); + + this.getMethod = getMethod; + this.setMethod = setMethod; + } + + /// Get the get accessor of the property + public MethodInfo GetGetMethod() + { + return getMethod; + } + + /// Get the set accessor of the property + public MethodInfo GetSetMethod() + { + return setMethod; + } + + /// Get the value of the property using the get accessor + public MemberValue GetValue(Value objectInstance) + { + return GetValue(objectInstance, null); + } + + /// Get the value of indexer property + public MemberValue GetValue(Value objectInstance, Value[] parameters) + { + if (getMethod == null) throw new CannotGetValueException("Property does not have a get method"); + + Value returnedValue = getMethod.Invoke(objectInstance, parameters ?? new Value[0]); + + return new MemberValue( + this, + this.Process, + new IExpirable[] {returnedValue}, + new IMutable[] {returnedValue}, + delegate { return returnedValue.CorValue; } + ); + } + + /// Set the value of the property using the set accessor + public Value SetValue(Value objectInstance, Value newValue) + { + return SetValue(objectInstance, newValue, null); + } + + /// Set the value of indexer property + public Value SetValue(Value objectInstance, Value newValue, Value[] parameters) + { + if (setMethod == null) throw new CannotGetValueException("Property does not have a set method"); + + parameters = parameters ?? new Value[0]; + Value[] allParams = new Value[1 + parameters.Length]; + allParams[0] = newValue; + parameters.CopyTo(allParams, 1); + + return setMethod.Invoke(objectInstance, allParams); + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs deleted file mode 100644 index 4e84b27ab3..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; - -namespace Debugger -{ - public class UnavailableValue: ValueProxy - { - string message; - - public override string AsString { - get { - return message; - } - } - - public override string Type { - get { - return String.Empty; - } - } - - internal UnavailableValue(Value @value, string message):base(@value) - { - this.message = message; - } - - protected override bool GetMayHaveSubVariables() - { - return false; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs deleted file mode 100644 index 8c8fcabb8d..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs +++ /dev/null @@ -1,446 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; - -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - /// - /// Delegate that is used to get value. This delegate may be called at any time and should never return null. - /// - delegate ICorDebugValue CorValueGetter(); - - /// - /// Value is a container which holds data necessaty to obtain - /// the value of a given object even after continue. This level of - /// abstraction is necessary because the type of a value can change - /// (eg for local variable of type object) - /// - /// Expiration: Once value expires it can not be used anymore. - /// Expiration is permanet - once value expires it stays expired. - /// Value expires when any object specified in constructor expires - /// or when process exits. - /// - /// Mutation: As long as any dependecy does not mutate the last - /// obteined value is still considered up to date. (If continue is - /// called and internal value is neutred new copy will be obatined) - /// - public class Value: IExpirable, IMutable - { - protected Process process; - - CorValueGetter corValueGetter; - IMutable[] mutateDependencies; - - protected ValueProxy currentValue; - protected ICorDebugValue currentCorValue; - protected PauseSession currentCorValuePauseSession; - - bool isExpired = false; - - public event EventHandler Expired; - public event EventHandler Changed; - - public Process Process { - get { - return process; - } - } - - public ICorDebugValue CorValue { - get { - return DereferenceUnbox(RawCorValue); - } - } - - internal CorElementType CorType { - get { - return GetCorType(this.CorValue); - } - } - - internal static CorElementType GetCorType(ICorDebugValue corValue) - { - if (corValue == null) { - return (CorElementType)0; - } - return (CorElementType)corValue.Type; - } - - protected virtual ICorDebugValue RawCorValue { - get { - if (this.HasExpired) throw new CannotGetValueException("CorValue has expired"); - if (currentCorValue == null || (currentCorValuePauseSession != process.PauseSession && !currentCorValue.Is())) { - currentCorValue = corValueGetter(); - currentCorValuePauseSession = process.PauseSession; - } - return currentCorValue; - } - } - - public ValueProxy ValueProxy { - get { - if (currentValue == null) { - try { - currentValue = CreateValue(); - } catch (CannotGetValueException e) { - currentValue = new UnavailableValue(this, e.Message); - } - } - return currentValue; - } - } - - public bool HasExpired { - get { - return isExpired; - } - } - - public ICorDebugValue SoftReference { - get { - if (this.HasExpired) throw new DebuggerException("CorValue has expired"); - - ICorDebugValue corValue = RawCorValue; - if (corValue != null && corValue.Is()) { - return corValue; - } - corValue = DereferenceUnbox(corValue); - if (corValue != null && corValue.Is()) { - return corValue.As().CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION).CastTo(); - } else { - return corValue; // Value type - return value type - } - } - } - - internal Value(Process process, - IExpirable[] expireDependencies, - IMutable[] mutateDependencies, - CorValueGetter corValueGetter) - { - this.process = process; - - foreach(IExpirable exp in expireDependencies) { - AddExpireDependency(exp); - } - AddExpireDependency(process); - - this.mutateDependencies = mutateDependencies; - if (!this.HasExpired) { - foreach(IMutable mut in mutateDependencies) { - AddMutateDependency(mut); - } - } - - this.corValueGetter = corValueGetter; - } - - void AddExpireDependency(IExpirable dependency) - { - if (dependency.HasExpired) { - MakeExpired(); - } else { - dependency.Expired += delegate { MakeExpired(); }; - } - } - - void AddMutateDependency(IMutable dependency) - { - dependency.Changed += DependencyChanged; - } - - void MakeExpired() - { - if (!isExpired) { - isExpired = true; - OnExpired(new ValueEventArgs(this)); - foreach(IMutable mut in mutateDependencies) { - mut.Changed -= DependencyChanged; - } - } - } - - void DependencyChanged(object sender, ProcessEventArgs e) - { - NotifyChange(); - } - - protected virtual void ClearCurrentValue() - { - currentValue = null; - currentCorValue = null; - currentCorValuePauseSession = null; - } - - internal void NotifyChange() - { - ClearCurrentValue(); - if (!isExpired) { - OnChanged(new ValueEventArgs(this)); - } - } - - protected virtual void OnChanged(ProcessEventArgs e) - { - if (Changed != null) { - Changed(this, e); - } - } - - protected virtual void OnExpired(EventArgs e) - { - if (Expired != null) { - Expired(this, e); - } - } - - internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) - { - // Method arguments can be passed 'by ref' - if (corValue.Type == (uint)CorElementType.BYREF) { - corValue = corValue.CastTo().Dereference(); - } - - // Pointers may be used in 'unsafe' code - CorElementType.PTR - // Classes need to be dereferenced - while (corValue.Is()) { - ICorDebugReferenceValue refValue = corValue.CastTo(); - if (refValue.IsNull != 0) { - return null; // Reference is null - } else { - try { - corValue = refValue.Dereference(); - // TODO: Investigate: Must not acutally be null - // eg. Assembly.AssemblyHandle See SD2-1117 - if (corValue == null) return null; // Dereference() returned null - } catch { - return null; // Error during dereferencing - } - } - } - - // Unbox value types - if (corValue.Is()) { - corValue = corValue.CastTo().Object.CastTo(); - } - - return corValue; - } - - public enum ValueType {Null, Primitive, Array, Object, Unknown}; - - ValueType GetValueType() - { - ICorDebugValue corValue = this.CorValue; - - if (corValue == null) { - return ValueType.Null; - } - - switch(GetCorType(corValue)) { - case CorElementType.BOOLEAN: - case CorElementType.CHAR: - case CorElementType.I1: - case CorElementType.U1: - case CorElementType.I2: - case CorElementType.U2: - case CorElementType.I4: - case CorElementType.U4: - case CorElementType.I8: - case CorElementType.U8: - case CorElementType.R4: - case CorElementType.R8: - case CorElementType.I: - case CorElementType.U: - case CorElementType.STRING: - return ValueType.Primitive; - - case CorElementType.ARRAY: - case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array - return ValueType.Array; - - case CorElementType.VALUETYPE: - case CorElementType.CLASS: - case CorElementType.OBJECT: // Short-cut for Class "System.Object" - return ValueType.Object; - - default: // Unknown type - return ValueType.Unknown; - } - } - - ValueProxy CreateValue() - { - ICorDebugValue corValue = this.CorValue; - - switch(GetValueType()) { - case ValueType.Null: return new NullValue(this); - case ValueType.Primitive: return new PrimitiveValue(this); - case ValueType.Array: return new ArrayValue(this); - case ValueType.Object: return new ObjectValue(this); - default: throw new CannotGetValueException("Unknown value type"); - } - } - - public bool SetValue(Value newValue) - { - ICorDebugValue corValue = this.RawCorValue; - ICorDebugValue newCorValue = newValue.RawCorValue; - if (newCorValue.Type == (uint)CorElementType.BYREF) { - newCorValue = newCorValue.As().Dereference(); - } - - if (corValue.Is()) { - if (newCorValue.Is()) { - ICorDebugClass corClass = newCorValue.As().Class; - ICorDebugValue box = Eval.NewObject(process, corClass).RawCorValue; - newCorValue = box; - } - corValue.CastTo().SetValue(newCorValue.CastTo().Value); - return true; - } else { - return false; - } - } - - /// - /// Returns true if the value is signed or unsigned integer of any size - /// - public bool IsInteger { - get { - CorElementType corType = CorType; - return corType == CorElementType.I1 || - corType == CorElementType.U1 || - corType == CorElementType.I2 || - corType == CorElementType.U2 || - corType == CorElementType.I4 || - corType == CorElementType.U4 || - corType == CorElementType.I8 || - corType == CorElementType.U8 || - corType == CorElementType.I || - corType == CorElementType.U; - } - } - - public VariableCollection GetDebugInfo() - { - return GetDebugInfo(this.RawCorValue); - } - - public static VariableCollection GetDebugInfo(ICorDebugValue corValue) - { - List items = new List(); - - if (corValue.Is()) { - List more = new List(); - more.Add(new VariableCollection("type", ((CorElementType)corValue.Type).ToString())); - more.Add(new VariableCollection("size", corValue.Size.ToString())); - more.Add(new VariableCollection("address", corValue.Address.ToString("X"))); - items.Add(new VariableCollection("ICorDebugValue", "", more, null)); - } - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugValue2", "", null, null)); - if (corValue.Is()) { - List more = new List(); - try { - byte[] bytes = corValue.CastTo().RawValue; - 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") + " "; - } - more.Add(new VariableCollection("data" + i.ToString("X2"), val)); - } - } catch (ArgumentException) { - more.Add(new VariableCollection("data", "N/A")); - } - items.Add(new VariableCollection("ICorDebugGenericValue", "", more, null)); - } - if (corValue.Is()) { - List more = new List(); - ICorDebugReferenceValue refValue = corValue.CastTo(); - bool isNull = refValue.IsNull != 0; - more.Add(new VariableCollection("isNull", isNull.ToString())); - if (!isNull) { - more.Add(new VariableCollection("address", refValue.Value.ToString("X"))); - if (refValue.Dereference() != null) { - VariableCollection deRef = GetDebugInfo(refValue.Dereference()); - more.Add(new VariableCollection("dereferenced", deRef.Value, deRef.SubCollections, deRef.Items)); - } else { - more.Add(new VariableCollection("dereferenced", "N/A", null, null)); - } - - } - items.Add(new VariableCollection("ICorDebugReferenceValue", "", more, null)); - } - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHeapValue", "", null, null)); - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHeapValue2", "", null, null)); - if (corValue.Is()) { - List more = new List(); - bool isValue = corValue.CastTo().IsValueClass != 0; - more.Add(new VariableCollection("isValue", isValue.ToString())); - items.Add(new VariableCollection("ICorDebugObjectValue", "", more, null)); - } - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugObjectValue2", "", null, null)); - if (corValue.Is()) { - List more = new List(); - VariableCollection unboxed = GetDebugInfo(corValue.CastTo().Object.CastTo()); - more.Add(new VariableCollection("unboxed", unboxed.Value, unboxed.SubCollections, unboxed.Items)); - items.Add(new VariableCollection("ICorDebugBoxValue", "", more, null)); - } - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugStringValue", "", null, null)); - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugArrayValue", "", null, null)); - if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHandleValue", "", null, null)); - - return new VariableCollection("$debugInfo", ((CorElementType)corValue.Type).ToString(), items.ToArray(), null); - } - - internal static System.Type CorTypeToManagedType(CorElementType corType) - { - switch(corType) - { - case CorElementType.BOOLEAN: return typeof(System.Boolean); - case CorElementType.CHAR: return typeof(System.Char); - case CorElementType.I1: return typeof(System.SByte); - case CorElementType.U1: return typeof(System.Byte); - case CorElementType.I2: return typeof(System.Int16); - case CorElementType.U2: return typeof(System.UInt16); - case CorElementType.I4: return typeof(System.Int32); - case CorElementType.U4: return typeof(System.UInt32); - case CorElementType.I8: return typeof(System.Int64); - case CorElementType.U8: return typeof(System.UInt64); - case CorElementType.R4: return typeof(System.Single); - case CorElementType.R8: return typeof(System.Double); - case CorElementType.I: return typeof(int); - case CorElementType.U: return typeof(uint); - case CorElementType.SZARRAY: - case CorElementType.ARRAY: return typeof(System.Array); - case CorElementType.OBJECT: return typeof(System.Object); - case CorElementType.STRING: return typeof(System.String); - default: return null; - } - } - - internal static string CorTypeToString(CorElementType corType) - { - Type manType = CorTypeToManagedType(corType); - if (manType == null) return ""; - return manType.ToString(); - } - } - - class CannotGetValueException: System.Exception - { - public CannotGetValueException(string message):base(message) - { - - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ValueProxy.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ValueProxy.cs deleted file mode 100644 index da645106b5..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ValueProxy.cs +++ /dev/null @@ -1,93 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - /// - /// Provides more specific access - /// - public abstract class ValueProxy: RemotingObjectBase - { - Value val; - - public Value TheValue { - get { - return val; - } - } - - public abstract string AsString { - get; - } - - public virtual string Type { - get{ - return Value.CorTypeToString(TheValue.CorType); - } - } - - public virtual Type ManagedType { - get { - return Value.CorTypeToManagedType(TheValue.CorType); - } - } - - public bool MayHaveSubVariables { - get { - #if DEBUG - return true; - #else - return GetMayHaveSubVariables(); - #endif - } - } - - protected abstract bool GetMayHaveSubVariables(); - - public VariableCollection SubVariables { - get { - VariableCollection subVars = GetSubVariables(); - #if DEBUG - return new VariableCollection(subVars.Name, - subVars.Value, - Util.MergeLists(val.GetDebugInfo(), subVars.SubCollections).ToArray(), - subVars.Items); - #else - return subVars; - #endif - } - } - - protected virtual VariableCollection GetSubVariables() - { - return new VariableCollection(new Variable[] {}); - } - - public Variable this[string variableName] { - get { - foreach(Variable v in SubVariables) { - if (v.Name == variableName) return v; - } - throw new DebuggerException("Subvariable " + variableName + " does not exist"); - } - } - - protected ValueProxy(Value @value) - { - if (@value == null) throw new ArgumentNullException("value"); - this.val = @value; - } - - public override string ToString() - { - return AsString; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/NamedValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/NamedValue.cs new file mode 100644 index 0000000000..c9536a36e9 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/NamedValue.cs @@ -0,0 +1,51 @@ +// +// +// +// +// $Revision: 2022 $ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// NamedValue is a Value which has some name associated with it - + /// eg the name of the field that holds the value. + /// + public class NamedValue: Value + { + string name; + + /// Gets the name associated with the value + public string Name { + get { + return name; + } + } + + internal NamedValue(string name, + Process process, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + CorValueGetter corValueGetter) + :base (process, + expireDependencies, + mutateDependencies, + corValueGetter) + { + this.name = name; + + // TODO: clean up + if (name.StartsWith("<") && name.Contains(">") && name != "") { + string middle = name.TrimStart('<').Split('>')[0]; // Get text between '<' and '>' + if (middle != "") { + this.name = middle; + } + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/NamedValueCollection.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/NamedValueCollection.cs new file mode 100644 index 0000000000..618a27edb2 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/NamedValueCollection.cs @@ -0,0 +1,71 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Debugger +{ + /// + /// An enumerable collection of values accessible by name. + /// + public class NamedValueCollection: RemotingObjectBase, IEnumerable, IEnumerable + { + internal static NamedValueCollection Empty = new NamedValueCollection(new NamedValue[0]); + + Dictionary> collection = new Dictionary>(); + + IEnumerator IEnumerable.GetEnumerator() + { + foreach(KeyValuePair> kvp in collection) { + foreach(NamedValue namedValue in kvp.Value) { + yield return namedValue; + } + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)this).GetEnumerator(); + } + + internal NamedValueCollection(IEnumerable namedValues) + { + foreach(NamedValue namedValue in namedValues) { + string name = namedValue.Name; + if (collection.ContainsKey(name)) { + collection[name].Add(namedValue); + } else { + collection[name] = new List(new NamedValue[] {namedValue}); + } + } + } + + /// + /// Gets a value by its name. + /// + public virtual NamedValue this[string variableName] { + get { + if (collection.ContainsKey(variableName)) { + foreach(NamedValue namedValue in collection[variableName]) { + return namedValue; + } + } + +// int index = variableName.IndexOf('.'); +// if (index != -1) { +// string rootVariable = variableName.Substring(0, index); +// string subVariable = variableName.Substring(index + 1); +// return this[rootVariable].Value.SubVariables[subVariable]; +// } + + throw new DebuggerException("Variable \"" + variableName + "\" is not in collection"); + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Array.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Array.cs new file mode 100644 index 0000000000..b898955651 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Array.cs @@ -0,0 +1,131 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; + +//TODO: Support for lower bound + +namespace Debugger +{ + // This part of the class provides support for arrays + public partial class Value + { + ICorDebugArrayValue CorArrayValue { + get { + if (IsArray) { + return CorValue.CastTo(); + } else { + throw new DebuggerException("Value is not an array"); + } + } + } + + /// Returns true if the value is an array + public bool IsArray { + get { + return !IsNull && this.Type.IsArray; + } + } + + /// + /// Gets the number of elements the array can store. + /// eg new object[4,5] returns 20 + /// + public uint ArrayLenght { + get { + return CorArrayValue.Count; + } + } + + /// + /// Gets the number of dimensions of the array. + /// eg new object[4,5] returns 2 + /// + public uint ArrayRank { + get { + return CorArrayValue.Rank; + } + } + + /// + /// Gets the lengths of individual dimensions. + /// eg new object[4,5] returns {4,5}; + /// + public uint[] ArrayDimensions { + get { + return CorArrayValue.Dimensions; + } + } + + /// Returns an element of a single-dimensional array + public ArrayElement GetArrayElement(uint index) + { + return GetArrayElement(new uint[] {index}); + } + + /// Returns an element of an array + public ArrayElement GetArrayElement(uint[] elementIndices) + { + uint[] indices = (uint[])elementIndices.Clone(); + + return new ArrayElement( + indices, + Process, + new IExpirable[] {this}, + new IMutable[] {this}, + delegate { return GetCorValueOfArrayElement(indices); } + ); + } + + // May be called later + ICorDebugValue GetCorValueOfArrayElement(uint[] indices) + { + if (!IsArray) { + throw new CannotGetValueException("The value is not an array"); + } + if (indices.Length != ArrayRank) { + throw new CannotGetValueException("Given indicies do not have the same dimension as array."); + } + for (int i = 0; i < indices.Length; i++) { + if (indices[i] > ArrayDimensions[i]) { + throw new CannotGetValueException("Given indices are out of range of the array"); + } + } + + return CorArrayValue.GetElement(indices); + } + + /// Returns all elements in the array + public NamedValueCollection GetArrayElements() + { + return new NamedValueCollection(GetArrayElementsEnum()); + } + + IEnumerable GetArrayElementsEnum() + { + uint[] indices = new uint[ArrayRank]; + uint rank = ArrayRank; + uint[] dimensions = ArrayDimensions; + + while(true) { // Go thought all combinations + for (uint i = rank - 1; i >= 1; i--) { + if (indices[i] >= dimensions[i]) { + indices[i] = 0; + indices[i-1]++; + } + } + if (indices[0] >= dimensions[0]) break; // We are done + + yield return GetArrayElement(indices); + + indices[rank - 1]++; + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Common.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Common.cs new file mode 100644 index 0000000000..479abad2aa --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Common.cs @@ -0,0 +1,72 @@ +// +// +// +// +// $Revision$ +// + +using System; +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// Provides more specific access + /// + public partial class Value + { + /// Returns true if the value is null + public bool IsNull { + get { + return CorValue == null; + } + } + + /// Gets a string representation of the value + public string AsString { + get { + if (IsNull) return ""; + if (IsArray) return "{" + this.Type.Name + "}"; + if (IsObject) return "{" + this.Type.Name + "}"; + if (IsPrimitive) return PrimitiveValue != null ? PrimitiveValue.ToString() : String.Empty; + throw new DebuggerException("Unknown value type"); + } + } + +// public bool MayHaveSubVariables { +// get { +// #if DEBUG +// if (IsNull) return true; +// if (IsArray) return true; +// if (IsObject) return true; +// if (IsPrimitive) return true; +// #else +// if (IsNull) return false; +// if (IsArray) return true; +// if (IsObject) return true; +// if (IsPrimitive) return false; +// #endif +// throw new DebuggerException("Unknown value type"); +// } +// } +// +// public VariableCollection SubVariables { +// get { +// VariableCollection subVars = null; +// if (IsNull) subVars = new VariableCollection(new Variable[] {}); +// if (IsArray) subVars = new VariableCollection(GetArrayElements()); +// if (IsObject) subVars = this.ObjectSubVariables; +// if (IsPrimitive) subVars = new VariableCollection(new Variable[] {}); +// if (subVars == null) throw new DebuggerException("Unknown value type"); +// #if DEBUG +// return new VariableCollection(subVars.Name, +// subVars.Value, +// Util.MergeLists(this.GetDebugInfo(), subVars.SubCollections).ToArray(), +// subVars.Items); +// #else +// return subVars; +// #endif +// } +// } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Helpers.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Helpers.cs new file mode 100644 index 0000000000..326557d419 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Helpers.cs @@ -0,0 +1,124 @@ +// +// +// +// +// $Revision: 2022 $ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + public partial class Value + { + internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) + { + // Method arguments can be passed 'by ref' + if (corValue.Type == (uint)CorElementType.BYREF) { + corValue = corValue.CastTo().Dereference(); + } + + // Pointers may be used in 'unsafe' code - CorElementType.PTR + // Classes need to be dereferenced + while (corValue.Is()) { + ICorDebugReferenceValue refValue = corValue.CastTo(); + if (refValue.IsNull != 0) { + return null; // Reference is null + } else { + try { + corValue = refValue.Dereference(); + // TODO: Investigate: Must not acutally be null + // eg. Assembly.AssemblyHandle See SD2-1117 + if (corValue == null) return null; // Dereference() returned null + } catch { + return null; // Error during dereferencing + } + } + } + + // Unbox value types + if (corValue.Is()) { + corValue = corValue.CastTo().Object.CastTo(); + } + + return corValue; + } + + /* + internal VariableCollection GetDebugInfo() + { + return GetDebugInfo(this.RawCorValue); + } + + internal static VariableCollection GetDebugInfo(ICorDebugValue corValue) + { + List items = new List(); + + if (corValue.Is()) { + List more = new List(); + more.Add(new VariableCollection("type", ((CorElementType)corValue.Type).ToString())); + more.Add(new VariableCollection("size", corValue.Size.ToString())); + more.Add(new VariableCollection("address", corValue.Address.ToString("X"))); + items.Add(new VariableCollection("ICorDebugValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugValue2", "", null, null)); + if (corValue.Is()) { + List more = new List(); + try { + byte[] bytes = corValue.CastTo().RawValue; + 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") + " "; + } + more.Add(new VariableCollection("data" + i.ToString("X2"), val)); + } + } catch (ArgumentException) { + more.Add(new VariableCollection("data", "N/A")); + } + items.Add(new VariableCollection("ICorDebugGenericValue", "", more, null)); + } + if (corValue.Is()) { + List more = new List(); + ICorDebugReferenceValue refValue = corValue.CastTo(); + bool isNull = refValue.IsNull != 0; + more.Add(new VariableCollection("isNull", isNull.ToString())); + if (!isNull) { + more.Add(new VariableCollection("address", refValue.Value.ToString("X"))); + if (refValue.Dereference() != null) { + VariableCollection deRef = GetDebugInfo(refValue.Dereference()); + more.Add(new VariableCollection("dereferenced", deRef.Value, deRef.SubCollections, deRef.Items)); + } else { + more.Add(new VariableCollection("dereferenced", "N/A", null, null)); + } + + } + items.Add(new VariableCollection("ICorDebugReferenceValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHeapValue", "", null, null)); + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHeapValue2", "", null, null)); + if (corValue.Is()) { + List more = new List(); + bool isValue = corValue.CastTo().IsValueClass != 0; + more.Add(new VariableCollection("isValue", isValue.ToString())); + items.Add(new VariableCollection("ICorDebugObjectValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugObjectValue2", "", null, null)); + if (corValue.Is()) { + List more = new List(); + VariableCollection unboxed = GetDebugInfo(corValue.CastTo().Object.CastTo()); + more.Add(new VariableCollection("unboxed", unboxed.Value, unboxed.SubCollections, unboxed.Items)); + items.Add(new VariableCollection("ICorDebugBoxValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugStringValue", "", null, null)); + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugArrayValue", "", null, null)); + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHandleValue", "", null, null)); + + return new VariableCollection("$debugInfo", ((CorElementType)corValue.Type).ToString(), items.ToArray(), null); + } + */ + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Object.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Object.cs new file mode 100644 index 0000000000..73af2cc2f2 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Object.cs @@ -0,0 +1,130 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + // This part of the class provides support for classes and structures + public partial class Value + { + internal ICorDebugObjectValue CorObjectValue { + get { + if (IsObject) { + return CorValue.CastTo(); + } else { + throw new DebuggerException("Value is not an object"); + } + } + } + + /// Returns true if the value is a class or value type + public bool IsObject { + get { + return !IsNull && (this.Type.IsClass || this.Type.IsValueType); + } + } + + /// Returns a text which is produced by calling object.ToString() + public Value ObjectToString { + get { + return Eval.AsyncInvokeMethod( + MethodInfo.GetFromName(Process, typeof(object), "ToString", 0), + this, + null + ).Result; + } + } + + /// + /// Get a field or property of an object with a given name. + /// + public NamedValue GetMember(string name) + { + return GetMembers()[name]; + } + + /// + /// Get all fields and properties of an object. + /// + public NamedValueCollection GetMembers() + { + return GetMembers(null, BindingFlags.All); + } + + /// + /// Get fields and properties of an object which are defined by a given type. + /// + /// Limit to type, null for all types + /// Get only members with certain flags + public NamedValueCollection GetMembers(DebugType type, BindingFlags bindingFlags) + { + if (IsObject) { + return new NamedValueCollection(GetObjectMembersEnum(type, bindingFlags)); + } else { + return NamedValueCollection.Empty; + } + } + + IEnumerable GetObjectMembersEnum(DebugType type, BindingFlags bindingFlags) + { + DebugType currentType = type ?? this.Type; + while (currentType != null) { + foreach(FieldInfo field in currentType.GetFields(bindingFlags)) { + yield return field.GetValue(this); + } + foreach(PropertyInfo property in currentType.GetProperties(bindingFlags)) { + yield return property.GetValue(this); + } + if (type == null) { + currentType = currentType.BaseType; + } else { + yield break; + } + } + } + +// public VariableCollection ObjectSubVariables { +// get { +// return new VariableCollection(String.Empty, +// String.Empty, +// GetSubCollections(this.Type), +// GetSubVariables(this.Type, BindingFlags.Public | BindingFlags.Instance)); +// } +// } + +// IEnumerable GetSubCollections(DebugType type) +// { +// if (type.BaseType != null) { +// yield return new VariableCollection("Base class", +// "{" + type.BaseType.Name + "}", +// GetSubCollections(type.BaseType), +// GetSubVariables(type.BaseType, BindingFlags.Public | BindingFlags.Instance)); +// } +// VariableCollection privateStatic = new VariableCollection("Private static members", +// String.Empty, +// new VariableCollection[0], +// GetSubVariables(type, BindingFlags.NonPublic | BindingFlags.Static)); +// VariableCollection privateInstance = new VariableCollection("Private members", +// String.Empty, +// privateStatic.IsEmpty ? new VariableCollection[0] : new VariableCollection[] {privateStatic}, +// GetSubVariables(type, BindingFlags.NonPublic | BindingFlags.Instance)); +// if (!privateInstance.IsEmpty) { +// yield return privateInstance; +// } +// VariableCollection publicStatic = new VariableCollection("Static members", +// String.Empty, +// new VariableCollection[0], +// GetSubVariables(type, BindingFlags.Public | BindingFlags.Static)); +// if (!publicStatic.IsEmpty) { +// yield return publicStatic; +// } +// } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Primitive.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Primitive.cs new file mode 100644 index 0000000000..f781a6adfa --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value-Primitive.cs @@ -0,0 +1,76 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + // This part of the class provides support for primitive types + // eg int, bool, string + public partial class Value + { + ICorDebugGenericValue CorGenericValue { + get { + if (IsPrimitive) { + return CorValue.CastTo(); + } else { + throw new DebuggerException("Value is not a primitive type"); + } + } + } + + /// + /// Returns true if the value is an primitive type. + /// eg int, bool, string + /// + public bool IsPrimitive { + get { + return !IsNull && this.Type.IsPrimitive; + } + } + + /// Gets a value indicating whether the type is an integer type + public bool IsInteger { + get { + return !IsNull && this.Type.IsInteger; + } + } + + /// + /// Gets or sets the value of a primitive type. + /// + /// If setting of a value fails, NotSupportedException is thrown. + /// + public object PrimitiveValue { + get { + if (CorType == CorElementType.STRING) { + return (CorValue.CastTo()).String; + } else { + return CorGenericValue.Value; + } + } + set { + object newValue; + TypeConverter converter = TypeDescriptor.GetConverter(this.Type.ManagedType); + try { + newValue = converter.ConvertFrom(value); + } catch { + throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + this.Type.ManagedType.ToString()); + } + + if (CorType == CorElementType.STRING) { + throw new NotSupportedException(); + } else { + CorGenericValue.Value = newValue; + } + NotifyChange(); + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.cs new file mode 100644 index 0000000000..87cdab99a7 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.cs @@ -0,0 +1,217 @@ +// +// +// +// +// $Revision: 2022 $ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// Delegate that is used to get value. This delegate may be called at any time and should never return null. + /// + delegate ICorDebugValue CorValueGetter(); + + /// + /// Value class holds data necessaty to obtain the value of a given object + /// even after continue. It provides functions to examine the object. + /// + /// + /// + /// Expiration: Once value expires it can not be used anymore. + /// Expiration is permanet - once value expires it stays expired. + /// Value expires when any object specified in constructor expires + /// or when process exits. + /// + /// + /// Mutation: As long as any dependecy does not mutate the last + /// obteined value is still considered up to date. (If continue is + /// called and internal value is neutred, new copy will be obatined) + /// + /// + public partial class Value: RemotingObjectBase, IExpirable, IMutable + { + Process process; + + CorValueGetter corValueGetter; + + ICorDebugValue currentCorValue; + PauseSession currentCorValuePauseSession; + + /// Occurs when the Value can not be used anymore + public event EventHandler Expired; + + /// Occurs when the Value have potentialy changed + public event EventHandler Changed; + + bool isExpired = false; + + /// The process that owns the value + public Process Process { + get { + return process; + } + } + + /// Returns true if the Value have expired + /// and can not be used anymore + public bool HasExpired { + get { + return isExpired; + } + } + + internal ICorDebugValue CorValue { + get { + return DereferenceUnbox(RawCorValue); + } + } + + internal CorElementType CorType { + get { + ICorDebugValue corValue = this.CorValue; + if (corValue == null) { + return (CorElementType)0; + } + return (CorElementType)corValue.Type; + } + } + + ICorDebugValue RawCorValue { + get { + if (this.HasExpired) throw new CannotGetValueException("CorValue has expired"); + if (currentCorValue == null || (currentCorValuePauseSession != process.PauseSession && !currentCorValue.Is())) { + currentCorValue = corValueGetter(); + currentCorValuePauseSession = process.PauseSession; + } + return currentCorValue; + } + } + + internal ICorDebugValue SoftReference { + get { + if (this.HasExpired) throw new DebuggerException("CorValue has expired"); + + ICorDebugValue corValue = RawCorValue; + if (corValue != null && corValue.Is()) { + return corValue; + } + corValue = DereferenceUnbox(corValue); + if (corValue != null && corValue.Is()) { + return corValue.As().CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION).CastTo(); + } else { + return corValue; // Value type - return value type + } + } + } + + internal Value(Process process, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + CorValueGetter corValueGetter) + { + this.process = process; + + AddExpireDependency(process); + foreach(IExpirable exp in expireDependencies) { + AddExpireDependency(exp); + } + + foreach(IMutable mut in mutateDependencies) { + AddMutateDependency(mut); + } + + this.corValueGetter = corValueGetter; + } + + void AddExpireDependency(IExpirable dependency) + { + if (dependency.HasExpired) { + MakeExpired(); + } else { + dependency.Expired += delegate { MakeExpired(); }; + } + } + + void MakeExpired() + { + if (!isExpired) { + isExpired = true; + OnExpired(new ValueEventArgs(this)); + } + } + + void AddMutateDependency(IMutable dependency) + { + dependency.Changed += delegate { NotifyChange(); }; + } + + internal void NotifyChange() + { + if (!isExpired) { + currentCorValue = null; + currentCorValuePauseSession = null; + OnChanged(new ValueEventArgs(this)); + } + } + + /// Is called when the value changes + protected virtual void OnChanged(ProcessEventArgs e) + { + if (Changed != null) { + Changed(this, e); + } + } + + /// Is called when the value expires and can not be + /// used anymore + protected virtual void OnExpired(EventArgs e) + { + if (Expired != null) { + Expired(this, e); + } + } + + /// Returns the of the value + public DebugType Type { + get { + return DebugType.Create(process, RawCorValue.As().ExactType); + } + } + + /// Copy the acutal value from some other Value object + public bool SetValue(Value newValue) + { + ICorDebugValue corValue = this.RawCorValue; + ICorDebugValue newCorValue = newValue.RawCorValue; + if (newCorValue.Type == (uint)CorElementType.BYREF) { + newCorValue = newCorValue.As().Dereference(); + } + + if (corValue.Is()) { + if (newCorValue.Is()) { + ICorDebugClass corClass = newCorValue.As().Class; + ICorDebugValue box = Eval.NewObject(process, corClass).RawCorValue; + newCorValue = box; + } + corValue.CastTo().SetValue(newCorValue.CastTo().Value); + return true; + } else { + return false; + } + } + } + + public class CannotGetValueException: DebuggerException + { + public CannotGetValueException(string message):base(message) + { + + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ValueEventArgs.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/ValueEventArgs.cs similarity index 67% rename from src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ValueEventArgs.cs rename to src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/ValueEventArgs.cs index 4095ea7c2f..d08c77767c 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ValueEventArgs.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/ValueEventArgs.cs @@ -9,17 +9,22 @@ using System; namespace Debugger { + /// + /// Provides data for events related to class + /// [Serializable] public class ValueEventArgs : ProcessEventArgs { Value val; + /// The value that caused the event public Value Value { get { return val; } } + /// Initializes a new instance of the class public ValueEventArgs(Value val): base(val.Process) { this.val = val; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs deleted file mode 100644 index 0d18c1f3be..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs +++ /dev/null @@ -1,91 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; - -using Debugger.Wrappers.CorDebug; - -namespace Debugger -{ - /// - /// - /// - public class Variable: IExpirable, IMutable - { - string name; - Value val; - bool hasExpired; - - public event EventHandler Expired; - public event EventHandler Changed; - - public Process Process { - get { - return val.Process; - } - } - - public string Name { - get { - return name; - } - } - - public Value Value { - get { - return val; - } - } - - public ValueProxy ValueProxy { - get { - return val.ValueProxy; - } - } - - public bool HasExpired { - get { - return hasExpired; - } - } - - internal Variable(string name, Value @value) - { - if (@value == null) throw new ArgumentNullException("value"); - - this.name = name; - this.val = @value; - this.val.Expired += delegate(object sender, EventArgs e) { OnExpired(e); }; - this.val.Changed += delegate(object sender, ProcessEventArgs e) { OnChanged(e); }; - - if (name.StartsWith("<") && name.Contains(">") && name != "") { - string middle = name.TrimStart('<').Split('>')[0]; // Get text between '<' and '>' - if (middle != "") { - this.name = middle; - } - } - } - - protected virtual void OnExpired(EventArgs e) - { - if (!hasExpired) { - hasExpired = true; - if (Expired != null) { - Expired(this, e); - } - } - } - - protected virtual void OnChanged(ProcessEventArgs e) - { - if (Changed != null) { - Changed(this, e); - } - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs deleted file mode 100644 index b1e90a1881..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs +++ /dev/null @@ -1,115 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Debugger -{ - [Serializable] - public class VariableCollection: RemotingObjectBase, IEnumerable - { - public static VariableCollection Empty = new VariableCollection(new Variable[] {}); - - string name; - string val; - IEnumerable subCollectionsEnum; - IEnumerable collectionEnum; - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return Items.GetEnumerator(); - } - - public string Name { - get { - return name; - } - } - - public string Value { - get { - return val; - } - } - - public IEnumerable SubCollections { - get { - return subCollectionsEnum; - } - } - - public IEnumerable Items { - get { - return collectionEnum; - } - } - - public bool IsEmpty { - get { - return !SubCollections.GetEnumerator().MoveNext() && - !Items.GetEnumerator().MoveNext(); - } - } - - internal VariableCollection(IEnumerable collectionEnum) - :this(String.Empty, String.Empty, new VariableCollection[0], collectionEnum) - { - } - - public VariableCollection(string name, string val):this(name, val, null, null) - { - } - - public VariableCollection(string name, string val, IEnumerable subCollectionsEnum, IEnumerable collectionEnum) - { - this.name = name; - this.val = val; - if (subCollectionsEnum != null) { - this.subCollectionsEnum = subCollectionsEnum; - } else { - this.subCollectionsEnum = new VariableCollection[0]; - } - if (collectionEnum != null) { - this.collectionEnum = collectionEnum; - } else { - this.collectionEnum = new Variable[0]; - } - } - - - public virtual Variable this[string variableName] { - get { - int index = variableName.IndexOf('.'); - if (index != -1) { - string rootVariable = variableName.Substring(0, index); - string subVariable = variableName.Substring(index + 1); - return this[rootVariable].ValueProxy.SubVariables[subVariable]; - } else { - foreach (Variable v in this) { - if (v.Name == variableName) return v; - } - } - throw new DebuggerException("Variable \"" + variableName + "\" is not in collection"); - } - } - - public override string ToString() { - string txt = ""; - foreach(Variable v in this) { - txt += v.ToString() + "\n"; - } - return txt; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableEventArgs.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableEventArgs.cs deleted file mode 100644 index 3a872e70b2..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableEventArgs.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; - -namespace Debugger -{ - public class VariableEventArgs: ProcessEventArgs - { - Variable variable; - - public Variable Variable { - get { - return variable; - } - } - - public VariableEventArgs(Variable variable): base(variable.Value.Process) - { - this.variable = variable; - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/ArrayElement.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/ArrayElement.cs new file mode 100644 index 0000000000..29c525076b --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/ArrayElement.cs @@ -0,0 +1,56 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// Represents an element of an array + /// + public class ArrayElement: NamedValue + { + uint[] indicies; + + /// + /// The indicies of the element; one for each dimension of + /// the array. + /// + public uint[] Indicies { + get { + return indicies; + } + } + + internal ArrayElement(uint[] indicies, + Process process, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + CorValueGetter corValueGetter) + :base (GetNameFromIndices(indicies), + process, + expireDependencies, + mutateDependencies, + corValueGetter) + { + this.indicies = indicies; + } + + static string GetNameFromIndices(uint[] indices) + { + string elementName = "["; + for (int i = 0; i < indices.Length; i++) { + elementName += indices[i].ToString() + ","; + } + elementName = elementName.TrimEnd(new char[] {','}) + "]"; + return elementName; + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/LocalVariable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/LocalVariable.cs new file mode 100644 index 0000000000..ef24eac79d --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/LocalVariable.cs @@ -0,0 +1,34 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// Represents a local variable in a function + /// + public class LocalVariable: NamedValue + { + internal LocalVariable(string name, + Process process, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + CorValueGetter corValueGetter) + :base (name, + process, + expireDependencies, + mutateDependencies, + corValueGetter) + { + + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/MemberVariable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/MemberVariable.cs new file mode 100644 index 0000000000..e1a47cbf7e --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/MemberVariable.cs @@ -0,0 +1,47 @@ +// +// +// +// +// $Revision: 2022 $ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// Represents a member of class or value type - + /// that is, a field or a property + /// + public class MemberValue: NamedValue + { + MemberInfo memberInfo; + + /// + /// Gets an MemberInfo object which can be used to obtain + /// metadata information about the member. + /// + public MemberInfo MemberInfo { + get { + return memberInfo; + } + } + + internal MemberValue(MemberInfo memberInfo, + Process process, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + CorValueGetter corValueGetter) + :base (memberInfo.Name, + process, + expireDependencies, + mutateDependencies, + corValueGetter) + { + this.memberInfo = memberInfo; + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/MethodArgument.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/MethodArgument.cs new file mode 100644 index 0000000000..3141981901 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/MethodArgument.cs @@ -0,0 +1,50 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// Represents an argument of a function. That is, it refers to + /// the runtime value of function parameter. + /// + public class MethodArgument: NamedValue + { + int index; + + /// + /// The index of the function parameter starting at 0. + /// + /// + /// The implicit 'this' is excluded. + /// + public int Index { + get { + return index; + } + } + + internal MethodArgument(string name, + int index, + Process process, + IExpirable[] expireDependencies, + IMutable[] mutateDependencies, + CorValueGetter corValueGetter) + :base (name, + process, + expireDependencies, + mutateDependencies, + corValueGetter) + { + this.index = index; + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/LocalVariable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/Variable.cs similarity index 64% rename from src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/LocalVariable.cs rename to src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/Variable.cs index 76817f62e0..d4d845cc92 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/LocalVariable.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/Variable.cs @@ -2,7 +2,7 @@ // // // -// $Revision$ +// $Revision: 2022 $ // using System; @@ -12,11 +12,5 @@ using Debugger.Wrappers.CorDebug; namespace Debugger { - public class LocalVariable: Variable - { - public LocalVariable(string name, Value @value) - :base (name, @value) - { - } - } + } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/VariableCollection.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/VariableCollection.cs new file mode 100644 index 0000000000..de74bbc2b7 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/VariableCollection.cs @@ -0,0 +1,107 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Debugger +{ +// public class NamedValueCollection: RemotingObjectBase, IEnumerable +// { +// public static NamedValueCollection Empty = new NamedValueCollection(new NamedValue[0]); +// +// string name; +// string val; +// IEnumerable subCollectionsEnum; +// IEnumerable collectionEnum; +// +// IEnumerator IEnumerable.GetEnumerator() +// { +// return GetEnumerator(); +// } +// +// public IEnumerator GetEnumerator() +// { +// return Items.GetEnumerator(); +// } +// +// public string Name { +// get { +// return name; +// } +// } +// +// public string Value { +// get { +// return val; +// } +// } +// +// public IEnumerable SubCollections { +// get { +// return subCollectionsEnum; +// } +// } +// +// public IEnumerable Items { +// get { +// return collectionEnum; +// } +// } +// +// public bool IsEmpty { +// get { +// return !SubCollections.GetEnumerator().MoveNext() && +// !Items.GetEnumerator().MoveNext(); +// } +// } +// +// internal NamedValueCollection(IEnumerable collectionEnum) +// :this(String.Empty, String.Empty, new VariableCollection[0], collectionEnum) +// { +// } +// +// public NamedValueCollection(string name, string val):this(name, val, null, null) +// { +// } +// +// public NamedValueCollection(string name, string val, IEnumerable subCollectionsEnum, IEnumerable collectionEnum) +// { +// this.name = name; +// this.val = val; +// this.subCollectionsEnum = subCollectionsEnum ?? new VariableCollection[0]; +// this.collectionEnum = collectionEnum ?? new Variable[0]; +// } +// +// +// public virtual NamedValue this[string variableName] { +// get { +// int index = variableName.IndexOf('.'); +// if (index != -1) { +// string rootVariable = variableName.Substring(0, index); +// string subVariable = variableName.Substring(index + 1); +// return this[rootVariable].Value.SubVariables[subVariable]; +// } else { +// foreach (Variable v in this) { +// if (v.Name == variableName) return v; +// } +// } +// throw new DebuggerException("Variable \"" + variableName + "\" is not in collection"); +// } +// } +// +// public override string ToString() +// { +// string txt = ""; +// foreach(Variable v in this) { +// txt += v.ToString() + "\n"; +// } +// return txt; +// } +// } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/VariableEventArgs.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/VariableEventArgs.cs new file mode 100644 index 0000000000..c296e4f1bd --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variables/VariableEventArgs.cs @@ -0,0 +1,27 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace Debugger +{ +// public class VariableEventArgs: ProcessEventArgs +// { +// Variable variable; +// +// public Variable Variable { +// get { +// return variable; +// } +// } +// +// public VariableEventArgs(Variable variable): base(variable.Value.Process) +// { +// this.variable = variable; +// } +// } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugClass2.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugClass2.cs index 3723e4e044..67cb905aae 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugClass2.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugClass2.cs @@ -98,13 +98,29 @@ namespace Debugger.Wrappers.CorDebug } - public ICorDebugType GetParameterizedType(uint elementType, uint nTypeArgs, ref ICorDebugType ppTypeArgs) + public ICorDebugType GetParameterizedType(uint elementType, uint nTypeArgs, ICorDebugType[] ppTypeArgs) { ICorDebugType ppType; - Debugger.Interop.CorDebug.ICorDebugType ref_ppTypeArgs = ppTypeArgs.WrappedObject; + Debugger.Interop.CorDebug.ICorDebugType[] array_ppTypeArgs = new Debugger.Interop.CorDebug.ICorDebugType[ppTypeArgs.Length]; + for (int i = 0; (i < ppTypeArgs.Length); i = (i + 1)) + { + if ((ppTypeArgs[i] != null)) + { + array_ppTypeArgs[i] = ppTypeArgs[i].WrappedObject; + } + } Debugger.Interop.CorDebug.ICorDebugType out_ppType; - this.WrappedObject.GetParameterizedType(elementType, nTypeArgs, ref ref_ppTypeArgs, out out_ppType); - ppTypeArgs = ICorDebugType.Wrap(ref_ppTypeArgs); + this.WrappedObject.GetParameterizedType(elementType, nTypeArgs, array_ppTypeArgs, out out_ppType); + for (int i = 0; (i < ppTypeArgs.Length); i = (i + 1)) + { + if ((array_ppTypeArgs[i] != null)) + { + ppTypeArgs[i] = ICorDebugType.Wrap(array_ppTypeArgs[i]); + } else + { + ppTypeArgs[i] = null; + } + } ppType = ICorDebugType.Wrap(out_ppType); return ppType; } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugArrayValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugArrayValue.cs new file mode 100644 index 0000000000..ab00c179d2 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugArrayValue.cs @@ -0,0 +1,35 @@ +// +// +// +// +// $Revision: 1965 $ +// + +#pragma warning disable 1591 + +namespace Debugger.Wrappers.CorDebug +{ + using System; + + public partial class ICorDebugArrayValue + { + public unsafe uint[] Dimensions { + get { + uint[] dimensions = new uint[this.Rank]; + fixed (void* pDimensions = dimensions) { + this.GetDimensions((uint)dimensions.Length, new IntPtr(pDimensions)); + } + return dimensions; + } + } + + public unsafe ICorDebugValue GetElement(uint[] indices) + { + fixed (void* pIndices = indices) { + return this.GetElement((uint)indices.Length, new IntPtr(pIndices)); + } + } + } +} + +#pragma warning restore 1591 \ No newline at end of file diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/FieldProps.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/FieldProps.cs index 63b99c37d5..1d2f6d4eac 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/FieldProps.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/FieldProps.cs @@ -5,11 +5,13 @@ // $Revision$ // +#pragma warning disable 1591 + using System; namespace Debugger.Wrappers.MetaData { - struct FieldProps + public struct FieldProps { public uint Token; public string Name; @@ -35,3 +37,5 @@ namespace Debugger.Wrappers.MetaData } } } + +#pragma warning restore 1591 diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs index 4f566327d2..49a5f90196 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MetaData.cs @@ -5,6 +5,8 @@ // $Revision$ // +#pragma warning disable 1591 + using System; using System.Collections.Generic; using Debugger.Interop.MetaData; @@ -13,7 +15,10 @@ using Debugger.Wrappers.CorSym; namespace Debugger.Wrappers.MetaData { - class MetaData: IDisposable + /// + /// Wrapper for the unmanaged metadata API + /// + public class MetaData: IDisposable { IMetaDataImport metaData; @@ -166,10 +171,6 @@ namespace Debugger.Wrappers.MetaData out methodProps.ImplFlags); }); - methodProps.Signature = null; - //methodProps.Signature = new SignatureStream(pSigBlob, sigBlobSize); - //Marshal.FreeCoTaskMem(pSigBlob); - return methodProps; } @@ -229,16 +230,7 @@ namespace Debugger.Wrappers.MetaData metaData.FindTypeDefByName(typeName, enclosingClassToken, out typeDefToken); return GetTypeDefProps(typeDefToken); } - - public MethodProps GetMethod(string type, string name, int paramCount) - { - TypeDefProps typeDefProps = FindTypeDefByName(type, 0); - foreach(MethodProps method in EnumMethodsWithName(typeDefProps.Token, name)) { - if (GetParamCount(method.Token) == paramCount) { - return method; - } - } - throw new DebuggerException("Not found"); - } } } + +#pragma warning restore 1591 diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MethodProps.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MethodProps.cs index d8c9b00813..a1dba4bbe6 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MethodProps.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/MethodProps.cs @@ -5,11 +5,13 @@ // $Revision$ // +#pragma warning disable 1591 + using System; namespace Debugger.Wrappers.MetaData { - struct MethodProps + public struct MethodProps { public uint Token; public string Name; @@ -17,7 +19,6 @@ namespace Debugger.Wrappers.MetaData public uint Flags; public uint ImplFlags; public uint CodeRVA; - public SignatureStream Signature; public bool IsStatic { get { @@ -38,3 +39,5 @@ namespace Debugger.Wrappers.MetaData } } } + +#pragma warning restore 1591 diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/ParamProps.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/ParamProps.cs index de66efa199..0e580636b9 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/ParamProps.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/ParamProps.cs @@ -5,11 +5,13 @@ // $Revision$ // +#pragma warning disable 1591 + using System; namespace Debugger.Wrappers.MetaData { - struct ParamProps + public struct ParamProps { public uint Token; public string Name; @@ -18,3 +20,5 @@ namespace Debugger.Wrappers.MetaData public uint Flags; } } + +#pragma warning restore 1591 diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeDefProps.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeDefProps.cs index 7b8479b4e5..c73c1a4f1b 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeDefProps.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeDefProps.cs @@ -5,11 +5,13 @@ // $Revision$ // +#pragma warning disable 1591 + using System; namespace Debugger.Wrappers.MetaData { - struct TypeDefProps + public struct TypeDefProps { public uint Token; public string Name; @@ -17,3 +19,5 @@ namespace Debugger.Wrappers.MetaData public uint SuperClassToken; } } + +#pragma warning restore 1591 diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeRefProps.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeRefProps.cs index 8c43051b13..5004543f55 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeRefProps.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/MetaData/TypeRefProps.cs @@ -5,13 +5,17 @@ // $Revision$ // +#pragma warning disable 1591 + using System; namespace Debugger.Wrappers.MetaData { - struct TypeRefProps + public struct TypeRefProps { public uint Token; public string Name; } } + +#pragma warning restore 1591 diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/NativeMethods.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/NativeMethods.cs index 3993aafdea..c50fe301ca 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/NativeMethods.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/NativeMethods.cs @@ -11,9 +11,9 @@ using System; using System.Runtime.InteropServices; using System.Text; -namespace Debugger +namespace Debugger.Interop { - internal static class NativeMethods + public static class NativeMethods { [DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr handle); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/ResourceManager.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/ResourceManager.cs index 90430b3039..811a53b5fc 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/ResourceManager.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/ResourceManager.cs @@ -11,6 +11,8 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using Debugger.Interop; + namespace Debugger.Wrappers { class TrackedObjectMetaData