diff --git a/.editorconfig b/.editorconfig index 3a08978605e93..699750fb32348 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,301 +1,4 @@ -# EditorConfig is awesome: https://EditorConfig.org +[*.cs] -# top-most EditorConfig file -root = true - -# Don't use tabs for indentation. -[*] -indent_style = space -# (Please don't specify an indent_size here; that has too many unintended consequences.) - -# Code files -[*.{cs,csx,vb,vbx}] -indent_size = 4 -insert_final_newline = true -charset = utf-8-bom - -# XML project files -[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] -indent_size = 2 - -# XML config files -[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] -indent_size = 2 - -# JSON files -[*.json] -indent_size = 2 - -# Powershell files -[*.ps1] -indent_size = 2 - -# Shell script files -[*.sh] -end_of_line = lf -indent_size = 2 - -# Dotnet code style settings: -[*.{cs,vb}] - -# IDE0055: Fix formatting -dotnet_diagnostic.IDE0055.severity = warning - -# Sort using and Import directives with System.* appearing first -dotnet_sort_system_directives_first = true -dotnet_separate_import_directive_groups = false -# Avoid "this." and "Me." if not necessary -dotnet_style_qualification_for_field = false:refactoring -dotnet_style_qualification_for_property = false:refactoring -dotnet_style_qualification_for_method = false:refactoring -dotnet_style_qualification_for_event = false:refactoring - -# Use language keywords instead of framework type names for type references -dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion -dotnet_style_predefined_type_for_member_access = true:suggestion - -# Suggest more modern language features when available -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion - -# Whitespace options -dotnet_style_allow_multiple_blank_lines_experimental = false - -# Non-private static fields are PascalCase -dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields -dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style - -dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field -dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected -dotnet_naming_symbols.non_private_static_fields.required_modifiers = static - -dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case - -# Non-private readonly fields are PascalCase -dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields -dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_readonly_field_style - -dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field -dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected -dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly - -dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case - -# Constants are PascalCase -dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants -dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style - -dotnet_naming_symbols.constants.applicable_kinds = field, local -dotnet_naming_symbols.constants.required_modifiers = const - -dotnet_naming_style.constant_style.capitalization = pascal_case - -# Static fields are camelCase and start with s_ -dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion -dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields -dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style - -dotnet_naming_symbols.static_fields.applicable_kinds = field -dotnet_naming_symbols.static_fields.required_modifiers = static - -dotnet_naming_style.static_field_style.capitalization = camel_case -dotnet_naming_style.static_field_style.required_prefix = s_ - -# Instance fields are camelCase and start with _ -dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion -dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields -dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style - -dotnet_naming_symbols.instance_fields.applicable_kinds = field - -dotnet_naming_style.instance_field_style.capitalization = camel_case -dotnet_naming_style.instance_field_style.required_prefix = _ - -# Locals and parameters are camelCase -dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion -dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters -dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style - -dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local - -dotnet_naming_style.camel_case_style.capitalization = camel_case - -# Local functions are PascalCase -dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions -dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style - -dotnet_naming_symbols.local_functions.applicable_kinds = local_function - -dotnet_naming_style.local_function_style.capitalization = pascal_case - -# By default, name items with PascalCase -dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members -dotnet_naming_rule.members_should_be_pascal_case.style = pascal_case_style - -dotnet_naming_symbols.all_members.applicable_kinds = * - -dotnet_naming_style.pascal_case_style.capitalization = pascal_case - -# error RS2008: Enable analyzer release tracking for the analyzer project containing rule '{0}' -dotnet_diagnostic.RS2008.severity = none - -# IDE0073: File header -dotnet_diagnostic.IDE0073.severity = warning -file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE file in the project root for more information. - -# IDE0035: Remove unreachable code -dotnet_diagnostic.IDE0035.severity = warning - -# IDE0036: Order modifiers -dotnet_diagnostic.IDE0036.severity = warning - -# IDE0043: Format string contains invalid placeholder -dotnet_diagnostic.IDE0043.severity = warning - -# IDE0044: Make field readonly -dotnet_diagnostic.IDE0044.severity = warning - -# RS0016: Only enable if API files are present -dotnet_public_api_analyzer.require_api_files = true - -# CSharp code style settings: -[*.cs] -# Newline settings -csharp_new_line_before_open_brace = all -csharp_new_line_before_else = true -csharp_new_line_before_catch = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_between_query_expression_clauses = true - -# Indentation preferences -csharp_indent_block_contents = true -csharp_indent_braces = false -csharp_indent_case_contents = true -csharp_indent_case_contents_when_block = true -csharp_indent_switch_labels = true -csharp_indent_labels = flush_left - -# Whitespace options -csharp_style_allow_embedded_statements_on_same_line_experimental = false -csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false -csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false - -# Prefer "var" everywhere -csharp_style_var_for_built_in_types = true:suggestion -csharp_style_var_when_type_is_apparent = true:suggestion -csharp_style_var_elsewhere = true:suggestion - -# Prefer method-like constructs to have a block body -csharp_style_expression_bodied_methods = false:none -csharp_style_expression_bodied_constructors = false:none -csharp_style_expression_bodied_operators = false:none - -# Prefer property-like constructs to have an expression-body -csharp_style_expression_bodied_properties = true:none -csharp_style_expression_bodied_indexers = true:none -csharp_style_expression_bodied_accessors = true:none - -# Suggest more modern language features when available -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion - -# Space preferences -csharp_space_after_cast = false -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_after_comma = true -csharp_space_after_dot = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_after_semicolon_in_for_statement = true -csharp_space_around_binary_operators = before_and_after -csharp_space_around_declaration_statements = do_not_ignore -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_before_comma = false -csharp_space_before_dot = false -csharp_space_before_open_square_brackets = false -csharp_space_before_semicolon_in_for_statement = false -csharp_space_between_empty_square_brackets = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_declaration_name_and_open_parenthesis = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_between_square_brackets = false - -# Blocks are allowed -csharp_prefer_braces = true:silent -csharp_preserve_single_line_blocks = true -csharp_preserve_single_line_statements = true - -# Currently only enabled for C# due to crash in VB analyzer. VB can be enabled once -# https://github.com/dotnet/roslyn/pull/54259 has been published. -dotnet_style_allow_statement_immediately_after_block_experimental = false - -[src/{Analyzers,CodeStyle,Features,Workspaces,EditorFeatures,VisualStudio}/**/*.{cs,vb}] - -# IDE0011: Add braces -csharp_prefer_braces = when_multiline:warning -# NOTE: We need the below severity entry for Add Braces due to https://github.com/dotnet/roslyn/issues/44201 -dotnet_diagnostic.IDE0011.severity = warning - -# IDE0040: Add accessibility modifiers -dotnet_diagnostic.IDE0040.severity = warning - -# CONSIDER: Are IDE0051 and IDE0052 too noisy to be warnings for IDE editing scenarios? Should they be made build-only warnings? -# IDE0051: Remove unused private member -dotnet_diagnostic.IDE0051.severity = warning - -# IDE0052: Remove unread private member -dotnet_diagnostic.IDE0052.severity = warning - -# IDE0059: Unnecessary assignment to a value -dotnet_diagnostic.IDE0059.severity = warning - -# IDE0060: Remove unused parameter -dotnet_diagnostic.IDE0060.severity = warning - -# CA1012: Abstract types should not have public constructors -dotnet_diagnostic.CA1012.severity = warning - -# CA1822: Make member static -dotnet_diagnostic.CA1822.severity = warning - -# Prefer "var" everywhere -dotnet_diagnostic.IDE0007.severity = warning -csharp_style_var_for_built_in_types = true:warning -csharp_style_var_when_type_is_apparent = true:warning -csharp_style_var_elsewhere = true:warning - -# dotnet_style_allow_multiple_blank_lines_experimental -dotnet_diagnostic.IDE2000.severity = warning - -# csharp_style_allow_embedded_statements_on_same_line_experimental -dotnet_diagnostic.IDE2001.severity = warning - -# csharp_style_allow_blank_lines_between_consecutive_braces_experimental -dotnet_diagnostic.IDE2002.severity = warning - -# dotnet_style_allow_statement_immediately_after_block_experimental -dotnet_diagnostic.IDE2003.severity = warning - -# csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental -dotnet_diagnostic.IDE2004.severity = warning - -[src/{VisualStudio}/**/*.{cs,vb}] -# CA1822: Make member static -# There is a risk of accidentally breaking an internal API that partners rely on though IVT. -dotnet_code_quality.CA1822.api_surface = private +# IDE0058: Expression value is never used +csharp_style_unused_value_expression_statement_preference = unused_local_variable diff --git a/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs index 540a1a2521913..eade815ae34f3 100644 --- a/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Simplification; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Formatting; @@ -65,14 +66,17 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) #if CODE_STYLE var options = document.Project.AnalyzerOptions.GetAnalyzerOptionSet(syntaxRoot.SyntaxTree, cancellationToken); + var simplifierOptions = CSharpSimplifierOptions.Create(options, fallbackOptions: null); #else var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(document, fallbackOptions: context.Options(document.Project.LanguageServices).SimplifierOptions, cancellationToken).ConfigureAwait(false); #endif + var codeStyleOption = options.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement); // Read the preferred placement option and verify if it can be applied to this code file. // There are cases where we will not be able to fix the diagnostic and the user will need to resolve // it manually. - var (placement, preferPreservation) = DeterminePlacement(compilationUnit, options); + var (placement, preferPreservation) = DeterminePlacement(compilationUnit, codeStyleOption); if (preferPreservation) return; @@ -81,24 +85,22 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( CSharpAnalyzersResources.Move_misplaced_using_directives, - token => GetTransformedDocumentAsync(document, compilationUnit, GetAllUsingDirectives(compilationUnit), placement, token), + token => GetTransformedDocumentAsync(document, compilationUnit, GetAllUsingDirectives(compilationUnit), placement, simplifierOptions, token), nameof(CSharpAnalyzersResources.Move_misplaced_using_directives)), diagnostic); } } - internal static async Task TransformDocumentIfRequiredAsync(Document document, CancellationToken cancellationToken) + internal static async Task TransformDocumentIfRequiredAsync( + Document document, + SimplifierOptions simplifierOptions, + CodeStyleOption2 importPlacementStyleOption, + CancellationToken cancellationToken) { var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var compilationUnit = (CompilationUnitSyntax)syntaxRoot; -#if CODE_STYLE - var options = document.Project.AnalyzerOptions.GetAnalyzerOptionSet(syntaxRoot.SyntaxTree, cancellationToken); -#else - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); -#endif - - var (placement, preferPreservation) = DeterminePlacement(compilationUnit, options); + var (placement, preferPreservation) = DeterminePlacement(compilationUnit, importPlacementStyleOption); if (preferPreservation) { return document; @@ -112,7 +114,7 @@ internal static async Task TransformDocumentIfRequiredAsync(Document d return document; } - return await GetTransformedDocumentAsync(document, compilationUnit, allUsingDirectives, placement, cancellationToken).ConfigureAwait(false); + return await GetTransformedDocumentAsync(document, compilationUnit, allUsingDirectives, placement, simplifierOptions, cancellationToken).ConfigureAwait(false); } private static ImmutableList GetAllUsingDirectives(CompilationUnitSyntax compilationUnit) @@ -127,6 +129,7 @@ private static async Task GetTransformedDocumentAsync( CompilationUnitSyntax compilationUnit, IEnumerable allUsingDirectives, AddImportPlacement placement, + SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { var bannerService = document.GetRequiredLanguageService(); @@ -149,8 +152,13 @@ private static async Task GetTransformedDocumentAsync( var newDocument = document.WithSyntaxRoot(newCompilationUnitWithHeader); // Simplify usings now that they have been moved and are in the proper context. - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - return await Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, options, cancellationToken).ConfigureAwait(false); +#if CODE_STYLE +#pragma warning disable RS0030 // Do not used banned APIs + return await Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, optionSet: null, cancellationToken).ConfigureAwait(false); +#pragma warning restore +#else + return await Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, simplifierOptions, cancellationToken).ConfigureAwait(false); +#endif } private static async Task ExpandUsingDirectivesAsync(Document document, CompilationUnitSyntax containerNode, IEnumerable allUsingDirectives, CancellationToken cancellationToken) @@ -360,12 +368,10 @@ private static TSyntaxNode EnsureLeadingBlankLineBeforeFirstMember( return node.ReplaceNode(firstMember, newFirstMember); } - private static (AddImportPlacement placement, bool preferPreservation) DeterminePlacement(CompilationUnitSyntax compilationUnit, OptionSet options) + private static (AddImportPlacement placement, bool preferPreservation) DeterminePlacement(CompilationUnitSyntax compilationUnit, CodeStyleOption2 styleOption) { - var codeStyleOption = options.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement); - - var placement = codeStyleOption.Value; - var preferPreservation = codeStyleOption.Notification == NotificationOption2.None; + var placement = styleOption.Value; + var preferPreservation = styleOption.Notification == NotificationOption2.None; if (preferPreservation || placement == AddImportPlacement.OutsideNamespace) return (placement, preferPreservation); diff --git a/src/Deployment/RoslynDeployment.csproj b/src/Deployment/RoslynDeployment.csproj index f173c1fd74b80..5852601dc1206 100644 --- a/src/Deployment/RoslynDeployment.csproj +++ b/src/Deployment/RoslynDeployment.csproj @@ -15,6 +15,7 @@ false + Designer diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs index 89b9c9a95ef9e..6c66369c81fb8 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs @@ -168,8 +168,9 @@ private Solution CreateSolutionWithEventHandler( } var formattingOptions = SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).WaitAndGetResult(cancellationToken); + var simplifierOptions = document.GetSimplifierOptionsAsync(_globalOptions, cancellationToken).WaitAndGetResult(cancellationToken); - var simplifiedDocument = Simplifier.ReduceAsync(documentWithNameAndAnnotationsAdded.WithSyntaxRoot(updatedRoot), Simplifier.Annotation, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken); + var simplifiedDocument = Simplifier.ReduceAsync(documentWithNameAndAnnotationsAdded.WithSyntaxRoot(updatedRoot), Simplifier.Annotation, simplifierOptions, cancellationToken).WaitAndGetResult(cancellationToken); var formattedDocument = Formatter.FormatAsync(simplifiedDocument, Formatter.Annotation, formattingOptions, cancellationToken).WaitAndGetResult(cancellationToken); var newRoot = formattedDocument.GetSyntaxRootSynchronously(cancellationToken); diff --git a/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs b/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs index 115762c6da533..0ac259ae9afb6 100644 --- a/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs +++ b/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs @@ -4,6 +4,7 @@ using System; using Microsoft.CodeAnalysis.AddMissingImports; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Options; @@ -125,11 +126,11 @@ private void ExecuteCommandWorker( #pragma warning disable VSTHRD102 // Implement internal logic asynchronously var updatedDocument = _threadingContext.JoinableTaskFactory.Run(async () => { - var placement = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); var options = new AddMissingImportsOptions( - HideAdvancedMembers: _globalOptions.GetOption(CompletionOptionsStorage.HideAdvancedMembers, document.Project.Language), - placement); + CleanupOptions: cleanupOptions, + HideAdvancedMembers: _globalOptions.GetOption(CompletionOptionsStorage.HideAdvancedMembers, document.Project.Language)); return await addMissingImportsService.AddMissingImportsAsync(document, textSpan, options, cancellationToken).ConfigureAwait(false); }); diff --git a/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs b/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs index 35174142febdc..d6ccb9b5bc7d1 100644 --- a/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs +++ b/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs @@ -885,8 +885,9 @@ public void Dispose() this.Document = this.Result; var formattingOptions = IsVisualBasic ? (SyntaxFormattingOptions)VisualBasicSyntaxFormattingOptions.Default : CSharpSyntaxFormattingOptions.Default; + var simplifierOptions = IsVisualBasic ? (SimplifierOptions)VisualBasicSimplifierOptions.Default : CSharpSimplifierOptions.Default; - var simplified = Simplifier.ReduceAsync(this.Document, Simplifier.Annotation).Result; + var simplified = Simplifier.ReduceAsync(this.Document, Simplifier.Annotation, simplifierOptions, CancellationToken.None).Result; var actual = Formatter.FormatAsync(simplified, Formatter.Annotation, formattingOptions, CancellationToken.None).Result.GetSyntaxRootAsync().Result.ToFullString(); Assert.Equal(_expected, actual); diff --git a/src/EditorFeatures/Test2/Expansion/AbstractExpansionTest.vb b/src/EditorFeatures/Test2/Expansion/AbstractExpansionTest.vb index 9ff69b2523c3d..bdc1b5ea7fcb4 100644 --- a/src/EditorFeatures/Test2/Expansion/AbstractExpansionTest.vb +++ b/src/EditorFeatures/Test2/Expansion/AbstractExpansionTest.vb @@ -27,6 +27,9 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Expansion Dim root = Await document.GetSyntaxRootAsync() + Dim formattingOptions = Await SyntaxFormattingOptions.FromDocumentAsync(document, CancellationToken.None) + Dim simplifierOptions = Await simplifierOptions.FromDocumentAsync(document, fallbackOptions: Nothing, CancellationToken.None) + If (hostDocument.AnnotatedSpans.ContainsKey("Expand")) Then For Each span In hostDocument.AnnotatedSpans("Expand") Dim node = GetExpressionSyntaxWithSameSpan(root.FindToken(span.Start).Parent, span.End) @@ -37,13 +40,11 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Expansion Dim node = GetExpressionSyntaxWithSameSpan(root.FindToken(span.Start).Parent, span.End) root = root.ReplaceNode(node, Await Simplifier.ExpandAsync(node, document, expandInsideNode:=Nothing, expandParameter:=expandParameter)) document = document.WithSyntaxRoot(root) - document = Await Simplifier.ReduceAsync(document, Simplifier.Annotation) + document = Await Simplifier.ReduceAsync(document, Simplifier.Annotation, simplifierOptions, CancellationToken.None) root = Await document.GetSyntaxRootAsync() Next End If - Dim formattingOptions = Await SyntaxFormattingOptions.FromDocumentAsync(document, CancellationToken.None) - document = document.WithSyntaxRoot(root) document = Await Formatter.FormatAsync(document, FormattingOptions, CancellationToken.None) diff --git a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb index 4a23a6a4834a2..6e604bb4e1624 100644 --- a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb @@ -114,12 +114,14 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification document = document.WithSyntaxRoot(root) +#Disable Warning RS0030 ' Do Not used banned APIs Dim simplifiedDocument As Document If Not explicitSpansToSimplifyWithin.IsDefaultOrEmpty Then simplifiedDocument = Await Simplifier.ReduceAsync(document, explicitSpansToSimplifyWithin, optionSet) Else simplifiedDocument = Await Simplifier.ReduceAsync(document, Simplifier.Annotation, optionSet) End If +#Enable Warning RS0030 Return simplifiedDocument End Function diff --git a/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs b/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs index 432ae717e94cc..a4603c33d98cf 100644 --- a/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs +++ b/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; @@ -66,8 +67,8 @@ private async Task TestCoreAsync(string testCode, string expected, (OptionKey var document = workspace.CurrentSolution.Projects.First().Documents.First(); var formattingService = document.GetRequiredLanguageService(); - var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, CancellationToken.None).ConfigureAwait(false); - var formattedDocument = await formattingService.FormatNewDocumentAsync(document, hintDocument: null, formattingOptions, CancellationToken.None); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, CancellationToken.None).ConfigureAwait(false); + var formattedDocument = await formattingService.FormatNewDocumentAsync(document, hintDocument: null, cleanupOptions, CancellationToken.None); var actual = await formattedDocument.GetTextAsync(); AssertEx.EqualOrDiff(expected, actual.ToString()); diff --git a/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb b/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb index 6c506446963db..0d77f26a96de0 100644 --- a/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb +++ b/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.ComponentModel.Composition Imports System.Threading +Imports Microsoft.CodeAnalysis.AddImport Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.CodeCleanup.Providers Imports Microsoft.CodeAnalysis.Formatting @@ -90,7 +91,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LineCommit Dim cleanupService = document.GetRequiredLanguageService(Of ICodeCleanerService) Dim simplifierOptions = document.GetSimplifierOptionsAsync(_globalOptions, cancellationToken).WaitAndGetResult(cancellationToken) - Dim cleanupOptions = New CodeCleanupOptions(formattingOptions, simplifierOptions) + Dim addImportOptions = AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).WaitAndGetResult(cancellationToken) + Dim cleanupOptions = New CodeCleanupOptions(formattingOptions, simplifierOptions, addImportOptions) Dim finalDocument As Document If useSemantics OrElse isExplicitFormat Then diff --git a/src/EditorFeatures/VisualBasicTest/CaseCorrecting/CaseCorrectionServiceTests.vb b/src/EditorFeatures/VisualBasicTest/CaseCorrecting/CaseCorrectionServiceTests.vb index 68369fd90e01a..c9c2de0f14ce7 100644 --- a/src/EditorFeatures/VisualBasicTest/CaseCorrecting/CaseCorrectionServiceTests.vb +++ b/src/EditorFeatures/VisualBasicTest/CaseCorrecting/CaseCorrectionServiceTests.vb @@ -4,14 +4,11 @@ Imports System.Collections.Immutable Imports System.Threading -Imports System.Xml.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.CodeCleanup.Providers Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces -Imports Microsoft.CodeAnalysis.Formatting -Imports Microsoft.CodeAnalysis.Simplification Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CaseCorrecting <[UseExportProvider]> @@ -36,9 +33,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CaseCorrecting Dim document = workspace.CurrentSolution.GetDocument(hostDocument.Id) Dim span = (Await document.GetSyntaxRootAsync()).FullSpan - Dim options = New CodeCleanupOptions( - Await SyntaxFormattingOptions.FromDocumentAsync(document, CancellationToken.None), - Await SimplifierOptions.FromDocumentAsync(document, fallbackOptions:=Nothing, CancellationToken.None)) + Dim options = Await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions:=Nothing, CancellationToken.None) Dim service = document.GetLanguageService(Of ICodeCleanerService) Dim newDocument = Await service.CleanupAsync( diff --git a/src/Features/CSharp/Portable/Formatting/CSharpAccessibilityModifiersNewDocumentFormattingProvider.cs b/src/Features/CSharp/Portable/Formatting/CSharpAccessibilityModifiersNewDocumentFormattingProvider.cs index ba53dbbc9a20f..2c6ac1de5ab38 100644 --- a/src/Features/CSharp/Portable/Formatting/CSharpAccessibilityModifiersNewDocumentFormattingProvider.cs +++ b/src/Features/CSharp/Portable/Formatting/CSharpAccessibilityModifiersNewDocumentFormattingProvider.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.AddAccessibilityModifiers; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.LanguageServices; using Microsoft.CodeAnalysis.Editing; @@ -26,7 +27,7 @@ public CSharpAccessibilityModifiersNewDocumentFormattingProvider() { } - public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken) + public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var accessibilityPreferences = documentOptions.GetOption(CodeStyleOptions2.RequireAccessibilityModifiers, document.Project.Language); diff --git a/src/Features/CSharp/Portable/Formatting/CSharpNamespaceDeclarationNewDocumentFormattingProvider.cs b/src/Features/CSharp/Portable/Formatting/CSharpNamespaceDeclarationNewDocumentFormattingProvider.cs index 050e3b16ed36a..428db28a1c04a 100644 --- a/src/Features/CSharp/Portable/Formatting/CSharpNamespaceDeclarationNewDocumentFormattingProvider.cs +++ b/src/Features/CSharp/Portable/Formatting/CSharpNamespaceDeclarationNewDocumentFormattingProvider.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CSharp.ConvertNamespace; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; @@ -27,7 +28,7 @@ public CSharpNamespaceDeclarationNewDocumentFormattingProvider() { } - public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken) + public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { var optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var root = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -36,7 +37,7 @@ public async Task FormatNewDocumentAsync(Document document, Document? if (namespaces.Count != 1) return document; - return await ConvertNamespaceTransform.ConvertAsync(document, namespaces[0], options, cancellationToken).ConfigureAwait(false); + return await ConvertNamespaceTransform.ConvertAsync(document, namespaces[0], options.FormattingOptions, cancellationToken).ConfigureAwait(false); } private static IEnumerable GetNamespacesToReplace(Document document, CompilationUnitSyntax root, DocumentOptionSet optionSet) diff --git a/src/Features/CSharp/Portable/Formatting/CSharpOrganizeUsingsNewDocumentFormattingProvider.cs b/src/Features/CSharp/Portable/Formatting/CSharpOrganizeUsingsNewDocumentFormattingProvider.cs index ed370a01dd77a..4bfbf176acb6c 100644 --- a/src/Features/CSharp/Portable/Formatting/CSharpOrganizeUsingsNewDocumentFormattingProvider.cs +++ b/src/Features/CSharp/Portable/Formatting/CSharpOrganizeUsingsNewDocumentFormattingProvider.cs @@ -6,9 +6,14 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; +using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.MisplacedUsingDirectives; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.OrganizeImports; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Simplification; namespace Microsoft.CodeAnalysis.CSharp.Formatting { @@ -21,10 +26,17 @@ public CSharpOrganizeUsingsNewDocumentFormattingProvider() { } - public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken) + public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { - var organizedDocument = await Formatter.OrganizeImportsAsync(document, cancellationToken).ConfigureAwait(false); - return await MisplacedUsingDirectivesCodeFixProvider.TransformDocumentIfRequiredAsync(organizedDocument, cancellationToken).ConfigureAwait(false); + var organizeImportsService = document.GetRequiredLanguageService(); + + var organizeOptions = await OrganizeImportsOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var codeStyleOption = documentOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement); + + var organizedDocument = await organizeImportsService.OrganizeImportsAsync(document, organizeOptions, cancellationToken).ConfigureAwait(false); + + return await MisplacedUsingDirectivesCodeFixProvider.TransformDocumentIfRequiredAsync(organizedDocument, options.SimplifierOptions, codeStyleOption, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Features/CSharp/Portable/Formatting/CSharpUseProgramMainNewDocumentFormattingProvider.cs b/src/Features/CSharp/Portable/Formatting/CSharpUseProgramMainNewDocumentFormattingProvider.cs index a7cec74575b69..128f258cc56f6 100644 --- a/src/Features/CSharp/Portable/Formatting/CSharpUseProgramMainNewDocumentFormattingProvider.cs +++ b/src/Features/CSharp/Portable/Formatting/CSharpUseProgramMainNewDocumentFormattingProvider.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.ConvertProgram; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host.Mef; @@ -22,13 +23,13 @@ public CSharpUseProgramMainNewDocumentFormattingProvider() { } - public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken) + public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { - var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); // if the user prefers Program.Main style instead, then attempt to convert a template with // top-level-statements to that form. - var option = options.GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements); + var option = documentOptions.GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements); if (option.Value) return document; diff --git a/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerNewDocumentFormattingProvider.cs b/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerNewDocumentFormattingProvider.cs index 0e723e3457129..ef1f1a6f61d04 100644 --- a/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerNewDocumentFormattingProvider.cs +++ b/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerNewDocumentFormattingProvider.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.FileHeaders; @@ -19,7 +20,7 @@ internal abstract class AbstractAddFileBannerNewDocumentFormattingProvider : INe protected abstract SyntaxGeneratorInternal SyntaxGeneratorInternal { get; } protected abstract AbstractFileHeaderHelper FileHeaderHelper { get; } - public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken) + public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { var rootToFormat = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); @@ -28,7 +29,7 @@ public async Task FormatNewDocumentAsync(Document document, Document? var fileHeaderTemplate = documentOptions.GetOption(CodeStyleOptions2.FileHeaderTemplate); if (!string.IsNullOrEmpty(fileHeaderTemplate)) { - var newLineTrivia = SyntaxGeneratorInternal.EndOfLine(options.NewLine); + var newLineTrivia = SyntaxGeneratorInternal.EndOfLine(options.FormattingOptions.NewLine); var rootWithFileHeader = await AbstractFileHeaderCodeFixProvider.GetTransformedSyntaxRootAsync( SyntaxGenerator.SyntaxFacts, FileHeaderHelper, diff --git a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs index 44f09038a6057..2f687a4e61786 100644 --- a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Packaging; @@ -71,12 +72,12 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) searchOptions = searchOptions with { SearchNuGetPackages = false }; } - var placement = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); var addImportOptions = new AddImportOptions( searchOptions, - context.Options(document.Project.LanguageServices).HideAdvancedMembers, - placement); + cleanupOptions, + context.Options(document.Project.LanguageServices).HideAdvancedMembers); var fixesForDiagnostic = await addImportService.GetFixesForDiagnosticsAsync( document, span, diagnostics, MaxResults, symbolSearchService, addImportOptions, packageSources, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/AddImport/AbstractAddImportFeatureService.cs b/src/Features/Core/Portable/AddImport/AbstractAddImportFeatureService.cs index a6cb300bb006c..49bf94ea79a47 100644 --- a/src/Features/Core/Portable/AddImport/AbstractAddImportFeatureService.cs +++ b/src/Features/Core/Portable/AddImport/AbstractAddImportFeatureService.cs @@ -23,6 +23,7 @@ using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.CodeCleanup; namespace Microsoft.CodeAnalysis.AddImport { @@ -94,7 +95,7 @@ private async Task> GetFixesInCurrentProcessAsy { if (!cancellationToken.IsCancellationRequested) { - if (CanAddImport(node, options.Placement.AllowInHiddenRegions, cancellationToken)) + if (CanAddImport(node, options.CleanupOptions.AddImportOptions.AllowInHiddenRegions, cancellationToken)) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var allSymbolReferences = await FindResultsAsync( @@ -106,7 +107,7 @@ private async Task> GetFixesInCurrentProcessAsy { cancellationToken.ThrowIfCancellationRequested(); - var fixData = await reference.TryGetFixDataAsync(document, node, options.Placement, cancellationToken).ConfigureAwait(false); + var fixData = await reference.TryGetFixDataAsync(document, node, options.CleanupOptions, cancellationToken).ConfigureAwait(false); result.AddIfNotNull(fixData); } } diff --git a/src/Features/Core/Portable/AddImport/IAddImportFeatureService.cs b/src/Features/Core/Portable/AddImport/IAddImportFeatureService.cs index 453c8a89cd5c8..2f856e4edc061 100644 --- a/src/Features/Core/Portable/AddImport/IAddImportFeatureService.cs +++ b/src/Features/Core/Portable/AddImport/IAddImportFeatureService.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Packaging; using Microsoft.CodeAnalysis.SymbolSearch; @@ -17,8 +18,8 @@ namespace Microsoft.CodeAnalysis.AddImport [DataContract] internal readonly record struct AddImportOptions( [property: DataMember(Order = 0)] SymbolSearchOptions SearchOptions, - [property: DataMember(Order = 1)] bool HideAdvancedMembers, - [property: DataMember(Order = 2)] AddImportPlacementOptions Placement); + [property: DataMember(Order = 1)] CodeCleanupOptions CleanupOptions, + [property: DataMember(Order = 2)] bool HideAdvancedMembers); internal interface IAddImportFeatureService : ILanguageService { diff --git a/src/Features/Core/Portable/AddImport/References/AssemblyReference.cs b/src/Features/Core/Portable/AddImport/References/AssemblyReference.cs index 680218405a222..4e5fecb1a9af9 100644 --- a/src/Features/Core/Portable/AddImport/References/AssemblyReference.cs +++ b/src/Features/Core/Portable/AddImport/References/AssemblyReference.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.SymbolSearch; using Roslyn.Utilities; @@ -28,7 +29,7 @@ public AssemblyReference( } public override async Task TryGetFixDataAsync( - Document document, SyntaxNode node, AddImportPlacementOptions options, CancellationToken cancellationToken) + Document document, SyntaxNode node, CodeCleanupOptions options, CancellationToken cancellationToken) { var textChanges = await GetTextChangesAsync(document, node, options, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/AddImport/References/MetadataSymbolReference.cs b/src/Features/Core/Portable/AddImport/References/MetadataSymbolReference.cs index 1671105787b8a..bace3e619a3e3 100644 --- a/src/Features/Core/Portable/AddImport/References/MetadataSymbolReference.cs +++ b/src/Features/Core/Portable/AddImport/References/MetadataSymbolReference.cs @@ -9,6 +9,7 @@ using System.IO; using System.Threading; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Tags; using Microsoft.CodeAnalysis.Text; @@ -41,7 +42,7 @@ public MetadataSymbolReference( protected override bool ShouldAddWithExistingImport(Document document) => true; protected override (string description, bool hasExistingImport) GetDescription( - Document document, AddImportPlacementOptions options, SyntaxNode node, + Document document, CodeCleanupOptions options, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken) { var (description, hasExistingImport) = base.GetDescription(document, options, node, semanticModel, cancellationToken); diff --git a/src/Features/Core/Portable/AddImport/References/PackageReference.cs b/src/Features/Core/Portable/AddImport/References/PackageReference.cs index 0168a9f3d3830..e790aa14aa0ef 100644 --- a/src/Features/Core/Portable/AddImport/References/PackageReference.cs +++ b/src/Features/Core/Portable/AddImport/References/PackageReference.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Roslyn.Utilities; @@ -33,7 +34,7 @@ public PackageReference( } public override async Task TryGetFixDataAsync( - Document document, SyntaxNode node, AddImportPlacementOptions options, CancellationToken cancellationToken) + Document document, SyntaxNode node, CodeCleanupOptions options, CancellationToken cancellationToken) { var textChanges = await GetTextChangesAsync( document, node, options, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/AddImport/References/ProjectSymbolReference.cs b/src/Features/Core/Portable/AddImport/References/ProjectSymbolReference.cs index 3f85b7457f2f8..aed38f3db4a81 100644 --- a/src/Features/Core/Portable/AddImport/References/ProjectSymbolReference.cs +++ b/src/Features/Core/Portable/AddImport/References/ProjectSymbolReference.cs @@ -7,6 +7,7 @@ using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Tags; @@ -87,7 +88,7 @@ protected override AddImportFixData GetFixData( } protected override (string description, bool hasExistingImport) GetDescription( - Document document, AddImportPlacementOptions options, SyntaxNode node, + Document document, CodeCleanupOptions options, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken) { var (description, hasExistingImport) = base.GetDescription(document, options, node, semanticModel, cancellationToken); diff --git a/src/Features/Core/Portable/AddImport/References/Reference.cs b/src/Features/Core/Portable/AddImport/References/Reference.cs index 98dbb57fa3853..a9080a50f67e6 100644 --- a/src/Features/Core/Portable/AddImport/References/Reference.cs +++ b/src/Features/Core/Portable/AddImport/References/Reference.cs @@ -10,7 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; @@ -102,10 +102,10 @@ public override int GetHashCode() } public abstract Task TryGetFixDataAsync( - Document document, SyntaxNode node, AddImportPlacementOptions options, CancellationToken cancellationToken); + Document document, SyntaxNode node, CodeCleanupOptions options, CancellationToken cancellationToken); protected async Task> GetTextChangesAsync( - Document document, SyntaxNode node, AddImportPlacementOptions options, CancellationToken cancellationToken) + Document document, SyntaxNode node, CodeCleanupOptions options, CancellationToken cancellationToken) { var originalDocument = document; @@ -113,10 +113,10 @@ protected async Task> GetTextChangesAsync( node, document, cancellationToken).ConfigureAwait(false); var newDocument = await provider.AddImportAsync( - node, SearchResult.NameParts, document, options, cancellationToken).ConfigureAwait(false); + node, SearchResult.NameParts, document, options.AddImportOptions, cancellationToken).ConfigureAwait(false); var cleanedDocument = await CodeAction.CleanupDocumentAsync( - newDocument, cancellationToken).ConfigureAwait(false); + newDocument, options, cancellationToken).ConfigureAwait(false); var textChanges = await cleanedDocument.GetTextChangesAsync( originalDocument, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/AddImport/References/SymbolReference.cs b/src/Features/Core/Portable/AddImport/References/SymbolReference.cs index 45f8cf54a43f6..2b8eb2c7f361e 100644 --- a/src/Features/Core/Portable/AddImport/References/SymbolReference.cs +++ b/src/Features/Core/Portable/AddImport/References/SymbolReference.cs @@ -9,6 +9,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Tags; using Microsoft.CodeAnalysis.Text; @@ -52,7 +53,7 @@ public override int GetHashCode() private async Task> GetTextChangesAsync( Document document, SyntaxNode contextNode, - AddImportPlacementOptions options, bool hasExistingImport, + CodeCleanupOptions options, bool hasExistingImport, CancellationToken cancellationToken) { // Defer to the language to add the actual import/using. @@ -66,10 +67,10 @@ private async Task> GetTextChangesAsync( var updatedDocument = await provider.AddImportAsync( newContextNode, SymbolResult.Symbol, newDocument, - options, cancellationToken).ConfigureAwait(false); + options.AddImportOptions, cancellationToken).ConfigureAwait(false); var cleanedDocument = await CodeAction.CleanupDocumentAsync( - updatedDocument, cancellationToken).ConfigureAwait(false); + updatedDocument, options, cancellationToken).ConfigureAwait(false); var textChanges = await cleanedDocument.GetTextChangesAsync( document, cancellationToken).ConfigureAwait(false); @@ -79,7 +80,7 @@ private async Task> GetTextChangesAsync( public sealed override async Task TryGetFixDataAsync( Document document, SyntaxNode node, - AddImportPlacementOptions options, CancellationToken cancellationToken) + CodeCleanupOptions options, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var (description, hasExistingImport) = GetDescription(document, options, node, semanticModel, cancellationToken); @@ -127,11 +128,11 @@ protected abstract AddImportFixData GetFixData( protected abstract CodeActionPriority GetPriority(Document document); protected virtual (string description, bool hasExistingImport) GetDescription( - Document document, AddImportPlacementOptions options, SyntaxNode node, + Document document, CodeCleanupOptions options, SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken) { return provider.GetDescription( - document, options, SymbolResult.Symbol, semanticModel, node, cancellationToken); + document, options.AddImportOptions, SymbolResult.Symbol, semanticModel, node, cancellationToken); } } } diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index 48915313eab50..7f0bab1059332 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -12,7 +12,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.AddImport; -using Microsoft.CodeAnalysis.Completion; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.FindSymbols.Finders; @@ -416,12 +416,11 @@ private static async Task> FindChangeSignatureR foreach (var docId in nodesToUpdate.Keys) { var updatedDoc = currentSolution.GetRequiredDocument(docId).WithSyntaxRoot(updatedRoots[docId]); - var addImportOptions = await AddImportPlacementOptions.FromDocumentAsync(updatedDoc, cancellationToken).ConfigureAwait(false); - var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(updatedDoc, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(updatedDoc, fallbackOptions: null, cancellationToken).ConfigureAwait(false); - var docWithImports = await ImportAdder.AddImportsFromSymbolAnnotationAsync(updatedDoc, addImportOptions, cancellationToken).ConfigureAwait(false); - var reducedDoc = await Simplifier.ReduceAsync(docWithImports, Simplifier.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false); - var formattedDoc = await Formatter.FormatAsync(reducedDoc, SyntaxAnnotation.ElasticAnnotation, formattingOptions, cancellationToken).ConfigureAwait(false); + var docWithImports = await ImportAdder.AddImportsFromSymbolAnnotationAsync(updatedDoc, cleanupOptions.AddImportOptions, cancellationToken).ConfigureAwait(false); + var reducedDoc = await Simplifier.ReduceAsync(docWithImports, Simplifier.Annotation, cleanupOptions.SimplifierOptions, cancellationToken: cancellationToken).ConfigureAwait(false); + var formattedDoc = await Formatter.FormatAsync(reducedDoc, SyntaxAnnotation.ElasticAnnotation, cleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false); currentSolution = currentSolution.WithDocumentSyntaxRoot(docId, (await formattedDoc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!); } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs index 407042a49b2dd..f3373836744dd 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Formatting; using Roslyn.Utilities; +using Microsoft.CodeAnalysis.CodeCleanup; namespace Microsoft.CodeAnalysis.CodeFixes.Suppression { @@ -124,7 +125,7 @@ protected override async Task GetChangedSuppressionDocumentAsync(Cance var services = suppressionsDoc.Project.Solution.Workspace.Services; var suppressionsRoot = await suppressionsDoc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var addImportsService = suppressionsDoc.GetRequiredLanguageService(); - var options = await SyntaxFormattingOptions.FromDocumentAsync(suppressionsDoc, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(suppressionsDoc, fallbackOptions: null, cancellationToken).ConfigureAwait(false); foreach (var (targetSymbol, diagnostics) in _diagnosticsBySymbol) { @@ -133,12 +134,12 @@ protected override async Task GetChangedSuppressionDocumentAsync(Cance Contract.ThrowIfFalse(!diagnostic.IsSuppressed); suppressionsRoot = Fixer.AddGlobalSuppressMessageAttribute( suppressionsRoot, targetSymbol, _suppressMessageAttribute, diagnostic, - services, options, addImportsService, cancellationToken); + services, cleanupOptions.FormattingOptions, addImportsService, cancellationToken); } } var result = suppressionsDoc.WithSyntaxRoot(suppressionsRoot); - var final = await CleanupDocumentAsync(result, cancellationToken).ConfigureAwait(false); + var final = await CleanupDocumentAsync(result, cleanupOptions, cancellationToken).ConfigureAwait(false); return final; } diff --git a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs index 5c6001c3ddea6..17da6c72cc9d7 100644 --- a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsFeatureService.cs @@ -62,8 +62,8 @@ public async Task AnalyzeAsync(Document documen var addImportOptions = new AddImportOptions( SearchOptions: new(SearchReferenceAssemblies: true, SearchNuGetPackages: false), - HideAdvancedMembers: options.HideAdvancedMembers, - Placement: options.Placement); + CleanupOptions: options.CleanupOptions, + HideAdvancedMembers: options.HideAdvancedMembers); var unambiguousFixes = await addImportFeatureService.GetUniqueFixesAsync( document, textSpan, FixableDiagnosticIds, symbolSearchService, diff --git a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs index 8060fb3003584..a798c3084bbc8 100644 --- a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs @@ -7,14 +7,10 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.AddImport; -using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeRefactorings; -using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.PasteTracking; using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.AddMissingImports { @@ -39,8 +35,10 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // Check pasted text span for missing imports var addMissingImportsService = document.GetLanguageService(); - var placement = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); - var options = new AddMissingImportsOptions(context.Options(document.Project.LanguageServices).HideAdvancedMembers, placement); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var options = new AddMissingImportsOptions( + cleanupOptions, + context.Options(document.Project.LanguageServices).HideAdvancedMembers); var analysis = await addMissingImportsService.AnalyzeAsync(document, textSpan, options, cancellationToken).ConfigureAwait(false); if (!analysis.CanAddMissingImports) diff --git a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/IAddMissingImportsFeatureService.cs b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/IAddMissingImportsFeatureService.cs index 7cb68cf7d3cd9..aa84f876128a4 100644 --- a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/IAddMissingImportsFeatureService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/IAddMissingImportsFeatureService.cs @@ -5,8 +5,7 @@ using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.AddImport; -using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Text; @@ -14,8 +13,8 @@ namespace Microsoft.CodeAnalysis.AddMissingImports { [DataContract] internal readonly record struct AddMissingImportsOptions( - [property: DataMember(Order = 0)] bool HideAdvancedMembers, - [property: DataMember(Order = 1)] AddImportPlacementOptions Placement); + [property: DataMember(Order = 0)] CodeCleanupOptions CleanupOptions, + [property: DataMember(Order = 1)] bool HideAdvancedMembers); internal interface IAddMissingImportsFeatureService : ILanguageService { diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs index 8e4c0d35092ae..fb0a718f0f008 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.LanguageServices; @@ -85,9 +86,9 @@ private async Task DetermineNewDocumentAsync(Document document, Comple return document; } - var memberContainingDocumentFormattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); - var insertionRoot = await GetTreeWithAddedSyntaxNodeRemovedAsync(memberContainingDocument, memberContainingDocumentFormattingOptions, cancellationToken).ConfigureAwait(false); - var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, memberContainingDocumentFormattingOptions, cancellationToken).ConfigureAwait(false); + var memberContainingDocumentCleanupOptions = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var insertionRoot = await GetTreeWithAddedSyntaxNodeRemovedAsync(memberContainingDocument, memberContainingDocumentCleanupOptions, cancellationToken).ConfigureAwait(false); + var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, memberContainingDocumentCleanupOptions, cancellationToken).ConfigureAwait(false); var destinationSpan = ComputeDestinationSpan(insertionRoot); @@ -179,21 +180,21 @@ private TextSpan ComputeDestinationSpan(SyntaxNode insertionRoot) } private async Task GenerateInsertionTextAsync( - Document memberContainingDocument, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken) + Document memberContainingDocument, CodeCleanupOptions cleanupOptions, CancellationToken cancellationToken) { - memberContainingDocument = await Simplifier.ReduceAsync(memberContainingDocument, Simplifier.Annotation, optionSet: null, cancellationToken).ConfigureAwait(false); - memberContainingDocument = await Formatter.FormatAsync(memberContainingDocument, Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); + memberContainingDocument = await Simplifier.ReduceAsync(memberContainingDocument, Simplifier.Annotation, cleanupOptions.SimplifierOptions, cancellationToken).ConfigureAwait(false); + memberContainingDocument = await Formatter.FormatAsync(memberContainingDocument, Formatter.Annotation, cleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false); var root = await memberContainingDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); return root.GetAnnotatedNodes(_annotation).Single().ToString().Trim(); } private async Task GetTreeWithAddedSyntaxNodeRemovedAsync( - Document document, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken) + Document document, CodeCleanupOptions cleanupOptions, CancellationToken cancellationToken) { // Added imports are annotated for simplification too. Therefore, we simplify the document // before removing added member node to preserve those imports in the document. - document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, optionSet: null, cancellationToken).ConfigureAwait(false); + document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cleanupOptions.SimplifierOptions, cancellationToken).ConfigureAwait(false); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var members = root.GetAnnotatedNodes(_annotation).AsImmutable(); @@ -203,7 +204,7 @@ private async Task GetTreeWithAddedSyntaxNodeRemovedAsync( var dismemberedDocument = document.WithSyntaxRoot(root); - dismemberedDocument = await Formatter.FormatAsync(dismemberedDocument, Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); + dismemberedDocument = await Formatter.FormatAsync(dismemberedDocument, Formatter.Annotation, cleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false); return await dismemberedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index 0ea7726d5142a..9e3b7d1021387 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -289,6 +289,7 @@ private static async Task GetFormattedSolutionAsync(Solution unformatt var document = formattedSolution.GetDocument(documentId); var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); var formattedDocument = await Formatter.FormatAsync( document, @@ -299,7 +300,8 @@ private static async Task GetFormattedSolutionAsync(Solution unformatt var simplifiedDocument = await Simplifier.ReduceAsync( formattedDocument, Simplifier.Annotation, - cancellationToken: cancellationToken).ConfigureAwait(false); + simplifierOptions, + cancellationToken).ConfigureAwait(false); formattedSolution = simplifiedDocument.Project.Solution; } diff --git a/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs b/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs index b47327e345306..bc220976d354e 100644 --- a/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs +++ b/src/Features/Core/Portable/ExtractMethod/ExtractMethodResult.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -90,15 +91,16 @@ internal ExtractMethodResult( var root = await DocumentWithoutFinalFormatting.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); root = root.ReplaceToken(InvocationNameToken, InvocationNameToken.WithAdditionalAnnotations(annotation)); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(DocumentWithoutFinalFormatting, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var annotatedDocument = DocumentWithoutFinalFormatting.WithSyntaxRoot(root); - var simplifiedDocument = await Simplifier.ReduceAsync(annotatedDocument, Simplifier.Annotation, optionSet: null, cancellationToken).ConfigureAwait(false); + var simplifiedDocument = await Simplifier.ReduceAsync(annotatedDocument, Simplifier.Annotation, cleanupOptions.SimplifierOptions, cancellationToken).ConfigureAwait(false); var simplifiedRoot = await simplifiedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - 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)); + Formatter.Format(simplifiedRoot, Formatter.Annotation, services, cleanupOptions.FormattingOptions, FormattingRules, cancellationToken)); var formattedRoot = await formattedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); return (formattedDocument, formattedRoot.GetAnnotatedTokens(annotation).Single()); diff --git a/src/Features/Core/Portable/Formatting/AbstractNewDocumentFormattingService.cs b/src/Features/Core/Portable/Formatting/AbstractNewDocumentFormattingService.cs index e7f59e6c693dc..15d06e7a3ce98 100644 --- a/src/Features/Core/Portable/Formatting/AbstractNewDocumentFormattingService.cs +++ b/src/Features/Core/Portable/Formatting/AbstractNewDocumentFormattingService.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host.Mef; using Roslyn.Utilities; @@ -32,7 +33,7 @@ private IEnumerable GetProviders() return _providerValues; } - public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken) + public async Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { foreach (var provider in GetProviders()) { @@ -52,7 +53,7 @@ public async Task FormatNewDocumentAsync(Document document, Document? // before we call the next provider, otherwise they might not see things as they are meant to be. // Because formatting providers often re-use code fix logic, they are often written assuming this will // happen. - document = await CodeAction.CleanupDocumentAsync(document, cancellationToken).ConfigureAwait(false); + document = await CodeAction.CleanupDocumentAsync(document, options, cancellationToken).ConfigureAwait(false); } catch (Exception ex) when (FatalError.ReportAndCatchUnlessCanceled(ex, cancellationToken, ErrorSeverity.General)) { diff --git a/src/Features/Core/Portable/Formatting/INewDocumentFormattingProvider.cs b/src/Features/Core/Portable/Formatting/INewDocumentFormattingProvider.cs index 3012091569619..1612691204b45 100644 --- a/src/Features/Core/Portable/Formatting/INewDocumentFormattingProvider.cs +++ b/src/Features/Core/Portable/Formatting/INewDocumentFormattingProvider.cs @@ -4,12 +4,13 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; namespace Microsoft.CodeAnalysis.Formatting { internal interface INewDocumentFormattingProvider { - /// - Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken); + /// + Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/Formatting/INewDocumentFormattingService.cs b/src/Features/Core/Portable/Formatting/INewDocumentFormattingService.cs index 74b3452f825f7..80e6f58a7fdc5 100644 --- a/src/Features/Core/Portable/Formatting/INewDocumentFormattingService.cs +++ b/src/Features/Core/Portable/Formatting/INewDocumentFormattingService.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.Formatting @@ -16,6 +17,6 @@ internal interface INewDocumentFormattingService : ILanguageService /// The document to format. /// An optional additional document that can be used to inform the formatting operation. /// A cancellation token. - Task FormatNewDocumentAsync(Document document, Document? hintDocument, SyntaxFormattingOptions options, CancellationToken cancellationToken); + Task FormatNewDocumentAsync(Document document, Document? hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs index 4daf9502e6281..42db6a142687a 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.LanguageServices; @@ -312,8 +313,8 @@ private async Task> GetGenerateInNewFileOperati var formattingService = newDocument.GetLanguageService(); if (formattingService is not null) { - var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(_semanticDocument.Document, _cancellationToken).ConfigureAwait(false); - codeGenResult = await formattingService.FormatNewDocumentAsync(codeGenResult, _semanticDocument.Document, formattingOptions, _cancellationToken).ConfigureAwait(false); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(_semanticDocument.Document, fallbackOptions: null, _cancellationToken).ConfigureAwait(false); + codeGenResult = await formattingService.FormatNewDocumentAsync(codeGenResult, _semanticDocument.Document, cleanupOptions, _cancellationToken).ConfigureAwait(false); } } diff --git a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.AbstractIntroduceVariableCodeAction.cs b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.AbstractIntroduceVariableCodeAction.cs index 4d16d6b2d0f7f..38eb1732c5e5d 100644 --- a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.AbstractIntroduceVariableCodeAction.cs +++ b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.AbstractIntroduceVariableCodeAction.cs @@ -49,7 +49,8 @@ internal AbstractIntroduceVariableCodeAction( protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) { var changedDocument = await GetChangedDocumentCoreAsync(cancellationToken).ConfigureAwait(false); - return await Simplifier.ReduceAsync(changedDocument, cancellationToken: cancellationToken).ConfigureAwait(false); + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(changedDocument, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + return await Simplifier.ReduceAsync(changedDocument, simplifierOptions, cancellationToken).ConfigureAwait(false); } private async Task GetChangedDocumentCoreAsync(CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.IntroduceVariableAllOccurrenceCodeAction.cs b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.IntroduceVariableAllOccurrenceCodeAction.cs index b48273827f380..f3a6e31eafc5f 100644 --- a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.IntroduceVariableAllOccurrenceCodeAction.cs +++ b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.IntroduceVariableAllOccurrenceCodeAction.cs @@ -31,7 +31,9 @@ internal IntroduceVariableAllOccurrenceCodeAction( protected override async Task PostProcessChangesAsync(Document document, CancellationToken cancellationToken) { var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); - document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false); + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + + document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, simplifierOptions, cancellationToken).ConfigureAwait(false); document = await Formatter.FormatAsync(document, Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); document = await CaseCorrector.CaseCorrectAsync(document, CaseCorrector.Annotation, cancellationToken).ConfigureAwait(false); return document; diff --git a/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs b/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs index 1a1ef00e6a0ac..ed6501cd2ea4c 100644 --- a/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs +++ b/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; @@ -87,12 +88,12 @@ internal static class ExtractTypeHelpers context, cancellationToken).ConfigureAwait(false); - var newTypeFormattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(newTypeDocument, cancellationToken).ConfigureAwait(false); + var newCleanupOptions = await CodeCleanupOptions.FromDocumentAsync(newTypeDocument, fallbackOptions: null, cancellationToken).ConfigureAwait(false); var formattingService = newTypeDocument.GetLanguageService(); if (formattingService is not null) { - newTypeDocument = await formattingService.FormatNewDocumentAsync(newTypeDocument, hintDocument, newTypeFormattingOptions, cancellationToken).ConfigureAwait(false); + newTypeDocument = await formattingService.FormatNewDocumentAsync(newTypeDocument, hintDocument, newCleanupOptions, cancellationToken).ConfigureAwait(false); } var syntaxRoot = await newTypeDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -105,8 +106,8 @@ internal static class ExtractTypeHelpers newTypeDocument = newTypeDocument.WithSyntaxRoot(annotatedRoot); - var simplified = await Simplifier.ReduceAsync(newTypeDocument, cancellationToken: cancellationToken).ConfigureAwait(false); - var formattedDocument = await Formatter.FormatAsync(simplified, newTypeFormattingOptions, cancellationToken).ConfigureAwait(false); + var simplified = await Simplifier.ReduceAsync(newTypeDocument, newCleanupOptions.SimplifierOptions, cancellationToken).ConfigureAwait(false); + var formattedDocument = await Formatter.FormatAsync(simplified, newCleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false); return (formattedDocument, typeAnnotation); } diff --git a/src/Features/Core/Portable/Snippets/SnippetFunctionService.cs b/src/Features/Core/Portable/Snippets/SnippetFunctionService.cs index 4aa7f180eb464..c2b59bfcd6899 100644 --- a/src/Features/Core/Portable/Snippets/SnippetFunctionService.cs +++ b/src/Features/Core/Portable/Snippets/SnippetFunctionService.cs @@ -35,7 +35,7 @@ internal abstract class SnippetFunctionService : ILanguageService /// For a specified snippet field, replace it with the fully qualified name then simplify in the context of the document /// in order to retrieve the simplified type name. /// - public static async Task GetSimplifiedTypeNameAsync(Document document, TextSpan fieldSpan, string fullyQualifiedTypeName, CancellationToken cancellationToken) + public static async Task GetSimplifiedTypeNameAsync(Document document, TextSpan fieldSpan, string fullyQualifiedTypeName, SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { // Insert the function parameter (fully qualified type name) into the document. var updatedTextSpan = new TextSpan(fieldSpan.Start, fullyQualifiedTypeName.Length); @@ -45,7 +45,7 @@ internal abstract class SnippetFunctionService : ILanguageService var documentWithFullyQualifiedTypeName = document.WithText(text.WithChanges(textChange)); // Simplify - var simplifiedTypeName = await GetSimplifiedTypeNameAtSpanAsync(documentWithFullyQualifiedTypeName, updatedTextSpan, cancellationToken).ConfigureAwait(false); + var simplifiedTypeName = await GetSimplifiedTypeNameAtSpanAsync(documentWithFullyQualifiedTypeName, updatedTextSpan, simplifierOptions, cancellationToken).ConfigureAwait(false); return simplifiedTypeName; } @@ -53,7 +53,7 @@ internal abstract class SnippetFunctionService : ILanguageService /// For a document with the default switch snippet inserted, generate the expanded set of cases based on the value /// of the field currently inserted into the switch statement. /// - public async Task GetSwitchExpansionAsync(Document document, TextSpan caseGenerationLocation, TextSpan switchExpressionLocation, CancellationToken cancellationToken) + public async Task GetSwitchExpansionAsync(Document document, TextSpan caseGenerationLocation, TextSpan switchExpressionLocation, SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { var typeSymbol = await GetEnumSymbolAsync(document, switchExpressionLocation, cancellationToken).ConfigureAwait(false); if (typeSymbol?.TypeKind != TypeKind.Enum) @@ -69,7 +69,7 @@ internal abstract class SnippetFunctionService : ILanguageService // Find and use the most simplified legal version of the enum type name in this context var fullyQualifiedEnumName = typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - var simplifiedTypeName = await GetSimplifiedEnumNameAsync(document, fullyQualifiedEnumName, enumFields.First().Name, caseGenerationLocation, cancellationToken).ConfigureAwait(false); + var simplifiedTypeName = await GetSimplifiedEnumNameAsync(document, fullyQualifiedEnumName, enumFields.First().Name, caseGenerationLocation, simplifierOptions, cancellationToken).ConfigureAwait(false); if (simplifiedTypeName == null) { return null; @@ -126,17 +126,18 @@ public static bool TryGetSnippetFunctionInfo( string fullyQualifiedTypeName, string firstEnumMemberName, TextSpan caseGenerationLocation, + SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { // Insert switch with enum case into the document. var (documentWithFullyQualified, fullyQualifiedTypeLocation) = await GetDocumentWithEnumCaseAsync(document, fullyQualifiedTypeName, firstEnumMemberName, caseGenerationLocation, cancellationToken).ConfigureAwait(false); // Simplify enum case. - var simplifiedEnum = await GetSimplifiedTypeNameAtSpanAsync(documentWithFullyQualified, fullyQualifiedTypeLocation, cancellationToken).ConfigureAwait(false); + var simplifiedEnum = await GetSimplifiedTypeNameAtSpanAsync(documentWithFullyQualified, fullyQualifiedTypeLocation, simplifierOptions, cancellationToken).ConfigureAwait(false); return simplifiedEnum; } - private static async Task GetSimplifiedTypeNameAtSpanAsync(Document documentWithFullyQualifiedTypeName, TextSpan fullyQualifiedTypeSpan, CancellationToken cancellationToken) + private static async Task GetSimplifiedTypeNameAtSpanAsync(Document documentWithFullyQualifiedTypeName, TextSpan fullyQualifiedTypeSpan, SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { // Simplify var typeAnnotation = new SyntaxAnnotation(); @@ -151,7 +152,7 @@ public static bool TryGetSnippetFunctionInfo( var updatedRoot = syntaxRoot.ReplaceNode(nodeToReplace, nodeToReplace.WithAdditionalAnnotations(typeAnnotation, Simplifier.Annotation)); var documentWithAnnotations = documentWithFullyQualifiedTypeName.WithSyntaxRoot(updatedRoot); - var simplifiedDocument = await Simplifier.ReduceAsync(documentWithAnnotations, cancellationToken: cancellationToken).ConfigureAwait(false); + var simplifiedDocument = await Simplifier.ReduceAsync(documentWithAnnotations, simplifierOptions, cancellationToken).ConfigureAwait(false); var simplifiedRoot = await simplifiedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var simplifiedTypeName = simplifiedRoot.GetAnnotatedNodesAndTokens(typeAnnotation).Single().ToString(); return simplifiedTypeName; diff --git a/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs b/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs index 99540d07f0711..4846eb433a7aa 100644 --- a/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs +++ b/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Snippets; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LanguageServer.Protocol; @@ -99,8 +100,9 @@ public InlineCompletionsHandler(XmlSnippetParser xmlSnippetParser) // Use the formatting options specified by the client to format the snippet. var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(request.Options, context.Document, cancellationToken).ConfigureAwait(false); + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(context.Document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); - var formattedLspSnippet = await GetFormattedLspSnippetAsync(parsedSnippet, wordOnLeft.Value, context.Document, sourceText, formattingOptions, cancellationToken).ConfigureAwait(false); + var formattedLspSnippet = await GetFormattedLspSnippetAsync(parsedSnippet, wordOnLeft.Value, context.Document, sourceText, formattingOptions, simplifierOptions, cancellationToken).ConfigureAwait(false); return new VSInternalInlineCompletionList { @@ -122,11 +124,18 @@ public InlineCompletionsHandler(XmlSnippetParser xmlSnippetParser) /// /// Note that the operations in this method are sensitive to the context in the document and so must be calculated on each request. /// - private static async Task GetFormattedLspSnippetAsync(ParsedXmlSnippet parsedSnippet, TextSpan snippetShortcut, Document originalDocument, SourceText originalSourceText, SyntaxFormattingOptions options, CancellationToken cancellationToken) + private static async Task GetFormattedLspSnippetAsync( + ParsedXmlSnippet parsedSnippet, + TextSpan snippetShortcut, + Document originalDocument, + SourceText originalSourceText, + SyntaxFormattingOptions formattingOptions, + SimplifierOptions simplifierOptions, + CancellationToken cancellationToken) { // Calculate the snippet text with defaults + snippet function results. var (snippetFullText, fields, caretSpan) = await GetReplacedSnippetTextAsync( - originalDocument, originalSourceText, snippetShortcut, parsedSnippet, cancellationToken).ConfigureAwait(false); + originalDocument, originalSourceText, snippetShortcut, parsedSnippet, simplifierOptions, cancellationToken).ConfigureAwait(false); // Create a document with the default snippet text that we can use to format the snippet. var textChange = new TextChange(snippetShortcut, snippetFullText); @@ -136,7 +145,7 @@ private static async Task GetFormattedLspSnippetAsync(ParsedXmlSnippet p var root = await originalDocument.WithText(documentWithSnippetText).GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var spanToFormat = TextSpan.FromBounds(textChange.Span.Start, snippetEndPosition); - var formattingChanges = Formatter.GetFormattedTextChanges(root, spanToFormat, originalDocument.Project.Solution.Workspace.Services, options, cancellationToken: cancellationToken) + var formattingChanges = Formatter.GetFormattedTextChanges(root, spanToFormat, originalDocument.Project.Solution.Workspace.Services, formattingOptions, cancellationToken: cancellationToken) ?.ToImmutableArray() ?? ImmutableArray.Empty; var formattedText = documentWithSnippetText.WithChanges(formattingChanges); @@ -200,6 +209,7 @@ static TextSpan GetTextSpanInContextOfSnippet(int positionInFullText, int snippe SourceText originalSourceText, TextSpan snippetSpan, ParsedXmlSnippet parsedSnippet, + SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { var documentWithDefaultSnippet = originalDocument.WithText( @@ -228,7 +238,7 @@ static TextSpan GetTextSpanInContextOfSnippet(int positionInFullText, int snippe // To avoid a bunch of document changes and re-parsing, we always calculate the snippet function result // against the document with the default snippet text applied to it instead of with each incremental function result. // So we need to remember the index into the original document. - part = await functionPart.WithSnippetFunctionResultAsync(documentWithDefaultSnippet, new TextSpan(locationInDefaultSnippet, part.DefaultText.Length), cancellationToken).ConfigureAwait(false); + part = await functionPart.WithSnippetFunctionResultAsync(documentWithDefaultSnippet, new TextSpan(locationInDefaultSnippet, part.DefaultText.Length), simplifierOptions, cancellationToken).ConfigureAwait(false); } // Only store spans for editable fields or the cursor location, we don't need to get back to anything else. diff --git a/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/XmlSnippetParser.ParsedXmlSnippet.cs b/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/XmlSnippetParser.ParsedXmlSnippet.cs index 925d86259707b..d6ae271ecb170 100644 --- a/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/XmlSnippetParser.ParsedXmlSnippet.cs +++ b/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/XmlSnippetParser.ParsedXmlSnippet.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.LanguageServer.Handler.InlineCompletions; @@ -40,7 +41,7 @@ internal record SnippetFieldPart(string FieldName, string DefaultText, int? Edit internal record SnippetFunctionPart(string FieldName, string DefaultText, int? EditIndex, string FunctionName, string? FunctionParam) : SnippetFieldPart(FieldName, DefaultText, EditIndex) { - public async Task WithSnippetFunctionResultAsync(Document documentWithSnippet, TextSpan fieldSpan, CancellationToken cancellationToken) + public async Task WithSnippetFunctionResultAsync(Document documentWithSnippet, TextSpan fieldSpan, SimplifierOptions simplifierOptions, CancellationToken cancellationToken) { var snippetFunctionService = documentWithSnippet.Project.GetRequiredLanguageService(); switch (FunctionName) @@ -51,7 +52,7 @@ public async Task WithSnippetFunctionResultAsync(Document d return this; } - var simplifiedTypeName = await SnippetFunctionService.GetSimplifiedTypeNameAsync(documentWithSnippet, fieldSpan, FunctionParam, cancellationToken).ConfigureAwait(false); + var simplifiedTypeName = await SnippetFunctionService.GetSimplifiedTypeNameAsync(documentWithSnippet, fieldSpan, FunctionParam, simplifierOptions, cancellationToken).ConfigureAwait(false); if (simplifiedTypeName == null) { return this; diff --git a/src/Features/VisualBasic/Portable/Formatting/VisualBasicOrganizeUsingsNewDocumentFormattingProvider.vb b/src/Features/VisualBasic/Portable/Formatting/VisualBasicOrganizeUsingsNewDocumentFormattingProvider.vb index 7199cf45bd65a..51b0f473ae6cd 100644 --- a/src/Features/VisualBasic/Portable/Formatting/VisualBasicOrganizeUsingsNewDocumentFormattingProvider.vb +++ b/src/Features/VisualBasic/Portable/Formatting/VisualBasicOrganizeUsingsNewDocumentFormattingProvider.vb @@ -4,6 +4,7 @@ Imports System.Composition Imports System.Threading +Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host.Mef @@ -17,7 +18,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting Public Sub New() End Sub - Public Function FormatNewDocumentAsync(document As Document, hintDocument As Document, options As SyntaxFormattingOptions, cancellationToken As CancellationToken) As Task(Of Document) Implements INewDocumentFormattingProvider.FormatNewDocumentAsync + Public Function FormatNewDocumentAsync(document As Document, hintDocument As Document, options As CodeCleanupOptions, cancellationToken As CancellationToken) As Task(Of Document) Implements INewDocumentFormattingProvider.FormatNewDocumentAsync Return Formatter.OrganizeImportsAsync(document, cancellationToken) End Function End Class diff --git a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs index 56a7eef0495a3..4f0f721f5358f 100644 --- a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs @@ -9,6 +9,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -324,26 +325,26 @@ private async Task FormatDocumentCreatedFromTemplateAsync(IVsHierarchy hierarchy var documentId = DocumentId.CreateNewId(projectToAddTo.Id); var forkedSolution = projectToAddTo.Solution.AddDocument(DocumentInfo.Create(documentId, filePath, loader: new FileTextLoader(filePath, defaultEncoding: null), filePath: filePath)); - var addedDocument = forkedSolution.GetDocument(documentId)!; + var addedDocument = forkedSolution.GetRequiredDocument(documentId); - var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(addedDocument, cancellationToken).ConfigureAwait(true); + var cleanupOptions = await CodeCleanupOptions.FromDocumentAsync(addedDocument, fallbackOptions: null, cancellationToken).ConfigureAwait(true); // Call out to various new document formatters to tweak what they want var formattingService = addedDocument.GetLanguageService(); if (formattingService is not null) { - addedDocument = await formattingService.FormatNewDocumentAsync(addedDocument, hintDocument: null, formattingOptions, cancellationToken).ConfigureAwait(true); + addedDocument = await formattingService.FormatNewDocumentAsync(addedDocument, hintDocument: null, cleanupOptions, cancellationToken).ConfigureAwait(true); } var rootToFormat = await addedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(true); // Format document var unformattedText = await addedDocument.GetTextAsync(cancellationToken).ConfigureAwait(true); - var formattedRoot = Formatter.Format(rootToFormat, workspace.Services, formattingOptions, cancellationToken); + var formattedRoot = Formatter.Format(rootToFormat, workspace.Services, cleanupOptions.FormattingOptions, cancellationToken); var formattedText = formattedRoot.GetText(unformattedText.Encoding, unformattedText.ChecksumAlgorithm); // Ensure the line endings are normalized. The formatter doesn't touch everything if it doesn't need to. - var targetLineEnding = formattingOptions.NewLine; + var targetLineEnding = cleanupOptions.FormattingOptions.NewLine; var originalText = formattedText; foreach (var originalLine in originalText.Lines) diff --git a/src/VisualStudio/Core/Def/Snippets/AbstractSnippetExpansionClient.cs b/src/VisualStudio/Core/Def/Snippets/AbstractSnippetExpansionClient.cs index a4cd5c55d4fef..52968f5c64c83 100644 --- a/src/VisualStudio/Core/Def/Snippets/AbstractSnippetExpansionClient.cs +++ b/src/VisualStudio/Core/Def/Snippets/AbstractSnippetExpansionClient.cs @@ -65,7 +65,7 @@ internal abstract class AbstractSnippetExpansionClient : ForegroundThreadAffinit protected readonly Guid LanguageServiceGuid; protected readonly ITextView TextView; protected readonly ITextBuffer SubjectBuffer; - protected readonly IGlobalOptionService GlobalOptions; + internal readonly IGlobalOptionService GlobalOptions; private readonly ImmutableArray> _allArgumentProviders; private ImmutableArray _argumentProviders; diff --git a/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionGenerateSwitchCases.cs b/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionGenerateSwitchCases.cs index e5ae82936d202..bffd8dfbe24e7 100644 --- a/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionGenerateSwitchCases.cs +++ b/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionGenerateSwitchCases.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; using VsTextSpan = Microsoft.VisualStudio.TextManager.Interop.TextSpan; @@ -56,7 +57,9 @@ protected override int FieldChanged(string field, out int requeryFunction) return (VSConstants.S_OK, snippetFunctionService.SwitchDefaultCaseForm, hasCurrentValue); } - var value = await snippetFunctionService.GetSwitchExpansionAsync(document, caseGenerationSpan.Value, switchExpressionSpan.Value, cancellationToken).ConfigureAwait(false); + var simplifierOptions = await document.GetSimplifierOptionsAsync(snippetExpansionClient.GlobalOptions, cancellationToken).ConfigureAwait(false); + + var value = await snippetFunctionService.GetSwitchExpansionAsync(document, caseGenerationSpan.Value, switchExpressionSpan.Value, simplifierOptions, cancellationToken).ConfigureAwait(false); if (value == null) { return (VSConstants.S_OK, snippetFunctionService.SwitchDefaultCaseForm, hasCurrentValue); diff --git a/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionSimpleTypeName.cs b/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionSimpleTypeName.cs index a4771e60f23c3..6a4aa15ccc149 100644 --- a/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionSimpleTypeName.cs +++ b/src/VisualStudio/Core/Def/Snippets/SnippetFunctions/SnippetFunctionSimpleTypeName.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Simplification; using Microsoft.VisualStudio.Text; using TextSpan = Microsoft.CodeAnalysis.Text.TextSpan; using VsTextSpan = Microsoft.VisualStudio.TextManager.Interop.TextSpan; @@ -45,7 +45,9 @@ public SnippetFunctionSimpleTypeName( return (VSConstants.E_FAIL, value, hasDefaultValue); } - var simplifiedTypeName = await SnippetFunctionService.GetSimplifiedTypeNameAsync(document, fieldSpan.Value, _fullyQualifiedName, cancellationToken).ConfigureAwait(false); + var simplifierOptions = await document.GetSimplifierOptionsAsync(snippetExpansionClient.GlobalOptions, cancellationToken).ConfigureAwait(false); + + var simplifiedTypeName = await SnippetFunctionService.GetSimplifiedTypeNameAsync(document, fieldSpan.Value, _fullyQualifiedName, simplifierOptions, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(simplifiedTypeName)) { return (VSConstants.E_FAIL, value, hasDefaultValue); diff --git a/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs b/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs index e841628c3c4b9..a82086259243f 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs @@ -1083,13 +1083,11 @@ private SyntaxNode InsertNode( if (!batchMode) { - document = _threadingContext.JoinableTaskFactory.Run(() => - Simplifier.ReduceAsync( - document, - annotation, - optionSet: null, - cancellationToken: cancellationToken) - ); + document = _threadingContext.JoinableTaskFactory.Run(async () => + { + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + return await Simplifier.ReduceAsync(document, annotation, simplifierOptions, cancellationToken).ConfigureAwait(false); + }); } document = FormatAnnotatedNode(document, annotation, new[] { _lineAdjustmentFormattingRule, _endRegionFormattingRule }, cancellationToken); diff --git a/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs b/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs index 849133f824a22..388795532ac15 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs @@ -703,8 +703,11 @@ int IVBFileCodeModelEvents.EndEdit() if (_batchDocument != null) { // perform expensive operations at once - var newDocument = State.ThreadingContext.JoinableTaskFactory.Run(() => - Simplifier.ReduceAsync(_batchDocument, Simplifier.Annotation, cancellationToken: CancellationToken.None)); + var newDocument = State.ThreadingContext.JoinableTaskFactory.Run(async () => + { + var simplifierOptions = await SimplifierOptions.FromDocumentAsync(_batchDocument, fallbackOptions: null, CancellationToken.None).ConfigureAwait(false); + return await Simplifier.ReduceAsync(_batchDocument, Simplifier.Annotation, simplifierOptions, CancellationToken.None).ConfigureAwait(false); + }); _batchDocument.Project.Solution.Workspace.TryApplyChanges(newDocument.Project.Solution); diff --git a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs index 708440802f964..4eea7b3ee3cfe 100644 --- a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs +++ b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.AddImport; using Microsoft.CodeAnalysis.CaseCorrection; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.Editing; @@ -309,27 +310,27 @@ protected async Task PostProcessChangesAsync(Solution changedSolution, /// The document changed by the . /// A cancellation token. /// A document with the post processing changes applied. - protected virtual Task PostProcessChangesAsync(Document document, CancellationToken cancellationToken) - => CleanupDocumentAsync(document, cancellationToken); + protected virtual async Task PostProcessChangesAsync(Document document, CancellationToken cancellationToken) + { + var options = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + return await CleanupDocumentAsync(document, options, cancellationToken).ConfigureAwait(false); + } internal static async Task CleanupDocumentAsync( - Document document, CancellationToken cancellationToken) + Document document, CodeCleanupOptions options, CancellationToken cancellationToken) { if (document.SupportsSyntaxTree) { - var addImportOptions = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); - var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); - document = await ImportAdder.AddImportsFromSymbolAnnotationAsync( - document, Simplifier.AddImportsAnnotation, addImportOptions, cancellationToken).ConfigureAwait(false); + document, Simplifier.AddImportsAnnotation, options.AddImportOptions, cancellationToken).ConfigureAwait(false); - document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false); + document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, options.SimplifierOptions, cancellationToken).ConfigureAwait(false); // format any node with explicit formatter annotation - document = await Formatter.FormatAsync(document, Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); + document = await Formatter.FormatAsync(document, Formatter.Annotation, options.FormattingOptions, cancellationToken).ConfigureAwait(false); // format any elastic whitespace - document = await Formatter.FormatAsync(document, SyntaxAnnotation.ElasticAnnotation, formattingOptions, cancellationToken).ConfigureAwait(false); + document = await Formatter.FormatAsync(document, SyntaxAnnotation.ElasticAnnotation, options.FormattingOptions, cancellationToken).ConfigureAwait(false); document = await CaseCorrector.CaseCorrectAsync(document, CaseCorrector.Annotation, cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs b/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs index abae6e02a8bd7..e82151c164474 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/CodeCleaner.cs @@ -79,10 +79,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 formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); - var simplifierOptions = await SimplifierOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); - var options = new CodeCleanupOptions(formattingOptions, simplifierOptions); + var options = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); return await cleanupService.CleanupAsync(document, spans, options, providers, cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Core/Portable/CodeCleanup/CodeCleanupOptions.cs b/src/Workspaces/Core/Portable/CodeCleanup/CodeCleanupOptions.cs index db0f071de0198..16be6e9049815 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/CodeCleanupOptions.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/CodeCleanupOptions.cs @@ -7,19 +7,22 @@ using System.Runtime.Serialization; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Simplification; +using Microsoft.CodeAnalysis.AddImport; namespace Microsoft.CodeAnalysis.CodeCleanup { [DataContract] internal readonly record struct CodeCleanupOptions( [property: DataMember(Order = 0)] SyntaxFormattingOptions FormattingOptions, - [property: DataMember(Order = 1)] SimplifierOptions SimplifierOptions) + [property: DataMember(Order = 1)] SimplifierOptions SimplifierOptions, + [property: DataMember(Order = 2)] AddImportPlacementOptions AddImportOptions) { public static async ValueTask FromDocumentAsync(Document document, CodeCleanupOptions? fallbackOptions, CancellationToken cancellationToken) { var formattingOptions = await SyntaxFormattingOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); var simplifierOptions = await SimplifierOptions.FromDocumentAsync(document, fallbackOptions?.SimplifierOptions, cancellationToken).ConfigureAwait(false); - return new CodeCleanupOptions(formattingOptions, simplifierOptions); + var addImportOptions = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false); + return new CodeCleanupOptions(formattingOptions, simplifierOptions, addImportOptions); } } } diff --git a/src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs b/src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs index 7d5663897dfb3..07a0d90b694df 100644 --- a/src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs +++ b/src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs @@ -28,8 +28,7 @@ namespace Microsoft.CodeAnalysis.Editing /// The trees generated by this API will try to respect user preferences when /// possible. For example, generating /// will be done in a way such that "this." or "Me." will be simplified according to user - /// preference if any - /// overload is called. + /// preference if is used. /// public abstract class SyntaxGenerator : ILanguageService { diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs index 81103af8b8978..507a5c1249a7a 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs @@ -159,8 +159,9 @@ internal async Task SimplifyAsync(Solution solution, IEnumerable ReduceAsync(Document document, OptionSet? opt } var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); +#pragma warning disable RS0030 // Do not used banned APIs return await ReduceAsync(document, root.FullSpan, optionSet, cancellationToken).ConfigureAwait(false); +#pragma warning restore } internal static async Task ReduceAsync(Document document, SimplifierOptions options, CancellationToken cancellationToken) @@ -171,7 +173,9 @@ public static async Task ReduceAsync(Document document, SyntaxAnnotati } var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); +#pragma warning disable RS0030 // Do not used banned APIs return await ReduceAsync(document, root.GetAnnotatedNodesAndTokens(annotation).Select(t => t.FullSpan), optionSet, cancellationToken).ConfigureAwait(false); +#pragma warning restore } internal static async Task ReduceAsync(Document document, SyntaxAnnotation annotation, SimplifierOptions options, CancellationToken cancellationToken) @@ -191,8 +195,10 @@ public static Task ReduceAsync(Document document, TextSpan span, Optio throw new ArgumentNullException(nameof(document)); } +#pragma warning disable RS0030 // Do not used banned APIs return ReduceAsync(document, SpecializedCollections.SingletonEnumerable(span), optionSet, cancellationToken); } +#pragma warning restore internal static Task ReduceAsync(Document document, TextSpan span, SimplifierOptions options, CancellationToken cancellationToken) => ReduceAsync(document, SpecializedCollections.SingletonEnumerable(span), options, cancellationToken); diff --git a/src/Workspaces/CoreTest/Simplifier/SimplifierTests.cs b/src/Workspaces/CoreTest/Simplifier/SimplifierTests.cs index 1bc070a413ae2..c4849e3621f84 100644 --- a/src/Workspaces/CoreTest/Simplifier/SimplifierTests.cs +++ b/src/Workspaces/CoreTest/Simplifier/SimplifierTests.cs @@ -60,12 +60,14 @@ public async Task ReduceAsync_BadArguments() { var document = GetDocument(); +#pragma warning disable RS0030 // Do not used banned APIs await Assert.ThrowsAsync("document", () => Simplifier.ReduceAsync(document: null!)); await Assert.ThrowsAsync("document", () => Simplifier.ReduceAsync(document: null!, annotation: null!)); await Assert.ThrowsAsync("annotation", () => Simplifier.ReduceAsync(document, annotation: null!)); await Assert.ThrowsAsync("document", () => Simplifier.ReduceAsync(document: null!, span: default)); await Assert.ThrowsAsync("document", () => Simplifier.ReduceAsync(document: null!, spans: null!)); await Assert.ThrowsAsync("spans", () => Simplifier.ReduceAsync(document, spans: null!)); +#pragma warning restore } [Fact] diff --git a/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs b/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs index fb0b5cb700709..188a9b4f787d9 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.ConvertTupleToStruct; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; @@ -79,8 +80,11 @@ private static async Task CleanupAsync(Solution oldSolution, Solution foreach (var docId in changes) { - var cleaned = await CodeAction.CleanupDocumentAsync( - newSolution.GetDocument(docId), cancellationToken).ConfigureAwait(false); + var document = newSolution.GetDocument(docId); + + var options = await CodeCleanupOptions.FromDocumentAsync(document, fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var cleaned = await CodeAction.CleanupDocumentAsync(document, options, cancellationToken).ConfigureAwait(false); + var cleanedRoot = await cleaned.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); final = final.WithDocumentSyntaxRoot(docId, cleanedRoot); } diff --git a/src/Workspaces/VisualBasicTest/CodeGeneration/AddImportsTests.vb b/src/Workspaces/VisualBasicTest/CodeGeneration/AddImportsTests.vb index 3ff21757710de..a8e54ef524c68 100644 --- a/src/Workspaces/VisualBasicTest/CodeGeneration/AddImportsTests.vb +++ b/src/Workspaces/VisualBasicTest/CodeGeneration/AddImportsTests.vb @@ -88,6 +88,7 @@ End NameSpace" AllowInHiddenRegions:=False) Dim formattingOptions = VisualBasicSyntaxFormattingOptions.Default + Dim simplifierOptions = VisualBasicSimplifierOptions.Default Dim imported = If( useSymbolAnnotations, @@ -101,7 +102,7 @@ End NameSpace" End If If simplifiedText IsNot Nothing Then - Dim reduced = Await Simplifier.ReduceAsync(imported) + Dim reduced = Await Simplifier.ReduceAsync(imported, simplifierOptions, CancellationToken.None) Dim formatted = Await Formatter.FormatAsync(reduced, SyntaxAnnotation.ElasticAnnotation, formattingOptions, CancellationToken.None) Dim actualText = (Await formatted.GetTextAsync()).ToString() Assert.Equal(simplifiedText, actualText)