internal IVariableInformation[] Expand(IVariableInformation variable) { try { variable.EnsureChildren(); if (variable.IsVisualized) { return(ExpandVisualized(variable)); } IVariableInformation visView = GetVisualizationWrapper(variable); if (visView == null) { return(variable.Children); } List <IVariableInformation> children = new List <IVariableInformation>(); children.Add(visView); Array.ForEach(variable.Children, (c) => children.Add(c)); return(children.ToArray()); } catch (Exception e) { Logger.WriteLine("natvis Expand: " + e.Message); // TODO: add telemetry return(variable.Children); } }
internal IVariableInformation[] Expand(IVariableInformation variable) { try { variable.EnsureChildren(); if (variable.IsVisualized || ((ShowDisplayStrings == DisplayStringsState.On) && !(variable is VisualizerWrapper))) // visualize right away if DisplayStringsState.On, but only if not dummy var ([Raw View]) { return(ExpandVisualized(variable)); } IVariableInformation visView = GetVisualizationWrapper(variable); if (visView == null) { return(variable.Children); } List <IVariableInformation> children = new List <IVariableInformation>(); children.Add(visView); children.AddRange(variable.Children); return(children.ToArray()); } catch (Exception e) { _process.Logger.WriteLine("natvis Expand: " + e.Message); // TODO: add telemetry return(variable.Children); } }
// Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or fields of a class or struct. public int EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum) { ppEnum = null; _variableInformation.PropertyInfoFlags = dwFields; _variableInformation.EnsureChildren(); if (_variableInformation.CountChildren != 0) { try { _engine.DebuggedProcess.Natvis.WaitDialog.ShowWaitDialog(_variableInformation.Name); var children = _engine.DebuggedProcess.Natvis.Expand(_variableInformation); DEBUG_PROPERTY_INFO[] properties = new DEBUG_PROPERTY_INFO[children.Length]; for (int i = 0; i < children.Length; i++) { properties[i] = (new AD7Property(_engine, children[i])).ConstructDebugPropertyInfo(dwFields); } ppEnum = new AD7PropertyEnum(properties); return(Constants.S_OK); } finally { _engine.DebuggedProcess.Natvis.WaitDialog.EndWaitDialog(); } } return(Constants.S_FALSE); }
private IVariableInformation FindBaseClass(IVariableInformation variable) { variable.EnsureChildren(); if (variable.Children != null) { return(Array.Find(variable.Children, (c) => c.VariableNodeType == VariableInformation.NodeType.BaseClass)); } return(null); }
// Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or fields of a class or struct. public int EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum) { ppEnum = null; _variableInformation.PropertyInfoFlags = dwFields; _variableInformation.EnsureChildren(); if (_variableInformation.CountChildren != 0) { DEBUG_PROPERTY_INFO[] properties = new DEBUG_PROPERTY_INFO[_variableInformation.Children.Count]; for (int i = 0; i < _variableInformation.Children.Count; i++) { properties[i] = (new AD7Property(_engine, _variableInformation.Children[i])).ConstructDebugPropertyInfo(dwFields); } ppEnum = new AD7PropertyEnum(properties); return(VSConstants.S_OK); } return(VSConstants.S_FALSE); }
public void EnsureChildren() { Parent.EnsureChildren(); }
private IVariableInformation[] ExpandVisualized(IVariableInformation variable) { VisualizerInfo visualizer = FindType(variable); if (visualizer == null) { return(variable.Children); } List <IVariableInformation> children = new List <IVariableInformation>(); ExpandType1 expandType = (ExpandType1)Array.Find(visualizer.Visualizer.Items, (o) => { return(o is ExpandType1); }); if (expandType == null) { return(variable.Children); } foreach (var i in expandType.Items) { if (i is ItemType) { ItemType item = (ItemType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } IVariableInformation expr = GetExpression(item.Value, variable, visualizer.ScopedNames, item.Name); children.Add(expr); } else if (i is ArrayItemsType) { ArrayItemsType item = (ArrayItemsType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } uint size = 0; string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames); size = MICore.Debugger.ParseUint(val, throwOnError: true); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion ValuePointerType[] vptrs = item.ValuePointer; foreach (var vp in vptrs) { if (EvalCondition(vp.Condition, variable, visualizer.ScopedNames)) { IVariableInformation ptrExpr = GetExpression('*' + vp.Value, variable, visualizer.ScopedNames); string typename = ptrExpr.TypeName; if (String.IsNullOrWhiteSpace(typename)) { continue; } StringBuilder arrayBuilder = new StringBuilder(); arrayBuilder.Append('('); arrayBuilder.Append(typename); arrayBuilder.Append('['); arrayBuilder.Append(size); arrayBuilder.Append("])*("); arrayBuilder.Append(vp.Value); arrayBuilder.Append(')'); string arrayStr = arrayBuilder.ToString(); IVariableInformation arrayExpr = GetExpression(arrayStr, variable, visualizer.ScopedNames); arrayExpr.EnsureChildren(); if (arrayExpr.CountChildren != 0) { Array.ForEach(arrayExpr.Children, (c) => children.Add(c)); } break; } } } else if (i is TreeItemsType) { TreeItemsType item = (TreeItemsType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } if (String.IsNullOrWhiteSpace(item.Size) || String.IsNullOrWhiteSpace(item.HeadPointer) || String.IsNullOrWhiteSpace(item.LeftPointer) || String.IsNullOrWhiteSpace(item.RightPointer)) { continue; } if (item.ValueNode == null || String.IsNullOrWhiteSpace(item.ValueNode.Value)) { continue; } string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames); uint size = MICore.Debugger.ParseUint(val, throwOnError: true); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion IVariableInformation headVal = GetExpression(item.HeadPointer, variable, visualizer.ScopedNames); ulong head = MICore.Debugger.ParseAddr(headVal.Value); var content = new List <IVariableInformation>(); if (head != 0 && size != 0) { headVal.EnsureChildren(); Traverse goLeft = GetTraverse(item.LeftPointer, headVal); Traverse goRight = GetTraverse(item.RightPointer, headVal); Traverse getValue = null; if (item.ValueNode.Value == "this") // TODO: handle condition { getValue = (v) => v; } else if (headVal.FindChildByName(item.ValueNode.Value) != null) { getValue = (v) => v.FindChildByName(item.ValueNode.Value); } if (goLeft == null || goRight == null || getValue == null) { continue; } TraverseTree(headVal, goLeft, goRight, getValue, children, size); } } else if (i is LinkedListItemsType) { // example: // <LinkedListItems> // <Size>m_nElements</Size> -- optional, will go until NextPoint is 0 or == HeadPointer // <HeadPointer>m_pHead</HeadPointer> // <NextPointer>m_pNext</NextPointer> // <ValueNode>m_element</ValueNode> // </LinkedListItems> LinkedListItemsType item = (LinkedListItemsType)i; if (String.IsNullOrWhiteSpace(item.Condition)) { if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } } if (String.IsNullOrWhiteSpace(item.HeadPointer) || String.IsNullOrWhiteSpace(item.NextPointer)) { continue; } if (String.IsNullOrWhiteSpace(item.ValueNode)) { continue; } uint size = MAX_EXPAND; if (!String.IsNullOrWhiteSpace(item.Size)) { string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames); size = MICore.Debugger.ParseUint(val); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion } IVariableInformation headVal = GetExpression(item.HeadPointer, variable, visualizer.ScopedNames); ulong head = MICore.Debugger.ParseAddr(headVal.Value); var content = new List <IVariableInformation>(); if (head != 0 && size != 0) { headVal.EnsureChildren(); Traverse goNext = GetTraverse(item.NextPointer, headVal); Traverse getValue = null; if (item.ValueNode == "this") { getValue = (v) => v; } else if (headVal.FindChildByName(item.ValueNode) != null) { getValue = (v) => v.FindChildByName(item.ValueNode); } else { var value = GetExpression(item.ValueNode, headVal, visualizer.ScopedNames); if (value != null && !value.Error) { getValue = (v) => GetExpression(item.ValueNode, v, visualizer.ScopedNames); } } if (goNext == null || getValue == null) { continue; } TraverseList(headVal, goNext, getValue, children, size, item.NoValueHeadPointer); } } else if (i is IndexListItemsType) { // example: // <IndexListItems> // <Size>_M_vector._M_index</Size> // <ValueNode>*(_M_vector._M_array[$i])</ValueNode> // </IndexListItems> IndexListItemsType item = (IndexListItemsType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } var sizes = item.Size; uint size = 0; if (sizes == null) { continue; } foreach (var s in sizes) { if (string.IsNullOrWhiteSpace(s.Value)) { continue; } if (EvalCondition(s.Condition, variable, visualizer.ScopedNames)) { string val = GetExpressionValue(s.Value, variable, visualizer.ScopedNames); size = MICore.Debugger.ParseUint(val); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion break; } } var values = item.ValueNode; if (values == null) { continue; } foreach (var v in values) { if (string.IsNullOrWhiteSpace(v.Value)) { continue; } if (EvalCondition(v.Condition, variable, visualizer.ScopedNames)) { string processedExpr = ReplaceNamesInExpression(v.Value, variable, visualizer.ScopedNames); Dictionary <string, string> indexDic = new Dictionary <string, string>(); for (uint index = 0; index < size; ++index) { indexDic["$i"] = index.ToString(CultureInfo.InvariantCulture); string finalExpr = ReplaceNamesInExpression(processedExpr, null, indexDic); IVariableInformation expressionVariable = new VariableInformation(finalExpr, variable, _process.Engine, "[" + indexDic["$i"] + "]"); expressionVariable.SyncEval(); children.Add(expressionVariable); } break; } } } else if (i is ExpandedItemType) { ExpandedItemType item = (ExpandedItemType)i; // example: // <Type Name="std::auto_ptr<*>"> // <DisplayString>auto_ptr {*_Myptr}</DisplayString> // <Expand> // <ExpandedItem>_Myptr</ExpandedItem> // </Expand> // </Type> if (item.Condition != null) { if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } } if (String.IsNullOrWhiteSpace(item.Value)) { continue; } var expand = GetExpression(item.Value, variable, visualizer.ScopedNames); var eChildren = Expand(expand); if (eChildren != null) { Array.ForEach(eChildren, (c) => children.Add(c)); } } } if (!(variable is VisualizerWrapper)) // don't stack wrappers { // add the [Raw View] field IVariableInformation rawView = new VisualizerWrapper(ResourceStrings.RawView, _process.Engine, variable, visualizer, isVisualizerView: false); children.Add(rawView); } return(children.ToArray()); }
public void EnsureChildren() => Parent.EnsureChildren();
private IVariableInformation FindBaseClass(IVariableInformation variable) { variable.EnsureChildren(); if (variable.Children != null) { return Array.Find(variable.Children, (c) => c.VariableNodeType == VariableInformation.NodeType.BaseClass); } return null; }
internal IVariableInformation[] Expand(IVariableInformation variable) { try { variable.EnsureChildren(); if (variable.IsVisualized || ((ShowDisplayStrings == DisplayStringsState.On) && !(variable is VisualizerWrapper))) // visualize right away if DisplayStringsState.On, but only if not dummy var ([Raw View]) { return ExpandVisualized(variable); } IVariableInformation visView = GetVisualizationWrapper(variable); if (visView == null) { return variable.Children; } List<IVariableInformation> children = new List<IVariableInformation>(); children.Add(visView); children.AddRange(variable.Children); return children.ToArray(); } catch (Exception e) { Logger.WriteLine("natvis Expand: " + e.Message); // TODO: add telemetry return variable.Children; } }
internal IVariableInformation[] Expand(IVariableInformation variable) { try { variable.EnsureChildren(); if (variable.IsVisualized) { return ExpandVisualized(variable); } IVariableInformation visView = GetVisualizationWrapper(variable); if (visView == null) { return variable.Children; } List<IVariableInformation> children = new List<IVariableInformation>(); children.Add(visView); Array.ForEach(variable.Children, (c) => children.Add(c)); return children.ToArray(); } catch (Exception e) { Logger.WriteLine("natvis Expand: " + e.Message); // TODO: add telemetry return variable.Children; } }