private async Task <ImmutableArray <TextChange> > GetTextChangesAsync( Document document, SyntaxNode contextNode, bool placeSystemNamespaceFirst, bool allowInHiddenRegions, bool hasExistingImport, CancellationToken cancellationToken) { // Defer to the language to add the actual import/using. if (hasExistingImport) { return(ImmutableArray <TextChange> .Empty); } (var newContextNode, var newDocument) = await ReplaceNameNodeAsync( contextNode, document, cancellationToken).ConfigureAwait(false); var updatedDocument = await provider.AddImportAsync( newContextNode, SymbolResult.Symbol, newDocument, placeSystemNamespaceFirst, allowInHiddenRegions, cancellationToken).ConfigureAwait(false); var cleanedDocument = await CodeAction.CleanupDocumentAsync( updatedDocument, cancellationToken).ConfigureAwait(false); var textChanges = await cleanedDocument.GetTextChangesAsync( document, cancellationToken).ConfigureAwait(false); return(textChanges.ToImmutableArray()); }
protected async Task <ImmutableArray <TextChange> > GetTextChangesAsync( Document document, SyntaxNode node, bool placeSystemNamespaceFirst, bool allowInHiddenRegions, CancellationToken cancellationToken ) { var originalDocument = document; (node, document) = await ReplaceNameNodeAsync(node, document, cancellationToken) .ConfigureAwait(false); var newDocument = await provider .AddImportAsync( node, SearchResult.NameParts, document, placeSystemNamespaceFirst, allowInHiddenRegions, cancellationToken ) .ConfigureAwait(false); var cleanedDocument = await CodeAction .CleanupDocumentAsync(newDocument, cancellationToken) .ConfigureAwait(false); var textChanges = await cleanedDocument .GetTextChangesAsync(originalDocument, cancellationToken) .ConfigureAwait(false); return(textChanges.ToImmutableArray()); }
public async Task <Document> FormatNewDocumentAsync(Document document, Document?hintDocument, CancellationToken cancellationToken) { foreach (var provider in GetProviders()) { cancellationToken.ThrowIfCancellationRequested(); // If a single formatter has a bug, we still want to keep trying the others. // Since they are unordered it would be inappropriate for them to depend on each // other, so this shouldn't cause problems. try { // First we ask the provider to "format" the document. This could be formatting in terms // of adjusting block scopes to file scopes etc., but it could also be more akin to fixers // like adding access modifiers, or adding .ConfigureAwait() calls etc. document = await provider.FormatNewDocumentAsync(document, hintDocument, cancellationToken).ConfigureAwait(false); // Now that the above has changed the document, we use the code action engine to clean up the document // before we call the next provider, otherwise they might not see things as they are meant to be. // Because formatting providers often re-use code fix logic, they are often written assuming this will // happen. document = await CodeAction.CleanupDocumentAsync(document, cancellationToken).ConfigureAwait(false); } catch (Exception ex) when(FatalError.ReportAndCatchUnlessCanceled(ex, cancellationToken, ErrorSeverity.General)) { } } return(document); }
private async Task <Solution> CleanupAsync(Solution oldSolution, Solution newSolution, CancellationToken cancellationToken) { var changes = newSolution.GetChangedDocuments(oldSolution); var final = newSolution; foreach (var docId in changes) { var cleaned = await CodeAction.CleanupDocumentAsync( newSolution.GetDocument(docId), cancellationToken).ConfigureAwait(false); var cleanedRoot = await cleaned.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); final = final.WithDocumentSyntaxRoot(docId, cleanedRoot); } return(final); }