public GridValuesProvider(Expression targetObject, DebugType itemType) { this.targetObject = targetObject; this.itemType = itemType; this.memberFromNameMap = this.GetItemTypeMembers().MakeDictionary(memberInfo => memberInfo.Name); }
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; }
public IListNode(Expression targetObject, DebugType iListType) { this.targetObject = targetObject; this.iListType = iListType; this.Name = "IList"; this.ChildNodes = GetChildNodes(); }
public NonPublicInstanceMembersNode(Expression targetObject, DebugType shownType) { this.targetObject = targetObject; this.shownType = shownType; this.Name = StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"); this.ChildNodes = GetChildNodes(); }
public bool IsVisualizerAvailable(DebugType type) { if (type.IsAtomic()) { return false; } DebugType collectionType, itemType; // Visualizer available for IEnumerable<T> (that is, also IList<T>) return type.ResolveIEnumerableImplementation(out collectionType, out itemType); }
public DebugLocalVariableInfo(string name, int localIndex, int startOffset, int endOffset, DebugType localType, ValueGetter getter) { this.Name = name; this.localIndex = localIndex; this.StartOffset = startOffset; this.EndOffset = endOffset; this.localType = localType; this.getter = getter; }
internal DebugPropertyInfo(DebugType declaringType, string name, MethodInfo getMethod, MethodInfo setMethod) { if (getMethod == null && setMethod == null) throw new ArgumentNullException("Both getter and setter can not be null."); this.declaringType = declaringType; this.name = name; this.getMethod = getMethod; this.setMethod = setMethod; }
public IEnumerableNode(Expression targetObject, DebugType itemType) { this.targetObject = targetObject; this.Name = "IEnumerable"; this.Text = "Expanding will enumerate the IEnumerable"; DebugType debugListType; this.debugListExpression = DebuggerHelpers.CreateDebugListExpression(targetObject, itemType, out debugListType); this.ChildNodes = Utils.LazyGetItemsOfIList(this.debugListExpression); }
public BaseClassNode(Expression targetObject, DebugType shownType) { this.targetObject = targetObject; this.shownType = shownType; this.Image = IconService.GetBitmap("Icons.16x16.Class"); this.Name = StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}"); this.Type = shownType.FullName; if (shownType.FullName == "System.Object") { this.ChildNodes = null; } else { this.ChildNodes = Utils.GetChildNodesOfObject(targetObject, shownType); } }
public Expression[] AppendObjectMembers(DebugType type, BindingFlags bindingFlags) { List<Expression> members = new List<Expression>(); foreach(FieldInfo field in type.GetFields(bindingFlags)) { members.Add(this.AppendFieldReference(field)); } foreach(PropertyInfo property in type.GetProperties(bindingFlags)) { members.Add(this.AppendPropertyReference(property)); } members.Sort(); return members.ToArray(); }
/// <summary> /// Resolves implementation of a single-generic-argument interface on this type. /// </summary> /// <param name="fullNamePrefix">Interface name to search for (eg. "System.Collections.Generic.IList")</param> /// <param name="implementation">Result found implementation.</param> /// <param name="itemType">The only generic argument of <paramref name="implementation"/></param> /// <returns>True if found, false otherwise.</returns> public static bool ResolveGenericInterfaceImplementation(this DebugType type, string fullNamePrefix, out DebugType implementation, out DebugType itemType) { if (type == null) throw new ArgumentNullException("type"); implementation = null; itemType = null; implementation = type.GetGenericInterface(fullNamePrefix); if (implementation != null) { if (implementation.GetGenericArguments().Length == 1) { itemType = (DebugType)implementation.GetGenericArguments()[0]; return true; } } return false; }
public static IEnumerable<AbstractNode> GetChildNodesOfObject(Expression targetObject, DebugType shownType) { BindingFlags Flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty; if (shownType.BaseType != null) { yield return new BaseClassNode(targetObject, shownType.BaseType); } if (shownType.HasMembers(NonPublicInstanceMembersNode.Flags)) { yield return new NonPublicInstanceMembersNode(targetObject, shownType); } if (shownType.HasMembers(StaticMembersNode.Flags) || shownType.HasMembers(NonPublicStaticMembersNode.Flags)) { yield return new StaticMembersNode(targetObject, shownType); } DebugType iListType = shownType.GetInterface(typeof(IList).FullName); if (iListType != null) { yield return new IListNode(targetObject, iListType); } foreach(Expression childExpr in targetObject.AppendObjectMembers(shownType, Flags)) { yield return ValueNode.Create(childExpr); } }
static void AddCapturedLocalVariables(List<DebugLocalVariableInfo> vars, int scopeStartOffset, int scopeEndOffset, ValueGetter getCaptureClass, DebugType captureClassType) { if (captureClassType.IsDisplayClass || captureClassType.IsYieldEnumerator) { foreach(DebugFieldInfo fieldInfo in captureClassType.GetFields()) { DebugFieldInfo fieldInfoCopy = fieldInfo; if (fieldInfo.Name.StartsWith("CS$")) continue; // Ignore DebugLocalVariableInfo locVar = new DebugLocalVariableInfo( fieldInfo.Name, -1, scopeStartOffset, scopeEndOffset, (DebugType)fieldInfo.FieldType, delegate(StackFrame context) { return getCaptureClass(context).GetFieldValue(fieldInfoCopy); } ); locVar.IsCaptured = true; if (locVar.Name.StartsWith("<>")) { bool hasThis = false; foreach(DebugLocalVariableInfo l in vars) { if (l.IsThis) { hasThis = true; break; } } if (!hasThis && locVar.Name.EndsWith("__this")) { locVar.Name = "this"; locVar.IsThis = true; } else { continue; // Ignore } } if (locVar.Name.StartsWith("<")) { int endIndex = locVar.Name.IndexOf('>'); if (endIndex == -1) continue; // Ignore locVar.Name = fieldInfo.Name.Substring(1, endIndex - 1); } vars.Add(locVar); } } }
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; }
internal DebugFieldInfo(DebugType declaringType, FieldProps fieldProps) { this.declaringType = declaringType; this.fieldProps = fieldProps; }
/// <summary> /// Resolves implementation of System.Collections.Generic.IEnumerable on this type. /// </summary> /// <param name="iEnumerableType">Result found implementation of System.Collections.Generic.IEnumerable.</param> /// <param name="itemType">The only generic argument of <paramref name="implementation"/></param> /// <returns>True if found, false otherwise.</returns> public static bool ResolveIEnumerableImplementation(this DebugType type, out DebugType iEnumerableType, out DebugType itemType) { return type.ResolveGenericInterfaceImplementation( "System.Collections.Generic.IEnumerable", out iEnumerableType, out itemType); }
void LoadNodeCollectionContent(AbstractNode node, Expression thisObject, DebugType iListType) { thisObject = thisObject.CastToIList(); int listCount = thisObject.GetIListCount(); PropertyInfo indexerProp = iListType.GetProperty("Item"); for (int i = 0; i < listCount; i++) { Expression itemExpr = thisObject.AppendIndexer(i); PropertyNode itemNode = new PropertyNode( new ObjectGraphProperty { Name = "[" + i + "]", MemberInfo = indexerProp, Expression = itemExpr, Value = "", IsAtomic = true, TargetNode = null }); node.AddChild(itemNode); } }
internal bool Identical(DebugType type) { return this.type.Equals(type); }
/// <summary> /// Resolves implementation of System.Collections.Generic.IList on this type. /// </summary> /// <param name="iListType">Result found implementation of System.Collections.Generic.IList.</param> /// <param name="itemType">The only generic argument of <paramref name="implementation"/></param> /// <returns>True if found, false otherwise.</returns> public static bool ResolveIListImplementation(this DebugType type, out DebugType iListType, out DebugType itemType) { return type.ResolveGenericInterfaceImplementation( "System.Collections.Generic.IList", out iListType, out itemType); }
void LoadNodeObjectContent(AbstractNode node, Expression expression, DebugType type) { // base if (type.BaseType != null && type.BaseType.FullName != "System.Object") { var baseClassNode = new BaseClassNode(type.BaseType.FullName, type.BaseType.Name); node.AddChild(baseClassNode); LoadNodeObjectContent(baseClassNode, expression, (DebugType)type.BaseType); } // non-public members var nonPublicProperties = getProperties(expression, type, this.nonPublicInstanceMemberFlags); if (nonPublicProperties.Count > 0) { var nonPublicMembersNode = new NonPublicMembersNode(); node.AddChild(nonPublicMembersNode); foreach (var nonPublicProperty in nonPublicProperties) { nonPublicMembersNode.AddChild(new PropertyNode(nonPublicProperty)); } } // public members foreach (var property in getProperties(expression, type, this.publicInstanceMemberFlags)) { node.AddChild(new PropertyNode(property)); } }
internal MemberInfo(DebugType declaringType) { this.declaringType = declaringType; }
private List<ObjectGraphProperty> getProperties(Expression expression, DebugType shownType, BindingFlags flags) { List<ObjectGraphProperty> propertyList = new List<ObjectGraphProperty>(); foreach (MemberInfo memberProp in shownType.GetFieldsAndNonIndexedProperties(flags)) { if (memberProp.Name.Contains("<")) { // skip backing fields continue; } if (memberProp.DeclaringType != shownType) { // skip properties declared in the base type continue; } // ObjectGraphProperty needs an expression // to know whether it is expanded, and to evaluate Expression propExpression = expression.AppendMemberReference((IDebugMemberInfo)memberProp); // Value, IsAtomic are lazy evaluated propertyList.Add(new ObjectGraphProperty { Name = memberProp.Name, Expression = propExpression, Value = "", MemberInfo = memberProp, IsAtomic = true, TargetNode = null }); } return propertyList.Sorted(ObjectPropertyComparer.Instance); }
internal MethodInfo(DebugType declaringType, MethodProps methodProps) : base(declaringType) { this.methodProps = methodProps; }
/// <summary> Obtains instance of DebugType. Same types will return identical instance. </summary> static public DebugType Create(Process process, ICorDebugType corType) { DateTime startTime = Util.HighPrecisionTimer.Now; DebugType type = new DebugType(process, corType); // Get types with matching names from cache List<DebugType> typesWithMatchingName; if (!loadedTypes.TryGetValue(type.FullName, out typesWithMatchingName)) { // No types with such name - create a new list typesWithMatchingName = new List<DebugType>(1); loadedTypes.Add(type.FullName, typesWithMatchingName); } // Try to find the type foreach(DebugType loadedType in typesWithMatchingName) { if (loadedType.Equals(type)) { TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime; if (process.Options.Verbose) { process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)"); } return loadedType; // Type was loaded before } } // The type is not in the cache, finish loading it and add it to the cache if (type.IsClass || type.IsValueType) { type.LoadMemberInfo(); } typesWithMatchingName.Add(type); type.Process.Exited += delegate { typesWithMatchingName.Remove(type); }; TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime; string prefix = type.IsInterface ? "interface" : "type"; if (process.Options.Verbose) { process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds); foreach(DebugType inter in type.Interfaces) { process.TraceMessage(" - Implements {0}", inter.FullName); } } return type; }
/// <summary> Determines whether the current type is sublass of /// the the given type. That is, it derives from the given type. </summary> /// <remarks> Returns false if the given type is same as the current type </remarks> public bool IsSubclassOf(DebugType superType) { DebugType type = this; while (type != null) { if (type.Equals(superType)) return true; if (superType.IsInterface) { // Does this 'type' implement the interface? foreach(DebugType inter in type.Interfaces) { if (inter == superType) return true; } } type = type.BaseType; } return false; }
public bool IsVisualizerAvailable(DebugType type) { return type.FullName == typeof(string).FullName; }
static void AddCapturedLocalVariables(List <DebugLocalVariableInfo> vars, int scopeStartOffset, int scopeEndOffset, ValueGetter getCaptureClass, DebugType captureClassType) { if (captureClassType.IsDisplayClass || captureClassType.IsYieldEnumerator) { foreach (DebugFieldInfo fieldInfo in captureClassType.GetFields()) { DebugFieldInfo fieldInfoCopy = fieldInfo; if (fieldInfo.Name.StartsWith("CS$")) { continue; // Ignore } DebugLocalVariableInfo locVar = new DebugLocalVariableInfo( fieldInfo.Name, -1, scopeStartOffset, scopeEndOffset, (DebugType)fieldInfo.FieldType, delegate(StackFrame context) { return(getCaptureClass(context).GetFieldValue(fieldInfoCopy)); } ); locVar.IsCaptured = true; if (locVar.Name.StartsWith("<>")) { bool hasThis = false; foreach (DebugLocalVariableInfo l in vars) { if (l.IsThis) { hasThis = true; break; } } if (!hasThis && locVar.Name.EndsWith("__this")) { locVar.Name = "this"; locVar.IsThis = true; } else { continue; // Ignore } } if (locVar.Name.StartsWith("<")) { int endIndex = locVar.Name.IndexOf('>'); if (endIndex == -1) { continue; // Ignore } locVar.Name = fieldInfo.Name.Substring(1, endIndex - 1); } vars.Add(locVar); } } }
internal DebugMethodInfo(DebugType declaringType, MethodProps methodProps) { this.declaringType = declaringType; this.methodProps = methodProps; }
ListValuesProvider CreateListValuesProvider(ICSharpCode.NRefactory.Ast.Expression targetObject, DebugType iListType, DebugType listItemType) { var listValuesProvider = new ListValuesProvider(targetObject, iListType, listItemType); var virtCollection = new VirtualizingCollection<ObjectValue>(listValuesProvider); this.listView.ItemsSource = virtCollection; return listValuesProvider; }
public bool IsVisualizerAvailable(DebugType type) { return !type.IsAtomic() && !type.IsSystemDotObject(); }
internal TargetType(DebugType type) { this.typeId = ++typeIdCounter; this.type = type; typeList.Add(typeId, this); }
public static IEnumerable<TreeNode> LazyGetChildNodesOfObject(TreeNode current, Expression targetObject, DebugType shownType) { MemberInfo[] publicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); MemberInfo[] publicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); MemberInfo[] nonPublicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly); MemberInfo[] nonPublicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); DebugType baseType = (DebugType)shownType.BaseType; if (baseType != null) { yield return new TreeNode( DebuggerResourceService.GetImage("Icons.16x16.Class"), StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}"), baseType.Name, baseType.FullName, current, newNode => baseType.FullName == "System.Object" ? null : Utils.LazyGetChildNodesOfObject(newNode, targetObject, baseType) ); } if (nonPublicInstance.Length > 0) { yield return new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"), string.Empty, string.Empty, current, newNode => Utils.LazyGetMembersOfObject(newNode, targetObject, nonPublicInstance) ); } if (publicStatic.Length > 0 || nonPublicStatic.Length > 0) { yield return new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.StaticMembers}"), string.Empty, string.Empty, current, p => { var children = Utils.LazyGetMembersOfObject(p, targetObject, publicStatic); if (nonPublicStatic.Length > 0) { TreeNode nonPublicStaticNode = new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicStaticMembers}"), string.Empty, string.Empty, p, newNode => Utils.LazyGetMembersOfObject(newNode, targetObject, nonPublicStatic) ); children = Utils.PrependNode(nonPublicStaticNode, children); } return children; } ); } DebugType iListType = (DebugType)shownType.GetInterface(typeof(IList).FullName); if (iListType != null) { yield return new IListNode(current, targetObject); } else { DebugType iEnumerableType, itemType; if (shownType.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) { yield return new IEnumerableNode(current, targetObject, itemType); } } foreach(TreeNode node in LazyGetMembersOfObject(current, targetObject, publicInstance)) { yield return node; } }
/// <inheritdoc/> public override bool IsDefined(Type attributeType, bool inherit) { return(DebugType.IsDefined(this, inherit, attributeType)); }