private TreeViewItem CreateTreeItem(TreeListView tree, IResultVisualizer resultVisualizer, int level)
        {
            UIElement value = resultVisualizer.Value as UIElement;

            if (value == null)
            {
                value = new TextBlock()
                {
                    Text = resultVisualizer.ValueString,
                };
            }

            TreeViewItem item = CreateTreeItem(tree, resultVisualizer.Name, resultVisualizer.Image, level, value, resultVisualizer.Type);

            item.Tag = new TreeViewItemTag()
            {
                ResultTreeItem = resultVisualizer,
                Level          = level,
            };
            if (resultVisualizer.IsExpandable)
            {
                item.Items.Add(ExpandingItemText);
                item.Expanded += TreeViewItem_Expanded;
            }
            return(item);
        }
        public object Output(object obj)
        {
            // We don't visualize null
            if (obj == null)
            {
                return(null);
            }

            // Primitive types and strings are visualized as ToString
            if (obj.GetType().IsPrimitive || obj is string)
            {
                return(obj.ToString());
            }

            // UI elements should be resurfaced back.
            if (obj is UIElement)
            {
                return(obj);
            }

            // All other should be visualized in a table
            IResultVisualizer resultTreeItem = ResultVisualizer.Create(obj, obj.GetType(), "result", null, this);

            resultTreeItem.Initialize();
            return(new LazyUIResult(() => Visualize(resultTreeItem)));
        }
        /// <summary>
        /// Evaluates visual expression and converts it to result visualizer.
        /// </summary>
        private void Evaluate()
        {
            if (VisualizedExpression.TagValue == DkmVisualizedExpression.Tag.RootVisualizedExpression)
            {
                DkmRootVisualizedExpression rootVisualizedExpression = VisualizedExpression as DkmRootVisualizedExpression;
                int    processId  = rootVisualizedExpression.InspectionSession?.Process?.LivePart?.Id ?? 0;
                string moduleName = rootVisualizedExpression.Module?.Name;
                string typeString = rootVisualizedExpression.Type;
                ulong  address    = 0;
                bool   hasAddress = false;

                if (VisualizedExpression.ValueHome.TagValue == DkmExpressionValueHome.Tag.PointerValueHome)
                {
                    address    = (VisualizedExpression.ValueHome as DkmPointerValueHome).Address;
                    hasAddress = true;
                }

                if (string.IsNullOrEmpty(typeString) || string.IsNullOrEmpty(moduleName) || !hasAddress)
                {
                    string displayString = "{...CsDebugScript failure...}";

                    EvaluationResult = DkmSuccessEvaluationResult.Create(
                        VisualizedExpression.InspectionContext,
                        VisualizedExpression.StackFrame,
                        rootVisualizedExpression.Name,
                        rootVisualizedExpression.FullName,
                        DkmEvaluationResultFlags.ReadOnly,
                        displayString,
                        "",
                        rootVisualizedExpression.Type,
                        DkmEvaluationResultCategory.Other,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null,
                        null,
                        null,
                        null);
                    return;
                }

                string title;

                try
                {
                    Process  process  = Process.All.First(p => p.SystemId == processId);
                    Module   module   = process.ModulesByName[System.IO.Path.GetFileNameWithoutExtension(moduleName)];
                    CodeType codeType = ResolveCodeType(process, module, typeString);

                    Variable         = codeType.IsPointer ? Variable.CreatePointer(codeType, address) : Variable.Create(codeType, address);
                    title            = Variable.ToString();
                    ResultVisualizer = CsDebugScript.UI.ResultVisualizers.ResultVisualizer.Create(Variable, Variable.GetType(), "result", CompletionDataType.Unknown, dummyInteractiveResultVisualizer);
                }
                catch
                {
                    title = "{...CsDebugScript...}";
                }

                DkmDataAddress dkmDataAddress = DkmDataAddress.Create(VisualizedExpression.RuntimeInstance, address, rootVisualizedExpression.StackFrame?.InstructionAddress);

                EvaluationResult = DkmSuccessEvaluationResult.Create(
                    VisualizedExpression.InspectionContext,
                    VisualizedExpression.StackFrame,
                    rootVisualizedExpression.Name,
                    rootVisualizedExpression.FullName,
                    DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable,
                    title,
                    "",
                    rootVisualizedExpression.Type,
                    DkmEvaluationResultCategory.Other,
                    DkmEvaluationResultAccessType.None,
                    DkmEvaluationResultStorageType.None,
                    DkmEvaluationResultTypeModifierFlags.None,
                    dkmDataAddress,
                    VSUIVisualizerService.GetUIVisualizers(ResultVisualizer),
                    null,
                    null);
                return;
            }

            // This should never happen...
            throw new NotImplementedException();
        }
 /// <summary>
 /// Initializes the <see cref="VSCustomVisualizerEvaluator"/> class.
 /// </summary>
 /// <param name="evaluationResult"></param>
 /// <param name="resultVisualizer"></param>
 public VSCustomVisualizerEvaluator(DkmEvaluationResult evaluationResult, IResultVisualizer resultVisualizer)
 {
     EvaluationResult = evaluationResult;
     ResultVisualizer = resultVisualizer;
 }
        private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
        {
            try
            {
                TreeViewItem     item   = e.Source as TreeViewItem;
                TreeListView     tree   = null;
                FrameworkElement parent = item?.Parent as FrameworkElement;

                while (tree == null && parent != null)
                {
                    tree   = parent as TreeListView;
                    parent = parent.Parent as FrameworkElement;
                }

                if ((item.Items.Count == 1) && (item.Items[0].ToString() == ExpandingItemText))
                {
                    TreeViewItemTag tag = item.Tag as TreeViewItemTag;

                    System.Threading.Tasks.Task.Run(() =>
                    {
                        IResultVisualizer resultTreeItem         = tag.ResultTreeItem as IResultVisualizer;
                        IEnumerable <IResultVisualizer> children = tag.ResultTreeItem as IEnumerable <IResultVisualizer>;

                        try
                        {
                            if (resultTreeItem != null)
                            {
                                List <Tuple <string, IEnumerable <IResultVisualizer> > > customChildren = new List <Tuple <string, IEnumerable <IResultVisualizer> > >();

                                foreach (Tuple <string, IEnumerable <IResultVisualizer> > customChild in resultTreeItem.Children)
                                {
                                    if (customChild.Item2.Any())
                                    {
                                        if (customChild.Item1 == "[Expanded]")
                                        {
                                            List <IResultVisualizer> cachedItems = customChild.Item2.ToList();

                                            customChildren.Add(Tuple.Create(customChild.Item1, (IEnumerable <IResultVisualizer>)cachedItems));
                                            foreach (IResultVisualizer child in cachedItems)
                                            {
                                                child.Initialize();
                                            }
                                        }
                                        else
                                        {
                                            customChildren.Add(customChild);
                                        }
                                    }
                                }

                                item.Dispatcher.InvokeAsync(() =>
                                {
                                    try
                                    {
                                        int level = tag.Level;

                                        item.Items.Clear();
                                        foreach (Tuple <string, IEnumerable <IResultVisualizer> > customChild in customChildren)
                                        {
                                            if (customChild.Item1 == "[Expanded]")
                                            {
                                                foreach (IResultVisualizer child in customChild.Item2)
                                                {
                                                    item.Items.Add(CreateTreeItem(tree, child, level + 1));
                                                }
                                            }
                                            else
                                            {
                                                TreeViewItem customItem = CreateTreeItem(tree, customChild.Item1, CompletionData.GetImage(CompletionDataType.Namespace), level + 1, nameItalic: true);

                                                customItem.Tag = new TreeViewItemTag()
                                                {
                                                    Level          = level + 1,
                                                    ResultTreeItem = customChild.Item2,
                                                };
                                                customItem.Items.Add(ExpandingItemText);
                                                customItem.Expanded += TreeViewItem_Expanded;
                                                item.Items.Add(customItem);
                                            }
                                        }
                                    }
                                    catch (Exception ex3)
                                    {
                                        MessageBox.Show(ex3.ToString());
                                    }
                                });
                            }
                            else if (children != null)
                            {
                                List <IResultVisualizer> cachedItems = children.ToList();

                                foreach (IResultVisualizer child in children)
                                {
                                    child.Initialize();
                                }

                                item.Dispatcher.InvokeAsync(() =>
                                {
                                    try
                                    {
                                        int level = tag.Level;

                                        item.Items.Clear();
                                        foreach (IResultVisualizer child in cachedItems)
                                        {
                                            item.Items.Add(CreateTreeItem(tree, child, level + 1));
                                        }
                                    }
                                    catch (Exception ex3)
                                    {
                                        MessageBox.Show(ex3.ToString());
                                    }
                                });
                            }
                        }
                        catch (Exception ex2)
                        {
                            MessageBox.Show(ex2.ToString());
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private UIElement Visualize(IResultVisualizer resultVisualizer)
        {
            // Create tree and its columns
            TreeListView tree = new TreeListView();

            tree.Columns.Add(new GridViewColumn()
            {
                Header       = "Name",
                CellTemplate = new DataTemplate()
                {
                    VisualTree = CreateStackPanelFactory("Name")
                },
                Width = 200,
            });
            tree.Columns.Add(new GridViewColumn()
            {
                Header       = "Value",
                CellTemplate = new DataTemplate()
                {
                    VisualTree = CreateStackPanelFactory("Value")
                },
                Width = 600,
            });
            tree.Columns.Add(new GridViewColumn()
            {
                Header       = "Type",
                CellTemplate = new DataTemplate()
                {
                    VisualTree = CreateStackPanelFactory("Type")
                },
                Width = 200,
            });

            // Create header row
            TreeViewItem header = new TreeViewItem();

            header.Header = new GridViewHeaderRowPresenter()
            {
                Columns = tree.Columns,
            };
            tree.Items.Add(header);

            // Create result item
            TreeViewItem resultItem = CreateTreeItem(tree, resultVisualizer, 0);

            tree.Items.Add(resultItem);
            resultItem.IsExpanded = true;

            // Initialize tree events
            tree.PreviewMouseWheel += Tree_PreviewMouseWheel;
            tree.PreviewKeyDown    += Tree_PreviewKeyDown;
            tree.LostFocus         += (a, b) =>
            {
                var item = tree.SelectedItem as TreeViewItem;

                if (item != null)
                {
                    item.IsSelected = false;
                }
            };
            tree.GotFocus += (a, b) =>
            {
                var item = tree.SelectedItem as TreeViewItem;

                if (item == null)
                {
                    if (interactiveWindowContent.TraverseDirection.HasValue)
                    {
                        if (interactiveWindowContent.TraverseDirection == FocusNavigationDirection.Next)
                        {
                            item = tree.Items[1] as TreeViewItem;
                        }
                        else
                        {
                            item = tree.Items[tree.Items.Count - 1] as TreeViewItem;
                            while (item.IsExpanded)
                            {
                                item = item.Items[item.Items.Count - 1] as TreeViewItem;
                            }
                        }
                    }
                    else
                    {
                        item = tree.Items[1] as TreeViewItem;
                    }

                    if (item != null)
                    {
                        item.IsSelected = true;
                    }
                }
            };
            dispatcher = tree.Dispatcher;
            return(tree);
        }
Пример #7
0
        /// <summary>
        /// Returns child elements of previous evaluation.
        /// </summary>
        public void GetItems(DkmVisualizedExpression visualizedExpression, DkmEvaluationResultEnumContext enumContext, int startIndex, int count, out DkmChildVisualizedExpression[] items)
        {
            // Check if we want to use passthrough visualizer
            PassThroughVisualizer passThroughVisualizer = enumContext.GetDataItem <PassThroughVisualizer>();

            if (passThroughVisualizer != null)
            {
                passThroughVisualizer.GetItems(visualizedExpression, enumContext, startIndex, count, out items);
                return;
            }

            // Execute our regular visualizer
            VSCustomVisualizerEvaluator evaluator = visualizedExpression.GetDataItem <VSCustomVisualizerEvaluator>();

            IResultVisualizer[] itemsAsResults = evaluator.ResultVisualizer.Children.Skip(startIndex).Take(count).ToArray();

            items = new DkmChildVisualizedExpression[itemsAsResults.Length];
            for (int i = 0; i < items.Length; i++)
            {
                IResultVisualizer           item = itemsAsResults[i];
                DkmEvaluationResultCategory category;

                switch (item.DataType)
                {
                case CompletionDataType.Class:
                    category = DkmEvaluationResultCategory.Class;
                    break;

                case CompletionDataType.Property:
                case CompletionDataType.StaticProperty:
                    category = DkmEvaluationResultCategory.Property;
                    break;

                case CompletionDataType.Event:
                    category = DkmEvaluationResultCategory.Event;
                    break;

                case CompletionDataType.Method:
                    category = DkmEvaluationResultCategory.Method;
                    break;

                case CompletionDataType.Enum:
                case CompletionDataType.EnumValue:
                case CompletionDataType.Keyword:
                case CompletionDataType.Namespace:
                case CompletionDataType.StaticClass:
                case CompletionDataType.StaticEvent:
                case CompletionDataType.StaticMethod:
                case CompletionDataType.StaticVariable:
                case CompletionDataType.Unknown:
                case CompletionDataType.Variable:
                default:
                    category = DkmEvaluationResultCategory.Data;
                    break;
                }

                DkmExpressionValueHome valueHome = visualizedExpression.ValueHome;
                ulong  address  = 0;
                string fullName = string.Empty;
                string typeName = null;

                try
                {
                    if (item.Value is Variable variable)
                    {
                        address   = variable.GetPointerAddress();
                        typeName  = variable.GetCodeType().Name;
                        fullName  = $"*(({typeName}*)0x{address:X})";
                        valueHome = DkmPointerValueHome.Create(address);
                    }
                }
                catch
                {
                }

                DkmEvaluationResult result;
                DkmDataItem         dataItem = null;

                if (item.ShouldForceDefaultVisualizer && !string.IsNullOrEmpty(fullName))
                {
                    using (DkmLanguageExpression languageExpression = DkmLanguageExpression.Create(visualizedExpression.InspectionContext.Language, DkmEvaluationFlags.TreatAsExpression, fullName, null))
                    {
                        visualizedExpression.EvaluateExpressionCallback(visualizedExpression.InspectionContext, languageExpression, visualizedExpression.StackFrame, out result);
                    }

                    if (result is DkmSuccessEvaluationResult successResult)
                    {
                        dataItem = new PassThroughVisualizer(successResult);
                        result   = DkmSuccessEvaluationResult.Create(
                            successResult.InspectionContext,
                            successResult.StackFrame,
                            item.Name, // Name - Left column
                            successResult.FullName,
                            successResult.Flags,
                            successResult.Value, // Value - Middle column
                            successResult.EditableValue,
                            successResult.Type,  // Type - Right column
                            category,
                            successResult.Access,
                            successResult.StorageType,
                            successResult.TypeModifierFlags,
                            successResult.Address,
                            successResult.CustomUIVisualizers,
                            successResult.ExternalModules,
                            successResult.RefreshButtonText,
                            dataItem);
                    }
                }
                else
                {
                    result = DkmSuccessEvaluationResult.Create(
                        visualizedExpression.InspectionContext,
                        visualizedExpression.StackFrame,
                        item.Name,        // Name - Left column
                        fullName,         // FullName - What is being copied when "Add to watch"
                        DkmEvaluationResultFlags.ReadOnly | (item.IsExpandable ? DkmEvaluationResultFlags.Expandable : DkmEvaluationResultFlags.None),
                        item.ValueString, // Value - Middle column
                        "",
                        item.Type ?? "",  // Type - Right column
                        category,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null,
                        VSUIVisualizerService.GetUIVisualizers(item),
                        null,
                        null);
                    dataItem = new VSCustomVisualizerEvaluator(result, item);
                }
                items[i] = DkmChildVisualizedExpression.Create(
                    visualizedExpression.InspectionContext,
                    visualizedExpression.VisualizerId,
                    visualizedExpression.SourceId,
                    visualizedExpression.StackFrame,
                    valueHome,
                    result,
                    visualizedExpression,
                    (uint)(startIndex + i),
                    dataItem);
            }
        }
Пример #8
0
        /// <summary>
        /// Finds best collection of UI visualizers that will be used for result visualizer.
        /// </summary>
        /// <param name="resultVisualizer">Result visualizer.</param>
        /// <returns>Best collection of UI visualizers</returns>
        internal static ReadOnlyCollection <DkmCustomUIVisualizerInfo> GetUIVisualizers(IResultVisualizer resultVisualizer)
        {
            // Get resulting object that is being visualized
            object result = (resultVisualizer as ResultVisualizer)?.Result;

            // Variable can be visualized in all UI visualizers
            if (result is Variable)
            {
                return(AllCustomUiVisualizers);
            }

            // TODO: There are many examples of different visualizers, for example CodeType can be visualized per byte usage
            return(null);
        }
Пример #9
0
        public object Output(object obj)
        {
            // We don't visualize null
            if (obj == null)
            {
                return(null);
            }

            // Primitive types and strings are visualized as ToString
            if (obj.GetType().IsPrimitive || obj is string)
            {
                return(obj.ToString());
            }

            // UI elements should be resurfaced back.
            if (obj is UIElement)
            {
                return(obj);
            }

            // Drawing objects should be resurfaced back.
            IDrawing drawing = obj as IDrawing;

            if (drawing != null)
            {
                return(new LazyUIResult(() => new DrawingViewer(drawing)));
            }

            // All other should be visualized in a table
            IResultVisualizer resultTreeItem = ResultVisualizer.Create(obj, obj.GetType(), "result", CompletionDataType.Unknown, this);

            resultTreeItem.Initialize();

            // Check if we can also represent resulting object as a drawing
            IDrawingVisualizerObject drawingVisualizerObject = obj as IDrawingVisualizerObject;

            if (drawingVisualizerObject != null && drawingVisualizerObject.CanVisualize())
            {
                Graphics graphics = new Graphics(dispatcher);

                drawing = drawingVisualizerObject.CreateDrawing(graphics);
            }

            if (drawing != null)
            {
                // Create panel that will hold both elements.
                return(new LazyUIResult(() =>
                {
                    StackPanel panel = new StackPanel();

                    panel.Orientation = Orientation.Vertical;
                    panel.Children.Add(Visualize(resultTreeItem));
                    panel.Children.Add(new DrawingViewer(drawing));
                    return panel;
                }));
            }

            // Check if it is console printer
            if (obj is IConsoleVisualizer consoleVisualizer)
            {
                consoleVisualizer.PrintOnConsole();
                return(null);
            }

            return(new LazyUIResult(() => Visualize(resultTreeItem)));
        }