private InspectionData GetSiblingItemFromData(InspectionData data)
        {
            if (null == data || (null == dataCollection))
            {
                return(null);
            }

            ObservableCollection <InspectionData> collection = null;

            collection = (dataCollection.Data as ObservableCollection <InspectionData>);
            int index = collection.IndexOf(data);

            if (-1 == index)
            {
                return(null);
            }

            // Move to the next sibling by default. If doing so causes index
            // to go beyond the last valid item (not including the dummy empty
            // item), then move back to look for the previous item.
            index = index + 1;
            if (index >= collection.Count - 1)
            {
                index = index - 2;
            }
            if (index < 0)
            {
                return(null); // There's no sibling.
            }
            return(collection[index]);
        }
        private void ShowVariableEditBox(string initialString)
        {
            // Only clicking on the top-most level item should bring up edit box.
            InspectionViewItem parent = ContainerFromItem(null, inspectionView.SelectedItem);

            if (null == parent || (0 != parent.Level))
            {
                return;
            }

            currentEditingData = (InspectionData)inspectionView.SelectedItem;
            TextBlock nameBlock = FindDescendant <TextBlock>(parent);

            if (nameBlock != null)
            {
                txtVariableEditor.Height = nameBlock.Height;
                txtVariableEditor.Width  = colName.Width;

                GeneralTransform transform     = parent.TransformToAncestor(inspectionView);
                Point            leftTopCoords = transform.Transform(new Point(0, 0));

                if (string.IsNullOrEmpty(initialString))
                {
                    initialString = currentEditingData.DisplayText;
                }

                txtVariableEditor.Margin     = new Thickness(2, leftTopCoords.Y, 0, 0);
                txtVariableEditor.Text       = initialString;
                txtVariableEditor.Visibility = Visibility.Visible;
                txtVariableEditor.Focus();
                txtVariableEditor.SelectAll();
            }
        }
        private void OnWatchWindowMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            InspectionData itemSelected     = (InspectionData)inspectionView.SelectedItem;
            string         newQualifiedName = string.Empty;

            if (null != itemSelected)
            {
                newQualifiedName = itemSelected.GetQualifiedName();
            }

            if (currentQualifiedName == newQualifiedName)
            {
                return;
            }

            // Unhighlight through the current qualified name, if any.
            if (string.IsNullOrEmpty(currentQualifiedName) == false)
            {
                HighlightQualifiedName(currentQualifiedName, false);
            }

            // Highlight the new qualified name...
            currentQualifiedName = string.Empty;
            if (string.IsNullOrEmpty(newQualifiedName) == false)
            {
                if (HighlightQualifiedName(newQualifiedName, true))
                {
                    currentQualifiedName = newQualifiedName;
                }
            }
        }
        internal InspectionData AddDerivation(string childExpression, int childIndexer)
        {
            if (null == derivations)
            {
                derivations = new ObservableCollection <InspectionData>();
            }

            InspectionData data = new InspectionData(this, childExpression, childIndexer);

            derivations.Add(data);
            return(data);
        }
        private void OnDeleteClicked(object sender, RoutedEventArgs e)
        {
            InspectionData removedItem = (InspectionData)inspectionView.SelectedItem;

            if (removedItem != null)
            {
                if (dataCollection.RemoveInspectionData(inspectionView.SelectedItem))
                {
                    Solution.Current.RemoveWatchExpressions(removedItem.DisplayText);
                    inspectionView.Items.Refresh();
                }
            }
        }
        private void HideVariableEditBox(bool commitChanges, bool setFocusOnView)
        {
            if (null == currentEditingData)
            {
                return; // There's no editing item now.
            }
            if (currentEditingData.IsEmptyData == false)
            {
                Solution.Current.RemoveWatchExpressions(currentEditingData.Expression);
            }

            if (!string.IsNullOrEmpty(txtVariableEditor.Text) && (false != commitChanges))
            {
                int index = dataCollection.GetParentIndex(currentEditingData);
                if (index >= 0 && index < dataCollection.Data.Count)
                {
                    bool duplicateExpression = Solution.Current.AddWatchExpressions(txtVariableEditor.Text);
                    if (duplicateExpression == true)
                    {
                        TextEditorControl.Instance.DisplayStatusMessage(StatusTypes.Info, Configurations.WatchWindowDuplicateInfo, 3);
                        return;
                    }

                    dataCollection.UpdateVariableName(txtVariableEditor.Text, index);
                    RefreshInspectionView();
                }
            }

            InspectionViewItem viewItem = ContainerFromItem(null, currentEditingData);

            currentEditingData = null;

            if (null != viewItem)
            {
                viewItem.IsSelected = true;
            }

            txtVariableEditor.Visibility = Visibility.Hidden;
            UIElement elementToFocus = inspectionView;

            if (false != setFocusOnView)
            {
                elementToFocus = TextEditorControl.Instance.textCanvas;
            }

            elementToFocus.Focus();
        }
        private InspectionViewItem ContainerFromItem(InspectionData inspectionData)
        {
            List <InspectionData> reversedDataList = new List <InspectionData>();
            InspectionData        currentData      = inspectionData;

            while (null != currentData)
            {
                reversedDataList.Insert(0, currentData);
                currentData = currentData.ParentData;
            }

            InspectionViewItem viewItem = null;

            foreach (InspectionData data in reversedDataList)
            {
                viewItem = ContainerFromItem(viewItem, data);
            }

            return(viewItem);
        }
        /// <summary>
        /// Event trigger when a keyboard button is pressed in the watch window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">
        /// Keys accepted:
        /// Delete - to delete an item in the watch window
        /// Enter - to bring up the editing textbox for watch variables
        /// </param>
        private void OnWatchWindowKeyDown(object sender, KeyEventArgs e)
        {
            // Method to delete items from the watch window
            if (e.Key == Key.Delete)
            {
                InspectionData     selectedData = inspectionView.SelectedItem as InspectionData;
                InspectionViewItem parent       = ContainerFromItem(null, selectedData);
                if (null != parent && parent.Level == 0)
                {
                    // Get the sibling item so that we can move selection on it later.
                    InspectionData siblingData = GetSiblingItemFromData(selectedData);

                    InspectionData removedItem = (InspectionData)inspectionView.SelectedItem;
                    if (dataCollection.RemoveInspectionData(inspectionView.SelectedItem))
                    {
                        Solution.Current.RemoveWatchExpressions(removedItem.DisplayText);
                        inspectionView.Items.Refresh();
                    }

                    // Set focus back to the item.
                    InspectionViewItem siblingItem = ContainerFromItem(null, siblingData);
                    if (null != siblingItem)
                    {
                        siblingItem.IsSelected = true;
                    }
                }
            }
            // Method to allow user to bring up the editing textbox in the
            // watch window. This makes usage of watch window easy
            else if (e.Key == Key.Enter)
            {
                ShowVariableEditBox(null);
            }
            else if (e.Key >= Key.A && (e.Key <= Key.Z))
            {
                char character = TextEditorControl.GetKeyboardCharacter(e);
                ShowVariableEditBox(new string(character, 1));
            }
        }
 // This is only to be called from AddDerivation.
 private InspectionData(InspectionData parentData, string expression, int indexer)
 {
     this.arrayIndexer = indexer;
     this.parentData   = parentData;
     SetInitialExpression(expression);
 }
        /// <summary>
        /// This method retrieves the InspectionObject for a variable at any level of the watch window. 
        /// Eg:- a
        ///      -  b
        ///      -  c
        ///         -  d
        ///  The object for 'd' would be retrieved in a two step process
        ///  1. The top most parent is retrieved using the GetTopMostParent method - in this case 'a'
        ///  2. The GetTopMostParent method also tells you if the variable searched for is in the top level or inside
        ///  a child. In this case, bool IsInChild is set to true
        ///  3. Method GetChildObject is used to retrieve the child recursively
        ///  
        /// This is done because the ChildObject cannot be located without the topmost parent Obj
        /// </summary>
        /// <param name="data"> InspectionData object of the variable being searched </param>
        /// <returns> ProtoCore.Lang.Obj object returned for found variable </returns>
        private ProtoCore.Lang.Obj GetInnerInspectionObject(InspectionData data)
        {
            bool IsInChild = false;
            string parent = GetTopMostParent(data, out IsInChild);
            ProtoCore.Lang.Obj parentObj = GetStackValue(parent);

            if (!IsInChild)
                return parentObj;
            else
                return GetChildObject(parentObj, data);
        }
        /// <summary>
        /// Recursively go down the Variable tree child by child till the desired
        /// searched data is met.
        /// </summary>
        /// <param name="parentObj"> Obj object of the parent of the child being searched </param>
        /// <param name="searchedData"> Variable being searched to match child object </param>
        /// <param name="dataSet"> 
        /// if equal to null, it means topmost level parent (dataCollection)
        /// Otherwise send in the InspectedData.Derivations of the child
        /// </param>
        /// <returns></returns>
        private ProtoCore.Lang.Obj GetChildObject(ProtoCore.Lang.Obj parentObj, InspectionData searchedData, ObservableCollection<InspectionData> dataSet = null)
        {
            if (dataSet == null)
                dataSet = dataCollection;

            foreach (InspectionData item in dataSet)
            {
                if ((item.Expression == searchedData.Expression) && (item.Value == searchedData.Value) && (item.Type == searchedData.Type))
                {
                    return parentObj;
                }
                else if (item.HasItems)
                {
                    if (item.Type == "array")
                    {
                        List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(parentObj);
                        foreach (ProtoCore.Lang.Obj element in arrayElements)
                        {
                            ProtoCore.Lang.Obj child = GetChildObject(element, searchedData, item.Derivations);

                            if (null != child)
                                return child;
                        }
                    }
                    else
                    {
                        Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(parentObj);
                        if (null != classProperties)
                        {
                            foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties)
                            {
                                ProtoCore.Lang.Obj child = GetChildObject(property.Value, searchedData, item.Derivations);

                                if (null != child)
                                    return child;
                            }
                        }
                    }
                }
            }

            return null;
        }
        private void ExpandClassInspectionData(InspectionData selectedData)
        {
            // Expansion for a class and class properties
            ProtoCore.Lang.Obj stackValue = GetStackValue(selectedData.Name);
            Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(stackValue);

            if (null != classProperties)
            {
                ObservableCollection<InspectionData> oldDerivations = selectedData.Derivations;
                selectedData.ClearDerivations();

                int index = 0;
                foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties)
                {
                    InspectionData inspectionData = CreateInspectionData(property.Value, property.Key);
                    if (null != inspectionData)
                    {
                        selectedData.AddDerivation(inspectionData);
                        if (null != oldDerivations && (index < oldDerivations.Count))
                            inspectionData.IsExpanded = oldDerivations[index].IsExpanded;
                    }

                    index = index + 1;
                }
            }
        }
        //Recursive system to run through all branches of variable inspected
        public InspectionData MakeInspectionData(ProtoCore.Lang.Obj inspectionObj, string variableName, int limit = 100)
        {
            string stackValueType = GetStackValueType(inspectionObj);
            InspectionData inspectedScope = null;

            if (stackValueType == "int" || stackValueType == "double" || stackValueType == "null" || stackValueType == "bool")
            {
                string n = variableName;
                string v = (inspectionObj.Payload == null) ? ("null") : (inspectionObj.Payload.ToString());
                string t = stackValueType;
                inspectedScope = new InspectionData(n, v, t);
            }
            else if (stackValueType == "array")
            {
                string n = variableName;
                string t = stackValueType;

                List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(inspectionObj);
                int arrayIndex = 0;

                string v = stackValueType + "[" + arrayElements.Count + "]";
                inspectedScope = new InspectionData(n, v, t);

                foreach (ProtoCore.Lang.Obj element in arrayElements)
                {
                    string arrayName = variableName + "[" + arrayIndex + "]";
                    inspectedScope.AddDerivation(MakeInspectionData(element, arrayName));
                    arrayIndex++;
                }
            }
            else
            {
                Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(inspectionObj);

                if (null != classProperties)
                {
                    string n = variableName;
                    string v = stackValueType;
                    string t = stackValueType;

                    inspectedScope = new InspectionData(n, v, t);
                    foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties)
                    {
                        string propName = property.Key;
                        inspectedScope.AddDerivation(MakeInspectionData(property.Value, propName));
                    }
                }
            }

            return inspectedScope;
        }
        /// <summary>
        /// Method to create an inspection data out of a sent variable by talking
        /// to the Virtual machine. The watch window adds the variable with a dummy layer under the expansion. 
        /// The dummy level prevents the Virtual Machine being called too many times, 
        /// and should never be shown to the user.
        /// Eg: Variable name: 'a'
        /// In watch window:
        ///             Name    |Value|Type
        ///             'a'
        ///             - 'This' 'is'  'dummy'
        /// </summary>
        /// <param name="inspectionObj"> Obj type retrieved from Virtual Machine for given variable </param>
        /// <param name="variableName"> Name of the variable to be made into InspectionData </param>
        /// <returns> InspectionData object of the Variable </returns>
        private InspectionData CreateInspectionData(ProtoCore.Lang.Obj inspectionObj, string variableName)
        {
            string stackValueType = GetStackValueType(inspectionObj);
            InspectionData inspectedScope = null;

            if (stackValueType == "int" || stackValueType == "double" || stackValueType == "null" || stackValueType == "bool")
            {
                string n = variableName;
                string v = (inspectionObj.Payload == null) ? ("null") : (inspectionObj.Payload.ToString());
                string t = stackValueType;
                inspectedScope = new InspectionData(n, v, t);
            }
            else if (stackValueType == "array")
            {
                string n = variableName;
                string t = stackValueType;

                List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(inspectionObj);
                int arrayIndex = 0;

                foreach (ProtoCore.Lang.Obj element in arrayElements)
                {
                    string arrayName = variableName + "[" + arrayIndex + "]";
                    arrayIndex++;
                }

                string v = stackValueType + "[" + arrayElements.Count + "]";
                inspectedScope = new InspectionData(n, v, t);

                if (arrayElements.Count > 0)
                {
                    // By adding "this is dummy" into the watch window we aim to prevent overworking the
                    // Virtual Machine and expand only if necessary. Obviously, the user should NEVER see this
                    // so that will be a defect, if ever. This also notifies the XAML binding to show the [+]
                    // next to the watch variable.
                    inspectedScope.AddDerivation(new InspectionData(n, v, t));
                }
            }
            else
            {
                Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(inspectionObj);
                if (null != classProperties)
                {
                    foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties)
                    {
                        string propName = property.Key;
                    }

                    string n = variableName;
                    string v = stackValueType;
                    string t = stackValueType;

                    inspectedScope = new InspectionData(n, v, t);
                    if (classProperties.Count > 0)
                        inspectedScope.AddDerivation(new InspectionData(n, v, t));
                }
            }

            return inspectedScope;
        }
