public static IEnumerable <TreeNode> LazyGetItemsOfIList(TreeNode parent, Expression targetObject) { // Add a cast, so that we are sure the expression has an indexer. // (The expression can be e.g. of type 'object' but its value is a List. // Without the cast, evaluating "expr[i]" would fail, because object does not have an indexer). targetObject = targetObject.CastToIList(); int count = 0; GetValueException error = null; try { count = targetObject.GetIListCount(); } catch (GetValueException e) { // Cannot yield a value in the body of a catch clause (CS1631) error = e; } if (error != null) { yield return(new TreeNode(null, "(error)", error.Message, null, null, _ => null)); } else if (count == 0) { yield return(new TreeNode(null, "(empty)", null, null, null, _ => null)); } else { for (int i = 0; i < count; i++) { string imageName; var image = ExpressionNode.GetImageForArrayIndexer(out imageName); var itemNode = new ExpressionNode(parent, image, "[" + i + "]", targetObject.AppendIndexer(i)); itemNode.ImageName = imageName; yield return(itemNode); } } }
public ErrorNode(Expression targetObject, GetValueException error) { this.targetObject = targetObject; this.error = error; this.Name = targetObject.CodeTail; this.Text = error.Error; }
Value EvaluateOrError(Func <Value> expression, out GetValueException error) { error = null; Debugger.Value value; try { value = expression(); } catch (GetValueException ex) { error = ex; return(null); } if (value.Type.GetNonInterfaceBaseTypes().Any(t => t.IsKnownType(KnownTypeCode.Exception))) { error = new GetValueException(value.GetPropertyValue(WindowsDebugger.EvalThread, "Message").AsString()); return(null); } return(value); }
public static IEnumerable <TreeNode> LazyGetItemsOfIList(Expression targetObject) { // This is needed for expanding IEnumerable<T> var type = new SimpleType() { Identifier = typeof(IList).FullName }; type.AddAnnotation(typeof(IList)); targetObject = new CastExpression() { Expression = targetObject.Clone(), Type = type }; int count = 0; GetValueException error = null; try { count = GetIListCount(targetObject); } catch (GetValueException e) { // Cannot yield a value in the body of a catch clause (CS1631) error = e; } if (error != null) { yield return(new TreeNode(null, "(error)", error.Message, null, null)); } else if (count == 0) { yield return(new TreeNode(null, "(empty)", null, null, null)); } else { for (int i = 0; i < count; i++) { string imageName; var image = ExpressionNode.GetImageForArrayIndexer(out imageName); var expression = new ExpressionNode(image, "[" + i + "]", targetObject.AppendIndexer(i)); expression.ImageName = imageName; yield return(expression); } } }
public static IEnumerable <TreeNode> LazyGetItemsOfIList(Expression targetObject) { // This is needed for expanding IEnumerable<T> targetObject = new CastExpression( new TypeReference(typeof(IList).FullName), targetObject, CastType.Cast ); int count = 0; GetValueException error = null; try { count = GetIListCount(targetObject); } catch (GetValueException e) { // Cannot yield a value in the body of a catch clause (CS1631) error = e; } if (error != null) { yield return(new TreeNode(null, "(error)", error.Message, null, null)); } 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))); } } }
/// <summary> Get the value of the node and update the UI text fields. </summary> /// <remarks> This should be only called once so the Value is not cached. </remarks> void GetValueAndUpdateUI() { try { Stopwatch watch = new Stopwatch(); watch.Start(); // Do not keep permanent reference Value val = this.getValue(); if (val == null) { Value = string.Empty; Type = string.Empty; GetChildren = null; VisualizerCommands = null; return; } // Note that the child collections are lazy-evaluated if (val.IsNull) { this.GetChildren = null; } else if (val.Type.IsPrimitiveType() || val.Type.IsKnownType(KnownTypeCode.String)) { // Must be before IsClass this.GetChildren = null; } else if (val.Type.Kind == TypeKind.Array) { // Must be before IsClass var dimBase = val.ArrayBaseIndicies; // Eval now var dimSize = val.ArrayDimensions; // Eval now if (val.ArrayLength > 0) { this.GetChildren = () => GetArrayChildren(dimBase, dimSize); } } else if (val.Type.Kind == TypeKind.Class || val.Type.Kind == TypeKind.Struct) { if (val.Type.IsKnownType(typeof(List<>))) { if ((int)val.GetFieldValue("_size").PrimitiveValue > 0) this.GetChildren = () => GetIListChildren(this.GetValue); } else { this.GetChildren = () => GetObjectChildren(val.Type); } } else if (val.Type.Kind == TypeKind.Pointer) { if (val.Dereference() != null) { this.GetChildren = () => new[] { new ValueNode(ClassBrowserIconService.LocalVariable, "*" + this.Name, () => GetValue().Dereference()) }; } } // Do last since it may expire the object if (val.IsNull) { fullValue = "null"; } else if (val.Type.IsInteger()) { var i = val.PrimitiveValue; if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Decimal) { fullValue = i.ToString(); } else { string hex = string.Format("0x{0:X4}", i); if (hex.Length > 6 ) hex = string.Format("0x{0:X8}", i); if (hex.Length > 10) hex = string.Format("0x{0:X16}", i); if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Hexadecimal) { fullValue = hex; } else { fullValue = string.Format("{0} ({1})", i, hex); } } } else if (val.Type.Kind == TypeKind.Pointer) { fullValue = String.Format("0x{0:X}", val.PointerAddress); } else if (val.Type.IsKnownType(KnownTypeCode.String)) { fullValue = '"' + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + '"'; } else if (val.Type.IsKnownType(KnownTypeCode.Char)) { fullValue = "'" + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + "'"; } else if ((val.Type.Kind == TypeKind.Class || val.Type.Kind == TypeKind.Struct)) { fullValue = val.FormatByDebuggerDisplayAttribute(WindowsDebugger.EvalThread); if (fullValue == null) fullValue = val.InvokeToString(WindowsDebugger.EvalThread); } else if (val.Type.Kind == TypeKind.Enum) { var primitiveValue = val.PrimitiveValue; var builder = new TypeSystemAstBuilder(); builder.AlwaysUseShortTypeNames = true; AstNode node = builder.ConvertConstantValue(val.Type, primitiveValue); fullValue = node + "=" + primitiveValue; } else { fullValue = val.AsString(); } this.error = null; this.Value = (fullValue.Length > 256) ? fullValue.Substring(0, 256) + "..." : fullValue; this.Type = val.Type.Name; if (!val.IsNull) { this.VisualizerCommands = VisualizerDescriptors.GetAllDescriptors() .Where(descriptor => descriptor.IsVisualizerAvailable(val.Type)) .Select(descriptor => descriptor.CreateVisualizerCommand(this.Name, this.GetValue)) .ToList(); } LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms", this.Name, watch.ElapsedMilliseconds); } catch (GetValueException e) { error = e; this.Value = e.Message; this.Type = string.Empty; this.GetChildren = null; this.VisualizerCommands = null; } finally { if (error == null) ContextMenuAddInTreeEntry = "/AddIns/Debugger/Tooltips/ContextMenu/ValueNode"; else ContextMenuAddInTreeEntry = "/AddIns/Debugger/Tooltips/ContextMenu/ErrorNode"; } }
void EvaluateExpression() { evaluated = true; Value val; try { var frame = WindowsDebugger.DebuggedProcess.SelectedThread.MostRecentStackFrame; int token = frame.MethodInfo.MetadataToken; // get the target name int index = Name.IndexOf('.'); string targetName = Name; if (index != -1) { targetName = Name.Substring(0, index); } // get local variable index IEnumerable <ILVariable> list; if (DebugInformation.LocalVariables.TryGetValue(token, out list)) { var variable = list.FirstOrDefault(v => v.Name == targetName); if (variable != null && variable.OriginalVariable != null) { if (expression is MemberReferenceExpression) { var memberExpression = (MemberReferenceExpression)expression; memberExpression.Target.AddAnnotation(new [] { variable.OriginalVariable.Index }); } else { expression.AddAnnotation(new [] { variable.OriginalVariable.Index }); } } } // evaluate expression val = expression.Evaluate(WindowsDebugger.DebuggedProcess); } catch (GetValueException e) { error = e; this.Text = e.Message; return; } this.canSetText = val.Type.IsPrimitive; this.expressionType = val.Type; this.Type = val.Type.Name; this.valueIsNull = val.IsNull; // Note that these return enumerators so they are lazy-evaluated if (val.IsNull) { } else if (val.Type.IsPrimitive || val.Type.FullName == typeof(string).FullName) // Must be before IsClass { } else if (val.Type.IsArray) // Must be before IsClass { if (val.ArrayLength > 0) { this.ChildNodes = Utils.LazyGetChildNodesOfArray(this.Expression, val.ArrayDimensions); } } else if (val.Type.IsClass || val.Type.IsValueType) { if (val.Type.FullNameWithoutGenericArguments == typeof(List <>).FullName) { if ((int)val.GetMemberValue("_size").PrimitiveValue > 0) { this.ChildNodes = Utils.LazyGetItemsOfIList(this.expression); } } else { this.ChildNodes = Utils.LazyGetChildNodesOfObject(this.Expression, val.Type); } } else if (val.Type.IsPointer) { Value deRef = val.Dereference(); if (deRef != null) { this.ChildNodes = new ExpressionNode [] { new ExpressionNode(this.ImageSource, "*" + this.Name, this.Expression.AppendDereference()) }; } } // if (DebuggingOptions.Instance.ICorDebugVisualizerEnabled) { // TreeNode info = ICorDebug.GetDebugInfoRoot(val.AppDomain, val.CorValue); // this.ChildNodes = Utils.PrependNode(info, this.ChildNodes); // } // Do last since it may expire the object if (val.Type.IsInteger) { fullText = FormatInteger(val.PrimitiveValue); } else if (val.Type.IsPointer) { fullText = String.Format("0x{0:X}", val.PointerAddress); } else if ((val.Type.FullName == typeof(string).FullName || val.Type.FullName == typeof(char).FullName) && !val.IsNull) { try { fullText = '"' + Escape(val.InvokeToString()) + '"'; } catch (GetValueException e) { error = e; fullText = e.Message; return; } } else if ((val.Type.IsClass || val.Type.IsValueType) && !val.IsNull) { try { fullText = val.InvokeToString(); } catch (GetValueException e) { error = e; fullText = e.Message; return; } } else { fullText = val.AsString(); } this.Text = (fullText.Length > 256) ? fullText.Substring(0, 256) + "..." : fullText; }
/// <summary> Get the value of the node and update the UI text fields. </summary> /// <remarks> This should be only called once so the Value is not cached. </remarks> void GetValueAndUpdateUI() { try { Stopwatch watch = new Stopwatch(); watch.Start(); // Do not keep permanent reference Value val = this.getValue(); if (val == null) { Value = string.Empty; Type = string.Empty; GetChildren = null; VisualizerCommands = null; return; } // Note that the child collections are lazy-evaluated if (val.IsNull) { this.GetChildren = null; } else if (val.Type.IsPrimitiveType() || val.Type.IsKnownType(KnownTypeCode.String)) // Must be before IsClass { this.GetChildren = null; } else if (val.Type.Kind == TypeKind.Array) // Must be before IsClass { var dimBase = val.ArrayBaseIndicies; // Eval now var dimSize = val.ArrayDimensions; // Eval now if (val.ArrayLength > 0) { this.GetChildren = () => GetArrayChildren(dimBase, dimSize); } } else if (val.Type.Kind == TypeKind.Class || val.Type.Kind == TypeKind.Struct) { if (val.Type.IsKnownType(typeof(List <>))) { if ((int)val.GetFieldValue("_size").PrimitiveValue > 0) { this.GetChildren = () => GetIListChildren(this.GetValue); } } else { this.GetChildren = () => GetObjectChildren(val.Type); } } else if (val.Type.Kind == TypeKind.Pointer) { if (val.Dereference() != null) { this.GetChildren = () => new[] { new ValueNode(ClassBrowserIconService.LocalVariable, "*" + this.Name, () => GetValue().Dereference()) }; } } // Do last since it may expire the object if (val.IsNull) { fullValue = "null"; } else if (val.Type.IsInteger()) { var i = val.PrimitiveValue; if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Decimal) { fullValue = i.ToString(); } else { string hex = string.Format("0x{0:X4}", i); if (hex.Length > 6) { hex = string.Format("0x{0:X8}", i); } if (hex.Length > 10) { hex = string.Format("0x{0:X16}", i); } if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Hexadecimal) { fullValue = hex; } else { fullValue = string.Format("{0} ({1})", i, hex); } } } else if (val.Type.Kind == TypeKind.Pointer) { fullValue = String.Format("0x{0:X}", val.PointerAddress); } else if (val.Type.IsKnownType(KnownTypeCode.String)) { fullValue = '"' + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + '"'; } else if (val.Type.IsKnownType(KnownTypeCode.Char)) { fullValue = "'" + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + "'"; } else if ((val.Type.Kind == TypeKind.Class || val.Type.Kind == TypeKind.Struct)) { fullValue = val.FormatByDebuggerDisplayAttribute(WindowsDebugger.EvalThread); if (fullValue == null) { fullValue = val.InvokeToString(WindowsDebugger.EvalThread); } } else if (val.Type.Kind == TypeKind.Enum) { var primitiveValue = val.PrimitiveValue; var builder = new TypeSystemAstBuilder(); builder.AlwaysUseShortTypeNames = true; AstNode node = builder.ConvertConstantValue(val.Type, primitiveValue); fullValue = node + "=" + primitiveValue; } else { fullValue = val.AsString(); } this.error = null; this.Value = (fullValue.Length > 256) ? fullValue.Substring(0, 256) + "..." : fullValue; this.Type = val.Type.Name; if (!val.IsNull) { this.VisualizerCommands = VisualizerDescriptors.GetAllDescriptors() .Where(descriptor => descriptor.IsVisualizerAvailable(val.Type)) .Select(descriptor => descriptor.CreateVisualizerCommand(this.Name, this.GetValue)) .ToList(); } LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms", this.Name, watch.ElapsedMilliseconds); } catch (GetValueException e) { error = e; this.Value = e.Message; this.Type = string.Empty; this.GetChildren = null; this.VisualizerCommands = null; } finally { if (error == null) { ContextMenuAddInTreeEntry = "/AddIns/Debugger/Tooltips/ContextMenu/ValueNode"; } else { ContextMenuAddInTreeEntry = "/AddIns/Debugger/Tooltips/ContextMenu/ErrorNode"; } } }
void EvaluateExpression() { evaluated = true; Value val; try { var process = WindowsDebugger.DebuggedProcess; // evaluate expression val = expression.Evaluate(process); } catch (GetValueException e) { error = e; this.Text = e.Message; return; } this.canSetText = val.Type.IsPrimitive; this.expressionType = val.Type; this.Type = val.Type.Name; this.valueIsNull = val.IsNull; // Note that these return enumerators so they are lazy-evaluated if (val.IsNull) { } else if (val.Type.IsPrimitive || val.Type.FullName == typeof(string).FullName) { // Must be before IsClass } else if (val.Type.IsArray) { // Must be before IsClass if (val.ArrayLength > 0) this.ChildNodes = Utils.LazyGetChildNodesOfArray(this.Expression, val.ArrayDimensions); } else if (val.Type.IsClass || val.Type.IsValueType) { if (val.Type.FullNameWithoutGenericArguments == typeof(List<>).FullName) { if ((int)val.GetMemberValue("_size").PrimitiveValue > 0) this.ChildNodes = Utils.LazyGetItemsOfIList(this.expression); } else { this.ChildNodes = Utils.LazyGetChildNodesOfObject(this.Expression, val.Type); } } else if (val.Type.IsPointer) { Value deRef = val.Dereference(); if (deRef != null) { this.ChildNodes = new ExpressionNode [] { new ExpressionNode(this.IconImage, "*" + this.Name, this.Expression.AppendDereference()) }; } } if (DebuggingOptions.Instance.ICorDebugVisualizerEnabled) { TreeNode info = ICorDebug.GetDebugInfoRoot(val.AppDomain, val.CorValue); this.ChildNodes = Utils.PrependNode(info, this.ChildNodes); } // Do last since it may expire the object if (val.Type.IsInteger) { fullText = FormatInteger(val.PrimitiveValue); } else if (val.Type.IsPointer) { fullText = String.Format("0x{0:X}", val.PointerAddress); } else if ((val.Type.FullName == typeof(string).FullName || val.Type.FullName == typeof(char).FullName) && !val.IsNull) { try { fullText = '"' + Escape(val.InvokeToString()) + '"'; } catch (GetValueException e) { error = e; fullText = e.Message; return; } } else if ((val.Type.IsClass || val.Type.IsValueType) && !val.IsNull) { try { fullText = val.InvokeToString(); } catch (GetValueException e) { error = e; fullText = e.Message; return; } } else { fullText = val.AsString(); } this.Text = (fullText.Length > 256) ? fullText.Substring(0, 256) + "..." : fullText; }
void EvaluateExpression() { evaluated = true; Value val; try { val = expression.Evaluate(WindowsDebugger.DebuggedProcess); } catch (GetValueException e) { error = e; this.Text = e.Message; return; } this.canSetText = val.Type.IsPrimitive; this.expressionType = val.Type; this.Type = val.Type.Name; this.valueIsNull = val.IsNull; // Note that these return enumerators so they are lazy-evaluated if (val.IsNull) { } else if (val.Type.IsPrimitive || val.Type.FullName == typeof(string).FullName) // Must be before IsClass { } else if (val.Type.IsArray) // Must be before IsClass { if (val.ArrayLength > 0) { this.ChildNodes = Utils.LazyGetChildNodesOfArray(this.Expression, val.ArrayDimensions); } } else if (val.Type.IsClass || val.Type.IsValueType) { if (val.Type.FullNameWithoutGenericArguments == typeof(List <>).FullName) { if ((int)val.GetMemberValue("_size").PrimitiveValue > 0) { this.ChildNodes = Utils.LazyGetItemsOfIList(this.expression); } } else { this.ChildNodes = Utils.LazyGetChildNodesOfObject(this.Expression, val.Type); } } else if (val.Type.IsPointer) { Value deRef = val.Dereference(); if (deRef != null) { this.ChildNodes = new ExpressionNode [] { new ExpressionNode(this.IconImage, "*" + this.Name, this.Expression.AppendDereference()) }; } } if (DebuggingOptions.Instance.ICorDebugVisualizerEnabled) { TreeNode info = ICorDebug.GetDebugInfoRoot(val.AppDomain, val.CorValue); this.ChildNodes = Utils.PrependNode(info, this.ChildNodes); } // Do last since it may expire the object if (val.Type.IsInteger) { fullText = FormatInteger(val.PrimitiveValue); } else if (val.Type.IsPointer) { fullText = String.Format("0x{0:X}", val.PointerAddress); } else if ((val.Type.FullName == typeof(string).FullName || val.Type.FullName == typeof(char).FullName) && !val.IsNull) { try { fullText = '"' + Escape(val.InvokeToString()) + '"'; } catch (GetValueException e) { error = e; fullText = e.Message; return; } } else if ((val.Type.IsClass || val.Type.IsValueType) && !val.IsNull) { try { fullText = val.InvokeToString(); } catch (GetValueException e) { error = e; fullText = e.Message; return; } } else { fullText = val.AsString(); } this.Text = (fullText.Length > 256) ? fullText.Substring(0, 256) + "..." : fullText; }
Value EvaluateOrError(Func<Value> expression, out GetValueException error) { error = null; Debugger.Value value; try { value = expression(); } catch (GetValueException ex) { error = ex; return null; } if (value.Type.GetNonInterfaceBaseTypes().Any(t => t.IsKnownType(KnownTypeCode.Exception))) { error = new GetValueException(value.GetPropertyValue(WindowsDebugger.EvalThread, "Message").AsString()); return null; } return value; }
internal static object GetValue(ResourceProperty property, object clrObject) { string name; int num; int num1 = -1; string[] strArrays = null; if (property.GetCustomState() != null && property.GetCustomState().PsProperty != null) { char[] chrArray = new char[1]; chrArray[0] = '.'; strArrays = property.GetCustomState().PsProperty.Split(chrArray); num1 = 0; } do { if (num1 > -1) { name = strArrays[num1]; } else { name = property.Name; } string str = name; if (clrObject as PSObject == null) { clrObject = TypeSystem.GetPropertyValue(clrObject, str, false); } else { PSObject pSObject = clrObject as PSObject; PSPropertyInfo item = pSObject.Properties[str]; if (item != null) { try { clrObject = item.Value; } catch (GetValueException getValueException1) { GetValueException getValueException = getValueException1; TraceHelper.Current.SerializationPropertyNotFound(str, getValueException.Message); if (!property.ResourceType.IsPrimitive() || property.ResourceType.IsNullable()) { clrObject = null; } else { throw new PSObjectSerializationFailedException(string.Format(Resources.PropertyRetrievalFailed, str, getValueException.Message)); } } } else { object[] objArray = new object[1]; objArray[0] = str; TraceHelper.Current.SerializationPropertyNotFound(str, string.Format(CultureInfo.CurrentCulture, Resources.PropertyNotFoundInPSObject, objArray)); if (!property.ResourceType.IsPrimitive() || property.ResourceType.IsNullable()) { clrObject = null; break; } else { object[] objArray1 = new object[1]; objArray1[0] = str; throw new PSObjectSerializationFailedException(string.Format(CultureInfo.CurrentCulture, Resources.PropertyNotFoundInPSObject, objArray1)); } } } if (clrObject == null || strArrays == null) { break; } num = num1 + 1; num1 = num; }while (num < (int)strArrays.Length); return(clrObject); }