Microsoft.R.Editor.Tree.EditorTree.InvalidateInRange C# (CSharp) Method

InvalidateInRange() private method

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 node removal intellisense and syntax checker may end up processing nodes that are out of date. Where possible stops at the nearest scope level so scope nodes may still be used in smart indenter.
private InvalidateInRange ( ITextRange range ) : bool
range ITextRange Range to invalidate elements in
return bool
        internal bool InvalidateInRange(ITextRange range) {
            var removedElements = new List<IAstNode>();
            int firstToRemove = -1;
            int lastToRemove = -1;

            var node = AstRoot.NodeFromRange(range);
            var scope = node as IScope;
            while (scope == null || scope.OpenCurlyBrace == null || scope.CloseCurlyBrace == null ||
                    TextRange.Intersect(range, scope.OpenCurlyBrace) || TextRange.Intersect(range, scope.CloseCurlyBrace)) {
                scope = node.GetEnclosingScope();
                if(scope is GlobalScope) {
                    break;
                }
                node = scope;
            }

            for (int i = 0; i < scope.Children.Count; i++) {
                var child = scope.Children[i];
                if (TextRange.Intersect(range, child)) {
                    if (firstToRemove < 0) {
                        firstToRemove = i;
                    } else {
                        lastToRemove = i;
                    }
                }
            }

            if (firstToRemove >= 0) {
                if(lastToRemove < 0) {
                    lastToRemove = firstToRemove;
                }
                for (int i = firstToRemove; i <= lastToRemove; i++) {
                    IAstNode child = scope.Children[i];
                    removedElements.Add(child);
                    _astRoot.Errors.RemoveInRange(child);
                }
                scope.RemoveChildren(firstToRemove, lastToRemove - firstToRemove + 1);
            }

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

            return false;
        }

Usage Example

Example #1
0
        /// <summary>
        /// Handles non-trivial changes like changes that delete elements,
        /// change identifier names, introducing new braces: changes
        /// that cannot be handled without background parse.
        /// </summary>
        private void ProcessComplexChange(TextChangeContext context)
        {
            // Cancel background parse if it is running
            Cancel();

            TextChange textChange = new TextChange()
            {
                OldTextProvider = context.OldTextProvider,
                NewTextProvider = context.NewTextProvider
            };

            try {
                // Get write lock since there may be concurrent readers
                // of the tree. Note that there are no concurrent writers
                // since changes can only come from a background parser
                // and are always applied from the main thread.
                _editorTree.AcquireWriteLock();

                if (_pendingChanges.FullParseRequired)
                {
                    // When full parse is required, change is like replace the entire file
                    textChange.OldRange = TextRange.FromBounds(0, context.OldText.Length);
                    textChange.NewRange = TextRange.FromBounds(0, context.NewText.Length);

                    // Remove damaged elements if any and reflect text change.
                    // Although we are invalidating the AST next, old copy will
                    // be kept for operations that may need it such as smart indent.
                    bool elementsChanged;
                    _editorTree.InvalidateInRange(_editorTree.AstRoot, context.OldRange, out elementsChanged);
                    _editorTree.NotifyTextChange(context.NewStart, context.OldLength, context.NewLength);
                    // Invalidate will store existing AST as previous snapshot
                    // and create temporary empty AST until the next async parse.
                    _editorTree.Invalidate();
                }
                else
                {
                    textChange.OldRange = context.OldRange;
                    textChange.NewRange = context.NewRange;

                    DeleteAndShiftElements(context);
                    Debug.Assert(_editorTree.AstRoot.Children.Count > 0);
                }

                _pendingChanges.Combine(textChange);
                _pendingChanges.Version = TextBuffer != null ? TextBuffer.CurrentSnapshot.Version.VersionNumber : 1;

                UpdateTreeTextSnapshot();
            } finally {
                // Lock must be released before firing events otherwise we may hang
                _editorTree.ReleaseWriteLock();
            }

            _editorTree.FireOnUpdateCompleted(TreeUpdateType.NodesRemoved);
        }
All Usage Examples Of Microsoft.R.Editor.Tree.EditorTree::InvalidateInRange