From 7abb41a1fc4dd50d20ac2cd789235046b66ff30a Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Jun 2017 10:24:10 -0700 Subject: [PATCH] Do not call GetOpenDocumentInCurrentContextWithChanges(...) in AbstractMemberInsertingCompletionProvider I noticed this while working through an issue using the CompletionService in OmniSharp. `GetOpenDocumentInCurrentContextWithChanges(...)` allows the caller to retrieve a Document from a SourceText. It achieves this be calling `Workspace.TryGetWorkspace(...)` with the SourceText's SourceTextContainer. However, in the case of a standard SourceText, this is just a StaticContainer that changes every time `SourceText.WithChanges(...)` is called. So, if the SourceText is updated for a particular Document in an AdhocWorkspace, calling `GetOpenDocumentInCurrentContextWithChanges(...)` for the new SourceText will fail because its container is different than the one that was initially registered with the Workspace. --- ...AbstractMemberInsertingCompletionProvider.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs index 98c75f7cd1ead..e4eb4ddb36725 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs @@ -32,9 +32,7 @@ public AbstractMemberInsertingCompletionProvider() public override async Task GetChangeAsync(Document document, CompletionItem item, char? commitKey = default(char?), CancellationToken cancellationToken = default(CancellationToken)) { - var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - var newDocument = await DetermineNewDocumentAsync(item, text, cancellationToken).ConfigureAwait(false); - + var newDocument = await DetermineNewDocumentAsync(document, item, cancellationToken).ConfigureAwait(false); var newText = await newDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -90,14 +88,12 @@ private TextChange Collapse(SourceText newText, List changes) return new TextChange(totalOldSpan, newText.ToString(totalNewSpan)); } - private async Task DetermineNewDocumentAsync(CompletionItem completionItem, SourceText sourceText, CancellationToken cancellationToken) + private async Task DetermineNewDocumentAsync(Document document, CompletionItem completionItem, CancellationToken cancellationToken) { - // The span we're going to replace - var line = sourceText.Lines[MemberInsertionCompletionItem.GetLine(completionItem)]; + var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - //var sourceText = textSnapshot.AsText(); - var document = sourceText.GetOpenDocumentInCurrentContextWithChanges(); - Contract.ThrowIfNull(document); + // The span we're going to replace + var line = text.Lines[MemberInsertionCompletionItem.GetLine(completionItem)]; // Annotate the line we care about so we can find it after adding usings var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); @@ -112,7 +108,8 @@ private async Task DetermineNewDocumentAsync(CompletionItem completion var destinationSpan = ComputeDestinationSpan(insertionRoot, insertionText); - var finalText = insertionRoot.GetText(sourceText.Encoding).Replace(destinationSpan, insertionText.Trim()); + var finalText = insertionRoot.GetText(text.Encoding) + .Replace(destinationSpan, insertionText.Trim()); document = document.WithText(finalText); var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);