Esempio n. 1
0
        /// <summary>
        /// Removes nodes from the tree collection if node range is
        /// // partially or entirely within the deleted region.
        /// This is needed since parsing is asynchronous and without
        /// removing damaged nodes so intellisense will still be able
        /// to find them in the tree which actually they are gone.
        /// Returns true if full parse required.
        /// </summary>
        /// <param name="node">Node to start from</param>
        /// <param name="range">Range to invalidate elements in</param>
        internal bool InvalidateInRange(IAstNode node, ITextRange range, out bool nodesChanged)
        {
            var  removedElements   = new List <IAstNode>();
            bool fullParseRequired = false;
            int  firstToRemove     = -1;
            int  lastToRemove      = -1;

            nodesChanged = false;

            for (int i = 0; i < node.Children.Count; i++)
            {
                var  child       = node.Children[i];
                bool removeChild = false;

                if (range.Start == child.Start && range.Length == 0)
                {
                    // Change is right before the node
                    break;
                }

                if (!removeChild && TextRange.Intersect(range, child))
                {
                    bool childElementsChanged;

                    if (child is TokenNode)
                    {
                        childElementsChanged = true;
                        fullParseRequired    = true;
                        nodesChanged         = true;
                    }
                    else
                    {
                        fullParseRequired |= InvalidateInRange(child, range, out childElementsChanged);
                        if (childElementsChanged)
                        {
                            nodesChanged = true;
                        }
                    }

                    removeChild = true;
                }

                if (removeChild)
                {
                    if (firstToRemove < 0)
                    {
                        firstToRemove = i;
                    }

                    lastToRemove = i;
                }
            }

            if (firstToRemove >= 0)
            {
                for (int i = firstToRemove; i <= lastToRemove; i++)
                {
                    IAstNode child = node.Children[i];
                    removedElements.Add(child);

                    _astRoot.Errors.RemoveInRange(child);
                }

                node.RemoveChildren(firstToRemove, lastToRemove - firstToRemove + 1);
            }

            if (removedElements.Count > 0)
            {
                nodesChanged = true;
                FireOnNodesRemoved(removedElements);
            }

            return(fullParseRequired);
        }
Esempio n. 2
0
        /// <summary>
        /// Removes nodes from the tree collection if node range is 
        /// // partially or entirely within the deleted region.
        /// This is needed since parsing is asynchronous and without
        /// removing damaged nodes so intellisense will still be able
        /// to find them in the tree which actually they are gone.
        /// Returns true if full parse required.
        /// </summary>
        /// <param name="node">Node to start from</param>
        /// <param name="range">Range to invalidate elements in</param>
        internal bool InvalidateInRange(IAstNode node, ITextRange range, out bool nodesChanged) {
            var removedElements = new List<IAstNode>();
            bool fullParseRequired = false;
            int firstToRemove = -1;
            int lastToRemove = -1;

            nodesChanged = false;

            for (int i = 0; i < node.Children.Count; i++) {
                var child = node.Children[i];
                bool removeChild = false;

                if (range.Start == child.Start && range.Length == 0) {
                    // Change is right before the node
                    break;
                }

                if (!removeChild && TextRange.Intersect(range, child)) {
                    bool childElementsChanged;

                    if (child is TokenNode) {
                        childElementsChanged = true;
                        fullParseRequired = true;
                        nodesChanged = true;
                    } else {
                        fullParseRequired |= InvalidateInRange(child, range, out childElementsChanged);
                        if (childElementsChanged) {
                            nodesChanged = true;
                        }
                    }

                    removeChild = true;
                }

                if (removeChild) {
                    if (firstToRemove < 0)
                        firstToRemove = i;

                    lastToRemove = i;
                }
            }

            if (firstToRemove >= 0) {
                for (int i = firstToRemove; i <= lastToRemove; i++) {
                    IAstNode child = node.Children[i];
                    removedElements.Add(child);

                    _astRoot.Errors.RemoveInRange(child);
                }

                node.RemoveChildren(firstToRemove, lastToRemove - firstToRemove + 1);
            }

            if (removedElements.Count > 0) {
                nodesChanged = true;
                FireOnNodesRemoved(removedElements);
            }

            return fullParseRequired;
        }