diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs index 03203f7732..75b907e72e 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ArrayRangeNode.cs @@ -15,7 +15,8 @@ namespace Debugger.AddIn.TreeModel { public static IEnumerable LazyGetChildNodesOfArray(Expression expression, ArrayDimensions dimensions) { - if (dimensions.TotalElementCount == 0) return new TreeNode[0]; + if (dimensions.TotalElementCount == 0) + return new TreeNode[] { new TreeNode(null, "(empty)", null, null, null) }; return new ArrayRangeNode(expression, dimensions, dimensions).ChildNodes; } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs index 983b8386b2..aa4a03f18f 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ChildNodesOfObject.cs @@ -96,15 +96,28 @@ namespace Debugger.AddIn.TreeModel public static IEnumerable LazyGetItemsOfIList(Expression targetObject) { + // This is needed for expanding IEnumerable + targetObject = new CastExpression( + new TypeReference(typeof(IList).FullName), + targetObject, + CastType.Cast + ); int count = 0; + GetValueException error = null; try { count = GetIListCount(targetObject); - } catch (GetValueException) { - yield break; + } catch (GetValueException e) { + // Cannot yield a value in the body of a catch clause (CS1631) + error = e; } - - for(int i = 0; i < count; i++) { - yield return new ExpressionNode(ExpressionNode.GetImageForArrayIndexer(), "[" + i + "]", targetObject.AppendIndexer(i)); + if (error != null) { + yield return new TreeNode(null, "(error)", error.Message, null, null); + } else if (count == 0) { + yield return new TreeNode(null, "(empty)", null, null, null); + } else { + for(int i = 0; i < count; i++) { + yield return new ExpressionNode(ExpressionNode.GetImageForArrayIndexer(), "[" + i + "]", targetObject.AppendIndexer(i)); + } } } @@ -116,9 +129,8 @@ namespace Debugger.AddIn.TreeModel { Value list = targetObject.Evaluate(WindowsDebugger.CurrentProcess); var iCollectionInterface = list.Type.GetInterface(typeof(ICollection).FullName); - if (iCollectionInterface == null) { + if (iCollectionInterface == null) throw new GetValueException(targetObject, targetObject.PrettyPrint() + " does not implement System.Collections.ICollection"); - } PropertyInfo countProperty = iCollectionInterface.GetProperty("Count"); // Do not get string representation since it can be printed in hex return (int)list.GetPropertyValue(countProperty).PrimitiveValue; diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs index 31f1ec7b60..2fb66bd1b0 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs @@ -160,14 +160,17 @@ namespace Debugger.AddIn.TreeModel // Note that these return enumerators so they are lazy-evaluated if (val.IsNull) { + } else if (val.Type.IsPrimitive) { // Must be before IsClass + } else if (val.Type.IsArray) { // Must be before IsClass + if (val.ArrayLength > 0) + this.ChildNodes = Utils.LazyGetChildNodesOfArray(this.Expression, val.ArrayDimensions); } else if (val.Type.IsClass || val.Type.IsValueType) { if (val.Type.FullNameWithoutGenericArguments == typeof(List<>).FullName) { - this.ChildNodes = Utils.LazyGetItemsOfIList(this.expression); + if ((int)val.GetMemberValue("_size").PrimitiveValue > 0) + this.ChildNodes = Utils.LazyGetItemsOfIList(this.expression); } else { this.ChildNodes = Utils.LazyGetChildNodesOfObject(this.Expression, val.Type); } - } else if (val.Type.IsArray) { - this.ChildNodes = Utils.LazyGetChildNodesOfArray(this.Expression, val.ArrayDimensions); } else if (val.Type.IsPointer) { Value deRef = val.Dereference(); if (deRef != null) { diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Visualizers/IListNode.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Visualizers/IListNode.cs index 82d5450dab..48bccfe32d 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Visualizers/IListNode.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Visualizers/IListNode.cs @@ -29,6 +29,6 @@ namespace Debugger.AddIn.TreeModel public override bool HasChildNodes { get { return this.count > 0; } - } + } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/ManagedCallback.cs b/src/AddIns/Misc/Debugger/Debugger.Core/ManagedCallback.cs index d95a5bc82a..494972ffbe 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/ManagedCallback.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/ManagedCallback.cs @@ -51,6 +51,7 @@ namespace Debugger // After break is pressed we may receive some messages that were already queued if (process.IsPaused && process.PauseSession.PausedReason == PausedReason.ForcedBreak) { + // TODO: This does not work well if exception if being processed and the user continues it process.TraceMessage("Processing post-break callback"); // This compensates for the break call and we are in normal callback handling mode process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] {}, null);