private async Task EnqueueProcessSnapshotWorkerAsync(Document currentDocument, CancellationToken cancellationToken)
            {
                // we will enqueue new one soon, cancel pending refresh right away
                _reportChangeCancellationSource.Cancel();

                var currentText = await currentDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

                var currentSnapshot = currentText.FindCorrespondingEditorTextSnapshot();

                if (currentSnapshot == null)
                {
                    // It's possible that we're seeing a notification for an update that happened
                    // just before the file was opened, and so the document we're given is still the
                    // old one.
                    return;
                }

                object       currentCachedData;
                SnapshotSpan changedSpan;

                using (var _ = new RequestLatencyTracker(SyntacticLspLogger.RequestType.SyntacticTagger))
                {
                    var service = TryGetClassificationService(currentSnapshot);

                    // preemptively allow the classification service to compute and cache data for this file.  For
                    // example, in C# and VB we will parse the file so that are called from tagger from UI thread,
                    // we have the root of the tree ready to go.
                    currentCachedData = service == null
                        ? null
                        : await service.GetDataToCacheAsync(currentDocument, cancellationToken).ConfigureAwait(false);

                    // Query the service to determine waht span of the document actually changed and should be
                    // reclassified in the host editor.
                    changedSpan = await GetChangedSpanAsync(currentDocument, currentSnapshot, cancellationToken).ConfigureAwait(false);
                }

                lock (_gate)
                {
                    _lastProcessedSnapshot   = currentSnapshot;
                    _lastProcessedDocument   = currentDocument;
                    _lastProcessedCachedData = currentCachedData;
                }

                _reportChangeCancellationSource = new CancellationTokenSource();
                _notificationService.RegisterNotification(() =>
                {
                    _workQueue.AssertIsForeground();
                    ReportChangedSpan(changedSpan);
                },
                                                          ReportChangeDelayInMilliseconds,
                                                          _listener.BeginAsyncOperation("ReportEntireFileChanged"),
                                                          _reportChangeCancellationSource.Token);
            }
示例#2
0
            private async Task EnqueueProcessSnapshotWorkerAsync(Document document, CancellationToken cancellationToken)
            {
                // we will enqueue new one soon, cancel pending refresh right away
                _reportChangeCancellationSource.Cancel();

                var newText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                var snapshot = newText.FindCorrespondingEditorTextSnapshot();

                if (snapshot == null)
                {
                    // It's possible that we're seeing a notification for an update that happened
                    // just before the file was opened, and so the document we're given is still the
                    // old one.
                    return;
                }

                var latencyTracker = new RequestLatencyTracker(SyntacticLspLogger.RequestType.SyntacticTagger);

                using (latencyTracker)
                {
                    // preemptively parse file in background so that when we are called from tagger from UI thread, we have tree ready.
                    // F#/typescript and other languages that doesn't support syntax tree will return null here.
                    _ = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                }

                lock (_gate)
                {
                    _lastProcessedSnapshot = snapshot;
                    _lastProcessedDocument = document;
                }

                _reportChangeCancellationSource = new CancellationTokenSource();
                _notificationService.RegisterNotification(() =>
                {
                    _workQueue.AssertIsForeground();
                    ReportChangedSpan(snapshot.GetFullSpan());
                },
                                                          ReportChangeDelayInMilliseconds,
                                                          _listener.BeginAsyncOperation("ReportEntireFileChanged"),
                                                          _reportChangeCancellationSource.Token);
            }