Asynchronous text change processing task
Inheritance: Microsoft.Languages.Editor.Tasks.CancellableTask
Example #1
0
 /// <summary>
 /// Initiates processing of pending changes synchronously.
 /// </summary>
 internal void ProcessChanges()
 {
     if (this.IsDirty)
     {
         TreeUpdateTask.ProcessPendingTextBufferChanges(false);
     }
 }
Example #2
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (TextBuffer != null)
                {
                    if (Closing != null)
                    {
                        Closing(this, null);
                    }

                    if (TreeUpdateTask != null)
                    {
                        TreeUpdateTask.Dispose();
                        TreeUpdateTask = null;
                    }

                    if (TreeLock != null)
                    {
                        TreeLock.Dispose();
                        TreeLock = null;
                    }

                    TextBuffer.ChangedHighPriority -= OnTextBufferChanged;
                    TextBuffer = null;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Builds initial AST. Subsequent updates should be coming from a background thread.
        /// </summary>
        public void Build()
        {
            if (_ownerThread != Thread.CurrentThread.ManagedThreadId)
            {
                throw new ThreadStateException("Method should only be called on the main thread");
            }

            var sw = Stopwatch.StartNew();

            TreeUpdateTask.Cancel();

            if (TextBuffer != null)
            {
                TextSnapshot = TextBuffer.CurrentSnapshot;
                _astRoot     = RParser.Parse(new TextProvider(TextBuffer.CurrentSnapshot));
            }

            TreeUpdateTask.ClearChanges();

            // Fire UpdatesPending notification, even though we don't have ranges for the event
            List <TextChangeEventArgs> textChanges = new List <TextChangeEventArgs>();

            FireOnUpdatesPending(textChanges);

            FireOnUpdateBegin();
            FireOnUpdateCompleted(TreeUpdateType.NewTree);

            sw.Stop();
        }
Example #4
0
        /// <summary>
        /// Creates document tree on a given text buffer.
        /// </summary>
        /// <param name="textBuffer">Text buffer</param>
        public EditorTree(ITextBuffer textBuffer)
        {
            _ownerThread = Thread.CurrentThread.ManagedThreadId;

            TextBuffer = textBuffer;
            TextBuffer.ChangedHighPriority += OnTextBufferChanged;

            TreeUpdateTask = new TreeUpdateTask(this);
            TreeLock       = new EditorTreeLock();
        }
Example #5
0
        /// <summary>
        /// Creates document tree on a given text buffer.
        /// </summary>
        /// <param name="textBuffer">Text buffer</param>
        /// <param name="shell"></param>
        public EditorTree(ITextBuffer textBuffer, ICoreShell shell, IExpressionTermFilter filter = null)
        {
            _ownerThread         = Thread.CurrentThread.ManagedThreadId;
            ExpressionTermFilter = filter;

            TextBuffer = textBuffer;
            TextBuffer.ChangedHighPriority += OnTextBufferChanged;

            TreeUpdateTask = new TreeUpdateTask(this, shell);
            TreeLock       = new EditorTreeLock();
        }
Example #6
0
 /// <summary>
 /// Initiates processing of pending changes asynchronously. When processing
 /// completes, tree will invoke completion callback on UI thread. Useful when building
 /// completion/intellisense list asynchronously.
 /// </summary>
 public void ProcessChangesAsync(Action treeUpdateCompleteCallback)
 {
     if (this.IsDirty)
     {
         TreeUpdateTask.RegisterCompletionCallback(treeUpdateCompleteCallback);
         TreeUpdateTask.ProcessPendingTextBufferChanges(true);
     }
     else
     {
         treeUpdateCompleteCallback.Invoke();
     }
 }
Example #7
0
        /// <summary>
        /// Ensures tree is up to date, matches current text buffer snapshot
        /// and all changes since the last update were processed. Blocks until
        /// all changes have been processed. Does not pump messages.
        /// </summary>
        public void EnsureTreeReady()
        {
            if (TreeUpdateTask == null)
            {
                return;
            }

            if (_ownerThread != Thread.CurrentThread.ManagedThreadId)
            {
                throw new ThreadStateException("Method should only be called on the main thread");
            }

            // OK to run in sync if changes are pending since we need it updated now
            TreeUpdateTask.EnsureProcessingComplete();
        }
Example #8
0
 private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e)
 {
     if (e.Changes.Count > 0)
     {
         // In case of tabbing multiple lines update comes as multiple changes
         // each is an insertion of whitespace in the beginning of the line.
         // We don't want to combine them since then change will technically
         // damage existing elements while actually it is just a whitespace change.
         // All changes are relative to the current snapshot hence we have to transform
         // them first and make them relative to each other so we can apply changes
         // sequentially as after every change element positions will shift and hence
         // next change must be relative to the new position and not to the current
         // text buffer snapshot. Changes are sorted by position.
         TreeUpdateTask.OnTextChanges(e.ConvertToRelative());
     }
 }
Example #9
0
 /// <summary>
 /// Provides a way to automatically invoke particular action
 /// once when tree becomes ready again. Typically used in
 /// asynchronous completion and signature help scenarios.
 /// </summary>
 /// <param name="action">Action to invoke</param>
 /// <param name="p">Parameter to pass to the action</param>
 /// <param name="type">Action identifier</param>
 /// <param name="processNow">
 /// If true, change processing begins now.
 /// If false, next regular parsing pass with process pending changes.
 /// </param>
 public void InvokeWhenReady(Action <object> action, object p, Type type, bool processNow = false)
 {
     if (IsReady)
     {
         action(p);
     }
     else
     {
         _actionsToInvokeOnReady[type] = new TreeReadyAction()
         {
             Action = action, Parameter = p
         };
         if (processNow)
         {
             TreeUpdateTask.ProcessPendingTextBufferChanges(async: true);
         }
     }
 }
Example #10
0
 /// <summary>
 /// Makes current thread owner of the tree.
 /// Normally only one thread can access the tree.
 /// </summary>
 internal void TakeThreadOwnerShip()
 {
     _ownerThread = Thread.CurrentThread.ManagedThreadId;
     TreeUpdateTask.TakeThreadOwnership();
     TreeLock.TakeThreadOwnership();
 }
Example #11
0
        /// <summary>
        /// Creates document tree on a given text buffer.
        /// </summary>
        /// <param name="textBuffer">Text buffer</param>
        public EditorTree(ITextBuffer textBuffer) {
            _ownerThread = Thread.CurrentThread.ManagedThreadId;

            TextBuffer = textBuffer;
            TextBuffer.ChangedHighPriority += OnTextBufferChanged;

            TreeUpdateTask = new TreeUpdateTask(this);
            TreeLock = new EditorTreeLock();
        }
Example #12
0
        /// <summary>
        /// Creates document tree on a given text buffer.
        /// </summary>
        /// <param name="textBuffer">Text buffer</param>
        /// <param name="shell"></param>
        public EditorTree(ITextBuffer textBuffer, ICoreShell shell, IExpressionTermFilter filter = null) {
            _ownerThread = Thread.CurrentThread.ManagedThreadId;
            ExpressionTermFilter = filter;

            TextBuffer = textBuffer;
            TextBuffer.ChangedHighPriority += OnTextBufferChanged;

            TreeUpdateTask = new TreeUpdateTask(this, shell);
            TreeLock = new EditorTreeLock();
        }