public override void UntrackDocument(ITextBuffer buffer) { if (buffer is null) { throw new ArgumentNullException(nameof(buffer)); } Debug.Assert(_joinableTaskContext.IsOnMainThread); var uri = _fileUriProvider.GetOrCreate(buffer); if (!_documents.TryGetValue(uri, out var lspDocument)) { // We don't know about this document, noop. return; } // Given we're no longer tracking the document we don't want to pin the Uri to the current state of the buffer (could have been renamed to another Uri). _fileUriProvider.Remove(buffer); if (_documents.TryRemove(uri, out _)) { var args = new LSPDocumentChangeEventArgs(lspDocument.CurrentSnapshot, @new: null, LSPDocumentChangeKind.Removed); Changed?.Invoke(this, args); } else { Debug.Fail($"Couldn't remove {uri.AbsolutePath}. This should never ever happen."); } lspDocument.Dispose(); }
public override void UpdateVirtualDocument <TVirtualDocument>( Uri hostDocumentUri, IReadOnlyList <ITextChange> changes, long hostDocumentVersion) { if (hostDocumentUri is null) { throw new ArgumentNullException(nameof(hostDocumentUri)); } if (changes is null) { throw new ArgumentNullException(nameof(changes)); } Debug.Assert(_joinableTaskContext.IsOnMainThread); if (!_documents.TryGetValue(hostDocumentUri, out var lspDocument)) { // Don't know about document, noop. return; } var virtualDocumentAcquired = lspDocument.TryGetVirtualDocument <TVirtualDocument>(out var virtualDocument); if (changes.Count == 0 && virtualDocumentAcquired && virtualDocument.HostDocumentSyncVersion == hostDocumentVersion) { // The current virtual document already knows about this update. Ignore it so we don't prematurely invoke a change event. return; } var old = lspDocument.CurrentSnapshot; var oldVirtual = virtualDocument.CurrentSnapshot; var @new = lspDocument.UpdateVirtualDocument <TVirtualDocument>(changes, hostDocumentVersion); if (old == @new) { return; } if (!lspDocument.TryGetVirtualDocument <TVirtualDocument>(out var newVirtualDocument)) { throw new InvalidOperationException("This should never ever happen."); } var newVirtual = newVirtualDocument.CurrentSnapshot; var args = new LSPDocumentChangeEventArgs( old, @new, oldVirtual, newVirtual, LSPDocumentChangeKind.VirtualDocumentChanged); Changed?.Invoke(this, args); }
// Internal for testing internal void DocumentManager_Changed(object sender, LSPDocumentChangeEventArgs args) { if (args is null) { throw new ArgumentNullException(nameof(args)); } lock (DocumentContextLock) { if (args.Kind == LSPDocumentChangeKind.Added) { var lspDocument = args.New; for (var i = 0; i < lspDocument.VirtualDocuments.Count; i++) { var virtualDocument = lspDocument.VirtualDocuments[i]; Debug.Assert(!_virtualDocumentContexts.ContainsKey(virtualDocument.Uri)); var virtualDocumentTextBuffer = virtualDocument.Snapshot.TextBuffer; virtualDocumentTextBuffer.PostChanged += VirtualDocumentBuffer_PostChanged; _virtualDocumentContexts[virtualDocument.Uri] = new DocumentContext(_synchronizationTimeout); } } else if (args.Kind == LSPDocumentChangeKind.Removed) { var lspDocument = args.Old; for (var i = 0; i < lspDocument.VirtualDocuments.Count; i++) { var virtualDocument = lspDocument.VirtualDocuments[i]; if (!_virtualDocumentContexts.TryGetValue(virtualDocument.Uri, out var virtualDocumentContext)) { Debug.Fail("Could not locate virtual document context, it should have been added."); continue; } var virtualDocumentTextBuffer = virtualDocument.Snapshot.TextBuffer; virtualDocumentTextBuffer.PostChanged -= VirtualDocumentBuffer_PostChanged; virtualDocumentContext.Dispose(); _virtualDocumentContexts.Remove(virtualDocument.Uri); } } else if (args.Kind == LSPDocumentChangeKind.VirtualDocumentChanged) { if (args.VirtualOld.Snapshot.Version == args.VirtualNew.Snapshot.Version) { // UpdateDocumentContextVersionInternal is typically invoked through a buffer notification, // however in the case where VirtualDocumentBase.Update is called with a zero change edit, // there won't be such an edit to hook into. Instead, we'll detect that case here and // update the document context version appropriately. UpdateDocumentContextVersionInternal(args.VirtualNew.Snapshot.TextBuffer); } } } }
// Internal for testing internal void DocumentManager_Changed(object sender, LSPDocumentChangeEventArgs args) { if (args is null) { throw new ArgumentNullException(nameof(args)); } lock (DocumentContextLock) { if (args.Kind == LSPDocumentChangeKind.Added) { var lspDocument = args.New; for (var i = 0; i < lspDocument.VirtualDocuments.Count; i++) { var virtualDocument = lspDocument.VirtualDocuments[i]; Debug.Assert(!_virtualDocumentContexts.ContainsKey(virtualDocument.Uri)); var virtualDocumentTextBuffer = virtualDocument.Snapshot.TextBuffer; virtualDocumentTextBuffer.PostChanged += VirtualDocumentBuffer_PostChanged; _virtualDocumentContexts[virtualDocument.Uri] = new DocumentContext(_synchronizationTimeout); } } else if (args.Kind == LSPDocumentChangeKind.Removed) { var lspDocument = args.Old; for (var i = 0; i < lspDocument.VirtualDocuments.Count; i++) { var virtualDocument = lspDocument.VirtualDocuments[i]; Debug.Assert(_virtualDocumentContexts.ContainsKey(virtualDocument.Uri)); var virtualDocumentTextBuffer = virtualDocument.Snapshot.TextBuffer; virtualDocumentTextBuffer.PostChanged -= VirtualDocumentBuffer_PostChanged; _virtualDocumentContexts.Remove(virtualDocument.Uri); } } } }
public override void TrackDocument(ITextBuffer buffer) { if (buffer is null) { throw new ArgumentNullException(nameof(buffer)); } Debug.Assert(_joinableTaskContext.IsOnMainThread); var uri = _fileUriProvider.GetOrCreate(buffer); if (_documents.TryGetValue(uri, out _)) { throw new InvalidOperationException($"Can not track document that's already being tracked {uri}"); } var lspDocument = _documentFactory.Create(buffer); _documents[uri] = lspDocument; var args = new LSPDocumentChangeEventArgs(old: null, lspDocument.CurrentSnapshot, LSPDocumentChangeKind.Added); Changed?.Invoke(this, args); }
private static void NotifyLSPDocumentAdded(LSPDocumentSnapshot lspDocument, DefaultLSPDocumentSynchronizer synchronizer) { var args = new LSPDocumentChangeEventArgs(old: null, @new: lspDocument, LSPDocumentChangeKind.Added); synchronizer.DocumentManager_Changed(sender: null, args); }