diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs index addfecf45c0a3..382f4023b31e8 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs @@ -416,16 +416,28 @@ public Document WithFilePath(string? filePath) => this.Project.Solution.WithDocumentFilePath(this.Id, filePath).GetRequiredDocument(Id); /// - /// Get the text changes between this document and a prior version of the same document. - /// The changes, when applied to the text of the old document, will produce the text of the current document. + /// Get the text changes between this document and a prior version of the same document. The changes, when applied + /// to the text of the old document, will produce the text of the current document. /// - public Task> GetTextChangesAsync(Document oldDocument, CancellationToken cancellationToken = default) + public async Task> GetTextChangesAsync(Document oldDocument, CancellationToken cancellationToken = default) { - return Task.FromResult>(GetTextChangesSynchronously(oldDocument, cancellationToken)); + return await GetTextChangesAsync(useAsync: true, oldDocument, cancellationToken).ConfigureAwait(false); } + /// + /// Similar to , but should be used when in a forced + /// synchronous context. + /// internal ImmutableArray GetTextChangesSynchronously( Document oldDocument, CancellationToken cancellationToken) + { + // Should always complete synchronously since we passed in 'useAsync: false' + var result = GetTextChangesAsync(useAsync: false, oldDocument, cancellationToken); + return result.VerifyCompleted(); + } + + private async Task> GetTextChangesAsync( + bool useAsync, Document oldDocument, CancellationToken cancellationToken) { try { @@ -462,16 +474,16 @@ internal ImmutableArray GetTextChangesSynchronously( // get changes by diffing the trees if (this.SupportsSyntaxTree) { - var tree = this.GetSyntaxTreeSynchronously(cancellationToken); - var oldTree = oldDocument.GetSyntaxTreeSynchronously(cancellationToken); + var tree = useAsync ? await GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false) : this.GetSyntaxTreeSynchronously(cancellationToken); + var oldTree = useAsync ? await oldDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false) : oldDocument.GetSyntaxTreeSynchronously(cancellationToken); RoslynDebug.Assert(tree is object); RoslynDebug.Assert(oldTree is object); return tree.GetChanges(oldTree).ToImmutableArray(); } - text = this.GetTextSynchronously(cancellationToken); - oldText = oldDocument.GetTextSynchronously(cancellationToken); + text = useAsync ? await this.GetTextAsync(cancellationToken).ConfigureAwait(false) : this.GetTextSynchronously(cancellationToken); + oldText = useAsync ? await oldDocument.GetTextAsync(cancellationToken).ConfigureAwait(false) : oldDocument.GetTextSynchronously(cancellationToken); return text.GetTextChanges(oldText).ToImmutableArray(); }