private GeneratedCodeContainer Create(string filePath) { var codeContainer = new GeneratedCodeContainer(); codeContainer.GeneratedCodeChanged += (sender, args) => { var generatedCodeContainer = (GeneratedCodeContainer)sender; IReadOnlyList <TextChange> textChanges; if (args.NewText.ContentEquals(args.OldText)) { // If the content is equal then no need to update the underlying CSharp buffer. textChanges = Array.Empty <TextChange>(); } else { textChanges = args.NewText.GetTextChanges(args.OldText); } var latestDocument = generatedCodeContainer.LatestDocument; Task.Factory.StartNew(() => { if (!_projectSnapshotManager.IsDocumentOpen(filePath)) { // Document isn't opened, no need to notify the client return; } if (!_documentVersionCache.TryGetDocumentVersion(latestDocument, out var hostDocumentVersion)) { // Cache entry doesn't exist, document most likely was evicted from the cache/too old. return; } var request = new UpdateCSharpBufferRequest() { HostDocumentFilePath = filePath, Changes = textChanges, HostDocumentVersion = hostDocumentVersion, }; _server.Value.Client.SendRequest("updateCSharpBuffer", request); }, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler); }; return(codeContainer); }
// Internal virtual for testing internal virtual void ReportUnsynchronizableContent(KeyValuePair <string, DocumentSnapshot>[] work) { _foregroundDispatcher.AssertForegroundThread(); // This method deals with reporting unsynchronized content. At this point we've force evaluation of each document // in the work queue; however, some documents may be identical versions of the last synchronized document if // one's content does not differ. In this case, the output of the two generated documents is the same but we still // need to let the client know that we've processed its latest text change. This allows the client to understand // when it's operating on out-of-date output. for (var i = 0; i < work.Length; i++) { var document = work[i].Value; if (!(document is DefaultDocumentSnapshot defaultDocument)) { continue; } if (!_documentVersionCache.TryGetDocumentVersion(document, out var syncVersion)) { // Document is no longer important. continue; } var latestSynchronizedDocument = defaultDocument.State.HostDocument.GeneratedCodeContainer.LatestDocument; if (latestSynchronizedDocument == null || latestSynchronizedDocument == document) { // Already up-to-date continue; } if (IdenticalOutputAfterParse(document, latestSynchronizedDocument, syncVersion)) { // Documents are identical but we didn't synchronize them because they didn't need to be re-evaluated. var request = new UpdateCSharpBufferRequest() { HostDocumentFilePath = document.FilePath, Changes = Array.Empty <TextChange>(), HostDocumentVersion = syncVersion }; _router.Client.SendRequest("updateCSharpBuffer", request); } } }
public override void DocumentProcessed(DocumentSnapshot document) { _foregroundDispatcher.AssertForegroundThread(); if (!_projectManager.IsDocumentOpen(document.FilePath)) { return; } if (!(document is DefaultDocumentSnapshot defaultDocument)) { return; } if (!_documentVersionCache.TryGetDocumentVersion(document, out var syncVersion)) { // Document is no longer important. return; } var latestSynchronizedDocument = defaultDocument.State.HostDocument.GeneratedCodeContainer.LatestDocument; if (latestSynchronizedDocument == null || latestSynchronizedDocument == document) { // Already up-to-date return; } if (IdenticalOutputAfterParse(document, latestSynchronizedDocument, syncVersion)) { // Documents are identical but we didn't synchronize them because they didn't need to be re-evaluated. var request = new UpdateCSharpBufferRequest() { HostDocumentFilePath = document.FilePath, Changes = Array.Empty <TextChange>(), HostDocumentVersion = syncVersion }; _router.Client.SendRequest("updateCSharpBuffer", request); } }
public override HostDocument Create(string documentFilePath) { var hostDocument = new HostDocument(documentFilePath, documentFilePath); hostDocument.GeneratedCodeContainer.GeneratedCodeChanged += (sender, args) => { var generatedCodeContainer = (GeneratedCodeContainer)sender; IReadOnlyList <TextChange> textChanges; if (args.NewText.ContentEquals(args.OldText)) { // If the content is equal then no need to update the underlying CSharp buffer. textChanges = Array.Empty <TextChange>(); } else { textChanges = args.NewText.GetTextChanges(args.OldText); } var latestDocument = generatedCodeContainer.LatestDocument; Task.Factory.StartNew(() => { if (!_documentVersionCache.TryGetDocumentVersion(latestDocument, out var hostDocumentVersion)) { // Cache entry doesn't exist, document most likely was evicted from the cache/too old. return; } var request = new UpdateCSharpBufferRequest() { HostDocumentFilePath = documentFilePath, Changes = textChanges, HostDocumentVersion = hostDocumentVersion }; _router.Client.SendRequest("updateCSharpBuffer", request); }, CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler); }; return(hostDocument); }
public override void Publish(string filePath, SourceText sourceText, long hostDocumentVersion) { if (filePath is null) { throw new ArgumentNullException(nameof(filePath)); } if (sourceText is null) { throw new ArgumentNullException(nameof(sourceText)); } _foregroundDispatcher.AssertForegroundThread(); if (!_publishedSourceText.TryGetValue(filePath, out var previouslyPublishedText)) { previouslyPublishedText = EmptySourceText; } IReadOnlyList <TextChange> textChanges = Array.Empty <TextChange>(); if (!sourceText.ContentEquals(previouslyPublishedText)) { textChanges = sourceText.GetTextChanges(previouslyPublishedText); } _publishedSourceText[filePath] = sourceText; var request = new UpdateCSharpBufferRequest() { HostDocumentFilePath = filePath, Changes = textChanges, HostDocumentVersion = hostDocumentVersion, }; _server.Value.Client.SendRequest("updateCSharpBuffer", request); }