From 2a8ed8e4c969d88c04d82cfc37de80d726577fd4 Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 22 Dec 2021 13:21:57 -0800 Subject: [PATCH] SyntaxFormattingOptions --- ...CSharpRemoveUnusedValuesCodeFixProvider.cs | 7 ++ ...stractRemoveUnusedValuesCodeFixProvider.cs | 29 +++-- ...UseConditionalExpressionCodeFixProvider.cs | 16 +-- ...lBasicRemoveUnusedValuesCodeFixProvider.vb | 8 ++ .../Analyzers/AbstractFormattingAnalyzer.cs | 6 +- .../Analyzers/Formatting/FormatterHelper.cs | 100 ++++-------------- .../Analyzers/FormattingAnalyzerHelper.cs | 13 ++- .../Core/CodeFixes/FormattingCodeFixHelper.cs | 17 +-- .../CodeFixes/FormattingCodeFixProvider.cs | 16 ++- .../TestExtractInterfaceOptions.cs | 4 +- .../CSharpSuppressionCodeFixProvider.cs | 12 +-- .../AbstractChangeSignatureService.cs | 5 +- ...uppressionCodeFixProvider.PragmaHelpers.cs | 18 ++-- ...CodeFixProvider.PragmaWarningCodeAction.cs | 17 +-- ...FixProvider.RemoveSuppressionCodeAction.cs | 4 +- ...ider.RemoveSuppressionCodeAction_Pragma.cs | 26 +++-- .../AbstractSuppressionCodeFixProvider.cs | 8 +- ...AbstractAddMissingImportsFeatureService.cs | 13 +-- .../AbstractChangeNamespaceService.cs | 4 +- .../AbstractExtractInterfaceService.cs | 10 +- .../IExtractInterfaceOptionsService.cs | 4 +- .../ExtractMethod/ExtractMethodResult.cs | 8 +- .../Formatting/FormattingCodeFixProvider.cs | 4 +- .../FormattingDiagnosticAnalyzer.cs | 6 +- .../Shared/Utilities/ExtractTypeHelpers.cs | 4 +- .../AbstractUseAutoPropertyCodeFixProvider.cs | 4 +- .../VisualBasicSuppressionCodeFixProvider.vb | 20 ++-- ...OmniSharpExtractInterfaceOptionsService.cs | 12 ++- ...ualStudioExtractInterfaceOptionsService.cs | 6 +- .../CSharpIndentationService.Indenter.cs | 8 +- .../Indentation/CSharpSmartTokenFormatter.cs | 19 ++-- .../CodeCleanup/AbstractCodeCleanerService.cs | 11 +- .../Core/Portable/CodeCleanup/CodeCleaner.cs | 6 +- .../CodeCleanup/ICodeCleanerService.cs | 6 +- .../Providers/FormatCodeCleanupProvider.cs | 9 +- .../Providers/ICodeCleanupProvider.cs | 6 +- .../SimplificationCodeCleanupProvider.cs | 6 +- .../Core/Portable/Formatting/Formatter.cs | 51 +++++++-- .../AbstractSyntaxFormattingService.cs | 8 +- .../Formatting/ISyntaxFormattingService.cs | 27 +++-- .../CSharpRemoveUnnecessaryImportsService.cs | 4 +- .../AbstractTokensCodeCleanupProvider.vb | 6 +- .../CaseCorrectionCodeCleanupProvider.vb | 6 +- ...ModifiersOrOperatorsCodeCleanupProvider.vb | 6 +- ...saryLineContinuationCodeCleanupProvider.vb | 6 +- .../VisualBasicIndentationService.Indenter.vb | 8 +- .../VisualBasicSmartTokenFormatter.vb | 10 +- 47 files changed, 316 insertions(+), 288 deletions(-) diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs index 24f21e1674b39..d5479027826e2 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnusedParametersAndValues/CSharpRemoveUnusedValuesCodeFixProvider.cs @@ -10,9 +10,11 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.CSharp.Shared.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.RemoveUnusedParametersAndValues; @@ -31,6 +33,11 @@ public CSharpRemoveUnusedValuesCodeFixProvider() { } +#if CODE_STYLE + protected override ISyntaxFormattingService GetSyntaxFormattingService() + => CSharpSyntaxFormattingService.Instance; +#endif + protected override BlockSyntax WrapWithBlockIfNecessary(IEnumerable statements) => SyntaxFactory.Block(statements); diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs index c75a0632e47db..c6abf5a787b54 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs @@ -27,6 +27,12 @@ using Microsoft.CodeAnalysis.Simplification; using Roslyn.Utilities; +#if CODE_STYLE +using Formatter = Microsoft.CodeAnalysis.Formatting.FormatterHelper; +#else +using Formatter = Microsoft.CodeAnalysis.Formatting.Formatter; +#endif + namespace Microsoft.CodeAnalysis.RemoveUnusedParametersAndValues { /// @@ -67,6 +73,8 @@ public sealed override ImmutableArray FixableDiagnosticIds internal sealed override CodeFixCategory CodeFixCategory => CodeFixCategory.CodeQuality; + protected abstract ISyntaxFormattingService GetSyntaxFormattingService(); + /// /// Method to update the identifier token for the local/parameter declaration or reference /// that was flagged as an unused value write by the analyzer. @@ -270,14 +278,14 @@ private static async Task PreprocessDocumentAsync(Document document, I protected sealed override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var preprocessedDocument = await PreprocessDocumentAsync(document, diagnostics, cancellationToken).ConfigureAwait(false); - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var options = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); var newRoot = await GetNewRootAsync(preprocessedDocument, options, diagnostics, cancellationToken).ConfigureAwait(false); editor.ReplaceNode(editor.OriginalRoot, newRoot); } private async Task GetNewRootAsync( Document document, - OptionSet options, + SyntaxFormattingOptions options, ImmutableArray diagnostics, CancellationToken cancellationToken) { @@ -721,7 +729,7 @@ bool ShouldRemoveStatement(TLocalDeclarationStatementSyntax localDeclarationStat private async Task PostProcessDocumentAsync( Document document, - OptionSet options, + SyntaxFormattingOptions options, SyntaxNode currentRoot, string diagnosticId, UnusedValuePreference preference, @@ -749,10 +757,10 @@ private async Task PostProcessDocumentAsync( } private static async Task PostProcessDocumentCoreAsync( - Func> processMemberDeclarationAsync, + Func> processMemberDeclarationAsync, SyntaxNode currentRoot, Document document, - OptionSet options, + SyntaxFormattingOptions options, CancellationToken cancellationToken) { // Process each member declaration which had at least one diagnostic reported in the original tree and hence @@ -780,7 +788,7 @@ private static async Task PostProcessDocumentCoreAsync( /// This is needed to prevent the code fix/FixAll from generating code with /// multiple local variables named '_', which is a compiler error. /// - private async Task ReplaceDiscardDeclarationsWithAssignmentsAsync(SyntaxNode memberDeclaration, Document document, OptionSet options, CancellationToken cancellationToken) + private async Task ReplaceDiscardDeclarationsWithAssignmentsAsync(SyntaxNode memberDeclaration, Document document, SyntaxFormattingOptions options, CancellationToken cancellationToken) { var service = document.GetLanguageService(); if (service == null) @@ -802,7 +810,7 @@ private async Task ReplaceDiscardDeclarationsWithAssignmentsAsync(Sy private static async Task AdjustLocalDeclarationsAsync( SyntaxNode memberDeclaration, Document document, - OptionSet options, + SyntaxFormattingOptions options, CancellationToken cancellationToken) { var moveDeclarationService = document.GetRequiredLanguageService(); @@ -826,7 +834,12 @@ private static async Task AdjustLocalDeclarationsAsync( var rootWithTrackedNodes = root.TrackNodes(originalDeclStatementsToMoveOrRemove); // Run formatter prior to invoking IMoveDeclarationNearReferenceService. - rootWithTrackedNodes = Formatter.Format(rootWithTrackedNodes, originalDeclStatementsToMoveOrRemove.Select(s => s.Span), document.Project.Solution.Workspace, options, cancellationToken: cancellationToken); +#if CODE_STYLE + var provider = document.Project.Solution.Workspace.Services; +#else + var provider = document.Project.Solution.Workspace.Services; +#endif + rootWithTrackedNodes = Formatter.Format(rootWithTrackedNodes, originalDeclStatementsToMoveOrRemove.Select(s => s.Span), provider, options, rules: null, cancellationToken); document = document.WithSyntaxRoot(rootWithTrackedNodes); await OnDocumentUpdatedAsync().ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs index 385a3eae9ab3d..09429dc404e05 100644 --- a/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs @@ -70,21 +70,15 @@ await FixOneAsync( // annotation on it. var rules = new List { GetMultiLineFormattingRule() }; - var options = document.Project.AnalyzerOptions.GetAnalyzerOptionSet(root.SyntaxTree, cancellationToken); + var options = SyntaxFormattingOptions.Create(document.Project.AnalyzerOptions.GetAnalyzerOptionSet(root.SyntaxTree, cancellationToken)); #if CODE_STYLE - var formattedRoot = FormatterHelper.Format(changedRoot, - GetSyntaxFormattingService(), - SpecializedFormattingAnnotation, - options, - rules, cancellationToken); + var provider = GetSyntaxFormattingService(); #else - var formattedRoot = Formatter.Format(changedRoot, - SpecializedFormattingAnnotation, - document.Project.Solution.Workspace, - options, - rules, cancellationToken); + var provider = document.Project.Solution.Workspace.Services; #endif + var formattedRoot = Formatter.Format(changedRoot, SpecializedFormattingAnnotation, provider, options, rules, cancellationToken); + changedRoot = formattedRoot; editor.ReplaceNode(root, changedRoot); diff --git a/src/Analyzers/VisualBasic/CodeFixes/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb index 0dabee3281c7b..a751f08efa9a1 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/RemoveUnusedParametersAndValues/VisualBasicRemoveUnusedValuesCodeFixProvider.vb @@ -6,8 +6,10 @@ Imports System.Composition Imports System.Diagnostics.CodeAnalysis Imports Microsoft.CodeAnalysis.CodeFixes Imports Microsoft.CodeAnalysis.Editing +Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.LanguageServices Imports Microsoft.CodeAnalysis.RemoveUnusedParametersAndValues +Imports Microsoft.CodeAnalysis.VisualBasic.Formatting Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnusedParametersAndValues @@ -23,6 +25,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnusedParametersAndValues Public Sub New() End Sub +#If CODE_STYLE Then + Protected Overrides Function GetSyntaxFormattingService() As ISyntaxFormattingService + Return VisualBasicSyntaxFormattingService.Instance + End Function +#End If + Protected Overrides Function WrapWithBlockIfNecessary(statements As IEnumerable(Of StatementSyntax)) As StatementSyntax ' Unreachable code path as VB statements don't need to be wrapped in special BlockSyntax. Throw ExceptionUtilities.Unreachable diff --git a/src/CodeStyle/Core/Analyzers/AbstractFormattingAnalyzer.cs b/src/CodeStyle/Core/Analyzers/AbstractFormattingAnalyzer.cs index 31b9440b912d8..3b51c026c3ec0 100644 --- a/src/CodeStyle/Core/Analyzers/AbstractFormattingAnalyzer.cs +++ b/src/CodeStyle/Core/Analyzers/AbstractFormattingAnalyzer.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Formatting; @@ -36,8 +34,8 @@ protected sealed override void InitializeWorker(AnalysisContext context) private void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context) { - var analyzerConfigOptions = context.Options.AnalyzerConfigOptionsProvider.GetOptions(context.Tree); - FormattingAnalyzerHelper.AnalyzeSyntaxTree(context, SyntaxFormattingService, Descriptor, analyzerConfigOptions); + var options = SyntaxFormattingOptions.Create(context.Options.AnalyzerConfigOptionsProvider.GetOptions(context.Tree)); + FormattingAnalyzerHelper.AnalyzeSyntaxTree(context, SyntaxFormattingService, Descriptor, options); } } } diff --git a/src/CodeStyle/Core/Analyzers/Formatting/FormatterHelper.cs b/src/CodeStyle/Core/Analyzers/Formatting/FormatterHelper.cs index b9537b346afeb..5a579ebdf66ee 100644 --- a/src/CodeStyle/Core/Analyzers/Formatting/FormatterHelper.cs +++ b/src/CodeStyle/Core/Analyzers/Formatting/FormatterHelper.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Generic; using System.Threading; @@ -12,7 +10,6 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Diagnostics; using Roslyn.Utilities; -using OptionSet = Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptions; using static Microsoft.CodeAnalysis.Formatting.FormattingExtensions; namespace Microsoft.CodeAnalysis.Formatting @@ -23,53 +20,15 @@ namespace Microsoft.CodeAnalysis.Formatting internal static class FormatterHelper { /// - /// Gets the formatting rules that would be applied if left unspecified. + /// The annotation used to mark portions of a syntax tree to be formatted. /// - internal static IEnumerable GetDefaultFormattingRules(ISyntaxFormattingService syntaxFormattingService) - { - if (syntaxFormattingService != null) - { - return syntaxFormattingService.GetDefaultFormattingRules(); - } - else - { - return SpecializedCollections.EmptyEnumerable(); - } - } + public static SyntaxAnnotation Annotation { get; } = new SyntaxAnnotation(); /// - /// Formats the whitespace in an area of a document corresponding to a text span. - /// - /// The document to format. - /// The span of the document's text to format. - /// An optional set of formatting options. If these options are not supplied the current set of options from the document's workspace will be used. - /// An optional cancellation token. - /// The formatted document. - public static Task FormatAsync(SyntaxTree syntaxTree, ISyntaxFormattingService syntaxFormattingService, TextSpan span, OptionSet options, CancellationToken cancellationToken) - => FormatAsync(syntaxTree, syntaxFormattingService, SpecializedCollections.SingletonEnumerable(span), options, cancellationToken); - - /// - /// Formats the whitespace in areas of a document corresponding to multiple non-overlapping spans. + /// Gets the formatting rules that would be applied if left unspecified. /// - /// The document to format. - /// The spans of the document's text to format. - /// An optional set of formatting options. If these options are not supplied the current set of options from the document's workspace will be used. - /// An optional cancellation token. - /// The formatted document. - public static Task FormatAsync(SyntaxTree syntaxTree, ISyntaxFormattingService syntaxFormattingService, IEnumerable spans, OptionSet options, CancellationToken cancellationToken) - => FormatAsync(syntaxTree, syntaxFormattingService, spans, options, rules: null, cancellationToken); - - internal static async Task FormatAsync(SyntaxTree syntaxTree, ISyntaxFormattingService syntaxFormattingService, IEnumerable spans, OptionSet options, IEnumerable rules, CancellationToken cancellationToken) - { - if (syntaxTree == null) - { - throw new ArgumentNullException(nameof(syntaxTree)); - } - - var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); - var documentOptions = options ?? DictionaryAnalyzerConfigOptions.Empty; - return syntaxTree.WithRootAndOptions(Format(root, syntaxFormattingService, spans, documentOptions, rules, cancellationToken), syntaxTree.Options); - } + internal static IEnumerable GetDefaultFormattingRules(ISyntaxFormattingService syntaxFormattingService) + => syntaxFormattingService.GetDefaultFormattingRules(); /// /// Formats the whitespace of a syntax tree. @@ -78,8 +37,11 @@ internal static async Task FormatAsync(SyntaxTree syntaxTree, ISynta /// An optional set of formatting options. If these options are not supplied the current set of options from the workspace will be used. /// An optional cancellation token. /// The formatted tree's root node. - public static SyntaxNode Format(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, OptionSet options, CancellationToken cancellationToken) - => Format(node, syntaxFormattingService, SpecializedCollections.SingletonEnumerable(node.FullSpan), options, rules: null, cancellationToken: cancellationToken); + public static SyntaxNode Format(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => Format(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), syntaxFormattingService, options, rules: null, cancellationToken: cancellationToken); + + public static SyntaxNode Format(SyntaxNode node, TextSpan spanToFormat, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => Format(node, SpecializedCollections.SingletonEnumerable(spanToFormat), syntaxFormattingService, options, rules: null, cancellationToken: cancellationToken); /// /// Formats the whitespace of a syntax tree. @@ -89,45 +51,23 @@ public static SyntaxNode Format(SyntaxNode node, ISyntaxFormattingService syntax /// An optional set of formatting options. If these options are not supplied the current set of options from the workspace will be used. /// An optional cancellation token. /// The formatted tree's root node. - public static SyntaxNode Format(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, SyntaxAnnotation annotation, OptionSet options, IEnumerable rules, CancellationToken cancellationToken) + public static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) { var spans = (annotation == SyntaxAnnotation.ElasticAnnotation) ? GetElasticSpans(node) : GetAnnotatedSpans(node, annotation); - return Format(node, syntaxFormattingService, spans, options, rules, cancellationToken: cancellationToken); - } - - internal static SyntaxNode Format(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, IEnumerable spans, OptionSet options, IEnumerable rules, CancellationToken cancellationToken) - { - var formattingResult = GetFormattingResult(node, syntaxFormattingService, spans, options, rules, cancellationToken); - return formattingResult == null ? node : formattingResult.GetFormattedRoot(cancellationToken); - } - - internal static IList GetFormattedTextChanges(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, IEnumerable spans, OptionSet options, IEnumerable rules, CancellationToken cancellationToken) - { - var formattingResult = GetFormattingResult(node, syntaxFormattingService, spans, options, rules, cancellationToken); - return formattingResult == null - ? SpecializedCollections.EmptyList() - : formattingResult.GetTextChanges(cancellationToken); + return Format(node, spans, syntaxFormattingService, options, rules, cancellationToken: cancellationToken); } - internal static IFormattingResult GetFormattingResult(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, IEnumerable spans, OptionSet options, IEnumerable rules, CancellationToken cancellationToken) - { - if (node == null) - { - throw new ArgumentNullException(nameof(node)); - } + internal static SyntaxNode Format(SyntaxNode node, IEnumerable spans, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + => GetFormattingResult(node, spans, syntaxFormattingService, options, rules, cancellationToken).GetFormattedRoot(cancellationToken); - if (syntaxFormattingService is null) - { - return null; - } + internal static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable spans, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + => GetFormattingResult(node, spans, syntaxFormattingService, options, rules, cancellationToken).GetTextChanges(cancellationToken); - options ??= DictionaryAnalyzerConfigOptions.Empty; - spans ??= SpecializedCollections.SingletonEnumerable(node.FullSpan); - return syntaxFormattingService.Format(node, spans, shouldUseFormattingSpanCollapse: false, options, rules, cancellationToken); - } + internal static IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerable spans, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + => syntaxFormattingService.GetFormattingResult(node, spans, options with { ShouldUseFormattingSpanCollapse = false }, rules, cancellationToken); /// /// Determines the changes necessary to format the whitespace of a syntax tree. @@ -136,7 +76,7 @@ internal static IFormattingResult GetFormattingResult(SyntaxNode node, ISyntaxFo /// An optional set of formatting options. If these options are not supplied the current set of options from the workspace will be used. /// An optional cancellation token. /// The changes necessary to format the tree. - public static IList GetFormattedTextChanges(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, OptionSet options, CancellationToken cancellationToken) - => GetFormattedTextChanges(node, syntaxFormattingService, SpecializedCollections.SingletonEnumerable(node.FullSpan), options, rules: null, cancellationToken: cancellationToken); + public static IList GetFormattedTextChanges(SyntaxNode node, ISyntaxFormattingService syntaxFormattingService, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => GetFormattedTextChanges(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), syntaxFormattingService, options, rules: null, cancellationToken: cancellationToken); } } diff --git a/src/CodeStyle/Core/Analyzers/FormattingAnalyzerHelper.cs b/src/CodeStyle/Core/Analyzers/FormattingAnalyzerHelper.cs index 0913f35235778..e6a0dd174a082 100644 --- a/src/CodeStyle/Core/Analyzers/FormattingAnalyzerHelper.cs +++ b/src/CodeStyle/Core/Analyzers/FormattingAnalyzerHelper.cs @@ -5,29 +5,28 @@ #nullable disable using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Text; #if CODE_STYLE using Formatter = Microsoft.CodeAnalysis.Formatting.FormatterHelper; -using FormatterState = Microsoft.CodeAnalysis.Formatting.ISyntaxFormattingService; -using OptionSet = Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptions; +using FormattingProvider = Microsoft.CodeAnalysis.Formatting.ISyntaxFormattingService; #else -using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Formatting; -using FormatterState = Microsoft.CodeAnalysis.Workspace; +using FormattingProvider = Microsoft.CodeAnalysis.Host.HostWorkspaceServices; #endif namespace Microsoft.CodeAnalysis.CodeStyle { internal static class FormattingAnalyzerHelper { - internal static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context, FormatterState formatterState, DiagnosticDescriptor descriptor, OptionSet options) + internal static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context, FormattingProvider formattingProvider, DiagnosticDescriptor descriptor, SyntaxFormattingOptions options) { var tree = context.Tree; var cancellationToken = context.CancellationToken; var oldText = tree.GetText(cancellationToken); - var formattingChanges = Formatter.GetFormattedTextChanges(tree.GetRoot(cancellationToken), formatterState, options, cancellationToken); + + var formattingChanges = Formatter.GetFormattedTextChanges(tree.GetRoot(cancellationToken), formattingProvider, options, cancellationToken); // formattingChanges could include changes that impact a larger section of the original document than // necessary. Before reporting diagnostics, process the changes to minimize the span of individual diff --git a/src/CodeStyle/Core/CodeFixes/FormattingCodeFixHelper.cs b/src/CodeStyle/Core/CodeFixes/FormattingCodeFixHelper.cs index e3b7be03eac26..c6f074a545a51 100644 --- a/src/CodeStyle/Core/CodeFixes/FormattingCodeFixHelper.cs +++ b/src/CodeStyle/Core/CodeFixes/FormattingCodeFixHelper.cs @@ -2,27 +2,24 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Text; #if CODE_STYLE using Formatter = Microsoft.CodeAnalysis.Formatting.FormatterHelper; -using FormatterState = Microsoft.CodeAnalysis.Formatting.ISyntaxFormattingService; -using OptionSet = Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptions; +using FormattingProvider = Microsoft.CodeAnalysis.Formatting.ISyntaxFormattingService; #else -using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; -using FormatterState = Microsoft.CodeAnalysis.Workspace; +using FormattingProvider = Microsoft.CodeAnalysis.Host.HostWorkspaceServices; #endif namespace Microsoft.CodeAnalysis { internal static class FormattingCodeFixHelper { - internal static async Task FixOneAsync(SyntaxTree syntaxTree, FormatterState formatterState, OptionSet options, Diagnostic diagnostic, CancellationToken cancellationToken) + internal static async Task FixOneAsync(SyntaxTree syntaxTree, FormattingProvider formattingProvider, SyntaxFormattingOptions options, Diagnostic diagnostic, CancellationToken cancellationToken) { // The span to format is the full line(s) containing the diagnostic var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); @@ -33,11 +30,7 @@ internal static async Task FixOneAsync(SyntaxTree syntaxTree, Format text.Lines[diagnosticLinePositionSpan.End.Line].End); var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); -#if CODE_STYLE - var formattedRoot = Formatter.Format(root, formatterState, new[] { spanToFormat }, options, Formatter.GetDefaultFormattingRules(formatterState), cancellationToken); -#else - var formattedRoot = Formatter.Format(root, spanToFormat, formatterState, options, cancellationToken); -#endif + var formattedRoot = Formatter.Format(root, spanToFormat, formattingProvider, options, cancellationToken); return syntaxTree.WithRootAndOptions(formattedRoot, syntaxTree.Options); } diff --git a/src/CodeStyle/Core/CodeFixes/FormattingCodeFixProvider.cs b/src/CodeStyle/Core/CodeFixes/FormattingCodeFixProvider.cs index dbffe192f1881..b2782fc2ace61 100644 --- a/src/CodeStyle/Core/CodeFixes/FormattingCodeFixProvider.cs +++ b/src/CodeStyle/Core/CodeFixes/FormattingCodeFixProvider.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; @@ -11,16 +9,14 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Shared.Extensions; #if CODE_STYLE -using OptionSet = Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptions; using Formatter = Microsoft.CodeAnalysis.Formatting.FormatterHelper; #endif namespace Microsoft.CodeAnalysis.CodeStyle { - using ISyntaxFormattingService = ISyntaxFormattingService; - internal abstract class AbstractFormattingCodeFixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds @@ -46,17 +42,17 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) private async Task FixOneAsync(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken) { var options = await GetOptionsAsync(context.Document, cancellationToken).ConfigureAwait(false); - var tree = await context.Document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var tree = await context.Document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var updatedTree = await FormattingCodeFixHelper.FixOneAsync(tree, SyntaxFormattingService, options, diagnostic, cancellationToken).ConfigureAwait(false); return context.Document.WithText(await updatedTree.GetTextAsync(cancellationToken).ConfigureAwait(false)); } - private static async Task GetOptionsAsync(Document document, CancellationToken cancellationToken) + private static async Task GetOptionsAsync(Document document, CancellationToken cancellationToken) { - var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var analyzerConfigOptions = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(tree); - return analyzerConfigOptions; + return SyntaxFormattingOptions.Create(analyzerConfigOptions); } public sealed override FixAllProvider GetFixAllProvider() @@ -64,7 +60,7 @@ public sealed override FixAllProvider GetFixAllProvider() { var cancellationToken = context.CancellationToken; var options = await GetOptionsAsync(document, cancellationToken).ConfigureAwait(false); - var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var updatedSyntaxRoot = Formatter.Format(syntaxRoot, this.SyntaxFormattingService, options, cancellationToken); return document.WithSyntaxRoot(updatedSyntaxRoot); }); diff --git a/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs b/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs index 22f4c525fae87..e0f799d2b1bc1 100644 --- a/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs +++ b/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Composition; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.ExtractInterface; using Microsoft.CodeAnalysis.Host.Mef; @@ -44,7 +45,8 @@ public Task GetExtractInterfaceOptionsAsync( List conflictingTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, - string languageName) + string languageName, + CancellationToken cancellationToken) { this.AllExtractableMembers = extractableMembers; this.DefaultInterfaceName = defaultInterfaceName; diff --git a/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs index 5c7f149b05ce2..d597b344c6817 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs @@ -31,27 +31,27 @@ public CSharpSuppressionCodeFixProvider() { } - protected override SyntaxTriviaList CreatePragmaRestoreDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine) + protected override SyntaxTriviaList CreatePragmaRestoreDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine, CancellationToken cancellationToken) { var restoreKeyword = SyntaxFactory.Token(SyntaxKind.RestoreKeyword); - return CreatePragmaDirectiveTrivia(restoreKeyword, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine); + return CreatePragmaDirectiveTrivia(restoreKeyword, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine, cancellationToken); } protected override SyntaxTriviaList CreatePragmaDisableDirectiveTrivia( - Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine) + Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine, CancellationToken cancellationToken) { var disableKeyword = SyntaxFactory.Token(SyntaxKind.DisableKeyword); - return CreatePragmaDirectiveTrivia(disableKeyword, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine); + return CreatePragmaDirectiveTrivia(disableKeyword, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine, cancellationToken); } private static SyntaxTriviaList CreatePragmaDirectiveTrivia( - SyntaxToken disableOrRestoreKeyword, Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine) + SyntaxToken disableOrRestoreKeyword, Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine, CancellationToken cancellationToken) { var diagnosticId = GetOrMapDiagnosticId(diagnostic, out var includeTitle); var id = SyntaxFactory.IdentifierName(diagnosticId); var ids = new SeparatedSyntaxList().Add(id); var pragmaDirective = SyntaxFactory.PragmaWarningDirectiveTrivia(disableOrRestoreKeyword, ids, true); - pragmaDirective = (PragmaWarningDirectiveTriviaSyntax)formatNode(pragmaDirective); + pragmaDirective = (PragmaWarningDirectiveTriviaSyntax)formatNode(pragmaDirective, cancellationToken); var pragmaDirectiveTrivia = SyntaxFactory.Trivia(pragmaDirective); var endOfLineTrivia = SyntaxFactory.CarriageReturnLineFeed; var triviaList = SyntaxFactory.TriviaList(pragmaDirectiveTrivia); diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index b27637de58c64..f79d2c37b6f84 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -398,12 +398,13 @@ private static async Task> FindChangeSignatureR }); var annotatedNodes = newRoot.GetAnnotatedNodes(syntaxAnnotation: changeSignatureFormattingAnnotation); + var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(doc, cancellationToken).ConfigureAwait(false); var formattedRoot = Formatter.Format( newRoot, changeSignatureFormattingAnnotation, - doc.Project.Solution.Workspace, - options: await doc.GetOptionsAsync(cancellationToken).ConfigureAwait(false), + doc.Project.Solution.Workspace.Services, + options: formattingOptions, rules: GetFormattingRules(doc), cancellationToken: CancellationToken.None); diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaHelpers.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaHelpers.cs index 5a1bf7eed6ac2..20e102c4bfaab 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaHelpers.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaHelpers.cs @@ -104,8 +104,9 @@ internal static SyntaxToken GetNewStartTokenWithAddedPragma( TextSpan currentDiagnosticSpan, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, - Func formatNode, - bool isRemoveSuppression = false) + Func formatNode, + bool isRemoveSuppression, + CancellationToken cancellationToken) { var trivia = startToken.LeadingTrivia.ToImmutableArray(); var index = GetPositionForPragmaInsertion(trivia, currentDiagnosticSpan, fixer, isStartToken: true, triviaAtIndex: out var insertAfterTrivia); @@ -126,8 +127,8 @@ internal static SyntaxToken GetNewStartTokenWithAddedPragma( } var pragmaTrivia = !isRemoveSuppression - ? fixer.CreatePragmaDisableDirectiveTrivia(diagnostic, formatNode, needsLeadingEOL, needsTrailingEndOfLine: true) - : fixer.CreatePragmaRestoreDirectiveTrivia(diagnostic, formatNode, needsLeadingEOL, needsTrailingEndOfLine: true); + ? fixer.CreatePragmaDisableDirectiveTrivia(diagnostic, formatNode, needsLeadingEOL, needsTrailingEndOfLine: true, cancellationToken) + : fixer.CreatePragmaRestoreDirectiveTrivia(diagnostic, formatNode, needsLeadingEOL, needsTrailingEndOfLine: true, cancellationToken); return startToken.WithLeadingTrivia(trivia.InsertRange(index, pragmaTrivia)); } @@ -155,8 +156,9 @@ internal static SyntaxToken GetNewEndTokenWithAddedPragma( TextSpan currentDiagnosticSpan, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, - Func formatNode, - bool isRemoveSuppression = false) + Func formatNode, + bool isRemoveSuppression, + CancellationToken cancellationToken) { ImmutableArray trivia; var isEOF = fixer.IsEndOfFileToken(endToken); @@ -186,8 +188,8 @@ internal static SyntaxToken GetNewEndTokenWithAddedPragma( } var pragmaTrivia = !isRemoveSuppression - ? fixer.CreatePragmaRestoreDirectiveTrivia(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL) - : fixer.CreatePragmaDisableDirectiveTrivia(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL); + ? fixer.CreatePragmaRestoreDirectiveTrivia(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL, cancellationToken) + : fixer.CreatePragmaDisableDirectiveTrivia(diagnostic, formatNode, needsLeadingEndOfLine: true, needsTrailingEndOfLine: needsTrailingEOL, cancellationToken); if (isEOF) { diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningCodeAction.cs index 3ceb8b0e9ddcf..bb2f8de920e15 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningCodeAction.cs @@ -16,12 +16,14 @@ internal sealed class PragmaWarningCodeAction : AbstractSuppressionCodeAction, I { private readonly SuppressionTargetInfo _suppressionTargetInfo; private readonly Document _document; + private readonly SyntaxFormattingOptions _options; private readonly Diagnostic _diagnostic; private readonly bool _forFixMultipleContext; public static PragmaWarningCodeAction Create( SuppressionTargetInfo suppressionTargetInfo, Document document, + SyntaxFormattingOptions options, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer) { @@ -29,12 +31,13 @@ public static PragmaWarningCodeAction Create( // the trailing trivia on its previous token (and similarly normalize trailing trivia for end token). PragmaHelpers.NormalizeTriviaOnTokens(fixer, ref document, ref suppressionTargetInfo); - return new PragmaWarningCodeAction(suppressionTargetInfo, document, diagnostic, fixer); + return new PragmaWarningCodeAction(suppressionTargetInfo, document, options, diagnostic, fixer); } private PragmaWarningCodeAction( SuppressionTargetInfo suppressionTargetInfo, Document document, + SyntaxFormattingOptions options, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, bool forFixMultipleContext = false) @@ -42,12 +45,14 @@ private PragmaWarningCodeAction( { _suppressionTargetInfo = suppressionTargetInfo; _document = document; + _options = options; _diagnostic = diagnostic; _forFixMultipleContext = forFixMultipleContext; } public PragmaWarningCodeAction CloneForFixMultipleContext() - => new(_suppressionTargetInfo, _document, _diagnostic, Fixer, forFixMultipleContext: true); + => new(_suppressionTargetInfo, _document, _options, _diagnostic, Fixer, forFixMultipleContext: true); + protected override string DiagnosticIdForEquivalenceKey => _forFixMultipleContext ? string.Empty : _diagnostic.Id; @@ -63,13 +68,13 @@ public async Task GetChangedDocumentAsync(bool includeStartTokenChange (startToken, currentDiagnosticSpan) => { return includeStartTokenChange - ? PragmaHelpers.GetNewStartTokenWithAddedPragma(startToken, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode) + ? PragmaHelpers.GetNewStartTokenWithAddedPragma(startToken, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode, isRemoveSuppression: false, cancellationToken) : startToken; }, (endToken, currentDiagnosticSpan) => { return includeEndTokenChange - ? PragmaHelpers.GetNewEndTokenWithAddedPragma(endToken, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode) + ? PragmaHelpers.GetNewEndTokenWithAddedPragma(endToken, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode, isRemoveSuppression: false, cancellationToken) : endToken; }, cancellationToken).ConfigureAwait(false); @@ -78,8 +83,8 @@ public async Task GetChangedDocumentAsync(bool includeStartTokenChange public SyntaxToken StartToken_TestOnly => _suppressionTargetInfo.StartToken; public SyntaxToken EndToken_TestOnly => _suppressionTargetInfo.EndToken; - private SyntaxNode FormatNode(SyntaxNode node) - => Formatter.Format(node, _document.Project.Solution.Workspace); + private SyntaxNode FormatNode(SyntaxNode node, CancellationToken cancellationToken) + => Formatter.Format(node, _document.Project.Solution.Workspace.Services, _options, cancellationToken); } } } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs index 52df1bf737b14..c1d861e38b421 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Formatting; namespace Microsoft.CodeAnalysis.CodeFixes.Suppression { @@ -35,7 +36,8 @@ public static async Task CreateAsync( } else if (documentOpt != null && !SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(diagnostic)) { - return PragmaRemoveAction.Create(suppressionTargetInfo, documentOpt, diagnostic, fixer); + var options = await SyntaxFormattingOptions.FromDocumentAsync(documentOpt, cancellationToken).ConfigureAwait(false); + return PragmaRemoveAction.Create(suppressionTargetInfo, documentOpt, options, diagnostic, fixer); } else { diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs index 23155cd268212..856de08fb5619 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs @@ -25,11 +25,13 @@ internal abstract partial class RemoveSuppressionCodeAction private class PragmaRemoveAction : RemoveSuppressionCodeAction, IPragmaBasedCodeAction { private readonly Document _document; + private readonly SyntaxFormattingOptions _options; private readonly SuppressionTargetInfo _suppressionTargetInfo; public static PragmaRemoveAction Create( SuppressionTargetInfo suppressionTargetInfo, Document document, + SyntaxFormattingOptions options, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer) { @@ -37,23 +39,25 @@ public static PragmaRemoveAction Create( // the trailing trivia on its previous token (and similarly normalize trailing trivia for end token). PragmaHelpers.NormalizeTriviaOnTokens(fixer, ref document, ref suppressionTargetInfo); - return new PragmaRemoveAction(suppressionTargetInfo, document, diagnostic, fixer); + return new PragmaRemoveAction(suppressionTargetInfo, document, options, diagnostic, fixer); } private PragmaRemoveAction( SuppressionTargetInfo suppressionTargetInfo, Document document, + SyntaxFormattingOptions options, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, bool forFixMultipleContext = false) : base(diagnostic, fixer, forFixMultipleContext) { _document = document; + _options = options; _suppressionTargetInfo = suppressionTargetInfo; } public override RemoveSuppressionCodeAction CloneForFixMultipleContext() - => new PragmaRemoveAction(_suppressionTargetInfo, _document, _diagnostic, Fixer, forFixMultipleContext: true); + => new PragmaRemoveAction(_suppressionTargetInfo, _document, _options, _diagnostic, Fixer, forFixMultipleContext: true); public override SyntaxTree SyntaxTreeToModify => _suppressionTargetInfo.StartToken.SyntaxTree; @@ -81,11 +85,11 @@ public async Task GetChangedDocumentAsync(bool includeStartTokenChange } SyntaxToken getNewStartToken(SyntaxToken startToken, TextSpan currentDiagnosticSpan) => includeStartTokenChange - ? GetNewTokenWithModifiedPragma(startToken, currentDiagnosticSpan, add, toggle, indexOfLeadingPragmaDisableToRemove, isStartToken: true) + ? GetNewTokenWithModifiedPragma(startToken, currentDiagnosticSpan, add, toggle, indexOfLeadingPragmaDisableToRemove, isStartToken: true, cancellationToken) : startToken; SyntaxToken getNewEndToken(SyntaxToken endToken, TextSpan currentDiagnosticSpan) => includeEndTokenChange - ? GetNewTokenWithModifiedPragma(endToken, currentDiagnosticSpan, add, toggle, indexOfTrailingPragmaEnableToRemove, isStartToken: false) + ? GetNewTokenWithModifiedPragma(endToken, currentDiagnosticSpan, add, toggle, indexOfTrailingPragmaEnableToRemove, isStartToken: false, cancellationToken) : endToken; return await PragmaHelpers.GetChangeDocumentWithPragmaAdjustedAsync( @@ -151,22 +155,22 @@ private static bool CanRemovePragmaTrivia(SyntaxToken token, Diagnostic diagnost return false; } - private SyntaxToken GetNewTokenWithModifiedPragma(SyntaxToken token, TextSpan currentDiagnosticSpan, bool add, bool toggle, int indexOfTriviaToRemoveOrToggle, bool isStartToken) + private SyntaxToken GetNewTokenWithModifiedPragma(SyntaxToken token, TextSpan currentDiagnosticSpan, bool add, bool toggle, int indexOfTriviaToRemoveOrToggle, bool isStartToken, CancellationToken cancellationToken) { return add - ? GetNewTokenWithAddedPragma(token, currentDiagnosticSpan, isStartToken) + ? GetNewTokenWithAddedPragma(token, currentDiagnosticSpan, isStartToken, cancellationToken) : GetNewTokenWithRemovedOrToggledPragma(token, indexOfTriviaToRemoveOrToggle, isStartToken, toggle); } - private SyntaxToken GetNewTokenWithAddedPragma(SyntaxToken token, TextSpan currentDiagnosticSpan, bool isStartToken) + private SyntaxToken GetNewTokenWithAddedPragma(SyntaxToken token, TextSpan currentDiagnosticSpan, bool isStartToken, CancellationToken cancellationToken) { if (isStartToken) { - return PragmaHelpers.GetNewStartTokenWithAddedPragma(token, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode, isRemoveSuppression: true); + return PragmaHelpers.GetNewStartTokenWithAddedPragma(token, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode, isRemoveSuppression: true, cancellationToken); } else { - return PragmaHelpers.GetNewEndTokenWithAddedPragma(token, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode, isRemoveSuppression: true); + return PragmaHelpers.GetNewEndTokenWithAddedPragma(token, currentDiagnosticSpan, _diagnostic, Fixer, FormatNode, isRemoveSuppression: true, cancellationToken); } } @@ -213,8 +217,8 @@ private async Task IsDiagnosticSuppressedBeforeLeadingPragmaAsync(int inde public SyntaxToken StartToken_TestOnly => _suppressionTargetInfo.StartToken; public SyntaxToken EndToken_TestOnly => _suppressionTargetInfo.EndToken; - private SyntaxNode FormatNode(SyntaxNode node) - => Formatter.Format(node, _document.Project.Solution.Workspace); + private SyntaxNode FormatNode(SyntaxNode node, CancellationToken cancellationToken) + => Formatter.Format(node, _document.Project.Solution.Workspace.Services, _options, cancellationToken); } } } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs index 68c9393666f94..3a8ff7d727826 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs @@ -42,8 +42,8 @@ public FixAllProvider GetFixAllProvider() public bool IsFixableDiagnostic(Diagnostic diagnostic) => SuppressionHelpers.CanBeSuppressed(diagnostic) || SuppressionHelpers.CanBeUnsuppressed(diagnostic); - protected abstract SyntaxTriviaList CreatePragmaDisableDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine); - protected abstract SyntaxTriviaList CreatePragmaRestoreDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine); + protected abstract SyntaxTriviaList CreatePragmaDisableDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine, CancellationToken cancellationToken); + protected abstract SyntaxTriviaList CreatePragmaRestoreDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine, CancellationToken cancellationToken); protected abstract SyntaxNode AddGlobalSuppressMessageAttribute( SyntaxNode newRoot, @@ -199,6 +199,7 @@ private async Task> GetSuppressionsAsync( skipSuppressMessage = suppressMessageAttribute == null || !suppressMessageAttribute.IsAttribute(); } + var lazyFormattingOptions = (SyntaxFormattingOptions?)null; var result = ArrayBuilder.GetInstance(); foreach (var diagnostic in diagnostics) { @@ -208,7 +209,8 @@ private async Task> GetSuppressionsAsync( if (diagnostic.Location.IsInSource && documentOpt != null) { // pragma warning disable. - nestedActions.Add(PragmaWarningCodeAction.Create(suppressionTargetInfo, documentOpt, diagnostic, this)); + lazyFormattingOptions ??= await SyntaxFormattingOptions.FromDocumentAsync(documentOpt, cancellationToken).ConfigureAwait(false); + nestedActions.Add(PragmaWarningCodeAction.Create(suppressionTargetInfo, documentOpt, lazyFormattingOptions.Value, diagnostic, this)); } // SuppressMessageAttribute suppression is not supported for compiler diagnostics. diff --git a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs index 55d6bdcacbbb5..eaa49c241a508 100644 --- a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs @@ -140,8 +140,7 @@ private static async Task ApplyFixesAsync(Document document, Immutable private static async Task CleanUpNewLinesAsync(Document document, IEnumerable insertSpans, CancellationToken cancellationToken) { - var languageFormatter = document.GetRequiredLanguageService(); - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var options = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); var newDocument = document; @@ -150,21 +149,19 @@ private static async Task CleanUpNewLinesAsync(Document document, IEnu // to separate the import section from the other content. foreach (var insertSpan in insertSpans) { - newDocument = await CleanUpNewLinesAsync(newDocument, insertSpan, languageFormatter, options, cancellationToken).ConfigureAwait(false); + newDocument = await CleanUpNewLinesAsync(newDocument, insertSpan, options, cancellationToken).ConfigureAwait(false); } return newDocument; } - private static async Task CleanUpNewLinesAsync(Document document, TextSpan insertSpan, ISyntaxFormattingService languageFormatter, OptionSet optionSet, CancellationToken cancellationToken) + private static async Task CleanUpNewLinesAsync(Document document, TextSpan insertSpan, SyntaxFormattingOptions options, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - var optionService = document.Project.Solution.Workspace.Services.GetRequiredService(); - var shouldUseFormattingSpanCollapse = optionSet.GetOption(FormattingBehaviorOptions.AllowDisjointSpanMerging); - var options = optionSet.AsAnalyzerConfigOptions(optionService, root.Language); + var services = document.Project.Solution.Workspace.Services; - var textChanges = languageFormatter.Format(root, new[] { insertSpan }, shouldUseFormattingSpanCollapse, options, new[] { new CleanUpNewLinesFormatter(text) }, cancellationToken).GetTextChanges(cancellationToken); + var textChanges = Formatter.GetFormattedTextChanges(root, new[] { insertSpan }, services, options, rules: new[] { new CleanUpNewLinesFormatter(text) }, cancellationToken); // If there are no changes then, do less work. if (textChanges.Count == 0) diff --git a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs index b2c6802a6bddd..92c99eb637d8c 100644 --- a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs @@ -623,7 +623,9 @@ private async Task FixDeclarationDocumentAsync( .WithAdditionalAnnotations(Formatter.Annotation); // Need to invoke formatter explicitly since we are doing the diff merge ourselves. - root = Formatter.Format(root, Formatter.Annotation, documentWithAddedImports.Project.Solution.Workspace, optionSet, cancellationToken); + var services = documentWithAddedImports.Project.Solution.Workspace.Services; + var formattingOptions = SyntaxFormattingOptions.Create(optionSet, services, root.Language); + root = Formatter.Format(root, Formatter.Annotation, services, formattingOptions, cancellationToken); root = root.WithAdditionalAnnotations(Simplifier.Annotation); var formattedDocument = documentWithAddedImports.WithSyntaxRoot(root); diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index fbefd43962602..11ca09855708a 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -250,7 +250,7 @@ private async Task ExtractInterfaceToSameFileAsync( navigationDocumentId: refactoringResult.DocumentToExtractFrom.Id); } - internal static Task GetExtractInterfaceOptionsAsync( + internal static async Task GetExtractInterfaceOptionsAsync( Document document, INamedTypeSymbol type, IEnumerable extractableMembers, @@ -262,10 +262,11 @@ internal static Task GetExtractInterfaceOptionsAs var defaultInterfaceName = NameGenerator.GenerateUniqueName(candidateInterfaceName, name => !conflictingTypeNames.Contains(name)); var syntaxFactsService = document.GetLanguageService(); var notificationService = document.Project.Solution.Workspace.Services.GetService(); - var generatedNameTypeParameterSuffix = ExtractTypeHelpers.GetTypeParameterSuffix(document, type, extractableMembers); + var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + var generatedNameTypeParameterSuffix = ExtractTypeHelpers.GetTypeParameterSuffix(document, formattingOptions, type, extractableMembers, cancellationToken); var service = document.Project.Solution.Workspace.Services.GetService(); - return service.GetExtractInterfaceOptionsAsync( + return await service.GetExtractInterfaceOptionsAsync( syntaxFactsService, notificationService, extractableMembers.ToList(), @@ -273,7 +274,8 @@ internal static Task GetExtractInterfaceOptionsAs conflictingTypeNames.ToList(), containingNamespace, generatedNameTypeParameterSuffix, - document.Project.Language); + document.Project.Language, + cancellationToken).ConfigureAwait(false); } private static async Task GetFormattedSolutionAsync(Solution unformattedSolution, IEnumerable documentIds, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs b/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs index 4bf9ed0dd0eb8..025edd6135834 100644 --- a/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs +++ b/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs @@ -5,6 +5,7 @@ #nullable disable using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServices; @@ -22,6 +23,7 @@ Task GetExtractInterfaceOptionsAsync( List conflictingTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, - string languageName); + string languageName, + CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs b/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs index a4344dbd5a215..b47327e345306 100644 --- a/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs +++ b/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs @@ -94,8 +94,12 @@ internal ExtractMethodResult( var simplifiedDocument = await Simplifier.ReduceAsync(annotatedDocument, Simplifier.Annotation, optionSet: null, cancellationToken).ConfigureAwait(false); var simplifiedRoot = await simplifiedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var documentOptions = await DocumentWithoutFinalFormatting.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - var formattedDocument = simplifiedDocument.WithSyntaxRoot(Formatter.Format(simplifiedRoot, Formatter.Annotation, DocumentWithoutFinalFormatting.Project.Solution.Workspace, documentOptions, FormattingRules, cancellationToken)); + var options = await SyntaxFormattingOptions.FromDocumentAsync(DocumentWithoutFinalFormatting, cancellationToken).ConfigureAwait(false); + var services = DocumentWithoutFinalFormatting.Project.Solution.Workspace.Services; + + var formattedDocument = simplifiedDocument.WithSyntaxRoot( + Formatter.Format(simplifiedRoot, Formatter.Annotation, services, options, FormattingRules, cancellationToken)); + var formattedRoot = await formattedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); return (formattedDocument, formattedRoot.GetAnnotatedTokens(annotation).Single()); } diff --git a/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs b/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs index 961e87a83bdb5..ba339b3690055 100644 --- a/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs +++ b/src/Features/Core/Portable/Formatting/FormattingCodeFixProvider.cs @@ -46,9 +46,9 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) private static async Task FixOneAsync(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken) { - var options = await context.Document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var options = await SyntaxFormattingOptions.FromDocumentAsync(context.Document, cancellationToken).ConfigureAwait(false); var tree = await context.Document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - var formattedTree = await FormattingCodeFixHelper.FixOneAsync(tree, context.Document.Project.Solution.Workspace, options, diagnostic, cancellationToken).ConfigureAwait(false); + var formattedTree = await FormattingCodeFixHelper.FixOneAsync(tree, context.Document.Project.Solution.Workspace.Services, options, diagnostic, cancellationToken).ConfigureAwait(false); return context.Document.WithSyntaxRoot(await formattedTree.GetRootAsync(cancellationToken).ConfigureAwait(false)); } diff --git a/src/Features/Core/Portable/Formatting/FormattingDiagnosticAnalyzer.cs b/src/Features/Core/Portable/Formatting/FormattingDiagnosticAnalyzer.cs index ab0ee07a389fb..61acf0f0ccee5 100644 --- a/src/Features/Core/Portable/Formatting/FormattingDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/Formatting/FormattingDiagnosticAnalyzer.cs @@ -38,10 +38,10 @@ private void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context) var tree = context.Tree; var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetAnalyzerOptionSet(tree, cancellationToken); + var options = SyntaxFormattingOptions.Create(optionSet, workspaceAnalyzerOptions.Services, tree.Options.Language); - var options = context.Options.GetAnalyzerOptionSet(tree, cancellationToken); - var workspace = workspaceAnalyzerOptions.Services.Workspace; - FormattingAnalyzerHelper.AnalyzeSyntaxTree(context, workspace, Descriptor, options); + FormattingAnalyzerHelper.AnalyzeSyntaxTree(context, workspaceAnalyzerOptions.Services, Descriptor, options); } } } diff --git a/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs b/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs index f61368657e11f..c075b5a90e15c 100644 --- a/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs +++ b/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs @@ -109,7 +109,7 @@ internal static class ExtractTypeHelpers return (formattedDocument, typeAnnotation); } - public static string GetTypeParameterSuffix(Document document, INamedTypeSymbol type, IEnumerable extractableMembers) + public static string GetTypeParameterSuffix(Document document, SyntaxFormattingOptions options, INamedTypeSymbol type, IEnumerable extractableMembers, CancellationToken cancellationToken) { var typeParameters = GetRequiredTypeParametersForMembers(type, extractableMembers); @@ -121,7 +121,7 @@ public static string GetTypeParameterSuffix(Document document, INamedTypeSymbol var typeParameterNames = typeParameters.SelectAsArray(p => p.Name); var syntaxGenerator = SyntaxGenerator.GetGenerator(document); - return Formatter.Format(syntaxGenerator.SyntaxGeneratorInternal.TypeParameterList(typeParameterNames), document.Project.Solution.Workspace).ToString(); + return Formatter.Format(syntaxGenerator.SyntaxGeneratorInternal.TypeParameterList(typeParameterNames), document.Project.Solution.Workspace.Services, options, cancellationToken).ToString(); } public static ImmutableArray GetRequiredTypeParametersForMembers(INamedTypeSymbol type, IEnumerable includedMembers) diff --git a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs index 795ebf87b57bf..1da942098fcb3 100644 --- a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs @@ -280,8 +280,8 @@ private async Task FormatAsync(SyntaxNode newRoot, Document document return newRoot; } - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - return Formatter.Format(newRoot, SpecializedFormattingAnnotation, document.Project.Solution.Workspace, options, formattingRules, cancellationToken); + var options = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + return Formatter.Format(newRoot, SpecializedFormattingAnnotation, document.Project.Solution.Workspace.Services, options, formattingRules, cancellationToken); } private static bool IsWrittenToOutsideOfConstructorOrProperty( diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb index ee3efba7ebf94..13610d84c62bb 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb @@ -24,18 +24,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Suppression Public Sub New() End Sub - Protected Overrides Function CreatePragmaRestoreDirectiveTrivia(diagnostic As Diagnostic, formatNode As Func(Of SyntaxNode, SyntaxNode), needsLeadingEndOfLine As Boolean, needsTrailingEndOfLine As Boolean) As SyntaxTriviaList + Protected Overrides Function CreatePragmaRestoreDirectiveTrivia(diagnostic As Diagnostic, formatNode As Func(Of SyntaxNode, CancellationToken, SyntaxNode), needsLeadingEndOfLine As Boolean, needsTrailingEndOfLine As Boolean, cancellationToken As CancellationToken) As SyntaxTriviaList Dim includeTitle As Boolean Dim errorCodes = GetErrorCodes(diagnostic, includeTitle) Dim pragmaDirective = SyntaxFactory.EnableWarningDirectiveTrivia(errorCodes) - Return CreatePragmaDirectiveTrivia(pragmaDirective, includeTitle, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine) + Return CreatePragmaDirectiveTrivia(pragmaDirective, includeTitle, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine, cancellationToken) End Function - Protected Overrides Function CreatePragmaDisableDirectiveTrivia(diagnostic As Diagnostic, formatNode As Func(Of SyntaxNode, SyntaxNode), needsLeadingEndOfLine As Boolean, needsTrailingEndOfLine As Boolean) As SyntaxTriviaList + Protected Overrides Function CreatePragmaDisableDirectiveTrivia(diagnostic As Diagnostic, formatNode As Func(Of SyntaxNode, CancellationToken, SyntaxNode), needsLeadingEndOfLine As Boolean, needsTrailingEndOfLine As Boolean, cancellationToken As CancellationToken) As SyntaxTriviaList Dim includeTitle As Boolean Dim errorCodes = GetErrorCodes(diagnostic, includeTitle) Dim pragmaDirective = SyntaxFactory.DisableWarningDirectiveTrivia(errorCodes) - Return CreatePragmaDirectiveTrivia(pragmaDirective, includeTitle, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine) + Return CreatePragmaDirectiveTrivia(pragmaDirective, includeTitle, diagnostic, formatNode, needsLeadingEndOfLine, needsTrailingEndOfLine, cancellationToken) End Function Private Shared Function GetErrorCodes(diagnostic As Diagnostic, ByRef includeTitle As Boolean) As SeparatedSyntaxList(Of IdentifierNameSyntax) @@ -47,8 +47,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Suppression Return New SeparatedSyntaxList(Of IdentifierNameSyntax)().Add(SyntaxFactory.IdentifierName(text)) End Function - Private Shared Function CreatePragmaDirectiveTrivia(enableOrDisablePragmaDirective As StructuredTriviaSyntax, includeTitle As Boolean, diagnostic As Diagnostic, formatNode As Func(Of SyntaxNode, SyntaxNode), needsLeadingEndOfLine As Boolean, needsTrailingEndOfLine As Boolean) As SyntaxTriviaList - enableOrDisablePragmaDirective = CType(formatNode(enableOrDisablePragmaDirective), StructuredTriviaSyntax) + Private Shared Function CreatePragmaDirectiveTrivia( + enableOrDisablePragmaDirective As StructuredTriviaSyntax, + includeTitle As Boolean, + diagnostic As Diagnostic, + formatNode As Func(Of SyntaxNode, CancellationToken, SyntaxNode), + needsLeadingEndOfLine As Boolean, + needsTrailingEndOfLine As Boolean, + cancellationToken As CancellationToken) As SyntaxTriviaList + + enableOrDisablePragmaDirective = CType(formatNode(enableOrDisablePragmaDirective, cancellationToken), StructuredTriviaSyntax) Dim pragmaDirectiveTrivia = SyntaxFactory.Trivia(enableOrDisablePragmaDirective) Dim endOfLineTrivia = SyntaxFactory.ElasticCarriageReturnLineFeed Dim triviaList = SyntaxFactory.TriviaList(pragmaDirectiveTrivia) diff --git a/src/Tools/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs b/src/Tools/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs index ffcb263fbf3d4..08a2264ccfe8c 100644 --- a/src/Tools/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs +++ b/src/Tools/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Composition; using System.Text; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.ExternalAccess.OmniSharp.ExtractInterface; using Microsoft.CodeAnalysis.ExtractInterface; @@ -28,7 +29,16 @@ public OmniSharpExtractInterfaceOptionsService(IOmniSharpExtractInterfaceOptions _omniSharpExtractInterfaceOptionsService = omniSharpExtractInterfaceOptionsService; } - public async Task GetExtractInterfaceOptionsAsync(ISyntaxFactsService syntaxFactsService, INotificationService notificationService, List extractableMembers, string defaultInterfaceName, List conflictingTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName) + public async Task GetExtractInterfaceOptionsAsync( + ISyntaxFactsService syntaxFactsService, + INotificationService notificationService, + List extractableMembers, + string defaultInterfaceName, + List conflictingTypeNames, + string defaultNamespace, + string generatedNameTypeParameterSuffix, + string languageName, + CancellationToken cancellationToken) { var result = await _omniSharpExtractInterfaceOptionsService.GetExtractInterfaceOptionsAsync(extractableMembers, defaultInterfaceName).ConfigureAwait(false); return new( diff --git a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs index 888947e05c4b5..91ac13f70a516 100644 --- a/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs +++ b/src/VisualStudio/Core/Def/Implementation/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Composition; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; @@ -43,9 +44,10 @@ public async Task GetExtractInterfaceOptionsAsync List allTypeNames, string defaultNamespace, string generatedNameTypeParameterSuffix, - string languageName) + string languageName, + CancellationToken cancellationToken) { - await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); var viewModel = new ExtractInterfaceDialogViewModel( syntaxFactsService, diff --git a/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.Indenter.cs b/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.Indenter.cs index 9768531512415..2f68fcc43c43a 100644 --- a/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.Indenter.cs +++ b/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.Indenter.cs @@ -24,11 +24,11 @@ protected override bool ShouldUseTokenIndenter(Indenter indenter, out SyntaxToke protected override ISmartTokenFormatter CreateSmartTokenFormatter(Indenter indenter) { - var workspace = indenter.Document.Project.Solution.Workspace; - var formattingRuleFactory = workspace.Services.GetRequiredService(); + var services = indenter.Document.Project.Solution.Workspace.Services; + var formattingRuleFactory = services.GetRequiredService(); var rules = formattingRuleFactory.CreateRule(indenter.Document.Document, indenter.LineToBeIndented.Start).Concat(Formatter.GetDefaultFormattingRules(indenter.Document.Document)); - - return new CSharpSmartTokenFormatter(indenter.OptionSet, rules, indenter.Root); + var formattingOptions = SyntaxFormattingOptions.Create(indenter.OptionSet, services, indenter.Document.Project.Language); + return new CSharpSmartTokenFormatter(formattingOptions, rules, indenter.Root); } protected override IndentationResult? GetDesiredIndentationWorker(Indenter indenter, SyntaxToken? tokenOpt, SyntaxTrivia? triviaOpt) diff --git a/src/Workspaces/CSharp/Portable/Indentation/CSharpSmartTokenFormatter.cs b/src/Workspaces/CSharp/Portable/Indentation/CSharpSmartTokenFormatter.cs index a6e8b6760756a..874a56a3e1410 100644 --- a/src/Workspaces/CSharp/Portable/Indentation/CSharpSmartTokenFormatter.cs +++ b/src/Workspaces/CSharp/Portable/Indentation/CSharpSmartTokenFormatter.cs @@ -22,21 +22,20 @@ namespace Microsoft.CodeAnalysis.CSharp.Indentation { internal class CSharpSmartTokenFormatter : ISmartTokenFormatter { - private readonly OptionSet _optionSet; + private readonly SyntaxFormattingOptions _options; private readonly IEnumerable _formattingRules; private readonly CompilationUnitSyntax _root; public CSharpSmartTokenFormatter( - OptionSet optionSet, + SyntaxFormattingOptions options, IEnumerable formattingRules, CompilationUnitSyntax root) { - Contract.ThrowIfNull(optionSet); Contract.ThrowIfNull(formattingRules); Contract.ThrowIfNull(root); - _optionSet = optionSet; + _options = options; _formattingRules = formattingRules; _root = root; @@ -61,9 +60,7 @@ public IList FormatRange( smartTokenformattingRules = (new NoLineChangeFormattingRule()).Concat(_formattingRules); } - var formatter = services.GetRequiredLanguageService(_root.Language); - return formatter.GetFormattingResult(_root, new[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, _optionSet, services, smartTokenformattingRules, cancellationToken). - GetTextChanges(cancellationToken); + return Formatter.GetFormattedTextChanges(_root, new[] { TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End) }, services, _options, smartTokenformattingRules, cancellationToken); } private static bool CloseBraceOfTryOrDoBlock(SyntaxToken endToken) @@ -103,9 +100,9 @@ public async Task> FormatTokenAsync( } } - var smartTokenformattingRules = (new SmartTokenFormattingRule()).Concat(_formattingRules); + var smartTokenformattingRules = new SmartTokenFormattingRule().Concat(_formattingRules); var adjustedStartPosition = previousToken.SpanStart; - var indentStyle = _optionSet.GetOption(FormattingOptions.SmartIndent, LanguageNames.CSharp); + var indentStyle = _options.Options.GetOption(FormattingOptions.SmartIndent); if (token.IsKind(SyntaxKind.OpenBraceToken) && indentStyle != FormattingOptions.IndentStyle.Smart) { @@ -117,9 +114,7 @@ public async Task> FormatTokenAsync( } } - var formatter = services.GetRequiredLanguageService(_root.Language); - return formatter.GetFormattingResult(_root, new[] { TextSpan.FromBounds(adjustedStartPosition, adjustedEndPosition) }, _optionSet, services, smartTokenformattingRules, cancellationToken). - GetTextChanges(cancellationToken); + return Formatter.GetFormattedTextChanges(_root, new[] { TextSpan.FromBounds(adjustedStartPosition, adjustedEndPosition) }, services, _options, smartTokenformattingRules, cancellationToken); } private class NoLineChangeFormattingRule : AbstractFormattingRule diff --git a/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs b/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs index 2f827d24b1cd1..b9a3a9f39cf3c 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs @@ -11,15 +11,14 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeCleanup.Providers; using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared; using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; +using Microsoft.CodeAnalysis.Formatting; namespace Microsoft.CodeAnalysis.CodeCleanup { @@ -28,7 +27,7 @@ internal abstract class AbstractCodeCleanerService : ICodeCleanerService public abstract ImmutableArray GetDefaultProviders(); protected abstract ImmutableArray GetSpansToAvoid(SyntaxNode root); - public async Task CleanupAsync(Document document, ImmutableArray spans, OptionSet options, ImmutableArray providers, CancellationToken cancellationToken) + public async Task CleanupAsync(Document document, ImmutableArray spans, SyntaxFormattingOptions options, ImmutableArray providers, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.CodeCleanup_CleanupAsync, cancellationToken)) { @@ -72,7 +71,7 @@ public async Task CleanupAsync(Document document, ImmutableArray CleanupAsync(SyntaxNode root, ImmutableArray spans, OptionSet options, HostWorkspaceServices services, ImmutableArray providers, CancellationToken cancellationToken) + public async Task CleanupAsync(SyntaxNode root, ImmutableArray spans, SyntaxFormattingOptions options, HostWorkspaceServices services, ImmutableArray providers, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.CodeCleanup_Cleanup, cancellationToken)) { @@ -456,7 +455,7 @@ private static bool CleanupWholeNode(TextSpan nodeSpan, ImmutableArray private async Task IterateAllCodeCleanupProvidersAsync( Document originalDocument, Document annotatedDocument, - OptionSet options, + SyntaxFormattingOptions options, Func> spanGetter, ImmutableArray codeCleaners, CancellationToken cancellationToken) @@ -537,7 +536,7 @@ private ImmutableArray GetSpans( private async Task IterateAllCodeCleanupProvidersAsync( SyntaxNode originalRoot, SyntaxNode annotatedRoot, - OptionSet options, + SyntaxFormattingOptions options, Func> spanGetter, HostWorkspaceServices services, ImmutableArray codeCleaners, diff --git a/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs b/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs index 1ae8fd14ee9bf..aee43fe399a36 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.Formatting; namespace Microsoft.CodeAnalysis.CodeCleanup { @@ -77,7 +78,7 @@ public static Task CleanupAsync(Document document, TextSpan span, Immu public static async Task CleanupAsync(Document document, ImmutableArray spans, ImmutableArray providers = default, CancellationToken cancellationToken = default) { var cleanupService = document.GetRequiredLanguageService(); - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var options = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); return await cleanupService.CleanupAsync(document, spans, options, providers, cancellationToken).ConfigureAwait(false); } @@ -95,7 +96,8 @@ public static Task CleanupAsync(SyntaxNode root, TextSpan span, Opti public static Task CleanupAsync(SyntaxNode root, ImmutableArray spans, OptionSet options, HostWorkspaceServices services, ImmutableArray providers = default, CancellationToken cancellationToken = default) { var cleanupService = services.GetLanguageServices(root.Language).GetRequiredService(); - return cleanupService.CleanupAsync(root, spans, options, services, providers, cancellationToken); + var formattingOptions = SyntaxFormattingOptions.Create(options, services, root.Language); + return cleanupService.CleanupAsync(root, spans, formattingOptions, services, providers, cancellationToken); } } } diff --git a/src/Workspaces/Core/Portable/CodeCleanup/ICodeCleanerService.cs b/src/Workspaces/Core/Portable/CodeCleanup/ICodeCleanerService.cs index b144328102b26..f9f47a1551ea9 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/ICodeCleanerService.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/ICodeCleanerService.cs @@ -6,7 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeCleanup.Providers; -using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Text; @@ -27,13 +27,13 @@ internal interface ICodeCleanerService : ILanguageService /// /// This will run all provided code cleaners in an order that is given to the method. /// - Task CleanupAsync(Document document, ImmutableArray spans, OptionSet options, ImmutableArray providers, CancellationToken cancellationToken); + Task CleanupAsync(Document document, ImmutableArray spans, SyntaxFormattingOptions options, ImmutableArray providers, CancellationToken cancellationToken); /// /// This will run all provided code cleaners in an order that is given to the method. /// /// This will do cleanups that don't require any semantic information. /// - Task CleanupAsync(SyntaxNode root, ImmutableArray spans, OptionSet options, HostWorkspaceServices services, ImmutableArray providers, CancellationToken cancellationToken); + Task CleanupAsync(SyntaxNode root, ImmutableArray spans, SyntaxFormattingOptions options, HostWorkspaceServices services, ImmutableArray providers, CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/CodeCleanup/Providers/FormatCodeCleanupProvider.cs b/src/Workspaces/Core/Portable/CodeCleanup/Providers/FormatCodeCleanupProvider.cs index e60fae987e8fb..073fb0fc3eafa 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/Providers/FormatCodeCleanupProvider.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/Providers/FormatCodeCleanupProvider.cs @@ -5,7 +5,6 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -17,11 +16,11 @@ internal sealed class FormatCodeCleanupProvider : ICodeCleanupProvider { public string Name => PredefinedCodeCleanupProviderNames.Format; - public async Task CleanupAsync(Document document, ImmutableArray spans, OptionSet options, CancellationToken cancellationToken) + public async Task CleanupAsync(Document document, ImmutableArray spans, SyntaxFormattingOptions options, CancellationToken cancellationToken) { var formatter = document.GetRequiredLanguageService(); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var result = formatter.GetFormattingResult(root, spans, options, document.Project.Solution.Workspace.Services, rules: null, cancellationToken); + var result = formatter.GetFormattingResult(root, spans, options, rules: null, cancellationToken); // apply changes to an old text if it already exists return document.TryGetText(out var oldText) ? @@ -29,10 +28,10 @@ public async Task CleanupAsync(Document document, ImmutableArray CleanupAsync(SyntaxNode root, ImmutableArray spans, OptionSet options, HostWorkspaceServices services, CancellationToken cancellationToken) + public Task CleanupAsync(SyntaxNode root, ImmutableArray spans, SyntaxFormattingOptions options, HostWorkspaceServices services, CancellationToken cancellationToken) { var formatter = services.GetRequiredLanguageService(root.Language); - var result = formatter.GetFormattingResult(root, spans, options, services, rules: null, cancellationToken); + var result = formatter.GetFormattingResult(root, spans, options, rules: null, cancellationToken); // apply changes to an old text if it already exists return (root.SyntaxTree != null && root.SyntaxTree.TryGetText(out var oldText)) ? diff --git a/src/Workspaces/Core/Portable/CodeCleanup/Providers/ICodeCleanupProvider.cs b/src/Workspaces/Core/Portable/CodeCleanup/Providers/ICodeCleanupProvider.cs index 823b57fb46bda..52f2f2959a1be 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/Providers/ICodeCleanupProvider.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/Providers/ICodeCleanupProvider.cs @@ -5,8 +5,8 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CodeCleanup.Providers @@ -24,13 +24,13 @@ internal interface ICodeCleanupProvider /// /// This should apply its code clean up logic to the spans of the document. /// - Task CleanupAsync(Document document, ImmutableArray spans, OptionSet options, CancellationToken cancellationToken); + Task CleanupAsync(Document document, ImmutableArray spans, SyntaxFormattingOptions options, CancellationToken cancellationToken); /// /// This will run all provided code cleaners in an order that is given to the method. /// /// This will do cleanups that don't require any semantic information /// - Task CleanupAsync(SyntaxNode root, ImmutableArray spans, OptionSet options, HostWorkspaceServices services, CancellationToken cancellationToken); + Task CleanupAsync(SyntaxNode root, ImmutableArray spans, SyntaxFormattingOptions options, HostWorkspaceServices services, CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/CodeCleanup/Providers/SimplificationCodeCleanupProvider.cs b/src/Workspaces/Core/Portable/CodeCleanup/Providers/SimplificationCodeCleanupProvider.cs index c4b372a73e608..70ea4aefd3909 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/Providers/SimplificationCodeCleanupProvider.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/Providers/SimplificationCodeCleanupProvider.cs @@ -6,7 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Text; @@ -16,10 +16,10 @@ internal class SimplificationCodeCleanupProvider : ICodeCleanupProvider { public string Name => PredefinedCodeCleanupProviderNames.Simplification; - public Task CleanupAsync(Document document, ImmutableArray spans, OptionSet options, CancellationToken cancellationToken) + public Task CleanupAsync(Document document, ImmutableArray spans, SyntaxFormattingOptions options, CancellationToken cancellationToken) => Simplifier.ReduceAsync(document, spans, null, cancellationToken); - public Task CleanupAsync(SyntaxNode root, ImmutableArray spans, OptionSet options, HostWorkspaceServices services, CancellationToken cancellationToken) + public Task CleanupAsync(SyntaxNode root, ImmutableArray spans, SyntaxFormattingOptions options, HostWorkspaceServices services, CancellationToken cancellationToken) { // Simplifier doesn't work without semantic information return Task.FromResult(root); diff --git a/src/Workspaces/Core/Portable/Formatting/Formatter.cs b/src/Workspaces/Core/Portable/Formatting/Formatter.cs index ca436b1a01317..6afb7bdae02e9 100644 --- a/src/Workspaces/Core/Portable/Formatting/Formatter.cs +++ b/src/Workspaces/Core/Portable/Formatting/Formatter.cs @@ -111,7 +111,9 @@ internal static async Task FormatAsync(Document document, IEnumerable< var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var documentOptions = options ?? await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); +#pragma warning disable CS0612 // Type or member is obsolete return document.WithSyntaxRoot(Format(root, spans, document.Project.Solution.Workspace, documentOptions, rules, cancellationToken)); +#pragma warning restore CS0612 // Type or member is obsolete } /// @@ -139,7 +141,9 @@ internal static async Task FormatAsync(Document document, SyntaxAnnota var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var documentOptions = options ?? await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); +#pragma warning disable CS0612 // Type or member is obsolete return document.WithSyntaxRoot(Format(root, annotation, document.Project.Solution.Workspace, documentOptions, rules, cancellationToken)); +#pragma warning restore CS0612 // Type or member is obsolete } /// @@ -153,7 +157,10 @@ internal static async Task FormatAsync(Document document, SyntaxAnnota /// The formatted tree's root node. [Obsolete] public static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, Workspace workspace, OptionSet? options = null, CancellationToken cancellationToken = default) - => Format(node, annotation, workspace, options, rules: null, cancellationToken: cancellationToken); + => Format(node, annotation, workspace, options, rules: null, cancellationToken); + + internal static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, HostWorkspaceServices services, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => Format(node, annotation, services, options, rules: null, cancellationToken); [Obsolete] internal static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, Workspace workspace, OptionSet? options, IEnumerable? rules, CancellationToken cancellationToken) @@ -180,6 +187,9 @@ internal static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, return Format(node, spans, workspace, options, rules, cancellationToken); } + internal static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, HostWorkspaceServices services, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + => Format(node, annotation, services, options, rules, cancellationToken: cancellationToken); + /// /// Formats the whitespace of a syntax tree. /// @@ -190,7 +200,10 @@ internal static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, /// The formatted tree's root node. [Obsolete] public static SyntaxNode Format(SyntaxNode node, Workspace workspace, OptionSet? options = null, CancellationToken cancellationToken = default) - => Format(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), workspace, options, rules: null, cancellationToken: cancellationToken); + => Format(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), workspace, options, rules: null, cancellationToken); + + internal static SyntaxNode Format(SyntaxNode node, HostWorkspaceServices services, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => Format(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), services, options, rules: null, cancellationToken); /// /// Formats the whitespace in areas of a syntax tree identified by a span. @@ -205,6 +218,9 @@ public static SyntaxNode Format(SyntaxNode node, Workspace workspace, OptionSet? public static SyntaxNode Format(SyntaxNode node, TextSpan span, Workspace workspace, OptionSet? options = null, CancellationToken cancellationToken = default) => Format(node, SpecializedCollections.SingletonEnumerable(span), workspace, options, rules: null, cancellationToken: cancellationToken); + internal static SyntaxNode Format(SyntaxNode node, TextSpan span, HostWorkspaceServices services, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => Format(node, SpecializedCollections.SingletonEnumerable(span), services, options, rules: null, cancellationToken: cancellationToken); + /// /// Formats the whitespace in areas of a syntax tree identified by multiple non-overlapping spans. /// @@ -225,6 +241,12 @@ internal static SyntaxNode Format(SyntaxNode node, IEnumerable? spans, return formattingResult == null ? node : formattingResult.GetFormattedRoot(cancellationToken); } + internal static SyntaxNode Format(SyntaxNode node, IEnumerable spans, HostWorkspaceServices services, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + { + var formatter = services.GetRequiredLanguageService(node.Language); + return formatter.GetFormattingResult(node, spans, options, rules, cancellationToken).GetFormattedRoot(cancellationToken); + } + [Obsolete] internal static IFormattingResult? GetFormattingResult(SyntaxNode node, IEnumerable? spans, Workspace workspace, OptionSet? options, IEnumerable? rules, CancellationToken cancellationToken) { @@ -244,12 +266,10 @@ internal static SyntaxNode Format(SyntaxNode node, IEnumerable? spans, return null; } - var optionService = workspace.Services.GetRequiredService(); - options ??= workspace.Options; spans ??= SpecializedCollections.SingletonEnumerable(node.FullSpan); - var shouldUseFormattingSpanCollapse = options.GetOption(FormattingBehaviorOptions.AllowDisjointSpanMerging); - return languageFormatter.Format(node, spans, shouldUseFormattingSpanCollapse, options.AsAnalyzerConfigOptions(optionService, node.Language), rules, cancellationToken); + var formattingOptions = SyntaxFormattingOptions.Create(options, workspace.Services, node.Language); + return languageFormatter.GetFormattingResult(node, spans, formattingOptions, rules, cancellationToken); } /// @@ -264,6 +284,9 @@ internal static SyntaxNode Format(SyntaxNode node, IEnumerable? spans, public static IList GetFormattedTextChanges(SyntaxNode node, Workspace workspace, OptionSet? options = null, CancellationToken cancellationToken = default) => GetFormattedTextChanges(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), workspace, options, rules: null, cancellationToken: cancellationToken); + internal static IList GetFormattedTextChanges(SyntaxNode node, HostWorkspaceServices services, SyntaxFormattingOptions options, CancellationToken cancellationToken) + => GetFormattedTextChanges(node, SpecializedCollections.SingletonEnumerable(node.FullSpan), services, options, rules: null, cancellationToken: cancellationToken); + /// /// Determines the changes necessary to format the whitespace of a syntax tree. /// @@ -275,7 +298,10 @@ public static IList GetFormattedTextChanges(SyntaxNode node, Workspa /// The changes necessary to format the tree. [Obsolete] public static IList GetFormattedTextChanges(SyntaxNode node, TextSpan span, Workspace workspace, OptionSet? options = null, CancellationToken cancellationToken = default) - => GetFormattedTextChanges(node, SpecializedCollections.SingletonEnumerable(span), workspace, options, rules: null, cancellationToken: cancellationToken); + => GetFormattedTextChanges(node, SpecializedCollections.SingletonEnumerable(span), workspace, options, rules: null, cancellationToken); + + internal static IList GetFormattedTextChanges(SyntaxNode node, TextSpan span, HostWorkspaceServices services, SyntaxFormattingOptions options, CancellationToken cancellationToken = default) + => GetFormattedTextChanges(node, SpecializedCollections.SingletonEnumerable(span), services, options, rules: null, cancellationToken); /// /// Determines the changes necessary to format the whitespace of a syntax tree. @@ -288,7 +314,10 @@ public static IList GetFormattedTextChanges(SyntaxNode node, TextSpa /// The changes necessary to format the tree. [Obsolete] public static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable? spans, Workspace workspace, OptionSet? options = null, CancellationToken cancellationToken = default) - => GetFormattedTextChanges(node, spans, workspace, options, rules: null, cancellationToken: cancellationToken); + => GetFormattedTextChanges(node, spans, workspace, options, rules: null, cancellationToken); + + internal static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable spans, HostWorkspaceServices services, SyntaxFormattingOptions options, CancellationToken cancellationToken = default) + => GetFormattedTextChanges(node, spans, services, options, rules: null, cancellationToken); [Obsolete] internal static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable? spans, Workspace workspace, OptionSet? options, IEnumerable? rules, CancellationToken cancellationToken) @@ -299,6 +328,12 @@ internal static IList GetFormattedTextChanges(SyntaxNode node, IEnum : formattingResult.GetTextChanges(cancellationToken); } + internal static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable spans, HostWorkspaceServices services, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken = default) + { + var formatter = services.GetRequiredLanguageService(node.Language); + return formatter.GetFormattingResult(node, spans, options, rules, cancellationToken).GetTextChanges(cancellationToken); + } + /// /// Organizes the imports in the document. /// diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormattingService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormattingService.cs index 514d1a3cb98de..7fe9d4c3dc9dc 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormattingService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormattingService.cs @@ -31,7 +31,7 @@ protected AbstractSyntaxFormattingService() protected abstract AbstractFormattingResult Format(SyntaxNode node, AnalyzerConfigOptions options, IEnumerable rules, SyntaxToken token1, SyntaxToken token2, CancellationToken cancellationToken); - public IFormattingResult Format(SyntaxNode node, IEnumerable spans, bool shouldUseFormattingSpanCollapse, AnalyzerConfigOptions options, IEnumerable? rules, CancellationToken cancellationToken) + public IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerable spans, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) { // quick exit check var spansToFormat = new NormalizedTextSpanCollection(spans.Where(s_notEmpty)); @@ -43,12 +43,12 @@ public IFormattingResult Format(SyntaxNode node, IEnumerable spans, bo rules ??= GetDefaultFormattingRules(); // check what kind of formatting strategy to use - if (AllowDisjointSpanMerging(spansToFormat, shouldUseFormattingSpanCollapse)) + if (AllowDisjointSpanMerging(spansToFormat, options.ShouldUseFormattingSpanCollapse)) { - return FormatMergedSpan(node, options, rules, spansToFormat, cancellationToken); + return FormatMergedSpan(node, options.Options, rules, spansToFormat, cancellationToken); } - return FormatIndividually(node, options, rules, spansToFormat, cancellationToken); + return FormatIndividually(node, options.Options, rules, spansToFormat, cancellationToken); } private IFormattingResult FormatMergedSpan( diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormattingService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormattingService.cs index 6b6831f22236b..81f93e0951b9c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormattingService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormattingService.cs @@ -23,20 +23,27 @@ internal interface ISyntaxFormattingService #endif { IEnumerable GetDefaultFormattingRules(); - IFormattingResult Format(SyntaxNode node, IEnumerable spans, bool shouldUseFormattingSpanCollapse, AnalyzerConfigOptions options, IEnumerable? rules, CancellationToken cancellationToken); + IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerable spans, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken); } -#if !CODE_STYLE - internal static class ISyntaxFormattingServiceExtensions + internal readonly record struct SyntaxFormattingOptions( + AnalyzerConfigOptions Options, + bool ShouldUseFormattingSpanCollapse) { - internal static IFormattingResult GetFormattingResult(this ISyntaxFormattingService service, SyntaxNode node, IEnumerable spans, OptionSet options, HostWorkspaceServices services, IEnumerable? rules, CancellationToken cancellationToken) - { - var optionService = services.GetRequiredService(); - var shouldUseFormattingSpanCollapse = options.GetOption(FormattingBehaviorOptions.AllowDisjointSpanMerging); - var configOptions = options.AsAnalyzerConfigOptions(optionService, node.Language); + public static SyntaxFormattingOptions Create(AnalyzerConfigOptions options) + => new(options, ShouldUseFormattingSpanCollapse: false); + +#if !CODE_STYLE + public static SyntaxFormattingOptions Create(OptionSet options, HostWorkspaceServices services, string language, bool? shouldUseFormattingSpanCollapse = null) + => new( + options.AsAnalyzerConfigOptions(services.GetRequiredService(), language), + shouldUseFormattingSpanCollapse ?? options.GetOption(FormattingBehaviorOptions.AllowDisjointSpanMerging)); - return service.Format(node, spans, shouldUseFormattingSpanCollapse, configOptions, rules, cancellationToken); + public static async ValueTask FromDocumentAsync(Document document, CancellationToken cancellationToken) + { + var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + return Create(documentOptions, document.Project.Solution.Workspace.Services, document.Project.Language); } - } #endif + } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.cs index 3a9ac27d3fa8e..f098c594b641d 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.cs @@ -62,8 +62,8 @@ private async Task FormatResultAsync(Document document, CompilationU { var spans = new List(); AddFormattingSpans(newRoot, spans, cancellationToken); - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - return Formatter.Format(newRoot, spans, document.Project.Solution.Workspace, options, cancellationToken: cancellationToken); + var options = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + return Formatter.Format(newRoot, spans, document.Project.Solution.Workspace.Services, options, rules: null, cancellationToken); } private void AddFormattingSpans( diff --git a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/AbstractTokensCodeCleanupProvider.vb b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/AbstractTokensCodeCleanupProvider.vb index 1420b76084647..9eef93cdd24c1 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/AbstractTokensCodeCleanupProvider.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/AbstractTokensCodeCleanupProvider.vb @@ -5,8 +5,8 @@ Imports System.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host -Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.Collections Imports Microsoft.CodeAnalysis.Text @@ -19,7 +19,7 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers Protected MustOverride Function GetRewriterAsync( document As Document, root As SyntaxNode, spans As ImmutableArray(Of TextSpan), cancellationToken As CancellationToken) As Task(Of Rewriter) - Public Async Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As OptionSet, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync + Public Async Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) Dim rewriter As Rewriter = Await GetRewriterAsync(document, root, spans, cancellationToken).ConfigureAwait(False) Dim newRoot = rewriter.Visit(root) @@ -27,7 +27,7 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers Return If(root Is newRoot, document, document.WithSyntaxRoot(newRoot)) End Function - Public Async Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As OptionSet, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync + Public Async Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync Dim rewriter As Rewriter = Await GetRewriterAsync(Nothing, root, spans, cancellationToken).ConfigureAwait(False) Return rewriter.Visit(root) End Function diff --git a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/CaseCorrectionCodeCleanupProvider.vb b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/CaseCorrectionCodeCleanupProvider.vb index ce096181027b6..e4cd067bbaf8f 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/CaseCorrectionCodeCleanupProvider.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/CaseCorrectionCodeCleanupProvider.vb @@ -7,8 +7,8 @@ Imports System.Composition Imports System.Diagnostics.CodeAnalysis Imports System.Threading Imports Microsoft.CodeAnalysis.CaseCorrection +Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host -Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Text Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers @@ -28,11 +28,11 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers End Get End Property - Public Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As OptionSet, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync + Public Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync Return CaseCorrector.CaseCorrectAsync(document, spans, cancellationToken) End Function - Public Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As OptionSet, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync + Public Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync Return Task.FromResult(CaseCorrector.CaseCorrect(root, spans, services, cancellationToken)) End Function End Class diff --git a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/NormalizeModifiersOrOperatorsCodeCleanupProvider.vb b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/NormalizeModifiersOrOperatorsCodeCleanupProvider.vb index 997322098aeda..7ad4b805deded 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/NormalizeModifiersOrOperatorsCodeCleanupProvider.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/NormalizeModifiersOrOperatorsCodeCleanupProvider.vb @@ -7,8 +7,8 @@ Imports System.Composition Imports System.Diagnostics.CodeAnalysis Imports System.Threading Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host -Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.Collections Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.CodeStyle @@ -31,14 +31,14 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers End Get End Property - Public Async Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As OptionSet, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync + Public Async Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) Dim newRoot = Await CleanupAsync(root, spans, options, document.Project.Solution.Workspace.Services, cancellationToken).ConfigureAwait(False) Return If(root Is newRoot, document, document.WithSyntaxRoot(newRoot)) End Function - Public Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As OptionSet, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync + Public Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync Dim rewriter = New Rewriter(spans, cancellationToken) Dim newRoot = rewriter.Visit(root) diff --git a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/RemoveUnnecessaryLineContinuationCodeCleanupProvider.vb b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/RemoveUnnecessaryLineContinuationCodeCleanupProvider.vb index 8954e34f6ee84..9bcd1c84bfdfc 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/RemoveUnnecessaryLineContinuationCodeCleanupProvider.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeCleanup/Providers/RemoveUnnecessaryLineContinuationCodeCleanupProvider.vb @@ -7,8 +7,8 @@ Imports System.Composition Imports System.Diagnostics.CodeAnalysis Imports System.Threading Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host -Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Syntax @@ -29,7 +29,7 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers End Get End Property - Public Async Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As OptionSet, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync + Public Async Function CleanupAsync(document As Document, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, cancellationToken As CancellationToken) As Task(Of Document) Implements ICodeCleanupProvider.CleanupAsync ' Is this VB 9? If so, we shouldn't remove line continuations because implicit line continuation was introduced in VB 10. Dim parseOptions = TryCast(document.Project.ParseOptions, VisualBasicParseOptions) If parseOptions?.LanguageVersion <= LanguageVersion.VisualBasic9 Then @@ -42,7 +42,7 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers Return If(newRoot Is root, document, document.WithSyntaxRoot(newRoot)) End Function - Public Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As OptionSet, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync + Public Function CleanupAsync(root As SyntaxNode, spans As ImmutableArray(Of TextSpan), options As SyntaxFormattingOptions, services As HostWorkspaceServices, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Implements ICodeCleanupProvider.CleanupAsync Return Task.FromResult(Replacer.Process(root, spans, cancellationToken)) End Function diff --git a/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb b/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb index bd37ccfb9a1a2..d4006252b31a4 100644 --- a/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb +++ b/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb @@ -17,11 +17,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Indentation End Function Protected Overrides Function CreateSmartTokenFormatter(indenter As Indenter) As ISmartTokenFormatter - Dim workspace = indenter.Document.Project.Solution.Workspace - Dim formattingRuleFactory = workspace.Services.GetService(Of IHostDependentFormattingRuleFactoryService)() + Dim services = indenter.Document.Project.Solution.Workspace.Services + Dim formattingRuleFactory = services.GetService(Of IHostDependentFormattingRuleFactoryService)() Dim rules = {New SpecialFormattingRule(indenter.OptionSet.GetOption(FormattingOptions.SmartIndent, indenter.Document.Root.Language)), formattingRuleFactory.CreateRule(indenter.Document.Document, indenter.LineToBeIndented.Start)}.Concat(Formatter.GetDefaultFormattingRules(indenter.Document.Document)) - - Return New VisualBasicSmartTokenFormatter(indenter.OptionSet, rules, indenter.Root) + Dim options = SyntaxFormattingOptions.Create(indenter.OptionSet, services, indenter.Document.Project.Language) + Return New VisualBasicSmartTokenFormatter(options, rules, indenter.Root) End Function Protected Overrides Function GetDesiredIndentationWorker( diff --git a/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicSmartTokenFormatter.vb b/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicSmartTokenFormatter.vb index 9bccbd262c2c0..c6df0a006973d 100644 --- a/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicSmartTokenFormatter.vb +++ b/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicSmartTokenFormatter.vb @@ -15,19 +15,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Indentation Friend Class VisualBasicSmartTokenFormatter Implements ISmartTokenFormatter - Private ReadOnly _optionSet As OptionSet + Private ReadOnly _options As SyntaxFormattingOptions Private ReadOnly _formattingRules As IEnumerable(Of AbstractFormattingRule) Private ReadOnly _root As CompilationUnitSyntax - Public Sub New(optionSet As OptionSet, + Public Sub New(options As SyntaxFormattingOptions, formattingRules As IEnumerable(Of AbstractFormattingRule), root As CompilationUnitSyntax) - Contract.ThrowIfNull(optionSet) Contract.ThrowIfNull(formattingRules) Contract.ThrowIfNull(root) - Me._optionSet = optionSet + Me._options = options Me._formattingRules = formattingRules Me._root = root @@ -40,8 +39,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Indentation Dim previousToken = token.GetPreviousToken() Dim spans = SpecializedCollections.SingletonEnumerable(TextSpan.FromBounds(previousToken.SpanStart, token.Span.End)) - Dim formatter = services.GetRequiredLanguageService(Of ISyntaxFormattingService)(_root.Language) - Return Task.FromResult(formatter.GetFormattingResult(_root, spans, _optionSet, services, _formattingRules, cancellationToken).GetTextChanges(cancellationToken)) + Return Task.FromResult(Formatter.GetFormattedTextChanges(_root, spans, services, _options, _formattingRules, cancellationToken)) End Function End Class End Namespace