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 = 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); var insertionRoot = await PrepareTreeForMemberInsertionAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false); var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false); var destinationSpan = ComputeDestinationSpan(insertionRoot, insertionText); var finalText = insertionRoot.GetText(sourceText.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 Formatter.FormatAsync(document, _annotation, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken); }
/// <summary> /// Tries to get the document corresponding to the text from the current partial solution /// associated with the text's container. If the document does not contain the exact text a document /// from a new solution containing the specified text is constructed. If no document is associated /// with the specified text's container, or the text's container isn't associated with a workspace, /// then the method returns false. /// </summary> internal static Document?GetDocumentWithFrozenPartialSemantics( this SourceText text, CancellationToken cancellationToken ) { var document = text.GetOpenDocumentInCurrentContextWithChanges(); return(document?.WithFrozenPartialSemantics(cancellationToken)); }
/// <summary> /// Tries to get the document corresponding to the text from the current partial solution /// associated with the text's container. If the document does not contain the exact text a document /// from a new solution containing the specified text is constructed. If no document is associated /// with the specified text's container, or the text's container isn't associated with a workspace, /// then the method returns false. /// </summary> internal static async Task <Document> GetDocumentWithFrozenPartialSemanticsAsync(this SourceText text, CancellationToken cancellationToken) { var document = text.GetOpenDocumentInCurrentContextWithChanges(); if (document != null) { return(await document.WithFrozenPartialSemanticsAsync(cancellationToken).ConfigureAwait(false)); } return(null); }
public IEnumerable<ActiveStatementTextSpan> GetSpans(SourceText source) { var document = source.GetOpenDocumentInCurrentContextWithChanges(); if (document == null) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } // We might be asked for spans in a different workspace than // the one we maintain tracking spans for (for example, a preview). if (document.Project.Solution.Workspace != _editSession.BaseSolution.Workspace) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } ITrackingSpan[] documentTrackingSpans; lock (_trackingSpans) { if (!_trackingSpans.TryGetValue(document.Id, out documentTrackingSpans) || documentTrackingSpans == null) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } } Debug.Assert(documentTrackingSpans.Length > 0); var snapshot = source.FindCorrespondingEditorTextSnapshot(); // The document might have been reopened with a new text buffer // and we haven't created tracking spans for the new text buffer yet. if (snapshot == null || snapshot.TextBuffer != documentTrackingSpans[0].TextBuffer) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } var baseStatements = _editSession.BaseActiveStatements[document.Id]; Debug.Assert(documentTrackingSpans.Length == baseStatements.Length); var result = new ActiveStatementTextSpan[documentTrackingSpans.Length]; for (int i = 0; i < documentTrackingSpans.Length; i++) { Debug.Assert(documentTrackingSpans[i].TextBuffer == snapshot.TextBuffer); result[i] = new ActiveStatementTextSpan( baseStatements[i].Flags, documentTrackingSpans[i].GetSpan(snapshot).Span.ToTextSpan()); } return result; }