Beispiel #15
0
 // This is only to be called from AddDerivation.
 private InspectionData(InspectionData parentData, string expression, int indexer)
 {
     this.arrayIndexer = indexer;
     this.parentData = parentData;
     SetInitialExpression(expression);
 }
        /// <summary>
        /// 'Expander' is part of the toggle button defined in the XAML that shows the [+] or [-]
        /// sign when there are items under the current watch variable that can be inspected.
        /// To maximise efficiency, the expansion of items must happen only when the expander is clicked
        /// when showing [+]. This generated the child items from the Virtual Machine.
        /// </summary>
        /// <param name="sender"> The sender is the Toggle Button</param>
        /// <param name="e"></param>
        private void OnExpanderClicked(object sender, RoutedEventArgs e)
        {
            ToggleButton expanderToggle = (ToggleButton)sender;

            if (null == expanderToggle)
            {
                return;
            }

            // The parent we are trying to locate here is the InspectionViewItem. The
            // expander is buried beneath several layers of stackpanels and grids under the Item
            // and therefore we have to make numerous calls to find the InspectionViewItem.
            InspectionViewItem parent = (InspectionViewItem)VisualTreeHelper.GetParent
                                            (VisualTreeHelper.GetParent
                                                (VisualTreeHelper.GetParent
                                                    (VisualTreeHelper.GetParent
                                                        (VisualTreeHelper.GetParent
                                                            (VisualTreeHelper.GetParent(expanderToggle))))));

            object         data         = ((null == parent) ? null : parent.DataContext);
            InspectionData selectedData = data as InspectionData;

            if (null == selectedData)
            {
                return;
            }

            // expanderToggle.IsChecked == true means the [+] --> [-]
            if (expanderToggle.IsChecked == true)
            {
                parent.IsExpanded = false;
                dataCollection.ExpandInspection(selectedData);
                parent.IsExpanded = true;

                UpdateExpansionStates();
                inspectionView.Items.Refresh();
                DoExpansion(dataCollection.Data);

#if false
                parent.IsExpanded = false;
                InspectionData selectedData = (InspectionData)parent.DataContext;
                dataCollection.ExpandInspection(selectedData);

                // If there is a large amount of data, the user may have to wait.
                // This is indicated by updating the mouse cursor.
                Mouse.SetCursor(Cursors.Wait);
                parent.IsSelected       = true;
                parent.IsExpanded       = true;
                selectedData.IsExpanded = true;

                UpdateExpansionStates();
                inspectionView.Items.Refresh();
                DoExpansion(dataCollection.Data);
                Mouse.SetCursor(Cursors.Arrow);
#endif
            }

            // Select the item that is currently being expanded/collapsed.
            InspectionViewItem itemToSelect = ContainerFromItem(selectedData);
            if (null != itemToSelect)
            {
                itemToSelect.IsSelected = true;
            }
        }
        /// <summary>
        /// Method to add new inspection data to the Watch Window/ToolTip
        /// This method uses the CreateInspectionData method to populate the information
        /// </summary>
        /// <param name="variableName"> Name of the variable to be added </param>
        /// <returns>
        /// True - if successfully added
        /// False - if exception was thrown
        /// </returns>
        public bool AddInspectionData(string variableName, bool isToolTip)
        {
            inspectionToolTip = isToolTip;
            if (false != inspectionToolTip)
                dataCollection.Clear();

            if (string.IsNullOrWhiteSpace(variableName))
                return false;

            // Always leave last item as  blank data
            InspectionData data = new InspectionData(variableName);
            if (dataCollection.Count == 0)
                dataCollection.Add(data);
            else
                dataCollection.Insert(dataCollection.Count - 1, data);

            // Inspection tool tip requires immediate validation.
            if (false != inspectionToolTip)
                CreateDataRecursive(data, GetStackValue(variableName));

            return true;
            #if false

            if (isToolTip)
            {
                toolTips = true;
                dataCollection.Clear();
            }

            if (string.IsNullOrWhiteSpace(variableName))
                return false;

            ProtoCore.Lang.Obj stackValue = null;
            InspectionParser parser = new InspectionParser(variableName);
            variableName = variableName.Trim();
            bool limit = false;
            int limitValue = 0;
            if (parser.NeedsParsing())
            {
                List<string> parsedCommands = parser.GetParsedCommands();
                if (parser.IsValid == true)
                {
                    stackValue = GetParsedObject(parsedCommands, out limit);
                    if (limit)
                    {
                        string val = parsedCommands[parsedCommands.Count - 1].Replace(",", string.Empty);
                        limitValue = Convert.ToInt32(val);
                    }
                }
                else
                    stackValue = null;
            }
            else
            {
                stackValue = GetStackValue(variableName);
            }

            if (stackValue == null)
            {
                //Throw exceptions
                string n = variableName;
                string v = GetStackValuePayload(n);
                string t = GetStackValueType(n);

                // Always leave last item as  blank data
                if (dataCollection.Count != 0)
                    dataCollection.Insert(dataCollection.Count - 1, new InspectionData(n, v, t));
                else
                    dataCollection.Add(new InspectionData(n, v, t));

                return false;
            }
            else
            {
                //Get actual data
                InspectionData inspectedData;
                inspectedData = CreateInspectionData(stackValue, variableName);

                if (dataCollection.Count != 0)
                    dataCollection.Insert(dataCollection.Count - 1, inspectedData);
                else
                    dataCollection.Add(inspectedData);

                return true;
            }
            #endif
        }
        private void CreateDataRecursive(InspectionData inspectionData, ProtoCore.Lang.Obj stackValue)
        {
            if (null == stackValue || null == stackValue.Payload)
            {
                inspectionData.Type = string.Empty;
                inspectionData.Value = string.Empty;
                if (!string.IsNullOrEmpty(inspectionData.DisplayText))
                    inspectionData.Value = "null";

                inspectionData.ClearDerivations();
                return;
            }

            inspectionData.OpType = stackValue.DsasmValue.optype;

            switch (stackValue.DsasmValue.optype)
            {
                case ProtoCore.DSASM.AddressType.ArrayPointer: // Array type
                    {
                        inspectionData.Type = "array";
                        inspectionData.Value = "array";

                        if (false == inspectionData.IsExpanded)
                        {
                            // If we are looking at an array, then make sure it
                            // at least have an empty child data (so that HasItems
                            // property returns "true"). This child data can later
                            // be replaced by the actual value upon expansion.
                            if (false == inspectionData.HasItems)
                            {
                                string parentExpression = inspectionData.Expression;
                                inspectionData.AddDerivation(parentExpression, 0);
                            }
                        }
                        else
                        {
                            List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(stackValue);
                            int elementCount = ((null == arrayElements) ? 0 : arrayElements.Count);
                            inspectionData.Type = string.Format("array[{0}]", elementCount);
                            inspectionData.Value = inspectionData.Type;

                            if (inspectionData.Derivations != null)
                                ShrinkDerivations(inspectionData, elementCount);

                            int elementsToDisplay = elementCount;
                            if (inspectionData.ExpansionLimit > 0)
                            {
                                elementsToDisplay = inspectionData.ExpansionLimit;
                                if (elementsToDisplay > elementCount)
                                    elementsToDisplay = elementCount;
                            }

                            string parentExpression = inspectionData.Expression;
                            for (int index = 0; index < elementsToDisplay; ++index)
                            {
                                InspectionData childData = inspectionData.GetDrivationAtIndex(index);
                                if (null == childData)
                                    childData = inspectionData.AddDerivation(parentExpression, index);

                                CreateDataRecursive(childData, arrayElements[index]);
                            }
                        }

                        break;
                    }

                case ProtoCore.DSASM.AddressType.Pointer: // Class type
                    {
                        if (inspectionData.Expression.Equals("this") && (Int64)stackValue.Payload == -1)
                        {
                            inspectionData.Type = "Invalid";
                            inspectionData.Value = "null";
                            break;
                        }

                        inspectionData.Type = GetStackValueType(stackValue);
                        inspectionData.Value = GetStackValueData(stackValue);

                        if (false == inspectionData.IsExpanded)
                        {
                            // If we are looking at a class, then make sure it
                            // at least have an empty child data (so that HasItems
                            // property returns "true"). This child data can later
                            // be replaced by the actual value upon expansion.
                            if (false == inspectionData.HasItems)
                                inspectionData.AddDerivation(string.Empty, -1);
                        }
                        else
                        {
                            // Expansion for a class and class properties
                            Dictionary<string, ProtoCore.Lang.Obj> properties = GetClassProperties(stackValue);
                            if (null == properties || (properties.Count <= 0))
                                return;

                            if (inspectionData.Derivations != null)
                                ShrinkDerivations(inspectionData, properties.Count);

                            int index = 0;
                            foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in properties)
                            {
                                InspectionData childData = inspectionData.GetDrivationAtIndex(index);
                                if (null == childData)
                                    childData = inspectionData.AddDerivation(property.Key, -1);

                                // The first child data that was created before this class gets
                                // expanded may not have the appropriate expression to begin with,
                                // so set it here...
                                childData.Expression = property.Key;

                                if (null != property.Value)
                                    CreateDataRecursive(childData, property.Value);
                                else
                                {
                                    // This may be an external property, try evaluating it for value.
                                    string qualifiedName = childData.GetQualifiedName();
                                    ProtoCore.Lang.Obj childStackValue = GetStackValue(qualifiedName);
                                    CreateDataRecursive(childData, childStackValue);
                                }

                                index = index + 1;
                            }
                        }

                        break;
                    }
                case ProtoCore.DSASM.AddressType.String:
                case ProtoCore.DSASM.AddressType.Char:
                    {
                        inspectionData.Type = GetStackValueType(stackValue);
                        inspectionData.Value = GetStackValueData(stackValue);
                        inspectionData.ClearDerivations();
                        break;
                    }
                default: // This applies to all other primitive types.
                    {
                        inspectionData.Type = GetStackValueType(stackValue);
                        inspectionData.Value = GetStackValuePayload(stackValue);
                        inspectionData.ClearDerivations();
                        break;
                    }
            }
        }
        /// <summary>
        /// This method is used to retrieve the index of an item that is selected. This method
        /// will only return the Parent Index of the selected so child items will return -1
        /// </summary>
        /// <param name="item"> InspectionData item selected </param>
        /// <returns></returns>
        public int GetParentIndex(InspectionData itemSelected)
        {
            int index = 0;
            foreach (InspectionData data in dataCollection)
            {
                if (itemSelected.Expression == data.Expression &&
                    itemSelected.Value == data.Value &&
                    itemSelected.Type == data.Type)
                {
                    break;
                }

                index++;
            }

            // The item selected is either not a parent item or doesn't exist
            if (index >= dataCollection.Count)
                return -1;

            return index;
        }
        /// <summary>
        /// This method is hit on one condition: the variable CAN be expanded by pressing the [+] 
        /// symbol in the watch window. This means some sort of expansion should replace the silly old
        /// 'This is dummy' and populate it. This method goes about populating the selectedData.Derivations
        /// for arrays and classes (which are the only expandable variables in a watch window). 
        /// For arrays, this method also tests if the array is larger than a certain value, indicating to
        /// the user that it may take some time to expand.
        /// </summary>
        /// <param name="selectedData"> InspectionData object of the variable that is to be expanded</param>
        public void ExpandInspection(InspectionData selectedData)
        {
            selectedData.IsExpanded = true;
            string qualifiedName = selectedData.GetQualifiedName();
            ProtoCore.Lang.Obj stackValue = GetStackValue(qualifiedName);
            CreateDataRecursive(selectedData, stackValue);
            #if false
            ProtoCore.Lang.Obj dataObj = null;

            // Use Inspection Parser to parse the string to decipher what kind of expansion required
            InspectionParser parser = new InspectionParser(selectedData.Name);
            bool limit = false;
            int limitValue = 0;
            List<string> parsedCommands = null;

            // An inspection variable needs parsing when it contains:
            // [] (array) and/or
            // '.' (class properties) and/or
            // ',' (limit)
            if (parser.NeedsParsing())
            {
                parsedCommands = parser.GetParsedCommands();
                if (parser.IsValid == true)
                {
                    // Use GetParsedObject method to decipher Obj from parsed string
                    dataObj = GetParsedObject(parsedCommands, out limit);

                    // A limit is indicated by a comma (,)
                    if (limit)
                    {
                        // The limit should ALWAYS be the last item in parsed commands
                        string val = parsedCommands[parsedCommands.Count - 1].Replace(",", string.Empty);
                        limitValue = Convert.ToInt32(val);
                    }
                }
                else
                    dataObj = null;
            }
            else
            {
                dataObj = GetInnerInspectionObject(selectedData);
            }

            // If, from any level above the dataObj is null, throw an exception
            if (dataObj == null)
            {
                //Throw exceptions
                string n = selectedData.Name;
                string v = GetStackValuePayload(n);
                string t = GetStackValueType(n);

                // Replace the current data with the exceptions relevant for it
                RemoveInspectionData(selectedData);
                dataCollection.Insert(dataCollection.Count - 1, new InspectionData(n, v, t));
            }
            // Otherwise expand it by one more level yo!
            else
            {
                if (selectedData.Type == "array")
                    ExpandArrayInspectionData(selectedData, limit);
                else
                    ExpandClassInspectionData(selectedData);
            }

            #endif
        }
        private void ExpandArrayInspectionData(InspectionData selectedData, bool limitExpansion)
        {
            ProtoCore.Lang.Obj stackValue = GetStackValue(selectedData.Name);
            List<ProtoCore.Lang.Obj> arrayStackValues = GetArrayStackValues(stackValue);

            ObservableCollection<InspectionData> derivations = new ObservableCollection<InspectionData>();
            int arrayIndex = 0;

            // Give user a notification if a large number of array elements are expanded
            // The limit set is located at Configurations.InspectionArrayLimit
            if ((arrayStackValues.Count > Configurations.InspectionArrayLimit) && !limitExpansion)
            {
                string message = "This array has a large number of items. Displaying may take several seconds. " +
                    "Show all elements anyway? Alternatively you can choose 'No' and limit your array expansion " +
                    "by adding a comma (,) after your variable followed by the number of elements to be shown.";

                MessageBoxResult result = MessageBox.Show(message, "Inspection", MessageBoxButton.YesNo);

                // If user chooses 'Yes' expand all items
                if (result == MessageBoxResult.Yes)
                {
                    foreach (ProtoCore.Lang.Obj element in arrayStackValues)
                    {
                        // Array name should be represented like a[3] for each element
                        string arrayName = (limit ? parsedCommands[0] : selectedData.Name) + "[" + arrayIndex + "]";
                        derivations.Add(CreateInspectionData(element, arrayName));
                        arrayIndex++;

                        if ((limit) && (derivations.Count > limitValue))
                        {
                            break;
                        }
                    }
                    // Value for an array is represented like array[10]
                    string v = selectedData.Type + "[" + arrayStackValues.Count + "]";
                    for (int i = 0; i < selectedData.Derivations.Count; i++)
                    {
                        if (selectedData.Derivations[i].IsExpanded == true)
                        {
                            if (i < derivations.Count)
                                derivations[i].IsExpanded = true;
                        }
                    }

                    selectedData.Derivations = derivations;
                }
            }
            // If there was no limit reached, proceed as normal
            else
            {
                foreach (ProtoCore.Lang.Obj element in arrayStackValues)
                {
                    string arrayName = (limit ? parsedCommands[0] : selectedData.Name) + "[" + arrayIndex + "]";
                    derivations.Add(CreateInspectionData(element, arrayName));
                    arrayIndex++;

                    if ((limit) && (derivations.Count > limitValue))
                    {
                        break;
                    }
                }

                string v = selectedData.Type + "[" + arrayStackValues.Count + "]";

                for (int i = 0; i < selectedData.Derivations.Count; i++)
                {
                    if (selectedData.Derivations[i].IsExpanded == true)
                    {
                        if (i < derivations.Count)
                            derivations[i].IsExpanded = true;
                    }
                }

                selectedData.Derivations = derivations;
            }
        }
 private void ShrinkDerivations(InspectionData inspectionData, int elementCount)
 {
     for (int i = inspectionData.Derivations.Count - 1; i >= elementCount; i--)
         inspectionData.Derivations.RemoveAt(i);
 }
        /// <summary>
        /// Retrieves the top-most parent for any InspectionData variable
        /// </summary>
        /// <param name="dataSearched"> InspectionData variable being searched </param>
        /// <param name="IsInChild"> out parameter that toggles to false if  top most parent is dataSearched, else false</param>
        /// <returns> Name of topmost parent of variable </returns>
        private string GetTopMostParent(InspectionData dataSearched, out bool IsInChild)
        {
            foreach (InspectionData item in dataCollection)
            {
                if (CheckChildren(item.Derivations, dataSearched) == true)
                {
                    IsInChild = true;
                    return item.Expression;
                }
                else if ((item.Expression == dataSearched.Expression) && (item.Value == dataSearched.Value) && (item.Type == dataSearched.Type))
                {
                    IsInChild = false;
                    return item.Expression;
                }
            }

            IsInChild = false;
            return null;
        }
        /// <summary>
        /// Recursively go down the Variable tree child by child to see if there is a valid child in the dataSet
        /// </summary>
        /// <param name="dataSet"> 
        /// if equal to null, it means there is no further dataSet to search so return false
        /// Else, send in InspectionData.Derivations
        /// </param>
        /// <param name="dataSearched"> InspectionData variable being searched </param>
        /// <returns> True id a child is found, false if no child</returns>
        private bool CheckChildren(ObservableCollection<InspectionData> dataSet, InspectionData dataSearched)
        {
            if (dataSet == null)
                return false;

            foreach (InspectionData item in dataSet)
            {
                if ((item.Expression == dataSearched.Expression) && (item.Value == dataSearched.Value) && (item.Type == dataSearched.Type))
                {
                    return true;
                }
                else if (item.HasItems)
                {
                    return CheckChildren(item.Derivations, dataSearched);
                }
            }

            return false;
        }
Beispiel #25
0
        internal InspectionData AddDerivation(string childExpression, int childIndexer)
        {
            if (null == derivations)
                derivations = new ObservableCollection<InspectionData>();

            InspectionData data = new InspectionData(this, childExpression, childIndexer);
            derivations.Add(data);
            return data;
        }