private async Task <Document> DetermineNewDocumentAsync(CompletionItem completionItem, SourceText sourceText, CancellationToken cancellationToken) { // The span we're going to replace var line = sourceText.Lines[MemberInsertionCompletionItem.GetLine(completionItem)]; //var line = textSnapshot.GetLineFromLineNumber(MemberInsertionCompletionItem.GetLine(completionItem)); //var sourceText = textSnapshot.AsText(); var document = sourceText.GetOpenDocumentInCurrentContextWithChanges(); Contract.ThrowIfNull(document); // Annotate the line we care about so we can find it after adding usings var tree = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken); var token = GetToken(completionItem, tree, cancellationToken); var annotatedRoot = tree.GetRoot(cancellationToken).ReplaceToken(token, token.WithAdditionalAnnotations(_otherAnnotation)); document = document.WithSyntaxRoot(annotatedRoot); var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false); var insertionRoot = PrepareTreeForMemberInsertion(memberContainingDocument, cancellationToken); var insertionText = GenerateInsertionText(memberContainingDocument, cancellationToken); var destinationSpan = ComputeDestinationSpan(insertionRoot, insertionText); var finalText = insertionRoot.GetText(sourceText.Encoding).Replace(destinationSpan, insertionText.Trim()); document = document.WithText(finalText); var newRoot = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken); var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End)); document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation))); return(Formatter.FormatAsync(document, _annotation, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken)); }
private async Task <Document> DetermineNewDocumentAsync(Document document, CompletionItem completionItem, CancellationToken cancellationToken) { var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); // 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); var token = GetToken(completionItem, tree, cancellationToken); var annotatedRoot = tree.GetRoot(cancellationToken).ReplaceToken(token, token.WithAdditionalAnnotations(_otherAnnotation)); document = document.WithSyntaxRoot(annotatedRoot); var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false); if (memberContainingDocument == null) { // Generating the new document failed because we somehow couldn't resolve // the underlying symbol's SymbolKey. At this point, we won't be able to // make any changes, so just return the document we started with. return(document); } var insertionRoot = await GetTreeWithAddedSyntaxNodeRemovedAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false); var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false); var destinationSpan = ComputeDestinationSpan(insertionRoot); var finalText = insertionRoot.GetText(text.Encoding) .Replace(destinationSpan, insertionText.Trim()); document = document.WithText(finalText); var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End)); document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation))); return(await Formatter.FormatAsync(document, _annotation, cancellationToken : cancellationToken).ConfigureAwait(false)); }