From b4dce0802fc31260d375f7b581963371f372925d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 24 Jun 2024 14:49:28 -0700 Subject: [PATCH 01/59] Update logic Update tests Add test NRT --- .../DesignerAttributeDiscoveryService.cs | 56 +++++- .../DesignerAttributeServiceTests.cs | 162 +++++++++++------- 2 files changed, 149 insertions(+), 69 deletions(-) diff --git a/src/Features/Core/Portable/DesignerAttribute/DesignerAttributeDiscoveryService.cs b/src/Features/Core/Portable/DesignerAttribute/DesignerAttributeDiscoveryService.cs index cbfd81891bc1e..dcbc91df9b4b9 100644 --- a/src/Features/Core/Portable/DesignerAttribute/DesignerAttributeDiscoveryService.cs +++ b/src/Features/Core/Portable/DesignerAttribute/DesignerAttributeDiscoveryService.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Composition; @@ -30,6 +31,17 @@ namespace Microsoft.CodeAnalysis.DesignerAttribute; [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal sealed partial class DesignerAttributeDiscoveryService() : IDesignerAttributeDiscoveryService { + /// + /// Ugly, but sufficient hack. During times where we're missing global usings (which may not always be available + /// while the sdk is regenerating/restoring on things like a tfm switch), we hardcode in knowledge we have about + /// which namespaces the core designable types are in. That way we can still make a solid guess about what the base + /// type is, even if we can't resolve it at this moment. + /// + private static readonly ImmutableArray s_wellKnownDesignerNamespaces = [ + "System.Windows.Forms.Form", + "System.Windows.Forms.Design", + "System.ComponentModel"]; + /// /// Cache from the individual references a project has, to a boolean specifying if reference knows about the /// System.ComponentModel.DesignerCategoryAttribute attribute. @@ -244,7 +256,7 @@ private async Task ScanForDesignerCategoryUsageAsync( } hasDesignerCategoryType ??= await HasDesignerCategoryTypeAsync(project, cancellationToken).ConfigureAwait(false); - var data = await ComputeDesignerAttributeDataAsync(project, documentId, filePath, hasDesignerCategoryType.Value).ConfigureAwait(false); + var data = await ComputeDesignerAttributeDataAsync(project, documentId, filePath, hasDesignerCategoryType.Value, existingInfo.category).ConfigureAwait(false); if (data.Category != existingInfo.category) results.Add((data, projectVersion)); } @@ -252,13 +264,13 @@ private async Task ScanForDesignerCategoryUsageAsync( return results.ToImmutableAndClear(); async Task ComputeDesignerAttributeDataAsync( - Project project, DocumentId documentId, string filePath, bool hasDesignerCategoryType) + Project project, DocumentId documentId, string filePath, bool hasDesignerCategoryType, string? existingCategory) { // We either haven't computed the designer info, or our data was out of date. We need // So recompute here. Figure out what the current category is, and if that's different // from what we previously stored. var category = await ComputeDesignerAttributeCategoryAsync( - hasDesignerCategoryType, project, documentId, cancellationToken).ConfigureAwait(false); + hasDesignerCategoryType, project, documentId, existingCategory, cancellationToken).ConfigureAwait(false); return new DesignerAttributeData { @@ -270,7 +282,7 @@ async Task ComputeDesignerAttributeDataAsync( } public static async Task ComputeDesignerAttributeCategoryAsync( - bool hasDesignerCategoryType, Project project, DocumentId documentId, CancellationToken cancellationToken) + bool hasDesignerCategoryType, Project project, DocumentId documentId, string? existingCategory, CancellationToken cancellationToken) { // simple case. If there's no DesignerCategory type in this compilation, then there's definitely no // designable types. @@ -292,10 +304,17 @@ async Task ComputeDesignerAttributeDataAsync( var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var firstClassType = (INamedTypeSymbol)semanticModel.GetRequiredDeclaredSymbol(firstClass, cancellationToken); - foreach (var type in firstClassType.GetBaseTypesAndThis()) + foreach (var type in GetBaseTypesAndThis(semanticModel.Compilation, firstClassType)) { cancellationToken.ThrowIfCancellationRequested(); + // If we hit an error type while walking up, then preserve the existing category. We do want a temporary + // invalid base type to not cause us to lose the existing category, causing a designable type to revert to + // an undesignable one. The designer can still support scenarios like this as it is itself error tolerant, + // falling back to the prior category in a case like this. + if (type is IErrorTypeSymbol errorType) + return existingCategory; + // See if it has the designer attribute on it. Use symbol-equivalence instead of direct equality // as the symbol we have var attribute = type.GetAttributes().FirstOrDefault(d => IsDesignerAttribute(d.AttributeClass)); @@ -305,6 +324,33 @@ async Task ComputeDesignerAttributeDataAsync( return null; + static IEnumerable GetBaseTypesAndThis(Compilation compilation, INamedTypeSymbol firstType) + { + var current = firstType; + while (current != null) + { + yield return current; + current = current.BaseType; + + if (current is IErrorTypeSymbol errorType) + current = TryMapToNonErrorType(compilation, errorType); + } + } + + static INamedTypeSymbol? TryMapToNonErrorType(Compilation compilation, IErrorTypeSymbol errorType) + { + foreach (var wellKnownNamespace in s_wellKnownDesignerNamespaces) + { + var wellKnownType = compilation.GetTypeByMetadataName($"{wellKnownNamespace}.{errorType.Name}"); + if (wellKnownType != null) + return wellKnownType; + } + + // Couldn't find a match. Just return the error type as is. Caller will handle this case and try to + // preserve the existing category. + return errorType; + } + static bool IsDesignerAttribute(INamedTypeSymbol? attributeClass) => attributeClass is { diff --git a/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs b/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs index f5e6e411f4b2f..49ac948899936 100644 --- a/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs +++ b/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs @@ -11,85 +11,119 @@ using Roslyn.Utilities; using Xunit; -namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.DesignerAttributes +namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.DesignerAttributes; + +[UseExportProvider] +public sealed class DesignerAttributeServiceTests { - [UseExportProvider] - public class DesignerAttributeServiceTests + [Fact] + public async Task NoDesignerTest1() { - [Fact] - public async Task NoDesignerTest1() - { - var code = @"class Test { }"; - - await TestAsync(code, category: null); - } - - [Fact] - public async Task NoDesignerOnSecondClass() - { - - await TestAsync( -@"class Test1 { } + await TestAsync(@"class Test { }", category: null); + } -[System.ComponentModel.DesignerCategory(""Form"")] -class Test2 { }", category: null); - } + [Fact] + public async Task NoDesignerOnSecondClass() + { + await TestAsync( + """ + class Test1 { } - [Fact] - public async Task NoDesignerOnStruct() - { + [System.ComponentModel.DesignerCategory("Form")] + class Test2 { } + """, category: null); + } - await TestAsync( -@" -[System.ComponentModel.DesignerCategory(""Form"")] -struct Test1 { }", category: null); - } + [Fact] + public async Task NoDesignerOnStruct() + { + await TestAsync( + """ - [Fact] - public async Task NoDesignerOnNestedClass() - { + [System.ComponentModel.DesignerCategory("Form")] + struct Test1 { } + """, category: null); + } - await TestAsync( -@"class Test1 -{ - [System.ComponentModel.DesignerCategory(""Form"")] - class Test2 { } -}", category: null); - } + [Fact] + public async Task NoDesignerOnNestedClass() + { + await TestAsync( + """ + class Test1 + { + [System.ComponentModel.DesignerCategory("Form")] + class Test2 { } + } + """, category: null); + } - [Fact] - public async Task SimpleDesignerTest() - { + [Fact] + public async Task SimpleDesignerTest() + { + await TestAsync( + """ + [System.ComponentModel.DesignerCategory("Form")] + class Test { } + """, "Form"); + } - await TestAsync( -@"[System.ComponentModel.DesignerCategory(""Form"")] -class Test { }", "Form"); - } + [Fact] + public async Task SimpleDesignerTest2() + { + await TestAsync( + """ + using System.ComponentModel; - [Fact] - public async Task SimpleDesignerTest2() - { + [DesignerCategory("Form")] + class Test { } + """, "Form"); + } - await TestAsync( -@"using System.ComponentModel; + [Theory] + [InlineData(null)] + [InlineData("Form")] + [InlineData("Form1")] + public async Task TestUnboundBase1(string? existingCategory) + { + await TestAsync( + """ + namespace System.Windows.Forms + { + [System.ComponentModel.DesignerCategory("Form")] + public class Form { } + } + + // The base type won't bind. That's ok. We should fallback to looking it up in a particular namespace. + // This should always work and not be impacted by the existing category. + class Test : Form { } + """, "Form", existingCategory); + } -[DesignerCategory(""Form"")] -class Test { }", "Form"); - } + [Theory] + [InlineData(null)] + [InlineData("Form")] + public async Task TestUnboundBaseUseOldValueIfNotFound(string? category) + { + await TestAsync( + """ + // The base type won't bind. Return existing category if we have one. + class Test : Form { } + """, category: category, existingCategory: category); + } - private static async Task TestAsync(string codeWithMarker, string? category) - { - using var workspace = TestWorkspace.CreateCSharp(codeWithMarker, openDocuments: false); + private static async Task TestAsync(string codeWithMarker, string? category, string? existingCategory = null) + { + using var workspace = TestWorkspace.CreateCSharp(codeWithMarker, openDocuments: false); - var hostDocument = workspace.Documents.First(); - var documentId = hostDocument.Id; - var document = workspace.CurrentSolution.GetRequiredDocument(documentId); + var hostDocument = workspace.Documents.First(); + var documentId = hostDocument.Id; + var document = workspace.CurrentSolution.GetRequiredDocument(documentId); - var compilation = await document.Project.GetRequiredCompilationAsync(CancellationToken.None); - var actual = await DesignerAttributeDiscoveryService.ComputeDesignerAttributeCategoryAsync( - compilation.DesignerCategoryAttributeType() != null, document.Project, document.Id, CancellationToken.None); + var compilation = await document.Project.GetRequiredCompilationAsync(CancellationToken.None); + var actual = await DesignerAttributeDiscoveryService.ComputeDesignerAttributeCategoryAsync( + compilation.DesignerCategoryAttributeType() != null, document.Project, document.Id, existingCategory, CancellationToken.None); - Assert.Equal(category, actual); - } + Assert.Equal(category, actual); } } From 10163787c19a455ab07252a94838f4cc8a792658 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 2 Jul 2024 12:48:41 +0000 Subject: [PATCH 02/59] Update dependencies from https://github.com/dotnet/arcade build 20240701.5 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk From Version 9.0.0-beta.24327.1 -> To Version 9.0.0-beta.24351.5 --- eng/Version.Details.xml | 12 ++++----- eng/common/core-templates/job/job.yml | 24 +++-------------- .../job/source-index-stage1.yml | 16 ++---------- .../steps/component-governance.yml | 2 +- eng/common/templates/job/job.yml | 26 +++++++++++++++++++ global.json | 4 +-- 6 files changed, 40 insertions(+), 44 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 50c39bec685ab..9826202868dc2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -122,14 +122,14 @@ - + https://github.com/dotnet/arcade - ede13bd35571c0c8b0c01edcb057031904c5c955 + 48f3eafb2fa9dddb1ca655b9ea96ebf4b5a2ba0a - + https://github.com/dotnet/arcade - ede13bd35571c0c8b0c01edcb057031904c5c955 + 48f3eafb2fa9dddb1ca655b9ea96ebf4b5a2ba0a @@ -156,9 +156,9 @@ https://github.com/dotnet/roslyn 5d10d428050c0d6afef30a072c4ae68776621877 - + https://github.com/dotnet/arcade - ede13bd35571c0c8b0c01edcb057031904c5c955 + 48f3eafb2fa9dddb1ca655b9ea96ebf4b5a2ba0a https://github.com/dotnet/roslyn-analyzers diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml index 7df58527978bb..c732bee9f4a6f 100644 --- a/eng/common/core-templates/job/job.yml +++ b/eng/common/core-templates/job/job.yml @@ -24,12 +24,11 @@ parameters: enablePublishTestResults: false enablePublishUsingPipelines: false enableBuildRetry: false - disableComponentGovernance: '' - componentGovernanceIgnoreDirectories: '' mergeTestResults: false testRunTitle: '' testResultsFormat: '' name: '' + componentGovernanceSteps: [] preSteps: [] artifactPublishSteps: [] runAsPublic: false @@ -170,17 +169,8 @@ jobs: uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} continueOnError: true - - template: /eng/common/core-templates/steps/component-governance.yml - parameters: - is1ESPipeline: ${{ parameters.is1ESPipeline }} - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true - ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + - ${{ each step in parameters.componentGovernanceSteps }}: + - ${{ step }} - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: @@ -190,14 +180,6 @@ jobs: continueOnError: ${{ parameters.continueOnError }} env: TeamName: $(_TeamName) - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/core-templates/steps/generate-sbom.yml - parameters: - is1ESPipeline: ${{ parameters.is1ESPipeline }} - PackageVersion: ${{ parameters.packageVersion}} - BuildDropPath: ${{ parameters.buildDropPath }} - IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - publishArtifacts: false # Publish test results - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml index 8328e52ab100c..945c1c19e8249 100644 --- a/eng/common/core-templates/job/source-index-stage1.yml +++ b/eng/common/core-templates/job/source-index-stage1.yml @@ -69,23 +69,11 @@ jobs: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: AzureCLI@2 - displayName: Get stage 1 auth token + displayName: Log in to Azure and upload stage1 artifacts to source index inputs: azureSubscription: 'SourceDotNet Stage1 Publish' addSpnToEnvironment: true scriptType: 'ps' scriptLocation: 'inlineScript' inlineScript: | - echo "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId" - echo "##vso[task.setvariable variable=ARM_ID_TOKEN]$env:idToken" - echo "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId" - - - script: | - echo "Client ID: $(ARM_CLIENT_ID)" - echo "ID Token: $(ARM_ID_TOKEN)" - echo "Tenant ID: $(ARM_TENANT_ID)" - az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN) - displayName: "Login to Azure" - - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 - displayName: Upload stage1 artifacts to source index + $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 diff --git a/eng/common/core-templates/steps/component-governance.yml b/eng/common/core-templates/steps/component-governance.yml index b8815892a5ef0..cf0649aa95653 100644 --- a/eng/common/core-templates/steps/component-governance.yml +++ b/eng/common/core-templates/steps/component-governance.yml @@ -13,4 +13,4 @@ steps: continueOnError: true displayName: ${{ parameters.displayName }} inputs: - ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file + ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 5920952c5ba69..8da477dd69f06 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -1,5 +1,11 @@ parameters: enablePublishBuildArtifacts: false + disableComponentGovernance: '' + componentGovernanceIgnoreDirectories: '' +# Sbom related params + enableSbom: true + PackageVersion: 9.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' jobs: - template: /eng/common/core-templates/job/job.yml @@ -13,6 +19,26 @@ jobs: steps: - ${{ each step in parameters.steps }}: - ${{ step }} + + componentGovernanceSteps: + - template: /eng/common/templates/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false + ${{ else }}: + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/templates/steps/generate-sbom.yml + parameters: + PackageVersion: ${{ parameters.packageVersion }} + BuildDropPath: ${{ parameters.buildDropPath }} + publishArtifacts: false + artifactPublishSteps: - ${{ if ne(parameters.artifacts.publish, '') }}: diff --git a/global.json b/global.json index d35d6bed9866b..8b2b2c602f942 100644 --- a/global.json +++ b/global.json @@ -11,8 +11,8 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24327.1", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24327.1", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24351.5", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24351.5", "Microsoft.Build.Traversal": "3.4.0" } } From 593f29abbd9269eb7d6ad9ea63e9259a675f694a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jul 2024 14:01:26 -0700 Subject: [PATCH 03/59] Batch settings update work into queue --- .../Aggregator/SettingsAggregator.cs | 64 ++++++++++++++----- .../Aggregator/SettingsAggregatorFactory.cs | 15 ++++- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs index 174e9d7c074f9..111531633500d 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs @@ -3,12 +3,15 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.Linq; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Shared.Collections; -using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings; @@ -16,18 +19,33 @@ internal partial class SettingsAggregator : ISettingsAggregator { private readonly Workspace _workspace; private readonly ISettingsProviderFactory _analyzerProvider; + private readonly AsyncBatchingWorkQueue _workQueue; + private ISettingsProviderFactory _whitespaceProvider; private ISettingsProviderFactory _namingStyleProvider; private ISettingsProviderFactory _codeStyleProvider; - public SettingsAggregator(Workspace workspace) + public SettingsAggregator( + Workspace workspace, + IThreadingContext threadingContext, + IAsynchronousOperationListener listener) { _workspace = workspace; _workspace.WorkspaceChanged += UpdateProviders; - _whitespaceProvider = GetOptionsProviderFactory(_workspace); - _codeStyleProvider = GetOptionsProviderFactory(_workspace); - _namingStyleProvider = GetOptionsProviderFactory(_workspace); - _analyzerProvider = GetOptionsProviderFactory(_workspace); + + // + var currentSolution = _workspace.CurrentSolution.SolutionState; + UpdateProviders(currentSolution); + + // TODO(cyrusn): Why do we not update this as well inside UpdateProviders when we hear about a workspace event? + _analyzerProvider = GetOptionsProviderFactory(currentSolution); + + // Batch these up so that we don't do a lot of expensive work when hearing a flurry of workspace events. + _workQueue = new AsyncBatchingWorkQueue( + TimeSpan.FromSeconds(1), + UpdateProvidersAsync, + listener, + threadingContext.DisposalToken); } private void UpdateProviders(object? sender, WorkspaceChangeEventArgs e) @@ -42,11 +60,7 @@ private void UpdateProviders(object? sender, WorkspaceChangeEventArgs e) case WorkspaceChangeKind.ProjectAdded: case WorkspaceChangeKind.ProjectRemoved: case WorkspaceChangeKind.ProjectChanged: - _whitespaceProvider = GetOptionsProviderFactory(_workspace); - _codeStyleProvider = GetOptionsProviderFactory(_workspace); - _namingStyleProvider = GetOptionsProviderFactory(_workspace); - break; - default: + _workQueue.AddWork(); break; } } @@ -76,14 +90,30 @@ private void UpdateProviders(object? sender, WorkspaceChangeEventArgs e) return null; } - private static ISettingsProviderFactory GetOptionsProviderFactory(Workspace workspace) + private ValueTask UpdateProvidersAsync(CancellationToken cancellationToken) + { + UpdateProviders(_workspace.CurrentSolution.SolutionState); + return ValueTaskFactory.CompletedTask; + } + + [MemberNotNull(nameof(_whitespaceProvider))] + [MemberNotNull(nameof(_codeStyleProvider))] + [MemberNotNull(nameof(_namingStyleProvider))] + private void UpdateProviders(SolutionState solution) + { + _whitespaceProvider = GetOptionsProviderFactory(solution); + _codeStyleProvider = GetOptionsProviderFactory(solution); + _namingStyleProvider = GetOptionsProviderFactory(solution); + } + + private static ISettingsProviderFactory GetOptionsProviderFactory(SolutionState solution) { using var providers = TemporaryArray>.Empty; - var commonProvider = workspace.Services.GetRequiredService>(); + var commonProvider = solution.Services.GetRequiredService>(); providers.Add(commonProvider); - var projectCountByLanguage = workspace.CurrentSolution.SolutionState.ProjectCountByLanguage; + var projectCountByLanguage = solution.ProjectCountByLanguage; TryAddProviderForLanguage(LanguageNames.CSharp); TryAddProviderForLanguage(LanguageNames.VisualBasic); @@ -94,7 +124,7 @@ void TryAddProviderForLanguage(string language) { if (projectCountByLanguage.ContainsKey(language)) { - var provider = workspace.Services.GetLanguageServices(language).GetService>(); + var provider = solution.Services.GetLanguageServices(language).GetService>(); if (provider != null) providers.Add(provider); } diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs index c0baf26042b58..5b18c1daa2ce4 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs @@ -4,20 +4,29 @@ using System; using System.Composition; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.TestHooks; namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings; [ExportWorkspaceServiceFactory(typeof(ISettingsAggregator), ServiceLayer.Default), Shared] -internal class SettingsAggregatorFactory : IWorkspaceServiceFactory +internal sealed class SettingsAggregatorFactory : IWorkspaceServiceFactory { + private readonly IThreadingContext _threadingContext; + private readonly IAsynchronousOperationListener _listener; + [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public SettingsAggregatorFactory() + public SettingsAggregatorFactory( + IThreadingContext threadingContext, + IAsynchronousOperationListenerProvider listenerProvider) { + _threadingContext = threadingContext; + _listener = listenerProvider.GetListener(FeatureAttribute.RuleSetEditor); } public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) - => new SettingsAggregator(workspaceServices.Workspace); + => new SettingsAggregator(workspaceServices.Workspace, _threadingContext, _listener); } From 0815c0f83954369dd2f3f722d9e92ca61fb5ccc7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 3 Jul 2024 12:53:01 +0000 Subject: [PATCH 04/59] Update dependencies from https://github.com/dotnet/arcade build 20240702.2 Microsoft.SourceBuild.Intermediate.arcade , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk From Version 9.0.0-beta.24327.1 -> To Version 9.0.0-beta.24352.2 --- eng/Version.Details.xml | 12 ++++++------ global.json | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9826202868dc2..49e3252e73c0a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -122,14 +122,14 @@ - + https://github.com/dotnet/arcade - 48f3eafb2fa9dddb1ca655b9ea96ebf4b5a2ba0a + 4a7d983f833d6b86365ea1b2b4d6ee72fbdbf944 - + https://github.com/dotnet/arcade - 48f3eafb2fa9dddb1ca655b9ea96ebf4b5a2ba0a + 4a7d983f833d6b86365ea1b2b4d6ee72fbdbf944 @@ -156,9 +156,9 @@ https://github.com/dotnet/roslyn 5d10d428050c0d6afef30a072c4ae68776621877 - + https://github.com/dotnet/arcade - 48f3eafb2fa9dddb1ca655b9ea96ebf4b5a2ba0a + 4a7d983f833d6b86365ea1b2b4d6ee72fbdbf944 https://github.com/dotnet/roslyn-analyzers diff --git a/global.json b/global.json index 8b2b2c602f942..2cd32c6ddbf19 100644 --- a/global.json +++ b/global.json @@ -11,8 +11,8 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24351.5", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24351.5", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24352.2", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24352.2", "Microsoft.Build.Traversal": "3.4.0" } } From fcebf4b20a3e6a850683736ff0918e5ae997276e Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 3 Jul 2024 09:38:59 -0500 Subject: [PATCH 05/59] Fix style binding failure in Document Outline Fixes #73810 --- .../Core/Def/DocumentOutline/DocumentOutlineView.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml index 4cff00aaa9311..b7a88103949c9 100644 --- a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml +++ b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml @@ -60,7 +60,7 @@ - From 82246672581fcd1c5c22fb713adb19b21ec60c7e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:01:29 -0700 Subject: [PATCH 06/59] Generated doc feedback --- .../IRemoteSourceGenerationService.cs | 22 +++--- ...ionCompilationState.ICompilationTracker.cs | 22 +++--- ...ilationState.RegularCompilationTracker.cs} | 11 ++- ...e.RegularCompilationTracker_Generators.cs} | 16 ++--- ...ceGeneratedDocumentsCompilationTracker.cs} | 67 ++++++++++--------- .../Solution/SolutionCompilationState.cs | 28 ++++---- 6 files changed, 78 insertions(+), 88 deletions(-) rename src/Workspaces/Core/Portable/Workspace/Solution/{SolutionCompilationState.CompilationTracker.cs => SolutionCompilationState.RegularCompilationTracker.cs} (99%) rename src/Workspaces/Core/Portable/Workspace/Solution/{SolutionCompilationState.CompilationTracker_Generators.cs => SolutionCompilationState.RegularCompilationTracker_Generators.cs} (97%) rename src/Workspaces/Core/Portable/Workspace/Solution/{SolutionCompilationState.GeneratedFileReplacingCompilationTracker.cs => SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs} (76%) diff --git a/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs b/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs index 1a6517862a9db..0785cd3c31824 100644 --- a/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs +++ b/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs @@ -27,24 +27,22 @@ internal interface IRemoteSourceGenerationService /// compare that to the prior generated documents it has to see if it can reuse those directly, or if it needs to /// remove any documents no longer around, add any new documents, or change the contents of any existing documents. /// - /// - /// Should only be called by the "RegularCompilationTracker", and should only return data from its view of the - /// world. Not from the view of a "GeneratedFileReplacingCompilationTracker". - /// - ValueTask> GetRegularCompilationTrackerSourceGenerationInfoAsync( - Checksum solutionChecksum, ProjectId projectId, CancellationToken cancellationToken); + /// Controls if the caller wants frozen source generator documents + /// included in the result, or if only the most underlying generated documents (produced by the real compiler shoudl be included. + ValueTask> GetSourceGenerationInfoAsync( + Checksum solutionChecksum, ProjectId projectId, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken); /// /// Given a particular set of generated document ids, returns the fully generated content for those documents. /// Should only be called by the host for documents it does not know about, or documents whose checksum contents are /// different than the last time the document was queried. /// - /// - /// Should only be called by the "RegularCompilationTracker", and should only return data from its view of the - /// world. Not from the view of a "GeneratedFileReplacingCompilationTracker". - /// - ValueTask> GetRegularCompilationTrackerContentsAsync( - Checksum solutionChecksum, ProjectId projectId, ImmutableArray documentIds, CancellationToken cancellationToken); + /// Controls if the caller wants frozen source generator documents + /// included in the result, or if only the most underlying generated documents (produced by the real compiler should be included. + ValueTask> GetContentsAsync( + Checksum solutionChecksum, ProjectId projectId, ImmutableArray documentIds, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken); /// /// Whether or not the specified analyzer references have source generators or not. diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs index 92c97cb4b292c..ac682025ddb86 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs @@ -56,21 +56,15 @@ bool ContainsAssemblyOrModuleOrDynamic( Task GetDependentChecksumAsync(SolutionCompilationState compilationState, CancellationToken cancellationToken); /// - /// Gets the *final* view of the generated documents for this tracker. If this is a this will be the true generated documents for this tracker (generated by - /// our underlying ). If this is a , then this will be the generated documents of its , along with all of its replacement - /// frozen documents overlaid on top. + /// Gets the source generator files generated by this . Controls whether frozen source generated documents are included + /// in the result. If this will call all the way through to the most underlying to get its generated documents. If this is then + /// this will be those same generated documents, along with all the generated documents from all wrapping 's frozen documents overlaid on top. /// - ValueTask> GetSourceGeneratedDocumentStatesAsync(SolutionCompilationState compilationState, CancellationToken cancellationToken); - - /// - /// Equivalent to , but only returning from the innermost - /// underlying . Any frozen generated documents in a will *not* be overlaid on top of this. - /// - ValueTask> GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync(SolutionCompilationState compilationState, CancellationToken cancellationToken); + ValueTask> GetSourceGeneratedDocumentStatesAsync( + SolutionCompilationState compilationState, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken); ValueTask> GetSourceGeneratorDiagnosticsAsync(SolutionCompilationState compilationState, CancellationToken cancellationToken); ValueTask GetSourceGeneratorRunResultAsync(SolutionCompilationState solution, CancellationToken cancellationToken); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs similarity index 99% rename from src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationTracker.cs rename to src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs index 488198f28cc33..b10dc55c31fb1 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs @@ -837,13 +837,12 @@ public ICompilationTracker WithDoNotCreateCreationPolicy(CancellationToken cance } } - public ValueTask> GetSourceGeneratedDocumentStatesAsync(SolutionCompilationState compilationState, CancellationToken cancellationToken) - // Just defer to the core function that creates these. They are the right values for both of these calls. - => GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync(compilationState, cancellationToken); - - public async ValueTask> GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync( - SolutionCompilationState compilationState, CancellationToken cancellationToken) + public async ValueTask> GetSourceGeneratedDocumentStatesAsync( + SolutionCompilationState compilationState, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken) { + // Note: withFrozenSourceGeneratedDocuments has no impact on is. We're always returning real generated + // docs, not frozen docs. Frozen docs are only involved with a GeneratedFileReplacingCompilationTracker + // If we don't have any generators, then we know we have no generated files, so we can skip the computation entirely. if (!await compilationState.HasSourceGeneratorsAsync(this.ProjectState.Id, cancellationToken).ConfigureAwait(false)) return TextDocumentStates.Empty; diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationTracker_Generators.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs similarity index 97% rename from src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationTracker_Generators.cs rename to src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs index 7a44a7216b47f..fea1281dcad1c 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.CompilationTracker_Generators.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs @@ -93,14 +93,14 @@ private partial class RegularCompilationTracker : ICompilationTracker // First, grab the info from our external host about the generated documents it has for this project. Note: // we ourselves are the innermost "RegularCompilationTracker" responsible for actually running generators. - // As such, our call to the oop side reflects that by asking for only *its* innermost - // RegularCompilationTracker to do the same. + // As such, our call to the oop side reflects that by asking for the real source generated docs, and *not* + // any overlaid 'frozen' source generated documents. var projectId = this.ProjectState.Id; var infosOpt = await connection.TryInvokeAsync( compilationState, projectId, - (service, solutionChecksum, cancellationToken) => service.GetRegularCompilationTrackerSourceGenerationInfoAsync( - solutionChecksum, projectId, cancellationToken), + (service, solutionChecksum, cancellationToken) => service.GetSourceGenerationInfoAsync( + solutionChecksum, projectId, withFrozenSourceGeneratedDocuments: false, cancellationToken), cancellationToken).ConfigureAwait(false); if (!infosOpt.HasValue) @@ -160,13 +160,13 @@ private partial class RegularCompilationTracker : ICompilationTracker // Either we generated a different number of files, and/or we had contents of files that changed. Ensure we // know the contents of any new/changed files. Note: we ourselves are the innermost // "RegularCompilationTracker" responsible for actually running generators. As such, our call to the oop - // side reflects that by asking for the source gen contents produced by *its* innermost - // RegularCompilationTracker. + // side reflects that by asking for the real source generated docs, and *not* any overlaid 'frozen' source + // generated documents. var generatedSourcesOpt = await connection.TryInvokeAsync( compilationState, projectId, - (service, solutionChecksum, cancellationToken) => service.GetRegularCompilationTrackerContentsAsync( - solutionChecksum, projectId, documentsToAddOrUpdate.ToImmutable(), cancellationToken), + (service, solutionChecksum, cancellationToken) => service.GetContentsAsync( + solutionChecksum, projectId, documentsToAddOrUpdate.ToImmutable(), withFrozenSourceGeneratedDocuments: false, cancellationToken), cancellationToken).ConfigureAwait(false); if (!generatedSourcesOpt.HasValue) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.GeneratedFileReplacingCompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs similarity index 76% rename from src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.GeneratedFileReplacingCompilationTracker.cs rename to src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs index eef55a0951986..111d7a8b9b7e2 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.GeneratedFileReplacingCompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs @@ -14,11 +14,17 @@ namespace Microsoft.CodeAnalysis; internal partial class SolutionCompilationState { /// - /// An implementation of that takes a compilation from another compilation tracker and updates it - /// to return a generated document with a specific content, regardless of what the generator actually produces. In other words, it says - /// "take the compilation this other thing produced, and pretend the generator gave this content, even if it wouldn't." + /// An implementation of that takes a compilation from another compilation tracker + /// and updates it to return a generated document with a specific content, regardless of what the generator actually + /// produces. In other words, it says "take the compilation this other thing produced, and pretend the generator + /// gave this content, even if it wouldn't." This is used by to ensure that a particular solution snapshot contains a + /// pre-existing generated document from a prior run that the user is interacting with in the host. The current + /// snapshot might not produce the same content from before (or may not even produce that document anymore). But we + /// want to still let the user work with that doc effectively up until the point that new generated documents are + /// produced and replace it in the host view. /// - private sealed class GeneratedFileReplacingCompilationTracker : ICompilationTracker + private sealed class WithFrozenSourceGeneratedDocumentsCompilationTracker : ICompilationTracker { private readonly TextDocumentStates _replacementDocumentStates; @@ -41,7 +47,7 @@ private sealed class GeneratedFileReplacingCompilationTracker : ICompilationTrac /// private SkeletonReferenceCache _skeletonReferenceCache; - public GeneratedFileReplacingCompilationTracker( + public WithFrozenSourceGeneratedDocumentsCompilationTracker( ICompilationTracker underlyingTracker, TextDocumentStates replacementDocumentStates) { @@ -80,7 +86,7 @@ public ICompilationTracker WithCreateCreationPolicy(bool forceRegeneration) var underlyingTracker = this.UnderlyingTracker.WithCreateCreationPolicy(forceRegeneration); return underlyingTracker == this.UnderlyingTracker ? this - : new GeneratedFileReplacingCompilationTracker(underlyingTracker, _replacementDocumentStates); + : new WithFrozenSourceGeneratedDocumentsCompilationTracker(underlyingTracker, _replacementDocumentStates); } public ICompilationTracker WithDoNotCreateCreationPolicy(CancellationToken cancellationToken) @@ -88,7 +94,7 @@ public ICompilationTracker WithDoNotCreateCreationPolicy(CancellationToken cance var underlyingTracker = this.UnderlyingTracker.WithDoNotCreateCreationPolicy(cancellationToken); return underlyingTracker == this.UnderlyingTracker ? this - : new GeneratedFileReplacingCompilationTracker(underlyingTracker, _replacementDocumentStates); + : new WithFrozenSourceGeneratedDocumentsCompilationTracker(underlyingTracker, _replacementDocumentStates); } public async Task GetCompilationAsync(SolutionCompilationState compilationState, CancellationToken cancellationToken) @@ -99,7 +105,8 @@ public async Task GetCompilationAsync(SolutionCompilationState comp return _compilationWithReplacements; } - var underlyingSourceGeneratedDocuments = await UnderlyingTracker.GetSourceGeneratedDocumentStatesAsync(compilationState, cancellationToken).ConfigureAwait(false); + var underlyingSourceGeneratedDocuments = await UnderlyingTracker.GetSourceGeneratedDocumentStatesAsync( + compilationState, withFrozenSourceGeneratedDocuments: true, cancellationToken).ConfigureAwait(false); var newCompilation = await UnderlyingTracker.GetCompilationAsync(compilationState, cancellationToken).ConfigureAwait(false); foreach (var (id, replacementState) in _replacementDocumentStates.States) @@ -159,41 +166,37 @@ await UnderlyingTracker.GetDependentChecksumAsync(compilationState, cancellation (await _replacementDocumentStates.GetDocumentChecksumsAndIdsAsync(cancellationToken).ConfigureAwait(false)).Checksum); public async ValueTask> GetSourceGeneratedDocumentStatesAsync( - SolutionCompilationState compilationState, CancellationToken cancellationToken) + SolutionCompilationState compilationState, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken) { var newStates = await UnderlyingTracker.GetSourceGeneratedDocumentStatesAsync( - compilationState, cancellationToken).ConfigureAwait(false); + compilationState, withFrozenSourceGeneratedDocuments, cancellationToken).ConfigureAwait(false); - foreach (var (id, replacementState) in _replacementDocumentStates.States) + // Only if the caller *wants* frozen source generated documents, then we will overlay the real underlying + // generated docs with the frozen ones we're pointing at. + if (withFrozenSourceGeneratedDocuments) { - if (newStates.Contains(id)) - { - // The generated file still exists in the underlying compilation, but the contents may not match the open file if the open file - // is stale. Replace the syntax tree so we have a tree that matches the text. - newStates = newStates.SetState(replacementState); - } - else + foreach (var (id, replacementState) in _replacementDocumentStates.States) { - // The generated output no longer exists in the underlying compilation. This could happen if the user made - // an edit which would cause this file to no longer exist, but they're still operating on an open representation - // of that file. To ensure that this snapshot is still usable, we'll just add this document back in. This is not a - // semantically correct operation, but working on stale snapshots never has that guarantee. - newStates = newStates.AddRange([replacementState]); + if (newStates.Contains(id)) + { + // The generated file still exists in the underlying compilation, but the contents may not match the open file if the open file + // is stale. Replace the syntax tree so we have a tree that matches the text. + newStates = newStates.SetState(replacementState); + } + else + { + // The generated output no longer exists in the underlying compilation. This could happen if the user made + // an edit which would cause this file to no longer exist, but they're still operating on an open representation + // of that file. To ensure that this snapshot is still usable, we'll just add this document back in. This is not a + // semantically correct operation, but working on stale snapshots never has that guarantee. + newStates = newStates.AddRange([replacementState]); + } } } return newStates; } - public ValueTask> GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync( - SolutionCompilationState compilationState, CancellationToken cancellationToken) - { - // Just defer to the underlying tracker. The caller only wants the innermost generated documents, not any - // frozen docs we'll overlay on top of it. The caller will already know about those frozen documents and - // will do its own overlay on these results. - return this.UnderlyingTracker.GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync(compilationState, cancellationToken); - } - public Task HasSuccessfullyLoadedAsync( SolutionCompilationState compilationState, CancellationToken cancellationToken) { diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs index 6048f7694f8cb..3b166e8edacbe 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs @@ -1029,23 +1029,15 @@ public Task HasSuccessfullyLoadedAsync(ProjectState project, CancellationT /// /// Returns the generated document states for source generated documents. /// - public ValueTask> GetSourceGeneratedDocumentStatesAsync( - ProjectState project, CancellationToken cancellationToken) - { - return project.SupportsCompilation - ? GetCompilationTracker(project.Id).GetSourceGeneratedDocumentStatesAsync(this, cancellationToken) - : new(TextDocumentStates.Empty); - } + public ValueTask> GetSourceGeneratedDocumentStatesAsync(ProjectState project, CancellationToken cancellationToken) + => GetSourceGeneratedDocumentStatesAsync(project, withFrozenSourceGeneratedDocuments: true, cancellationToken); - /// - /// Equivalent to , but only returning from the underlying . - /// - internal ValueTask> GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync( - ProjectState project, CancellationToken cancellationToken) + /// + public ValueTask> GetSourceGeneratedDocumentStatesAsync( + ProjectState project, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken) { return project.SupportsCompilation - ? GetCompilationTracker(project.Id).GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync(this, cancellationToken) + ? GetCompilationTracker(project.Id).GetSourceGeneratedDocumentStatesAsync(this, withFrozenSourceGeneratedDocuments, cancellationToken) : new(TextDocumentStates.Empty); } @@ -1160,7 +1152,11 @@ public SolutionCompilationState WithoutFrozenSourceGeneratedDocuments() foreach (var projectId in projectIdsToUnfreeze) { Contract.ThrowIfFalse(trackerMap.TryGetValue(projectId, out var existingTracker)); - var replacingItemTracker = (GeneratedFileReplacingCompilationTracker)existingTracker; + // TODO(cyrusn): Is it possible to wrap an underlying tracker with multiple frozen document + // compilation trackers? Should we be unwrapping as much as we can here? Or would that also be bad + // given that we're basing what we want to unfreeze on the FrozenSourceGeneratedDocumentStates, + // which may not represent those inner freezes. Unclear. There may be bugs here. + var replacingItemTracker = (WithFrozenSourceGeneratedDocumentsCompilationTracker)existingTracker; trackerMap[projectId] = replacingItemTracker.UnderlyingTracker; } }, @@ -1245,7 +1241,7 @@ public SolutionCompilationState WithFrozenSourceGeneratedDocuments( existingTracker = CreateCompilationTracker(projectId, arg.SolutionState); } - trackerMap[projectId] = new GeneratedFileReplacingCompilationTracker(existingTracker, new(documentStatesForProject)); + trackerMap[projectId] = new WithFrozenSourceGeneratedDocumentsCompilationTracker(existingTracker, new(documentStatesForProject)); } }, (documentStatesByProjectId, this.SolutionState), From 8ca12e4b9cefde6a94535190217c8e669d5a3a93 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:02:35 -0700 Subject: [PATCH 07/59] Update src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs --- .../Portable/SourceGeneration/IRemoteSourceGenerationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs b/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs index 0785cd3c31824..ca4cecd61de1d 100644 --- a/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs +++ b/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs @@ -29,7 +29,7 @@ internal interface IRemoteSourceGenerationService /// /// Controls if the caller wants frozen source generator documents /// included in the result, or if only the most underlying generated documents (produced by the real compiler shoudl be included. + /// cref="GeneratorDriver"/> should be included. ValueTask> GetSourceGenerationInfoAsync( Checksum solutionChecksum, ProjectId projectId, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken); From 226d668d6dcfa25bb37c9d8869142c368ca05ff3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:03:28 -0700 Subject: [PATCH 08/59] Names --- .../Solution/SolutionCompilationState.ICompilationTracker.cs | 2 +- .../SolutionCompilationState.RegularCompilationTracker.cs | 3 ++- .../Portable/Workspace/Solution/SolutionCompilationState.cs | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs index ac682025ddb86..21e53564084df 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.ICompilationTracker.cs @@ -61,7 +61,7 @@ bool ContainsAssemblyOrModuleOrDynamic( /// in the result. If this will call all the way through to the most underlying to get its generated documents. If this is then /// this will be those same generated documents, along with all the generated documents from all wrapping 's frozen documents overlaid on top. + /// cref="WithFrozenSourceGeneratedDocumentsCompilationTracker"/>'s frozen documents overlaid on top. /// ValueTask> GetSourceGeneratedDocumentStatesAsync( SolutionCompilationState compilationState, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs index b10dc55c31fb1..e2917700d9427 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker.cs @@ -841,7 +841,8 @@ public async ValueTask> GetSour SolutionCompilationState compilationState, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken) { // Note: withFrozenSourceGeneratedDocuments has no impact on is. We're always returning real generated - // docs, not frozen docs. Frozen docs are only involved with a GeneratedFileReplacingCompilationTracker + // docs, not frozen docs. Frozen docs are only involved with a + // WithFrozenSourceGeneratedDocumentsCompilationTracker // If we don't have any generators, then we know we have no generated files, so we can skip the computation entirely. if (!await compilationState.HasSourceGeneratorsAsync(this.ProjectState.Id, cancellationToken).ConfigureAwait(false)) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs index 3b166e8edacbe..40a180c4c8e48 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.cs @@ -1142,8 +1142,9 @@ public SolutionCompilationState WithoutFrozenSourceGeneratedDocuments() .Distinct() .ToImmutableArray(); - // Since we previously froze documents in these projects, we should have a CompilationTracker entry for it, and it should be a - // GeneratedFileReplacingCompilationTracker. To undo the operation, we'll just restore the original CompilationTracker. + // Since we previously froze documents in these projects, we should have a CompilationTracker entry for it, and + // it should be a WithFrozenSourceGeneratedDocumentsCompilationTracker. To undo the operation, we'll just + // restore the original CompilationTracker. var newTrackerMap = CreateCompilationTrackerMap( projectIdsToUnfreeze, this.SolutionState.GetProjectDependencyGraph(), From 1e376b15d93a72dfcfe121b992fbacb7316db899 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:05:06 -0700 Subject: [PATCH 09/59] Docs --- ...ate.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs index 111d7a8b9b7e2..d4c777ad64f9e 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.WithFrozenSourceGeneratedDocumentsCompilationTracker.cs @@ -105,6 +105,9 @@ public async Task GetCompilationAsync(SolutionCompilationState comp return _compilationWithReplacements; } + // We're building the real compilation for this tracker, so we want to include all generated docs at every + // level of compilation tracker wrapping. So pass along `withFrozenSourceGeneratedDocuments: true` to get a + // full view of that. var underlyingSourceGeneratedDocuments = await UnderlyingTracker.GetSourceGeneratedDocumentStatesAsync( compilationState, withFrozenSourceGeneratedDocuments: true, cancellationToken).ConfigureAwait(false); var newCompilation = await UnderlyingTracker.GetCompilationAsync(compilationState, cancellationToken).ConfigureAwait(false); From 87b64a75014bdf2d217bf33c8ce54770401341cd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:07:35 -0700 Subject: [PATCH 10/59] Remove --- .../Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs index 111531633500d..2260badd1ab46 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs @@ -33,7 +33,6 @@ public SettingsAggregator( _workspace = workspace; _workspace.WorkspaceChanged += UpdateProviders; - // var currentSolution = _workspace.CurrentSolution.SolutionState; UpdateProviders(currentSolution); From 6fe0dffb5838eaaa656932a1d1b0fbef7d31627e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:07:56 -0700 Subject: [PATCH 11/59] Primary constructor --- .../Aggregator/SettingsAggregatorFactory.cs | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs index 5b18c1daa2ce4..7417eefa40e25 100644 --- a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs @@ -12,20 +12,14 @@ namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings; [ExportWorkspaceServiceFactory(typeof(ISettingsAggregator), ServiceLayer.Default), Shared] -internal sealed class SettingsAggregatorFactory : IWorkspaceServiceFactory +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class SettingsAggregatorFactory( + IThreadingContext threadingContext, + IAsynchronousOperationListenerProvider listenerProvider) : IWorkspaceServiceFactory { - private readonly IThreadingContext _threadingContext; - private readonly IAsynchronousOperationListener _listener; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public SettingsAggregatorFactory( - IThreadingContext threadingContext, - IAsynchronousOperationListenerProvider listenerProvider) - { - _threadingContext = threadingContext; - _listener = listenerProvider.GetListener(FeatureAttribute.RuleSetEditor); - } + private readonly IThreadingContext _threadingContext = threadingContext; + private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.RuleSetEditor); public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) => new SettingsAggregator(workspaceServices.Workspace, _threadingContext, _listener); From 3eea1d1905a941d777072574c63f55e2d8291737 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 11:10:37 -0700 Subject: [PATCH 12/59] Fallout --- .../IRemoteSourceGenerationService.cs | 4 ++-- ...State.RegularCompilationTracker_Generators.cs | 2 +- .../RemoteSourceGenerationService.cs | 16 +++++++++------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs b/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs index ca4cecd61de1d..fffa94b324236 100644 --- a/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs +++ b/src/Workspaces/Core/Portable/SourceGeneration/IRemoteSourceGenerationService.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.SourceGeneration; [DataContract] -internal readonly record struct RegularCompilationTrackerSourceGenerationInfo( +internal readonly record struct SourceGeneratedDocmentInfo( [property: DataMember(Order = 0)] SourceGeneratedDocumentIdentity DocumentIdentity, [property: DataMember(Order = 1)] SourceGeneratedDocumentContentIdentity ContentIdentity, [property: DataMember(Order = 2)] DateTime GenerationDateTime); @@ -30,7 +30,7 @@ internal interface IRemoteSourceGenerationService /// Controls if the caller wants frozen source generator documents /// included in the result, or if only the most underlying generated documents (produced by the real compiler should be included. - ValueTask> GetSourceGenerationInfoAsync( + ValueTask> GetSourceGeneratedDocumentInfoAsync( Checksum solutionChecksum, ProjectId projectId, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken); /// diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs index fea1281dcad1c..c4e614fa3cc3e 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionCompilationState.RegularCompilationTracker_Generators.cs @@ -99,7 +99,7 @@ private partial class RegularCompilationTracker : ICompilationTracker var infosOpt = await connection.TryInvokeAsync( compilationState, projectId, - (service, solutionChecksum, cancellationToken) => service.GetSourceGenerationInfoAsync( + (service, solutionChecksum, cancellationToken) => service.GetSourceGeneratedDocumentInfoAsync( solutionChecksum, projectId, withFrozenSourceGeneratedDocuments: false, cancellationToken), cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/Remote/ServiceHub/Services/SourceGeneration/RemoteSourceGenerationService.cs b/src/Workspaces/Remote/ServiceHub/Services/SourceGeneration/RemoteSourceGenerationService.cs index 993f3a5e4cc91..f1cd430234c82 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/SourceGeneration/RemoteSourceGenerationService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/SourceGeneration/RemoteSourceGenerationService.cs @@ -29,15 +29,16 @@ protected override IRemoteSourceGenerationService CreateService(in ServiceConstr => new RemoteSourceGenerationService(arguments); } - public ValueTask> GetRegularCompilationTrackerSourceGenerationInfoAsync( - Checksum solutionChecksum, ProjectId projectId, CancellationToken cancellationToken) + public ValueTask> GetSourceGeneratedDocumentInfoAsync( + Checksum solutionChecksum, ProjectId projectId, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var project = solution.GetRequiredProject(projectId); - var documentStates = await solution.CompilationState.GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync(project.State, cancellationToken).ConfigureAwait(false); + var documentStates = await solution.CompilationState.GetSourceGeneratedDocumentStatesAsync( + project.State, withFrozenSourceGeneratedDocuments, cancellationToken).ConfigureAwait(false); - var result = new FixedSizeArrayBuilder(documentStates.States.Count); + var result = new FixedSizeArrayBuilder(documentStates.States.Count); foreach (var (id, state) in documentStates.States) { Contract.ThrowIfFalse(id.IsSourceGenerated); @@ -48,13 +49,14 @@ public ValueTask> }, cancellationToken); } - public ValueTask> GetRegularCompilationTrackerContentsAsync( - Checksum solutionChecksum, ProjectId projectId, ImmutableArray documentIds, CancellationToken cancellationToken) + public ValueTask> GetContentsAsync( + Checksum solutionChecksum, ProjectId projectId, ImmutableArray documentIds, bool withFrozenSourceGeneratedDocuments, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var project = solution.GetRequiredProject(projectId); - var documentStates = await solution.CompilationState.GetRegularCompilationTrackerSourceGeneratedDocumentStatesAsync(project.State, cancellationToken).ConfigureAwait(false); + var documentStates = await solution.CompilationState.GetSourceGeneratedDocumentStatesAsync( + project.State, withFrozenSourceGeneratedDocuments, cancellationToken).ConfigureAwait(false); var result = new FixedSizeArrayBuilder(documentIds.Length); foreach (var id in documentIds) From 602c4c770d45e6e57840f79a4c6e98e4dc56e6f6 Mon Sep 17 00:00:00 2001 From: Chris Sienkiewicz Date: Wed, 3 Jul 2024 11:23:43 -0700 Subject: [PATCH 13/59] New generator apis (#74127) * Add AsIncrementalGenerator API * Implement generator filtering and add tests * Update docs * Don't init generators if they're filtered * Add tests to ensure we re-parse init only trees if the parse options changed between filtered runs --- .../SourceGeneration/GeneratorDriverTests.cs | 237 ++++++++++++++++++ .../SourceGeneration/StateTableTests.cs | 3 +- .../Core/Portable/PublicAPI.Unshipped.txt | 10 + .../SourceGeneration/GeneratorAdaptor.cs | 10 + .../SourceGeneration/GeneratorDriver.cs | 43 +++- .../SourceGeneration/GeneratorDriverState.cs | 15 +- .../SourceGeneration/GeneratorExtensions.cs | 35 ++- .../SourceGeneration/GeneratorState.cs | 3 + .../SourceGeneration/IncrementalContexts.cs | 22 ++ 9 files changed, 352 insertions(+), 26 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs index d838db7356a0a..c512d89774c85 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs @@ -4199,6 +4199,186 @@ public static void Interceptor(this Program program, int param) } } + [Fact] + public void SourceGenerator_As_IncrementalGenerator_As_SourceGenerator() + { + ISourceGenerator generator = new TestSourceGenerator(); + + var incrementalGenerator = generator.AsIncrementalGenerator(); + var sourceGenerator = incrementalGenerator.AsSourceGenerator(); + + Assert.Same(generator, sourceGenerator); + } + + [Fact] + public void SourceGenerator_As_IncrementalGenerator_GetGeneratorType() + { + ISourceGenerator generator = new TestSourceGenerator(); + + var incrementalGenerator = generator.AsIncrementalGenerator(); + var type = incrementalGenerator.GetGeneratorType(); + + Assert.Same(generator.GetType(), type); + } + + [Fact] + public void IncrementalGenerator_As_SourceGenerator_As_IncrementalGenerator() + { + IIncrementalGenerator generator = new PipelineCallbackGenerator(ctx => { }); + + var sourceGenerator = generator.AsSourceGenerator(); + var incrementalGenerator = sourceGenerator.AsIncrementalGenerator(); + + Assert.Same(generator, incrementalGenerator); + } + + [Fact] + public void IncrementalGenerator_As_SourceGenerator_GetGeneratorType() + { + IIncrementalGenerator generator = new PipelineCallbackGenerator(ctx => { }); + + var sourceGenerator = generator.AsSourceGenerator(); + var type = sourceGenerator.GetGeneratorType(); + + Assert.Same(generator.GetType(), type); + } + + [Fact] + public void GeneratorDriver_CreateWith_Wrapped_ISourceGenerator() + { + bool executeCalled = false; + ISourceGenerator generator = new TestSourceGenerator() { ExecuteImpl = (context) => { executeCalled = true; } }; + + var incrementalGenerator = generator.AsIncrementalGenerator(); + + var generatorDriver = CSharpGeneratorDriver.Create(incrementalGenerator); + generatorDriver.RunGenerators(CreateCompilation("class C { }")); + + Assert.True(executeCalled); + } + + [Fact] + public void GeneratorDriver_CanFilter_GeneratorsToRun() + { + var generator1 = new PipelineCallbackGenerator((ctx) => { ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { spc.AddSource("gen1Source.cs", c.SyntaxTrees.First().GetRoot().ToFullString() + " //generator1"); }); }).AsSourceGenerator(); + var generator2 = new PipelineCallbackGenerator2((ctx) => { ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { spc.AddSource("gen2Source.cs", c.SyntaxTrees.First().GetRoot().ToFullString() + " //generator2"); }); }).AsSourceGenerator(); + + var compilation = CreateCompilation("class Compilation1{}"); + GeneratorDriver driver = CSharpGeneratorDriver.Create(generator1, generator2); + + driver = driver.RunGenerators(compilation); + var result = driver.GetRunResult(); + + Assert.Equal(2, result.GeneratedTrees.Length); + Assert.Equal("class Compilation1{} //generator1", result.GeneratedTrees[0].ToString()); + Assert.Equal("class Compilation1{} //generator2", result.GeneratedTrees[1].ToString()); + + // change the generated source, but only run generator 1 + compilation = CreateCompilation("class Compilation2{}"); + driver = driver.RunGenerators(compilation, ctx => ctx.Generator == generator1); + result = driver.GetRunResult(); + + // only the first generator should have run, generator 2 hasn't been updated + Assert.Equal(2, result.GeneratedTrees.Length); + Assert.Equal("class Compilation2{} //generator1", result.GeneratedTrees[0].ToString()); + Assert.Equal("class Compilation1{} //generator2", result.GeneratedTrees[1].ToString()); + + // now only run generator 2 + compilation = CreateCompilation("class Compilation3{}"); + driver = driver.RunGenerators(compilation, ctx => ctx.Generator == generator2); + result = driver.GetRunResult(); + + Assert.Equal(2, result.GeneratedTrees.Length); + Assert.Equal("class Compilation2{} //generator1", result.GeneratedTrees[0].ToString()); + Assert.Equal("class Compilation3{} //generator2", result.GeneratedTrees[1].ToString()); + + // run everything + compilation = CreateCompilation("class Compilation4{}"); + driver = driver.RunGenerators(compilation); + result = driver.GetRunResult(); + + Assert.Equal(2, result.GeneratedTrees.Length); + Assert.Equal("class Compilation4{} //generator1", result.GeneratedTrees[0].ToString()); + Assert.Equal("class Compilation4{} //generator2", result.GeneratedTrees[1].ToString()); + } + + [Fact] + public void GeneratorDriver_CanFilter_GeneratorsToRun_AndUpdateCompilation() + { + var generator1 = new PipelineCallbackGenerator((ctx) => { ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { spc.AddSource("gen1Source.cs", "//" + c.SyntaxTrees.First().GetRoot().ToFullString() + " generator1"); }); }).AsSourceGenerator(); + var generator2 = new PipelineCallbackGenerator2((ctx) => { ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { spc.AddSource("gen2Source.cs", "//" + c.SyntaxTrees.First().GetRoot().ToFullString() + " generator2"); }); }).AsSourceGenerator(); + + var parseOptions = CSharpParseOptions.Default; + var compilation = CreateCompilation("class Compilation1{}", parseOptions: parseOptions); + GeneratorDriver driver = CSharpGeneratorDriver.Create([generator1, generator2], parseOptions: parseOptions); + + driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var outputDiagnostics); + Assert.Empty(outputDiagnostics); + + // change the generated source, but only run generator 1 + compilation = CreateCompilation("class Compilation2{}", parseOptions: parseOptions); + driver = driver.RunGenerators(compilation, ctx => ctx.Generator == generator1); + + // now run all the generators and update the compilation + driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out outputCompilation, out outputDiagnostics); + Assert.Empty(outputDiagnostics); + } + + [Fact] + public void GeneratorDriver_ReturnsEmptyRunResult_IfFiltered_BeforeRunning() + { + bool initWasCalled = false; + + var generator1 = new PipelineCallbackGenerator((ctx) => { ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { spc.AddSource("gen1Source.cs", c.SyntaxTrees.First().GetRoot().ToFullString() + " //generator1"); }); }).AsSourceGenerator(); + var generator2 = new PipelineCallbackGenerator2((ctx) => { initWasCalled = true; ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { spc.AddSource("gen2Source.cs", c.SyntaxTrees.First().GetRoot().ToFullString() + " //generator2"); }); }).AsSourceGenerator(); + + var compilation = CreateCompilation("class Compilation1{}"); + GeneratorDriver driver = CSharpGeneratorDriver.Create(generator1, generator2); + + driver = driver.RunGenerators(compilation, ctx => ctx.Generator == generator1); + var result = driver.GetRunResult(); + + // only a single tree is generated + Assert.Equal(1, result.GeneratedTrees.Length); + Assert.Equal("class Compilation1{} //generator1", result.GeneratedTrees[0].ToString()); + + // but both generators are represented in the run results + Assert.Equal(2, result.Results.Length); + + Assert.Equal(generator1, result.Results[0].Generator); + Assert.Equal(1, result.Results[0].GeneratedSources.Length); + + // the second generator was never initialized and produced no results + Assert.False(initWasCalled); + Assert.Equal(generator2, result.Results[1].Generator); + Assert.True(result.Results[1].GeneratedSources.IsDefault); + } + + [Fact] + public void GeneratorDriver_GeneratorIsNotRun_IfAlreadyUpToDate_DueToFiltering() + { + bool stepRan = false; + var generator1 = new PipelineCallbackGenerator((ctx) => { ctx.RegisterSourceOutput(ctx.CompilationProvider, (spc, c) => { stepRan = true; }); }).AsSourceGenerator(); + + var compilation = CreateCompilation("class Compilation1{}"); + GeneratorDriver driver = CSharpGeneratorDriver.Create(generator1); + + // don't run + driver = driver.RunGenerators(compilation, ctx => false); + Assert.False(stepRan); + + // run + driver = driver.RunGenerators(compilation, ctx => true); + Assert.True(stepRan); + + // re-run everything + stepRan = false; + driver = driver.RunGenerators(compilation); + + // step didn't run because the generator was already up to date + Assert.False(stepRan); + } + [Fact] public void ReplaceGenerators_Initializes_New_Generators() { @@ -4228,5 +4408,62 @@ public void ReplaceGenerators_Initializes_New_Generators() Assert.True(initWasCalled); Assert.Single(results.GeneratedTrees); } + + // check post init trees get re-parsed if we change parse options while suppressed + + [Fact] + public void GeneratorDriver_DoesNotIncludePostInitTrees_WhenFiltered() + { + var generator = new PipelineCallbackGenerator((ctx) => { ctx.RegisterPostInitializationOutput(postInitCtx => { postInitCtx.AddSource("staticSource.cs", "//static"); }); }).AsSourceGenerator(); + + var parseOptions = CSharpParseOptions.Default; + var compilation = CreateCompilation("class Compilation1{}", parseOptions: parseOptions); + GeneratorDriver driver = CSharpGeneratorDriver.Create([generator], parseOptions: parseOptions); + + driver = driver.RunGenerators(compilation, (ctx) => false); + var result = driver.GetRunResult(); + + Assert.Empty(result.GeneratedTrees); + + driver = driver.RunGenerators(compilation); + result = driver.GetRunResult(); + + Assert.Single(result.GeneratedTrees); + } + + [Fact] + public void GeneratorDriver_ReparsesPostInitTrees_IfParseOptionsChange_WhileSuppressed() + { + var generator1 = new PipelineCallbackGenerator((ctx) => { ctx.RegisterPostInitializationOutput(postInitCtx => { postInitCtx.AddSource("staticSource.cs", "//static"); }); }).AsSourceGenerator(); + var generator2 = new PipelineCallbackGenerator2((ctx) => { ctx.RegisterPostInitializationOutput(postInitCtx => { postInitCtx.AddSource("staticSource2.cs", "//static 2"); }); }).AsSourceGenerator(); + + var parseOptions = CSharpParseOptions.Default; + var compilation = CreateCompilation("class Compilation1{}", parseOptions: parseOptions); + GeneratorDriver driver = CSharpGeneratorDriver.Create([generator1, generator2], parseOptions: parseOptions); + + driver = driver.RunGenerators(compilation); + var result = driver.GetRunResult(); + Assert.Equal(2, result.GeneratedTrees.Length); + + // change the parse options, but only run one of the generators + var newParseOptions = parseOptions.WithLanguageVersion(LanguageVersion.CSharp9); + compilation = CreateCompilation("class Compilation2{}", parseOptions: newParseOptions); + driver = driver.WithUpdatedParseOptions(newParseOptions); + driver = driver.RunGenerators(compilation, (ctx) => ctx.Generator == generator1); + result = driver.GetRunResult(); + + // the post init tree from generator2 still has the old parse options, as it didn't run + Assert.Equal(2, result.GeneratedTrees.Length); + Assert.Same(newParseOptions, result.GeneratedTrees[0].Options); + Assert.Same(parseOptions, result.GeneratedTrees[1].Options); + + // now run everything and ensure it brings the init trees up to date + driver = driver.RunGenerators(compilation); + result = driver.GetRunResult(); + + Assert.Equal(2, result.GeneratedTrees.Length); + Assert.Same(newParseOptions, result.GeneratedTrees[0].Options); + Assert.Same(newParseOptions, result.GeneratedTrees[1].Options); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs index 1422d3f9263e7..bb887e87ce6ec 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs @@ -1353,8 +1353,7 @@ private DriverStateTable.Builder GetBuilder(DriverStateTable previous, bool trac previous, SyntaxStore.Empty, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps), - runtime: TimeSpan.Zero, - parseOptionsChanged: false); + runtime: TimeSpan.Zero); return new DriverStateTable.Builder(c, state, SyntaxStore.Empty.ToBuilder(c, ImmutableArray.Empty, trackIncrementalGeneratorSteps, cancellationToken: default)); } diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 198973728f51e..daaad722b1479 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -1,5 +1,15 @@ +Microsoft.CodeAnalysis.GeneratorDriver.RunGenerators(Microsoft.CodeAnalysis.Compilation! compilation) -> Microsoft.CodeAnalysis.GeneratorDriver! +Microsoft.CodeAnalysis.GeneratorDriver.RunGenerators(Microsoft.CodeAnalysis.Compilation! compilation, System.Func? generatorFilter, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.GeneratorDriver! +Microsoft.CodeAnalysis.GeneratorDriver.RunGenerators(Microsoft.CodeAnalysis.Compilation! compilation, System.Threading.CancellationToken cancellationToken) -> Microsoft.CodeAnalysis.GeneratorDriver! +*REMOVED*Microsoft.CodeAnalysis.GeneratorDriver.RunGenerators(Microsoft.CodeAnalysis.Compilation! compilation, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.GeneratorDriver! +Microsoft.CodeAnalysis.GeneratorFilterContext +Microsoft.CodeAnalysis.GeneratorFilterContext.CancellationToken.get -> System.Threading.CancellationToken +Microsoft.CodeAnalysis.GeneratorFilterContext.Generator.get -> Microsoft.CodeAnalysis.ISourceGenerator! +Microsoft.CodeAnalysis.GeneratorFilterContext.GeneratorFilterContext() -> void Microsoft.CodeAnalysis.IPropertySymbol.PartialDefinitionPart.get -> Microsoft.CodeAnalysis.IPropertySymbol? Microsoft.CodeAnalysis.IPropertySymbol.PartialImplementationPart.get -> Microsoft.CodeAnalysis.IPropertySymbol? Microsoft.CodeAnalysis.IPropertySymbol.IsPartialDefinition.get -> bool Microsoft.CodeAnalysis.ITypeParameterSymbol.AllowsRefLikeType.get -> bool Microsoft.CodeAnalysis.RuntimeCapability.ByRefLikeGenerics = 8 -> Microsoft.CodeAnalysis.RuntimeCapability +static Microsoft.CodeAnalysis.GeneratorExtensions.AsIncrementalGenerator(this Microsoft.CodeAnalysis.ISourceGenerator! sourceGenerator) -> Microsoft.CodeAnalysis.IIncrementalGenerator! +static Microsoft.CodeAnalysis.GeneratorExtensions.GetGeneratorType(this Microsoft.CodeAnalysis.IIncrementalGenerator! generator) -> System.Type! \ No newline at end of file diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorAdaptor.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorAdaptor.cs index 1679928c0e43b..03f390a522bc4 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorAdaptor.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorAdaptor.cs @@ -15,6 +15,11 @@ namespace Microsoft.CodeAnalysis /// internal sealed class SourceGeneratorAdaptor : IIncrementalGenerator { + /// + /// A dummy extension that is used to indicate this adaptor was created outside of the driver. + /// + public const string DummySourceExtension = ".dummy"; + private readonly string _sourceExtension; internal ISourceGenerator SourceGenerator { get; } @@ -27,6 +32,11 @@ public SourceGeneratorAdaptor(ISourceGenerator generator, string sourceExtension public void Initialize(IncrementalGeneratorInitializationContext context) { + // We don't currently have any APIs that accept IIncrementalGenerator directly (even in construction we wrap and unwrap them) + // so it should be impossible to get here with a wrapper that was created via ISourceGenerator.AsIncrementalGenerator. + // If we ever do have such an API, we will need to make sure that the source extension is updated as part of adding it to the driver. + Debug.Assert(_sourceExtension != DummySourceExtension); + GeneratorInitializationContext generatorInitContext = new GeneratorInitializationContext(CancellationToken.None); SourceGenerator.Initialize(generatorInitContext); diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs index be1f7643f5433..b80ab17f9ef03 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs @@ -39,19 +39,36 @@ internal GeneratorDriver(GeneratorDriverState state) internal GeneratorDriver(ParseOptions parseOptions, ImmutableArray generators, AnalyzerConfigOptionsProvider optionsProvider, ImmutableArray additionalTexts, GeneratorDriverOptions driverOptions) { var incrementalGenerators = GetIncrementalGenerators(generators, SourceExtension); - _state = new GeneratorDriverState(parseOptions, optionsProvider, generators, incrementalGenerators, additionalTexts, ImmutableArray.Create(new GeneratorState[generators.Length]), DriverStateTable.Empty, SyntaxStore.Empty, driverOptions, runtime: TimeSpan.Zero, parseOptionsChanged: true); + _state = new GeneratorDriverState(parseOptions, optionsProvider, generators, incrementalGenerators, additionalTexts, ImmutableArray.Create(new GeneratorState[generators.Length]), DriverStateTable.Empty, SyntaxStore.Empty, driverOptions, runtime: TimeSpan.Zero); } - public GeneratorDriver RunGenerators(Compilation compilation, CancellationToken cancellationToken = default) + /// + /// Run generators and produce an updated containing the results. + /// + /// The compilation to run generators against + /// An updated driver that contains the results of the generators running. + public GeneratorDriver RunGenerators(Compilation compilation) => RunGenerators(compilation, generatorFilter: null, cancellationToken: default); + + // 4.11 BACKCOMPAT OVERLOAD -- DO NOT TOUCH + public GeneratorDriver RunGenerators(Compilation compilation, CancellationToken cancellationToken) => RunGenerators(compilation, generatorFilter: null, cancellationToken); + + /// + /// Run generators and produce an updated containing the results. + /// + /// The compilation to run generators against + /// A filter that specifies which generators to run. If null all generators will run. + /// Used to cancel an in progress operation. + /// An updated driver that contains the results of the generators running. + public GeneratorDriver RunGenerators(Compilation compilation, Func? generatorFilter, CancellationToken cancellationToken = default) { - var state = RunGeneratorsCore(compilation, diagnosticsBag: null, cancellationToken); //don't directly collect diagnostics on this path + var state = RunGeneratorsCore(compilation, diagnosticsBag: null, generatorFilter, cancellationToken); return FromState(state); } public GeneratorDriver RunGeneratorsAndUpdateCompilation(Compilation compilation, out Compilation outputCompilation, out ImmutableArray diagnostics, CancellationToken cancellationToken = default) { var diagnosticsBag = DiagnosticBag.GetInstance(); - var state = RunGeneratorsCore(compilation, diagnosticsBag, cancellationToken); + var state = RunGeneratorsCore(compilation, diagnosticsBag, generatorFilter: null, cancellationToken); // build the output compilation diagnostics = diagnosticsBag.ToReadOnlyAndFree(); @@ -147,7 +164,7 @@ public GeneratorDriver ReplaceAdditionalText(AdditionalText oldText, AdditionalT public GeneratorDriver ReplaceAdditionalTexts(ImmutableArray newTexts) => FromState(_state.With(additionalTexts: newTexts)); public GeneratorDriver WithUpdatedParseOptions(ParseOptions newOptions) => newOptions is object - ? FromState(_state.With(parseOptions: newOptions, parseOptionsChanged: true)) + ? FromState(_state.With(parseOptions: newOptions)) : throw new ArgumentNullException(nameof(newOptions)); public GeneratorDriver WithUpdatedAnalyzerConfigOptions(AnalyzerConfigOptionsProvider newOptions) => newOptions is object @@ -195,7 +212,7 @@ public GeneratorDriverTimingInfo GetTimingInfo() return new GeneratorDriverTimingInfo(_state.RunTime, generatorTimings); } - internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, DiagnosticBag? diagnosticsBag, CancellationToken cancellationToken = default) + internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, DiagnosticBag? diagnosticsBag, Func? generatorFilter = null, CancellationToken cancellationToken = default) { // with no generators, there is no work to do if (_state.Generators.IsEmpty) @@ -216,6 +233,12 @@ internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, Diagnos var generatorState = state.GeneratorStates[i]; var sourceGenerator = state.Generators[i]; + if (shouldSkipGenerator(sourceGenerator)) + { + stateBuilder.Add(generatorState); + continue; + } + // initialize the generator if needed if (!generatorState.Initialized) { @@ -256,7 +279,7 @@ internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, Diagnos ? new GeneratorState(postInitSources, inputNodes, outputNodes) : SetGeneratorException(compilation, MessageProvider, GeneratorState.Empty, sourceGenerator, ex, diagnosticsBag, cancellationToken, isInit: true); } - else if (state.ParseOptionsChanged && generatorState.PostInitTrees.Length > 0) + else if (generatorState.PostInitTrees.Length > 0 && generatorState.RequiresPostInitReparse(state.ParseOptions)) { // the generator is initialized, but we need to reparse the post-init trees as the parse options have changed var reparsedInitSources = ParseAdditionalSources(sourceGenerator, generatorState.PostInitTrees.SelectAsArray(t => new GeneratedSourceText(t.HintName, t.Text)), cancellationToken); @@ -291,7 +314,7 @@ internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, Diagnos for (int i = 0; i < state.IncrementalGenerators.Length; i++) { var generatorState = stateBuilder[i]; - if (generatorState.OutputNodes.Length == 0) + if (shouldSkipGenerator(state.Generators[i]) || generatorState.OutputNodes.Length == 0) { continue; } @@ -312,7 +335,7 @@ internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, Diagnos } } - state = state.With(stateTable: driverStateBuilder.ToImmutable(), syntaxStore: syntaxStoreBuilder.ToImmutable(), generatorStates: stateBuilder.ToImmutableAndFree(), runTime: timer.Elapsed, parseOptionsChanged: false); + state = state.With(stateTable: driverStateBuilder.ToImmutable(), syntaxStore: syntaxStoreBuilder.ToImmutable(), generatorStates: stateBuilder.ToImmutableAndFree(), runTime: timer.Elapsed); return state; static bool handleGeneratorException(Compilation compilation, CommonMessageProvider messageProvider, ISourceGenerator sourceGenerator, Exception e, bool isInit) @@ -326,6 +349,8 @@ static bool handleGeneratorException(Compilation compilation, CommonMessageProvi return true; } + + bool shouldSkipGenerator(ISourceGenerator generator) => generatorFilter?.Invoke(new GeneratorFilterContext(generator, cancellationToken)) == false; } private IncrementalExecutionContext UpdateOutputs(ImmutableArray outputNodes, IncrementalGeneratorOutputKind outputKind, GeneratorRunStateTable.Builder generatorRunStateBuilder, CancellationToken cancellationToken, DriverStateTable.Builder? driverStateBuilder = null) diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriverState.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriverState.cs index 1a16777ae0d31..d74010bdfc2fb 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriverState.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriverState.cs @@ -20,8 +20,7 @@ internal GeneratorDriverState(ParseOptions parseOptions, DriverStateTable stateTable, SyntaxStore syntaxStore, GeneratorDriverOptions driverOptions, - TimeSpan runtime, - bool parseOptionsChanged) + TimeSpan runtime) { Generators = sourceGenerators; IncrementalGenerators = incrementalGenerators; @@ -35,7 +34,6 @@ internal GeneratorDriverState(ParseOptions parseOptions, DisabledOutputs = driverOptions.DisabledOutputs; TrackIncrementalSteps = driverOptions.TrackIncrementalGeneratorSteps; RunTime = runtime; - ParseOptionsChanged = parseOptionsChanged; Debug.Assert(Generators.Length == GeneratorStates.Length); Debug.Assert(IncrementalGenerators.Length == GeneratorStates.Length); } @@ -104,11 +102,6 @@ internal GeneratorDriverState(ParseOptions parseOptions, // https://github.com/dotnet/roslyn/issues/72129: Change from field to property once issue is addressed internal readonly bool TrackIncrementalSteps; - /// - /// Tracks if the have been changed meaning post init trees will need to be re-parsed. - /// - internal readonly bool ParseOptionsChanged; - internal GeneratorDriverState With( ImmutableArray? sourceGenerators = null, ImmutableArray? incrementalGenerators = null, @@ -118,8 +111,7 @@ internal GeneratorDriverState With( SyntaxStore? syntaxStore = null, ParseOptions? parseOptions = null, AnalyzerConfigOptionsProvider? optionsProvider = null, - TimeSpan? runTime = null, - bool? parseOptionsChanged = null) + TimeSpan? runTime = null) { return new GeneratorDriverState( parseOptions ?? this.ParseOptions, @@ -131,8 +123,7 @@ internal GeneratorDriverState With( stateTable ?? this.StateTable, syntaxStore ?? this.SyntaxStore, this._driverOptions, - runTime ?? this.RunTime, - parseOptionsChanged ?? this.ParseOptionsChanged + runTime ?? this.RunTime ); } } diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorExtensions.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorExtensions.cs index 3626bb82fde9a..e2ec5a34bacdf 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorExtensions.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorExtensions.cs @@ -29,11 +29,40 @@ public static Type GetGeneratorType(this ISourceGenerator generator) return generator.GetType(); } + /// + /// Returns the underlying type of a given generator + /// + /// The generator to get the type of + /// The underlying generator type + public static Type GetGeneratorType(this IIncrementalGenerator generator) + { + if (generator is SourceGeneratorAdaptor adaptor) + { + return adaptor.SourceGenerator.GetType(); + } + return generator.GetType(); + } + /// /// Converts an into an object that can be used when constructing a /// - /// The incremental generator to wrap - /// A wrapped generator that can be passed to a generator driver - public static ISourceGenerator AsSourceGenerator(this IIncrementalGenerator incrementalGenerator) => new IncrementalGeneratorWrapper(incrementalGenerator); + /// The incremental generator to convert + /// An that can be passed to a generator driver + public static ISourceGenerator AsSourceGenerator(this IIncrementalGenerator incrementalGenerator) => incrementalGenerator switch + { + SourceGeneratorAdaptor adaptor => adaptor.SourceGenerator, + _ => new IncrementalGeneratorWrapper(incrementalGenerator) + }; + + /// + /// Converts an into an + /// + /// The source generator to convert + /// An incremental generator + public static IIncrementalGenerator AsIncrementalGenerator(this ISourceGenerator sourceGenerator) => sourceGenerator switch + { + IncrementalGeneratorWrapper wrapper => wrapper.Generator, + _ => new SourceGeneratorAdaptor(sourceGenerator, SourceGeneratorAdaptor.DummySourceExtension) + }; } } diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorState.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorState.cs index 8f76d7d8dd4ed..c58ad9ae2fe7a 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorState.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorState.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Immutable; using System.Diagnostics; +using System.Linq; namespace Microsoft.CodeAnalysis { @@ -124,5 +125,7 @@ public GeneratorState WithError(Exception exception, Diagnostic error, TimeSpan internal ImmutableDictionary> OutputSteps { get; } internal ImmutableArray<(string Key, string Value)> HostOutputs { get; } + + internal bool RequiresPostInitReparse(ParseOptions parseOptions) => PostInitTrees.Any(static (t, parseOptions) => t.Tree.Options != parseOptions, parseOptions); } } diff --git a/src/Compilers/Core/Portable/SourceGeneration/IncrementalContexts.cs b/src/Compilers/Core/Portable/SourceGeneration/IncrementalContexts.cs index e3a49af2ca2cd..48120f02a5bbd 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/IncrementalContexts.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/IncrementalContexts.cs @@ -176,6 +176,28 @@ public void ReportDiagnostic(Diagnostic diagnostic) } } + /// + /// Context passed to a filter to determine if a generator should be executed or not. + /// + public readonly struct GeneratorFilterContext + { + internal GeneratorFilterContext(ISourceGenerator generator, CancellationToken cancellationToken) + { + Generator = generator; + CancellationToken = cancellationToken; + } + + /// + /// The generator instance that is being filtered + /// + public ISourceGenerator Generator { get; } + + /// + /// A that can be checked to see if the filtering should be cancelled. + /// + public CancellationToken CancellationToken { get; } + } + // https://github.com/dotnet/roslyn/issues/53608 right now we only support generating source + diagnostics, but actively want to support generation of other things internal readonly struct IncrementalExecutionContext { From 260f9e6e79c592d4c7338b3e0bcece88b91d2e75 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Wed, 3 Jul 2024 11:52:48 -0700 Subject: [PATCH 14/59] Fix flaky streaming FAR test --- .../FindAllReferencesHandlerTests.cs | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs index 34dad5ed303cf..645f7d49852c3 100644 --- a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs @@ -84,14 +84,6 @@ void M2() var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First(), progress); - Assert.Null(results); - - // BufferedProgress wraps individual elements in an array, so when they are nested them like this, - // with the test creating one, and the handler another, we have to unwrap. - // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual VSInternalReferenceItem - // so we have to correctly convert the JObject into the expected type. - results = progress.GetValues().SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)).ToArray(); - Assert.NotNull(results); Assert.NotEmpty(results); @@ -287,21 +279,51 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr PartialResultToken = progress }; - internal static async Task RunFindAllReferencesAsync(TestLspServer testLspServer, LSP.Location caret, IProgress progress = null) + internal static async Task RunFindAllReferencesAsync(TestLspServer testLspServer, LSP.Location caret, BufferedProgress? progress = null) { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); // Results are returned in a non-deterministic order, so we order them by location var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray(); + + // If we're using progress, we need to return the results from the progress object. + if (progress != null) + { + Assert.Null(orderedResults); + // BufferedProgress wraps individual elements in an array, so when they are nested them like this, + // with the test creating one, and the handler another, we have to unwrap. + // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual VSInternalReferenceItem + // so we have to correctly convert the JObject into the expected type. + orderedResults = progress.Value.GetValues() + .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) + .OrderBy(r => r.Location, new OrderLocations()) + .ToArray(); + } + return orderedResults; } - internal static async Task RunFindAllReferencesNonVSAsync(TestLspServer testLspServer, LSP.Location caret, IProgress progress = null) + internal static async Task RunFindAllReferencesNonVSAsync(TestLspServer testLspServer, LSP.Location caret, BufferedProgress? progress = null) { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); // Results are returned in a non-deterministic order, so we order them by location var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray(); + + // If we're using progress, we need to return the results from the progress object. + if (progress != null) + { + Assert.Null(orderedResults); + // BufferedProgress wraps individual elements in an array, so when they are nested them like this, + // with the test creating one, and the handler another, we have to unwrap. + // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual LSP.Location + // so we have to correctly convert the JObject into the expected type. + orderedResults = progress.Value.GetValues() + .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) + .OrderBy(r => r, new OrderLocations()) + .ToArray(); + } + return orderedResults; } From 1286730bbfbd5c37b0e6f7bfa90b6cdcdac111ce Mon Sep 17 00:00:00 2001 From: David Barbet Date: Wed, 3 Jul 2024 12:12:30 -0700 Subject: [PATCH 15/59] Cleanup a bit --- .../FindAllReferencesHandlerTests.cs | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs index 645f7d49852c3..f9422d9432c00 100644 --- a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs @@ -283,23 +283,16 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); - // Results are returned in a non-deterministic order, so we order them by location - var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray(); - // If we're using progress, we need to return the results from the progress object. + // If we're using progress, return the results from that instead. if (progress != null) { - Assert.Null(orderedResults); - // BufferedProgress wraps individual elements in an array, so when they are nested them like this, - // with the test creating one, and the handler another, we have to unwrap. - // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual VSInternalReferenceItem - // so we have to correctly convert the JObject into the expected type. - orderedResults = progress.Value.GetValues() - .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) - .OrderBy(r => r.Location, new OrderLocations()) - .ToArray(); + Assert.Null(results); + results = UnwrapProgress(progress.Value).ToArray(); } + // Results are returned in a non-deterministic order, so we order them by location + var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray(); return orderedResults; } @@ -307,26 +300,30 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); - // Results are returned in a non-deterministic order, so we order them by location - var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray(); - // If we're using progress, we need to return the results from the progress object. + // If we're using progress, return the results from that instead. if (progress != null) { - Assert.Null(orderedResults); - // BufferedProgress wraps individual elements in an array, so when they are nested them like this, - // with the test creating one, and the handler another, we have to unwrap. - // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual LSP.Location - // so we have to correctly convert the JObject into the expected type. - orderedResults = progress.Value.GetValues() - .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) - .OrderBy(r => r, new OrderLocations()) - .ToArray(); + Assert.Null(results); + results = UnwrapProgress(progress.Value).ToArray(); } + // Results are returned in a non-deterministic order, so we order them by location + var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray(); return orderedResults; } + private static T[] UnwrapProgress(BufferedProgress progress) + { + // BufferedProgress wraps individual elements in an array, so when they are nested them like this, + // with the test creating one, and the handler another, we have to unwrap. + // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual T type + // so we have to correctly convert the JObject into the expected type. + return progress.GetValues() + .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) + .ToArray(); + } + private static void AssertValidDefinitionProperties(LSP.VSInternalReferenceItem[] referenceItems, int definitionIndex, Glyph definitionGlyph) { var definition = referenceItems[definitionIndex]; From 2ee53757a847d680b8cd51218368b63172ce931e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 12:32:37 -0700 Subject: [PATCH 16/59] Pass along correct VS guid when reporting task list items --- .../AbstractPullDiagnosticHandler.cs | 32 ++++++----------- .../IDiagnosticProjectInformationService.cs | 35 ++++++++++++++++++ ...udioDiagnosticProjectInformationService.cs | 36 +++++++++++++++++++ 3 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs create mode 100644 src/VisualStudio/Core/Def/LanguageServer/Handler/Diagnostics/VisualStudioDiagnosticProjectInformationService.cs diff --git a/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs b/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs index 63690632a9793..9a200dbfa16e8 100644 --- a/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs @@ -26,7 +26,11 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics; /// The LSP input param type /// The LSP type that is reported via IProgress /// The LSP type that is returned on completion of the request. -internal abstract partial class AbstractPullDiagnosticHandler : ILspServiceRequestHandler +internal abstract partial class AbstractPullDiagnosticHandler( + IDiagnosticAnalyzerService diagnosticAnalyzerService, + IDiagnosticsRefresher diagnosticRefresher, + IGlobalOptionService globalOptions) + : ILspServiceRequestHandler where TDiagnosticsParams : IPartialResultParams { /// @@ -37,10 +41,10 @@ internal abstract partial class AbstractPullDiagnosticHandler /// Cache where we store the data produced by prior requests so that they can be returned if nothing of significance @@ -54,16 +58,6 @@ internal abstract partial class AbstractPullDiagnosticHandler false; public bool RequiresLSPSolution => true; - protected AbstractPullDiagnosticHandler( - IDiagnosticAnalyzerService diagnosticAnalyzerService, - IDiagnosticsRefresher diagnosticRefresher, - IGlobalOptionService globalOptions) - { - DiagnosticAnalyzerService = diagnosticAnalyzerService; - _diagnosticRefresher = diagnosticRefresher; - GlobalOptions = globalOptions; - } - /// /// Retrieve the previous results we reported. Used so we can avoid resending data for unchanged files. Also /// used so we can report which documents were removed and can have all their diagnostics cleared. @@ -411,17 +405,11 @@ LSP.VSDiagnostic CreateLspDiagnostic( if (capabilities.HasVisualStudioLspCapability()) { var expandedMessage = string.IsNullOrEmpty(diagnosticData.Description) ? null : diagnosticData.Description; + var informationService = project.Solution.Workspace.Services.GetRequiredService(); diagnostic.DiagnosticType = diagnosticData.Category; diagnostic.ExpandedMessage = expandedMessage; - diagnostic.Projects = - [ - new VSDiagnosticProjectInformation - { - ProjectIdentifier = project.Id.Id.ToString(), - ProjectName = project.Name, - }, - ]; + diagnostic.Projects = [informationService.GetDiagnosticProjectInformation(project)]; // Defines an identifier used by the client for merging diagnostics across projects. We want diagnostics // to be merged from separate projects if they have the same code, filepath, range, and message. diff --git a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs new file mode 100644 index 0000000000000..7e855621920ff --- /dev/null +++ b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; +using Roslyn.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics; + +internal interface IDiagnosticProjectInformationService : IWorkspaceService +{ + /// + /// + /// + VSDiagnosticProjectInformation GetDiagnosticProjectInformation(Project project); +} + +[ExportWorkspaceService(typeof(IDiagnosticProjectInformationService)), Shared] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class DefaultDiagnosticProjectInformationService() : IDiagnosticProjectInformationService +{ + public VSDiagnosticProjectInformation GetDiagnosticProjectInformation(Project project) + => GetDiagnosticProjectInformationHelper(project); + + public static VSDiagnosticProjectInformation GetDiagnosticProjectInformationHelper(Project project) + => new() + { + ProjectIdentifier = project.Id.Id.ToString(), + ProjectName = project.Name, + }; +} diff --git a/src/VisualStudio/Core/Def/LanguageServer/Handler/Diagnostics/VisualStudioDiagnosticProjectInformationService.cs b/src/VisualStudio/Core/Def/LanguageServer/Handler/Diagnostics/VisualStudioDiagnosticProjectInformationService.cs new file mode 100644 index 0000000000000..cc0a8d3a0e05e --- /dev/null +++ b/src/VisualStudio/Core/Def/LanguageServer/Handler/Diagnostics/VisualStudioDiagnosticProjectInformationService.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics; +using Roslyn.LanguageServer.Protocol; + +namespace Microsoft.VisualStudio.LanguageServices.LanguageServer.Handler.Diagnostics; + +[ExportWorkspaceService(typeof(IDiagnosticProjectInformationService), ServiceLayer.Host), Shared] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class VisualStudioDiagnosticProjectInformationService() : IDiagnosticProjectInformationService +{ + public VSDiagnosticProjectInformation GetDiagnosticProjectInformation(Project project) + { + if (project.Solution.Workspace is VisualStudioWorkspace workspace) + { + var guid = workspace.GetProjectGuid(project.Id); + if (guid != Guid.Empty) + { + return new() + { + ProjectIdentifier = guid.ToString(), + ProjectName = project.Name, + }; + } + } + + return DefaultDiagnosticProjectInformationService.GetDiagnosticProjectInformationHelper(project); + } +} From d9f63b6c1690af35225940ad16c3511361235240 Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Wed, 3 Jul 2024 12:37:24 -0700 Subject: [PATCH 17/59] Dispose various locations using PEReader (#74226) Attempt to address https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2104770 Multiple hdmps gathered for this bug indicate a leak of native memory in NativeHeapMemoryBlock+DisposableData. Tracking this backwards through code leads to a PEReader leak, but I wasn't able to keep tracking back from the data in the dmps. Looking at the PEReader objects in the dmp, I was able to infer that the PEStreamOptions.PrefetchEntireImage option was set when creating the PEReader. This led to the most likely culprit, CSharpDecompilationService.PerformDecompilation not disposing the PEFile it owns. Additionally, I noticed CompilationOutputs.TryCopyPdbToAsync wasn't disposing a PEReader it owned through the DebugInformationReaderProvider it owns from the call to OpenPdb. --- .../Core/Portable/Emit/CompilationOutputs.cs | 2 +- ...SharpCodeDecompilerDecompilationService.cs | 39 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Features/Core/Portable/Emit/CompilationOutputs.cs b/src/Features/Core/Portable/Emit/CompilationOutputs.cs index afb865532c903..6e0d4082e5ddc 100644 --- a/src/Features/Core/Portable/Emit/CompilationOutputs.cs +++ b/src/Features/Core/Portable/Emit/CompilationOutputs.cs @@ -165,7 +165,7 @@ internal async ValueTask TryCopyAssemblyToAsync(Stream stream, Cancellatio internal async ValueTask TryCopyPdbToAsync(Stream stream, CancellationToken cancellationToken) { - var pdb = OpenPdb(); + using var pdb = OpenPdb(); if (pdb == null) { return false; diff --git a/src/LanguageServer/Protocol/Features/DecompiledSource/CSharpCodeDecompilerDecompilationService.cs b/src/LanguageServer/Protocol/Features/DecompiledSource/CSharpCodeDecompilerDecompilationService.cs index 49aaa86be0ab9..ac05c4ad8a47e 100644 --- a/src/LanguageServer/Protocol/Features/DecompiledSource/CSharpCodeDecompilerDecompilationService.cs +++ b/src/LanguageServer/Protocol/Features/DecompiledSource/CSharpCodeDecompilerDecompilationService.cs @@ -50,29 +50,32 @@ public FileVersionInfo GetDecompilerVersion() if (file is null) return null; - // Initialize a decompiler with default settings. - var decompiler = new CSharpDecompiler(file, resolver, new DecompilerSettings()); - // Escape invalid identifiers to prevent Roslyn from failing to parse the generated code. - // (This happens for example, when there is compiler-generated code that is not yet recognized/transformed by the decompiler.) - decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers()); + using (file) + { + // Initialize a decompiler with default settings. + var decompiler = new CSharpDecompiler(file, resolver, new DecompilerSettings()); + // Escape invalid identifiers to prevent Roslyn from failing to parse the generated code. + // (This happens for example, when there is compiler-generated code that is not yet recognized/transformed by the decompiler.) + decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers()); - var fullTypeName = new FullTypeName(fullName); + var fullTypeName = new FullTypeName(fullName); - // ILSpy only allows decompiling a type that comes from the 'Main Module'. They will throw on anything - // else. Prevent this by doing this quick check corresponding to: - // https://github.com/icsharpcode/ILSpy/blob/4ebe075e5859939463ae420446f024f10c3bf077/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs#L978 - var type = decompiler.TypeSystem.MainModule.GetTypeDefinition(fullTypeName); - if (type is null) - return null; + // ILSpy only allows decompiling a type that comes from the 'Main Module'. They will throw on anything + // else. Prevent this by doing this quick check corresponding to: + // https://github.com/icsharpcode/ILSpy/blob/4ebe075e5859939463ae420446f024f10c3bf077/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs#L978 + var type = decompiler.TypeSystem.MainModule.GetTypeDefinition(fullTypeName); + if (type is null) + return null; - // Try to decompile; if an exception is thrown the caller will handle it - var text = decompiler.DecompileTypeAsString(fullTypeName); + // Try to decompile; if an exception is thrown the caller will handle it + var text = decompiler.DecompileTypeAsString(fullTypeName); - text += "#if false // " + FeaturesResources.Decompilation_log + Environment.NewLine; - text += logger.ToString(); - text += "#endif" + Environment.NewLine; + text += "#if false // " + FeaturesResources.Decompilation_log + Environment.NewLine; + text += logger.ToString(); + text += "#endif" + Environment.NewLine; - return document.WithText(SourceText.From(text, encoding: null, checksumAlgorithm: SourceHashAlgorithms.Default)); + return document.WithText(SourceText.From(text, encoding: null, checksumAlgorithm: SourceHashAlgorithms.Default)); + } } } } From 6dbfe7bc38b2a8d3ba81faf44c73e1e6c6b5712d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 12:48:09 -0700 Subject: [PATCH 18/59] Docs --- .../Handler/Diagnostics/IDiagnosticProjectInformationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs index 7e855621920ff..dd414ec4eeaff 100644 --- a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs +++ b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics; internal interface IDiagnosticProjectInformationService : IWorkspaceService { /// - /// + /// Allows the workspace to customize the project information it returns for a particular project. /// VSDiagnosticProjectInformation GetDiagnosticProjectInformation(Project project); } From 9b7daf9e9702d406c0df78eb43593e90977997d9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 12:49:16 -0700 Subject: [PATCH 19/59] Docs --- .../Diagnostics/IDiagnosticProjectInformationService.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs index dd414ec4eeaff..afcf866a8293b 100644 --- a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs +++ b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs @@ -29,6 +29,9 @@ public VSDiagnosticProjectInformation GetDiagnosticProjectInformation(Project pr public static VSDiagnosticProjectInformation GetDiagnosticProjectInformationHelper(Project project) => new() { + // When we have nothing better, just return the underlying roslyn-internal guid of this project. In + // practice, in VS this will actually become the real VS project guid for this project, as long as we can + // find that. ProjectIdentifier = project.Id.Id.ToString(), ProjectName = project.Name, }; From 84c97e99fd6290c5d5b31d90f796f58811ba858b Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 3 Jul 2024 09:38:59 -0500 Subject: [PATCH 20/59] Fix style binding failure in Document Outline Fixes #73810 --- .../Core/Def/DocumentOutline/DocumentOutlineView.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml index 4cff00aaa9311..b7a88103949c9 100644 --- a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml +++ b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineView.xaml @@ -60,7 +60,7 @@ - From 07ad2d9bd7a07ef0bf0ef82604136ac8560215c1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 12:59:39 -0700 Subject: [PATCH 21/59] Avoid workspace --- .../Handler/Diagnostics/AbstractPullDiagnosticHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs b/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs index 9a200dbfa16e8..5c35c9063208b 100644 --- a/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Diagnostics/AbstractPullDiagnosticHandler.cs @@ -405,7 +405,7 @@ LSP.VSDiagnostic CreateLspDiagnostic( if (capabilities.HasVisualStudioLspCapability()) { var expandedMessage = string.IsNullOrEmpty(diagnosticData.Description) ? null : diagnosticData.Description; - var informationService = project.Solution.Workspace.Services.GetRequiredService(); + var informationService = project.Solution.Services.GetRequiredService(); diagnostic.DiagnosticType = diagnosticData.Category; diagnostic.ExpandedMessage = expandedMessage; From 686eece57a11a21e6056354b9bc61df6424bbe7a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:01:24 -0700 Subject: [PATCH 22/59] docs --- .../Diagnostics/IDiagnosticProjectInformationService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs index afcf866a8293b..ff711921d75d5 100644 --- a/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs +++ b/src/LanguageServer/Protocol/Handler/Diagnostics/IDiagnosticProjectInformationService.cs @@ -13,7 +13,10 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics; internal interface IDiagnosticProjectInformationService : IWorkspaceService { /// - /// Allows the workspace to customize the project information it returns for a particular project. + /// Allows the workspace to customize the project information it returns for a particular project. Note: this + /// information may ultimately be racey. In that the LSP handler may call in the background for information that is + /// changing on the foreground. While not ideal, that's been how project-info has always worked in the diagnostic + /// subsystem, so we just live with it for the time being. /// VSDiagnosticProjectInformation GetDiagnosticProjectInformation(Project project); } From ffe406a2a7675be48372085e0a39bb5d5203bd4e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:02:49 -0700 Subject: [PATCH 23/59] Remove unused type --- .../AbstractTableEntriesSnapshot.cs | 303 ------------------ 1 file changed, 303 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/TableDataSource/AbstractTableEntriesSnapshot.cs diff --git a/src/VisualStudio/Core/Def/TableDataSource/AbstractTableEntriesSnapshot.cs b/src/VisualStudio/Core/Def/TableDataSource/AbstractTableEntriesSnapshot.cs deleted file mode 100644 index f8d24544fc016..0000000000000 --- a/src/VisualStudio/Core/Def/TableDataSource/AbstractTableEntriesSnapshot.cs +++ /dev/null @@ -1,303 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Navigation; -using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.Shell.TableManager; -using Microsoft.VisualStudio.Text; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource; - -/// -/// Base implementation of ITableEntriesSnapshot -/// -internal abstract class AbstractTableEntriesSnapshot : ITableEntriesSnapshot - where TItem : TableItem -{ - // TODO : remove these once we move to new drop which contains API change from editor team - protected const string ProjectNames = StandardTableKeyNames.ProjectName + "s"; - protected const string ProjectGuids = StandardTableKeyNames.ProjectGuid + "s"; - - private readonly int _version; - private readonly ImmutableArray _items; - private ImmutableArray _trackingPoints; - private FrameworkElement[]? _descriptions; - - protected AbstractTableEntriesSnapshot(IThreadingContext threadingContext, int version, ImmutableArray items, ImmutableArray trackingPoints) - { - ThreadingContext = threadingContext; - _version = version; - _items = items; - _trackingPoints = trackingPoints; - } - - public abstract bool TryNavigateTo(int index, NavigationOptions options, CancellationToken cancellationToken); - public abstract bool TryGetValue(int index, string columnName, [NotNullWhen(true)] out object? content); - - public int VersionNumber - { - get - { - return _version; - } - } - - public int Count - { - get - { - return _items.Length; - } - } - - protected IThreadingContext ThreadingContext { get; } - - public int IndexOf(int index, ITableEntriesSnapshot newerSnapshot) - { - var item = GetItem(index); - if (item == null) - { - return -1; - } - - if (newerSnapshot is not AbstractTableEntriesSnapshot ourSnapshot || ourSnapshot.Count == 0) - { - // not ours, we don't know how to track index - return -1; - } - - // quick path - this will deal with a case where we update data without any actual change - if (Count == ourSnapshot.Count) - { - var newItem = ourSnapshot.GetItem(index); - if (newItem != null && newItem.Equals(item)) - { - return index; - } - } - - // slow path. - for (var i = 0; i < ourSnapshot.Count; i++) - { - var newItem = ourSnapshot.GetItem(i); - - // GetItem only returns null for index out of range - RoslynDebug.AssertNotNull(newItem); - - if (item.EqualsIgnoringLocation(newItem)) - { - return i; - } - } - - // no similar item exist. table control itself will try to maintain selection - return -1; - } - - public void StopTracking() - { - // remove tracking points - _trackingPoints = default; - } - - public void Dispose() - => StopTracking(); - - internal TItem? GetItem(int index) - { - if (index < 0 || _items.Length <= index) - { - return null; - } - - return _items[index]; - } - - protected LinePosition GetTrackingLineColumn(Document document, int index) - { - if (_trackingPoints.IsDefaultOrEmpty) - { - return LinePosition.Zero; - } - - var trackingPoint = _trackingPoints[index]; - if (!document.TryGetText(out var text)) - { - return LinePosition.Zero; - } - - var snapshot = text.FindCorrespondingEditorTextSnapshot(); - if (snapshot != null) - { - return GetLinePosition(snapshot, trackingPoint); - } - - var textBuffer = text.Container.TryGetTextBuffer(); - if (textBuffer == null) - { - return LinePosition.Zero; - } - - var currentSnapshot = textBuffer.CurrentSnapshot; - return GetLinePosition(currentSnapshot, trackingPoint); - } - - private static LinePosition GetLinePosition(ITextSnapshot snapshot, ITrackingPoint trackingPoint) - { - var point = trackingPoint.GetPoint(snapshot); - var line = point.GetContainingLine(); - - return new LinePosition(line.LineNumber, point.Position - line.Start); - } - - protected bool TryNavigateTo(Workspace workspace, DocumentId documentId, LinePosition position, NavigationOptions options, CancellationToken cancellationToken) - { - var navigationService = workspace.Services.GetService(); - if (navigationService == null) - return false; - - return this.ThreadingContext.JoinableTaskFactory.Run(() => - navigationService.TryNavigateToLineAndOffsetAsync( - this.ThreadingContext, workspace, documentId, position.Line, position.Character, options, cancellationToken)); - } - - protected bool TryNavigateToItem(int index, NavigationOptions options, CancellationToken cancellationToken) - { - var item = GetItem(index); - if (item is null) - return false; - - var workspace = item.Workspace; - var solution = workspace.CurrentSolution; - var documentId = item.DocumentId; - if (documentId is null) - { - if (solution.GetProject(item.ProjectId) is { } project) - { - // We couldn't find a document ID when the item was created, so it may be a source generator output. - var documents = ThreadingContext.JoinableTaskFactory.Run(() => project.GetSourceGeneratedDocumentsAsync(cancellationToken).AsTask()); - var projectDirectory = Path.GetDirectoryName(project.FilePath); - documentId = documents.FirstOrDefault(document => Path.Combine(projectDirectory, document.FilePath) == item.GetOriginalFilePath())?.Id; - if (documentId is null) - return false; - } - else - { - return false; - } - } - - LinePosition position; - var document = solution.GetDocument(documentId); - if (document is not null - && workspace.IsDocumentOpen(documentId) - && GetTrackingLineColumn(document, index) is { } trackingLinePosition - && trackingLinePosition != LinePosition.Zero) - { - // For normal documents already open, try to map the diagnostic location to its current position in a - // potentially-edited document. - position = trackingLinePosition; - } - else - { - // Otherwise navigate to the original reported location. - position = item.GetOriginalPosition(); - } - - return TryNavigateTo(workspace, documentId, position, options, cancellationToken); - } - - // we don't use these -#pragma warning disable IDE0060 // Remove unused parameter - Implements interface method for sub-type - public object? Identity(int index) -#pragma warning restore IDE0060 // Remove unused parameter - => null; - - public void StartCaching() - { - } - - public void StopCaching() - { - } - - protected static bool CanCreateDetailsContent(int index, Func getDiagnosticTableItem) - { - var item = getDiagnosticTableItem(index)?.Data; - if (item == null) - { - return false; - } - - return !string.IsNullOrWhiteSpace(item.Description); - } - - protected bool TryCreateDetailsContent(int index, Func getDiagnosticTableItem, [NotNullWhen(returnValue: true)] out FrameworkElement? expandedContent) - { - var item = getDiagnosticTableItem(index)?.Data; - if (item == null) - { - expandedContent = null; - return false; - } - - expandedContent = GetOrCreateTextBlock(ref _descriptions, this.Count, index, item, i => GetDescriptionTextBlock(i)); - return true; - } - - protected static bool TryCreateDetailsStringContent(int index, Func getDiagnosticTableItem, [NotNullWhen(returnValue: true)] out string? content) - { - var item = getDiagnosticTableItem(index)?.Data; - if (item == null) - { - content = null; - return false; - } - - if (string.IsNullOrWhiteSpace(item.Description)) - { - content = null; - return false; - } - - content = item.Description; - return content != null; - } - - private static FrameworkElement GetDescriptionTextBlock(DiagnosticData item) - { - return new TextBlock() - { - Background = null, - Padding = new Thickness(10, 6, 10, 8), - TextWrapping = TextWrapping.Wrap, - Text = item.Description - }; - } - - private static FrameworkElement GetOrCreateTextBlock( - [NotNull] ref FrameworkElement[]? caches, int count, int index, DiagnosticData item, Func elementCreator) - { - caches ??= new FrameworkElement[count]; - - if (caches[index] == null) - { - caches[index] = elementCreator(item); - } - - return caches[index]; - } -} From 97f4ccf2c02861b904995c9b2734a1a31360f6d5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:06:31 -0700 Subject: [PATCH 24/59] Fallout --- ...ioDiagnosticListSuppressionStateService.cs | 42 +++---------------- ...StudioDiagnosticListTableCommandHandler.cs | 15 +------ 2 files changed, 7 insertions(+), 50 deletions(-) diff --git a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListSuppressionStateService.cs b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListSuppressionStateService.cs index ffba254c0b0e0..3056bfe21fb86 100644 --- a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListSuppressionStateService.cs +++ b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListSuppressionStateService.cs @@ -159,27 +159,9 @@ private static bool EntrySupportsSuppressionState(ITableEntryHandle entryHandle, isNoLocationDiagnosticEntry = !entryHandle.TryGetValue(StandardTableColumnDefinitions.DocumentName, out string filePath) || string.IsNullOrEmpty(filePath); - var roslynSnapshot = GetEntriesSnapshot(entryHandle, out var index); - if (roslynSnapshot == null) - { - isRoslynEntry = false; - isCompilerDiagnosticEntry = false; - return IsNonRoslynEntrySupportingSuppressionState(entryHandle, out isSuppressedEntry); - } - - var diagnosticData = roslynSnapshot?.GetItem(index)?.Data; - if (!IsEntryWithConfigurableSuppressionState(diagnosticData)) - { - isRoslynEntry = false; - isSuppressedEntry = false; - isCompilerDiagnosticEntry = false; - return false; - } - - isRoslynEntry = true; - isSuppressedEntry = diagnosticData.IsSuppressed; - isCompilerDiagnosticEntry = SuppressionHelpers.IsCompilerDiagnostic(diagnosticData); - return true; + isRoslynEntry = false; + isCompilerDiagnosticEntry = false; + return IsNonRoslynEntrySupportingSuppressionState(entryHandle, out isSuppressedEntry); } private static bool IsNonRoslynEntrySupportingSuppressionState(ITableEntryHandle entryHandle, out bool isSuppressedEntry) @@ -200,16 +182,6 @@ private static bool IsNonRoslynEntrySupportingSuppressionState(ITableEntryHandle private static bool IsEntryWithConfigurableSuppressionState([NotNullWhen(true)] DiagnosticData? entry) => entry != null && !SuppressionHelpers.IsNotConfigurableDiagnostic(entry); - private static AbstractTableEntriesSnapshot? GetEntriesSnapshot(ITableEntryHandle entryHandle, out int index) - { - if (!entryHandle.TryGetSnapshot(out var snapshot, out index)) - { - return null; - } - - return snapshot as AbstractTableEntriesSnapshot; - } - /// /// Gets objects for selected error list entries. /// For remove suppression, the method also returns selected external source diagnostics. @@ -228,12 +200,8 @@ public async Task> GetSelectedItemsAsync(bool isA cancellationToken.ThrowIfCancellationRequested(); DiagnosticData? diagnosticData = null; - var roslynSnapshot = GetEntriesSnapshot(entryHandle, out var index); - if (roslynSnapshot != null) - { - diagnosticData = roslynSnapshot.GetItem(index)?.Data; - } - else if (!isAddSuppression) + + if (!isAddSuppression) { // For suppression removal, we also need to handle FxCop entries. if (!IsNonRoslynEntrySupportingSuppressionState(entryHandle, out var isSuppressedEntry) || diff --git a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs index 71a1dad2dc78d..39e1915142a9d 100644 --- a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs +++ b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs @@ -234,20 +234,9 @@ async System.Threading.Tasks.Task ConfigureSeverityAsync(CancellationT } } - private DiagnosticData? TryGetSingleSelectedEntry() + private static DiagnosticData? TryGetSingleSelectedEntry() { - if (_tableControl?.SelectedEntries.Count() != 1) - { - return null; - } - - if (!_tableControl.SelectedEntry.TryGetSnapshot(out var snapshot, out var index) || - snapshot is not AbstractTableEntriesSnapshot roslynSnapshot) - { - return null; - } - - return roslynSnapshot.GetItem(index)?.Data; + return null; } private bool TryGetPathToAnalyzerConfigDoc(DiagnosticData selectedDiagnostic, [NotNullWhen(true)] out Project? project, [NotNullWhen(true)] out string? pathToAnalyzerConfigDoc) From 01d27cf835fb85922f0a3283327d6f0b7d17a75b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:13:49 -0700 Subject: [PATCH 25/59] Remove additional type --- .../TableDataSource/DiagnosticTableItem.cs | 141 ------------------ 1 file changed, 141 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/TableDataSource/DiagnosticTableItem.cs diff --git a/src/VisualStudio/Core/Def/TableDataSource/DiagnosticTableItem.cs b/src/VisualStudio/Core/Def/TableDataSource/DiagnosticTableItem.cs deleted file mode 100644 index 38e8a02a10716..0000000000000 --- a/src/VisualStudio/Core/Def/TableDataSource/DiagnosticTableItem.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource; - -internal sealed class DiagnosticTableItem : TableItem -{ - public readonly DiagnosticData Data; - - private DiagnosticTableItem( - Workspace workspace, - DiagnosticData data, - string? projectName, - Guid projectGuid, - string[] projectNames, - Guid[] projectGuids) - : base(workspace, projectName, projectGuid, projectNames, projectGuids) - { - Contract.ThrowIfNull(data); - Data = data; - } - - internal static DiagnosticTableItem Create(Workspace workspace, DiagnosticData data) - { - GetProjectNameAndGuid(workspace, data.ProjectId, out var projectName, out var projectGuid); - return new DiagnosticTableItem(workspace, data, projectName, projectGuid, projectNames: [], projectGuids: []); - } - - public override TableItem WithAggregatedData(string[] projectNames, Guid[] projectGuids) - => new DiagnosticTableItem(Workspace, Data, projectName: null, projectGuid: Guid.Empty, projectNames, projectGuids); - - public override DocumentId? DocumentId - => Data.DocumentId; - - public override ProjectId? ProjectId - => Data.ProjectId; - - // TODO: use of OriginalFileSpan seems very suspect here. It is used for navigation. But we should likely - // navigate to the remapped position. (Unless navigation already handles that? Unclear what the - // invariants/expectations are between these two components). - public override LinePosition GetOriginalPosition() - => Data.DataLocation.UnmappedFileSpan.StartLinePosition; - - public override string GetOriginalFilePath() - => Data.DataLocation.UnmappedFileSpan.Path; - - public override bool EqualsIgnoringLocation(TableItem other) - { - if (other is not DiagnosticTableItem otherDiagnosticItem) - { - return false; - } - - var diagnostic = Data; - var otherDiagnostic = otherDiagnosticItem.Data; - - // everything same except location - return diagnostic.Id == otherDiagnostic.Id && - diagnostic.ProjectId == otherDiagnostic.ProjectId && - diagnostic.DocumentId == otherDiagnostic.DocumentId && - diagnostic.Category == otherDiagnostic.Category && - diagnostic.Severity == otherDiagnostic.Severity && - diagnostic.WarningLevel == otherDiagnostic.WarningLevel && - diagnostic.Message == otherDiagnostic.Message; - } - - /// - /// Used to group diagnostics that only differ in the project they come from. - /// We want to avoid displaying diagnostic multuple times when it is reported from - /// multi-targeted projects and/or files linked to multiple projects. - /// Note that a linked file is represented by unique in each project it is linked to, - /// so we don't include in the comparison. - /// - internal sealed class GroupingComparer : IEqualityComparer, IEqualityComparer - { - public static readonly GroupingComparer Instance = new(); - - public bool Equals(DiagnosticData left, DiagnosticData right) - { - if (ReferenceEquals(left, right)) - return true; - - if (left is null || right is null) - return false; - - var leftLocation = left.DataLocation; - var rightLocation = right.DataLocation; - - // location-less or project level diagnostic: - if (left.DocumentId == null || right.DocumentId == null) - return left.Equals(right); - - return - leftLocation.UnmappedFileSpan == rightLocation.UnmappedFileSpan && - left.Severity == right.Severity && - left.IsSuppressed == right.IsSuppressed && - left.Id == right.Id && - left.Message == right.Message; - } - - public int GetHashCode(DiagnosticData data) - { - var location = data.DataLocation; - - // location-less or project level diagnostic: - if (data.DocumentId == null) - return data.GetHashCode(); - - return - Hash.Combine(location.UnmappedFileSpan.GetHashCode(), - Hash.Combine(data.IsSuppressed, - Hash.Combine(data.Id, ((int)data.Severity).GetHashCode()))); - } - - public bool Equals(DiagnosticTableItem left, DiagnosticTableItem right) - { - if (ReferenceEquals(left, right)) - { - return true; - } - - if (left is null || right is null) - { - return false; - } - - return Equals(left.Data, right.Data); - } - - public int GetHashCode(DiagnosticTableItem item) - => GetHashCode(item.Data); - } -} From 894050dce820e905d175cc6352bbe19aaacb5009 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:19:42 -0700 Subject: [PATCH 26/59] Remove additional type --- .../Core/Def/TableDataSource/TableItem.cs | 71 ------------------- 1 file changed, 71 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/TableDataSource/TableItem.cs diff --git a/src/VisualStudio/Core/Def/TableDataSource/TableItem.cs b/src/VisualStudio/Core/Def/TableDataSource/TableItem.cs deleted file mode 100644 index 29af0b244e6e2..0000000000000 --- a/src/VisualStudio/Core/Def/TableDataSource/TableItem.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Diagnostics.CodeAnalysis; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource; - -internal abstract class TableItem -{ - public readonly Workspace Workspace; - - private string? _lazyProjectName; - - // Guid.Empty if the item is aggregated, or the item doesn't have an associated project. - public readonly Guid ProjectGuid; - - // Empty for non-aggregated items: - public readonly string[] ProjectNames; - public readonly Guid[] ProjectGuids; - - public TableItem(Workspace workspace, string? projectName, Guid projectGuid, string[] projectNames, Guid[] projectGuids) - { - Contract.ThrowIfNull(workspace); - Contract.ThrowIfNull(projectNames); - Contract.ThrowIfNull(projectGuids); - - Workspace = workspace; - _lazyProjectName = projectName; - ProjectGuid = projectGuid; - ProjectNames = projectNames; - ProjectGuids = projectGuids; - } - - internal static void GetProjectNameAndGuid(Workspace workspace, ProjectId? projectId, [NotNullIfNotNull(nameof(projectId))] out string? projectName, out Guid projectGuid) - { - projectName = (projectId == null) ? null : workspace.CurrentSolution.GetProject(projectId)?.Name ?? ServicesVSResources.Unknown2; - projectGuid = (projectId != null && workspace is VisualStudioWorkspace vsWorkspace) ? vsWorkspace.GetProjectGuid(projectId) : Guid.Empty; - } - - public abstract TableItem WithAggregatedData(string[] projectNames, Guid[] projectGuids); - - public abstract DocumentId? DocumentId { get; } - public abstract ProjectId? ProjectId { get; } - - public abstract LinePosition GetOriginalPosition(); - public abstract string GetOriginalFilePath(); - public abstract bool EqualsIgnoringLocation(TableItem other); - - public string? ProjectName - { - get - { - if (_lazyProjectName != null) - { - return _lazyProjectName; - } - - if (ProjectNames.Length > 0) - { - return _lazyProjectName = string.Join(", ", ProjectNames); - } - - return null; - } - } -} From 7262ac6b821801d73e95fe5cc74b269868967dfa Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:23:09 -0700 Subject: [PATCH 27/59] Remove unused extension --- src/VisualStudio/Xaml/Impl/Extensions.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/VisualStudio/Xaml/Impl/Extensions.cs b/src/VisualStudio/Xaml/Impl/Extensions.cs index 151fc26996602..589e36befb12b 100644 --- a/src/VisualStudio/Xaml/Impl/Extensions.cs +++ b/src/VisualStudio/Xaml/Impl/Extensions.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Linq; -using Microsoft.VisualStudio.LanguageServices; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; @@ -12,9 +10,6 @@ namespace Microsoft.CodeAnalysis.Editor.Xaml { internal static class Extensions { - public static Guid GetProjectGuid(this VisualStudioWorkspace workspace, ProjectId projectId) - => workspace.GetProjectGuid(projectId); - public static string GetFilePath(this ITextView textView) => textView.TextBuffer.GetFilePath(); From 067bf523fc4dba9b84b012a10f729630dc690dbe Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:31:50 -0700 Subject: [PATCH 28/59] Remove more unused code --- .../Core/Def/ID.RoslynCommands.cs | 7 -- src/VisualStudio/Core/Def/RoslynPackage.cs | 2 +- ...StudioDiagnosticListTableCommandHandler.cs | 94 +------------------ 3 files changed, 2 insertions(+), 101 deletions(-) diff --git a/src/VisualStudio/Core/Def/ID.RoslynCommands.cs b/src/VisualStudio/Core/Def/ID.RoslynCommands.cs index a4f3cb0924c6b..35b69bdf39809 100644 --- a/src/VisualStudio/Core/Def/ID.RoslynCommands.cs +++ b/src/VisualStudio/Core/Def/ID.RoslynCommands.cs @@ -36,13 +36,6 @@ public static class RoslynCommands public const int AddSuppressionsInSource = 0x011f; public const int AddSuppressionsInSuppressionFile = 0x0120; public const int RemoveSuppressions = 0x0121; - public const int ErrorListSetSeveritySubMenu = 0x0122; - public const int ErrorListSetSeverityError = 0x0124; - public const int ErrorListSetSeverityWarning = 0x0125; - public const int ErrorListSetSeverityInfo = 0x0126; - public const int ErrorListSetSeverityHidden = 0x0127; - public const int ErrorListSetSeverityNone = 0x0128; - public const int ErrorListSetSeverityDefault = 0x0129; // Analyze and Code Cleanup menu IDs public const int AnalysisScopeDefault = 0x0131; diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 7db8d50df8e0d..8dfd128dd3e99 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -228,7 +228,7 @@ protected override async Task LoadComponentsAsync(CancellationToken cancellation // we need to load it as early as possible since we can have errors from // package from each language very early await this.ComponentModel.GetService().InitializeAsync(this).ConfigureAwait(false); - await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); + await this.ComponentModel.GetService().InitializeAsync(this).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); diff --git a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs index 39e1915142a9d..d5fb85a789cd9 100644 --- a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs +++ b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs @@ -7,12 +7,10 @@ using System.ComponentModel.Composition; using System.ComponentModel.Design; using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes.Configuration; -using Microsoft.CodeAnalysis.CodeFixes.Suppression; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; @@ -25,7 +23,6 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell.TableControl; using Microsoft.VisualStudio.Utilities; -using Roslyn.Utilities; using Task = System.Threading.Tasks.Task; namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource; @@ -67,40 +64,10 @@ public VisualStudioDiagnosticListTableCommandHandler( _listener = listenerProvider.GetListener(FeatureAttribute.ErrorList); } - public async Task InitializeAsync(IAsyncServiceProvider serviceProvider, CancellationToken cancellationToken) + public async Task InitializeAsync(IAsyncServiceProvider serviceProvider) { var errorList = await serviceProvider.GetServiceAsync(_threadingContext.JoinableTaskFactory, throwOnFailure: false).ConfigureAwait(false); _tableControl = errorList?.TableControl; - - // Add command handlers for bulk suppression commands. - var menuCommandService = await serviceProvider.GetServiceAsync(_threadingContext.JoinableTaskFactory, throwOnFailure: false).ConfigureAwait(false); - if (menuCommandService != null) - { - await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - AddErrorListSetSeverityMenuHandlers(menuCommandService); - - // The Add/Remove suppression(s) have been moved to the VS code analysis layer, so we don't add the commands here. - - // TODO: Figure out how to access menu commands registered by CodeAnalysisPackage and - // add the commands here if we cannot find the new command(s) in the code analysis layer. - - // AddSuppressionsCommandHandlers(menuCommandService); - } - } - - private void AddErrorListSetSeverityMenuHandlers(IMenuCommandService menuCommandService) - { - Contract.ThrowIfFalse(_threadingContext.HasMainThread); - - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeveritySubMenu, delegate { }, OnErrorListSetSeveritySubMenuStatus); - - // Severity menu items - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeverityDefault, SetSeverityHandler, delegate { }); - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeverityError, SetSeverityHandler, delegate { }); - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeverityWarning, SetSeverityHandler, delegate { }); - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeverityInfo, SetSeverityHandler, delegate { }); - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeverityHidden, SetSeverityHandler, delegate { }); - AddCommand(menuCommandService, ID.RoslynCommands.ErrorListSetSeverityNone, SetSeverityHandler, delegate { }); } /// @@ -155,41 +122,6 @@ private void OnAddSuppressionsInSuppressionFile(object sender, EventArgs e) private void OnRemoveSuppressions(object sender, EventArgs e) => _suppressionFixService.RemoveSuppressions(selectedErrorListEntriesOnly: true, projectHierarchy: null); - private void OnErrorListSetSeveritySubMenuStatus(object sender, EventArgs e) - { - // For now, we only enable the Set severity menu when a single configurable diagnostic is selected in the error list - // and we can update/create an editorconfig file for the configuration entry. - // In future, we can enable support for configuring in presence of multi-selection. - var command = (MenuCommand)sender; - var selectedEntry = TryGetSingleSelectedEntry(); - command.Visible = selectedEntry != null && - !SuppressionHelpers.IsNotConfigurableDiagnostic(selectedEntry) && - TryGetPathToAnalyzerConfigDoc(selectedEntry, out _, out _); - command.Enabled = command.Visible && !KnownUIContexts.SolutionBuildingContext.IsActive; - } - - private void SetSeverityHandler(object sender, EventArgs args) - { - var selectedItem = (MenuCommand)sender; - var reportDiagnostic = TryMapSelectedItemToReportDiagnostic(selectedItem); - if (reportDiagnostic == null) - { - return; - } - - var selectedDiagnostic = TryGetSingleSelectedEntry(); - if (selectedDiagnostic == null) - { - return; - } - - if (TryGetPathToAnalyzerConfigDoc(selectedDiagnostic, out var project, out _)) - { - // Fire and forget. - _ = SetSeverityHandlerAsync(reportDiagnostic.Value, selectedDiagnostic, project); - } - } - private async Task SetSeverityHandlerAsync(ReportDiagnostic reportDiagnostic, DiagnosticData selectedDiagnostic, Project project) { try @@ -234,34 +166,10 @@ async System.Threading.Tasks.Task ConfigureSeverityAsync(CancellationT } } - private static DiagnosticData? TryGetSingleSelectedEntry() - { - return null; - } - private bool TryGetPathToAnalyzerConfigDoc(DiagnosticData selectedDiagnostic, [NotNullWhen(true)] out Project? project, [NotNullWhen(true)] out string? pathToAnalyzerConfigDoc) { project = _workspace.CurrentSolution.GetProject(selectedDiagnostic.ProjectId); pathToAnalyzerConfigDoc = project?.TryGetAnalyzerConfigPathForProjectConfiguration(); return pathToAnalyzerConfigDoc is not null; } - - private static ReportDiagnostic? TryMapSelectedItemToReportDiagnostic(MenuCommand selectedItem) - { - if (selectedItem.CommandID.Guid == Guids.RoslynGroupId) - { - return selectedItem.CommandID.ID switch - { - ID.RoslynCommands.ErrorListSetSeverityDefault => ReportDiagnostic.Default, - ID.RoslynCommands.ErrorListSetSeverityError => ReportDiagnostic.Error, - ID.RoslynCommands.ErrorListSetSeverityWarning => ReportDiagnostic.Warn, - ID.RoslynCommands.ErrorListSetSeverityInfo => ReportDiagnostic.Info, - ID.RoslynCommands.ErrorListSetSeverityHidden => ReportDiagnostic.Hidden, - ID.RoslynCommands.ErrorListSetSeverityNone => ReportDiagnostic.Suppress, - _ => (ReportDiagnostic?)null - }; - } - - return null; - } } From a6fa0b8c9b21e4e298ce5f2047fe7fa72d5c00b4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:36:11 -0700 Subject: [PATCH 29/59] Remove more unused code --- ...StudioDiagnosticListTableCommandHandler.cs | 59 ------------------- 1 file changed, 59 deletions(-) diff --git a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs index d5fb85a789cd9..853d69a7b3c7b 100644 --- a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs +++ b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs @@ -70,58 +70,6 @@ public async Task InitializeAsync(IAsyncServiceProvider serviceProvider) _tableControl = errorList?.TableControl; } - /// - /// Add a command handler and status query handler for a menu item - /// - private static OleMenuCommand AddCommand( - IMenuCommandService menuCommandService, - int commandId, - EventHandler invokeHandler, - EventHandler beforeQueryStatus) - { - var commandIdWithGroupId = new CommandID(Guids.RoslynGroupId, commandId); - var command = new OleMenuCommand(invokeHandler, delegate { }, beforeQueryStatus, commandIdWithGroupId); - menuCommandService.AddCommand(command); - return command; - } - - private void OnAddSuppressionsStatus(object sender, EventArgs e) - { - var command = (MenuCommand)sender; - command.Visible = _suppressionStateService.CanSuppressSelectedEntries; - command.Enabled = command.Visible && !KnownUIContexts.SolutionBuildingContext.IsActive; - } - - private void OnRemoveSuppressionsStatus(object sender, EventArgs e) - { - var command = (MenuCommand)sender; - command.Visible = _suppressionStateService.CanRemoveSuppressionsSelectedEntries; - command.Enabled = command.Visible && !KnownUIContexts.SolutionBuildingContext.IsActive; - } - - private void OnAddSuppressionsInSourceStatus(object sender, EventArgs e) - { - var command = (MenuCommand)sender; - command.Visible = _suppressionStateService.CanSuppressSelectedEntriesInSource; - command.Enabled = command.Visible && !KnownUIContexts.SolutionBuildingContext.IsActive; - } - - private void OnAddSuppressionsInSuppressionFileStatus(object sender, EventArgs e) - { - var command = (MenuCommand)sender; - command.Visible = _suppressionStateService.CanSuppressSelectedEntriesInSuppressionFiles; - command.Enabled = command.Visible && !KnownUIContexts.SolutionBuildingContext.IsActive; - } - - private void OnAddSuppressionsInSource(object sender, EventArgs e) - => _suppressionFixService.AddSuppressions(selectedErrorListEntriesOnly: true, suppressInSource: true, projectHierarchy: null); - - private void OnAddSuppressionsInSuppressionFile(object sender, EventArgs e) - => _suppressionFixService.AddSuppressions(selectedErrorListEntriesOnly: true, suppressInSource: false, projectHierarchy: null); - - private void OnRemoveSuppressions(object sender, EventArgs e) - => _suppressionFixService.RemoveSuppressions(selectedErrorListEntriesOnly: true, projectHierarchy: null); - private async Task SetSeverityHandlerAsync(ReportDiagnostic reportDiagnostic, DiagnosticData selectedDiagnostic, Project project) { try @@ -165,11 +113,4 @@ async System.Threading.Tasks.Task ConfigureSeverityAsync(CancellationT return await ConfigurationUpdater.ConfigureSeverityAsync(reportDiagnostic, diagnostic, project, cancellationToken).ConfigureAwait(false); } } - - private bool TryGetPathToAnalyzerConfigDoc(DiagnosticData selectedDiagnostic, [NotNullWhen(true)] out Project? project, [NotNullWhen(true)] out string? pathToAnalyzerConfigDoc) - { - project = _workspace.CurrentSolution.GetProject(selectedDiagnostic.ProjectId); - pathToAnalyzerConfigDoc = project?.TryGetAnalyzerConfigPathForProjectConfiguration(); - return pathToAnalyzerConfigDoc is not null; - } } From 6f6824c69345040e8ad4a6d8920aa123506410ea Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:50:28 -0700 Subject: [PATCH 30/59] Remove uncalled method --- ...StudioDiagnosticListTableCommandHandler.cs | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs index 853d69a7b3c7b..40f4381256c18 100644 --- a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs +++ b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs @@ -69,48 +69,4 @@ public async Task InitializeAsync(IAsyncServiceProvider serviceProvider) var errorList = await serviceProvider.GetServiceAsync(_threadingContext.JoinableTaskFactory, throwOnFailure: false).ConfigureAwait(false); _tableControl = errorList?.TableControl; } - - private async Task SetSeverityHandlerAsync(ReportDiagnostic reportDiagnostic, DiagnosticData selectedDiagnostic, Project project) - { - try - { - using var token = _listener.BeginAsyncOperation(nameof(SetSeverityHandlerAsync)); - using var context = _uiThreadOperationExecutor.BeginExecute( - title: ServicesVSResources.Updating_severity, - defaultDescription: ServicesVSResources.Updating_severity, - allowCancellation: true, - showProgress: true); - - var newSolution = await ConfigureSeverityAsync(context.UserCancellationToken).ConfigureAwait(false); - var operations = ImmutableArray.Create(new ApplyChangesOperation(newSolution)); - using var scope = context.AddScope(allowCancellation: true, ServicesVSResources.Updating_severity); - await _editHandlerService.ApplyAsync( - _workspace, - project.Solution, - fromDocument: null, - operations, - title: ServicesVSResources.Updating_severity, - scope.GetCodeAnalysisProgress(), - context.UserCancellationToken).ConfigureAwait(false); - - // Kick off diagnostic re-analysis for affected document so that the configured diagnostic gets refreshed. - if (selectedDiagnostic.DocumentId != null) - _diagnosticService.RequestDiagnosticRefresh(); - } - catch (OperationCanceledException) - { - } - catch (Exception ex) when (FatalError.ReportAndCatch(ex)) - { - } - - return; - - // Local functions. - async System.Threading.Tasks.Task ConfigureSeverityAsync(CancellationToken cancellationToken) - { - var diagnostic = await selectedDiagnostic.ToDiagnosticAsync(project, cancellationToken).ConfigureAwait(false); - return await ConfigurationUpdater.ConfigureSeverityAsync(reportDiagnostic, diagnostic, project, cancellationToken).ConfigureAwait(false); - } - } } From a1cb67cea27ce0a53ab978a657f25fa051893117 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jul 2024 13:52:12 -0700 Subject: [PATCH 31/59] remove type that now serves no purpose --- src/VisualStudio/Core/Def/RoslynPackage.cs | 2 - ...StudioDiagnosticListTableCommandHandler.cs | 72 ------------------- 2 files changed, 74 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 8dfd128dd3e99..1ec2bec5601c6 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.Common; using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.AsyncCompletion; -using Microsoft.CodeAnalysis.Editor.QuickInfo; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Notification; @@ -228,7 +227,6 @@ protected override async Task LoadComponentsAsync(CancellationToken cancellation // we need to load it as early as possible since we can have errors from // package from each language very early await this.ComponentModel.GetService().InitializeAsync(this).ConfigureAwait(false); - await this.ComponentModel.GetService().InitializeAsync(this).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); diff --git a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs b/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs deleted file mode 100644 index 40f4381256c18..0000000000000 --- a/src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioDiagnosticListTableCommandHandler.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Immutable; -using System.ComponentModel.Composition; -using System.ComponentModel.Design; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeFixes.Configuration; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Progress; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.VisualStudio.LanguageServices.Implementation.Suppression; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Shell.TableControl; -using Microsoft.VisualStudio.Utilities; -using Task = System.Threading.Tasks.Task; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource; - -[Export(typeof(VisualStudioDiagnosticListTableCommandHandler))] -internal partial class VisualStudioDiagnosticListTableCommandHandler -{ - private readonly IThreadingContext _threadingContext; - private readonly VisualStudioWorkspace _workspace; - private readonly VisualStudioSuppressionFixService _suppressionFixService; - private readonly VisualStudioDiagnosticListSuppressionStateService _suppressionStateService; - private readonly IUIThreadOperationExecutor _uiThreadOperationExecutor; - private readonly IDiagnosticAnalyzerService _diagnosticService; - private readonly ICodeActionEditHandlerService _editHandlerService; - private readonly IAsynchronousOperationListener _listener; - - private IWpfTableControl? _tableControl; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public VisualStudioDiagnosticListTableCommandHandler( - IThreadingContext threadingContext, - SVsServiceProvider serviceProvider, - VisualStudioWorkspace workspace, - IVisualStudioSuppressionFixService suppressionFixService, - VisualStudioDiagnosticListSuppressionStateService suppressionStateService, - IUIThreadOperationExecutor uiThreadOperationExecutor, - IDiagnosticAnalyzerService diagnosticService, - ICodeActionEditHandlerService editHandlerService, - IAsynchronousOperationListenerProvider listenerProvider) - { - _threadingContext = threadingContext; - _workspace = workspace; - _suppressionFixService = (VisualStudioSuppressionFixService)suppressionFixService; - _suppressionStateService = suppressionStateService; - _uiThreadOperationExecutor = uiThreadOperationExecutor; - _diagnosticService = diagnosticService; - _editHandlerService = editHandlerService; - _listener = listenerProvider.GetListener(FeatureAttribute.ErrorList); - } - - public async Task InitializeAsync(IAsyncServiceProvider serviceProvider) - { - var errorList = await serviceProvider.GetServiceAsync(_threadingContext.JoinableTaskFactory, throwOnFailure: false).ConfigureAwait(false); - _tableControl = errorList?.TableControl; - } -} From 6e8362020c82c1235653d61acfe54ecf0b66550c Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Fri, 5 Jul 2024 07:57:40 -0700 Subject: [PATCH 32/59] Reduce allocations in SymbolDeclaredCompilationEvent (#74250) * Reduce allocations in SymbolDeclaredCompilationEvent The SymbolDeclaredCompilationEvent ctor is showing up as 0.5% of allocations in vbcscompiler.exe in a customer profile I'm looking at. All these costs are attributable to the use of Lazy in this class. Instead, just use a nullable field, and accept the fact that during extremely high contention, it is possible for an ImmutableArray to be created multiple times. --- .../SymbolDeclaredCompilationEvent.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/SymbolDeclaredCompilationEvent.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/SymbolDeclaredCompilationEvent.cs index f03018973710f..381f4f62f51ff 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/SymbolDeclaredCompilationEvent.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/SymbolDeclaredCompilationEvent.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis.Symbols; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics { @@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics /// internal sealed class SymbolDeclaredCompilationEvent : CompilationEvent { - private readonly Lazy> _lazyCachedDeclaringReferences; + private ImmutableArray _lazyCachedDeclaringReferences; public SymbolDeclaredCompilationEvent( Compilation compilation, @@ -25,7 +25,7 @@ public SymbolDeclaredCompilationEvent( { SymbolInternal = symbolInternal; SemanticModelWithCachedBoundNodes = semanticModelWithCachedBoundNodes; - _lazyCachedDeclaringReferences = new Lazy>(() => Symbol.DeclaringSyntaxReferences); + _lazyCachedDeclaringReferences = default(ImmutableArray); } public ISymbol Symbol => SymbolInternal.GetISymbol(); @@ -35,7 +35,16 @@ public SymbolDeclaredCompilationEvent( public SemanticModel? SemanticModelWithCachedBoundNodes { get; } // PERF: We avoid allocations in re-computing syntax references for declared symbol during event processing by caching them directly on this member. - public ImmutableArray DeclaringSyntaxReferences => _lazyCachedDeclaringReferences.Value; + public ImmutableArray DeclaringSyntaxReferences + { + get + { + return InterlockedOperations.Initialize( + ref _lazyCachedDeclaringReferences, + static self => self.Symbol.DeclaringSyntaxReferences, + this); + } + } public override string ToString() { From 4dbedf6dfabc2d2c13496ded946f3e61f3d8de7e Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Fri, 5 Jul 2024 07:59:37 -0700 Subject: [PATCH 33/59] Reduce closures allocated during invocation of CapturedSymbolReplacement.Replacement (#74258) * Reduce closures allocated during invocation of CapturedSymbolReplacement.Replacement This method previously took in a Func and most callers allocated a closure to implement the callback. This PR uses the args pattern and adds a parameter to the Replacement method that is passed back into that callback to better allow static lambdas to be used. This was the top allocating closure allocation in vbcscompiler in a customer profile I'm looking at (0.2% -- 42 MB) --- .../ClosureConversion/ClosureConversion.cs | 11 ++++-- .../Lowering/MethodToClassRewriter.cs | 6 +++- .../StateMachineRewriter/CapturedSymbol.cs | 12 +++---- .../MethodToStateMachineRewriter.cs | 8 ++--- .../StateMachineRewriter.cs | 35 ++++++++++++++----- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.cs b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.cs index 800a97a466638..01e209bb2bb5b 100644 --- a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.cs +++ b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.cs @@ -622,7 +622,10 @@ protected override BoundExpression FramePointer(SyntaxNode syntax, NamedTypeSymb // However, frame pointer local variables themselves can be "captured". In that case // the inner frames contain pointers to the enclosing frames. That is, nested // frame pointers are organized in a linked list. - return proxyField.Replacement(syntax, frameType => FramePointer(syntax, frameType)); + return proxyField.Replacement( + syntax, + static (frameType, arg) => arg.self.FramePointer(arg.syntax, frameType), + (syntax, self: this)); } var localFrame = (LocalSymbol)framePointer; @@ -777,7 +780,11 @@ private void InitVariableProxy(SyntaxNode syntax, Symbol symbol, LocalSymbol fra throw ExceptionUtilities.UnexpectedValue(symbol.Kind); } - var left = proxy.Replacement(syntax, frameType1 => new BoundLocal(syntax, framePointer, null, framePointer.Type)); + var left = proxy.Replacement( + syntax, + static (frameType1, arg) => new BoundLocal(arg.syntax, arg.framePointer, null, arg.framePointer.Type), + (syntax, framePointer)); + var assignToProxy = new BoundAssignmentOperator(syntax, left, value, value.Type); if (_currentMethod.MethodKind == MethodKind.Constructor && symbol == _currentMethod.ThisParameter && diff --git a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs index 49236fa2a3a89..fbc1881b5924f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs @@ -369,7 +369,11 @@ private bool TryReplaceWithProxy(Symbol parameterOrLocal, SyntaxNode syntax, [No { if (proxies.TryGetValue(parameterOrLocal, out CapturedSymbolReplacement? proxy)) { - replacement = proxy.Replacement(syntax, frameType => FramePointer(syntax, frameType)); + replacement = proxy.Replacement( + syntax, + static (frameType, arg) => arg.self.FramePointer(arg.syntax, frameType), + (syntax, self: this)); + return true; } diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/CapturedSymbol.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/CapturedSymbol.cs index 08ddeca6b61a9..a78955a399c9c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/CapturedSymbol.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/CapturedSymbol.cs @@ -23,7 +23,7 @@ public CapturedSymbolReplacement(bool isReusable) /// Rewrite the replacement expression for the hoisted local so all synthesized field are accessed as members /// of the appropriate frame. /// - public abstract BoundExpression Replacement(SyntaxNode node, Func makeFrame); + public abstract BoundExpression Replacement(SyntaxNode node, Func makeFrame, TArg arg); } internal sealed class CapturedToFrameSymbolReplacement : CapturedSymbolReplacement @@ -36,9 +36,9 @@ public CapturedToFrameSymbolReplacement(LambdaCapturedVariable hoistedField, boo this.HoistedField = hoistedField; } - public override BoundExpression Replacement(SyntaxNode node, Func makeFrame) + public override BoundExpression Replacement(SyntaxNode node, Func makeFrame, TArg arg) { - var frame = makeFrame(this.HoistedField.ContainingType); + var frame = makeFrame(this.HoistedField.ContainingType, arg); var field = this.HoistedField.AsMember((NamedTypeSymbol)frame.Type); return new BoundFieldAccess(node, frame, field, constantValueOpt: null); } @@ -54,9 +54,9 @@ public CapturedToStateMachineFieldReplacement(StateMachineFieldSymbol hoistedFie this.HoistedField = hoistedField; } - public override BoundExpression Replacement(SyntaxNode node, Func makeFrame) + public override BoundExpression Replacement(SyntaxNode node, Func makeFrame, TArg arg) { - var frame = makeFrame(this.HoistedField.ContainingType); + var frame = makeFrame(this.HoistedField.ContainingType, arg); var field = this.HoistedField.AsMember((NamedTypeSymbol)frame.Type); return new BoundFieldAccess(node, frame, field, constantValueOpt: null); } @@ -74,7 +74,7 @@ public CapturedToExpressionSymbolReplacement(BoundExpression replacement, Immuta this.HoistedFields = hoistedFields; } - public override BoundExpression Replacement(SyntaxNode node, Func makeFrame) + public override BoundExpression Replacement(SyntaxNode node, Func makeFrame, TArg arg) { // By returning the same replacement each time, it is possible we // are constructing a DAG instead of a tree for the translation. diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 25bb0a30587e4..673a6c968cb4c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -140,7 +140,7 @@ public MethodToStateMachineRewriter( proxies.TryGetValue(thisParameter, out thisProxy) && F.Compilation.Options.OptimizationLevel == OptimizationLevel.Release) { - BoundExpression thisProxyReplacement = thisProxy.Replacement(F.Syntax, frameType => F.This()); + BoundExpression thisProxyReplacement = thisProxy.Replacement(F.Syntax, static (frameType, F) => F.This(), F); Debug.Assert(thisProxyReplacement.Type is not null); this.cachedThis = F.SynthesizedLocal(thisProxyReplacement.Type, syntax: F.Syntax, kind: SynthesizedLocalKind.FrameCache); } @@ -925,7 +925,7 @@ protected BoundStatement CacheThisIfNeeded() if ((object)this.cachedThis != null) { CapturedSymbolReplacement proxy = proxies[this.OriginalMethod.ThisParameter]; - var fetchThis = proxy.Replacement(F.Syntax, frameType => F.This()); + var fetchThis = proxy.Replacement(F.Syntax, static (frameType, F) => F.This(), F); return F.Assignment(F.Local(this.cachedThis), fetchThis); } @@ -961,7 +961,7 @@ public sealed override BoundNode VisitThisReference(BoundThisReference node) else { Debug.Assert(proxy != null); - return proxy.Replacement(F.Syntax, frameType => F.This()); + return proxy.Replacement(F.Syntax, static (frameType, F) => F.This(), F); } } @@ -977,7 +977,7 @@ public override BoundNode VisitBaseReference(BoundBaseReference node) CapturedSymbolReplacement proxy = proxies[this.OriginalMethod.ThisParameter]; Debug.Assert(proxy != null); - return proxy.Replacement(F.Syntax, frameType => F.This()); + return proxy.Replacement(F.Syntax, static (frameType, F) => F.This(), F); } #endregion diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs index ef2ad4236dbb8..4720e12ee1dfb 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs @@ -311,7 +311,12 @@ protected BoundStatement GenerateParameterStorage(LocalSymbol stateMachineVariab CapturedSymbolReplacement proxy; if (proxies.TryGetValue(method.ThisParameter, out proxy)) { - bodyBuilder.Add(F.Assignment(proxy.Replacement(F.Syntax, frameType1 => F.Local(stateMachineVariable)), F.This())); + var leftExpression = proxy.Replacement( + F.Syntax, + static (frameType1, arg) => arg.F.Local(arg.stateMachineVariable), + (F, stateMachineVariable)); + + bodyBuilder.Add(F.Assignment(leftExpression, F.This())); } } @@ -320,8 +325,12 @@ protected BoundStatement GenerateParameterStorage(LocalSymbol stateMachineVariab CapturedSymbolReplacement proxy; if (proxies.TryGetValue(parameter, out proxy)) { - bodyBuilder.Add(F.Assignment(proxy.Replacement(F.Syntax, frameType1 => F.Local(stateMachineVariable)), - F.Parameter(parameter))); + var leftExpression = proxy.Replacement( + F.Syntax, + static (frameType1, arg) => arg.F.Local(arg.stateMachineVariable), + (F, stateMachineVariable)); + + bodyBuilder.Add(F.Assignment(leftExpression, F.Parameter(parameter))); } } @@ -456,10 +465,14 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy CapturedSymbolReplacement proxy; if (copyDest.TryGetValue(method.ThisParameter, out proxy)) { - bodyBuilder.Add( - F.Assignment( - proxy.Replacement(F.Syntax, stateMachineType => F.Local(resultVariable)), - copySrc[method.ThisParameter].Replacement(F.Syntax, stateMachineType => F.This()))); + var leftExpression = proxy.Replacement( + F.Syntax, + static (stateMachineType, arg) => arg.F.Local(arg.resultVariable), + (F, resultVariable)); + + var rightExpression = copySrc[method.ThisParameter].Replacement(F.Syntax, static (stateMachineType, F) => F.This(), F); + + bodyBuilder.Add(F.Assignment(leftExpression, rightExpression)); } } @@ -471,9 +484,13 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy if (copyDest.TryGetValue(parameter, out proxy)) { // result.parameter - BoundExpression resultParameter = proxy.Replacement(F.Syntax, stateMachineType => F.Local(resultVariable)); + BoundExpression resultParameter = proxy.Replacement( + F.Syntax, + static (stateMachineType, arg) => arg.F.Local(arg.resultVariable), + (F, resultVariable)); + // this.parameterProxy - BoundExpression parameterProxy = copySrc[parameter].Replacement(F.Syntax, stateMachineType => F.This()); + BoundExpression parameterProxy = copySrc[parameter].Replacement(F.Syntax, static (stateMachineType, F) => F.This(), F); BoundStatement copy = InitializeParameterField(getEnumeratorMethod, parameter, resultParameter, parameterProxy); bodyBuilder.Add(copy); From e6fcbcd32ff2703d82ad04a8ba63dcff69414435 Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Thu, 27 Jun 2024 14:42:05 -0700 Subject: [PATCH 34/59] Fix scenario where lightbulbs weren't being displayed Addresses https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2087100 The recent change to remove solution crawler has apparently caused some regressions in lightbulb functionality and performance. This PR attempts to address at least one functional issue introduced as part of that change. Previously, during solution load, solution crawler would cause the analyzer state sets to update via IncrementalAnalyzerProcessor.LowPriorityProcessor.ProcessProjectAsync's call to DiagnosticIncrementalAnalyzer.AnalyzeProjectAsync. Similarly, document updates would update the analyzer states the crawler's idle processing. Instead of trying to hook back in these calls, this PR instead changes the diagnostic analyzer service to no longer offer a TryGetDiagnosticsForSpanAsync, instead forcing users to use the GetDiagnosticsForSpanAsync instead. The only caller of TryGetDiagnosticsForSpanAsync was inside the CodeFixService, and it seems like that code should just go ahead and force correct results. Thus, there is no concept of a non-upToDate call into the diagnostic service. I'm going to separately investigate an issue with the StateManager's statesets not getting updated. I'm unsure why the code doesn't update the statesets upon calculation, but the fact that we are now recreating this on every lightbulb request is at least partly responsible for the recent lightbulb perf regression. --- .../Suggestions/SuggestedActionsSource.cs | 7 +- .../Diagnostics/DiagnosticServiceTests.vb | 56 -------------- .../MockDiagnosticAnalyzerService.cs | 3 - .../Core/Portable/CodeFixes/FirstFixResult.cs | 16 ---- .../Diagnostics/IDiagnosticAnalyzerService.cs | 20 ----- .../Features/CodeFixes/CodeFixService.cs | 9 +-- .../Features/CodeFixes/ICodeFixService.cs | 2 +- .../Diagnostics/DiagnosticAnalyzerService.cs | 29 +------- ...crementalAnalyzer_GetDiagnosticsForSpan.cs | 74 +++++-------------- .../ExternalDiagnosticUpdateSourceTests.vb | 4 - 10 files changed, 29 insertions(+), 191 deletions(-) delete mode 100644 src/Features/Core/Portable/CodeFixes/FirstFixResult.cs diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs index be9ddb850fc69..1989841dea054 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs @@ -256,10 +256,10 @@ private void OnTextViewClosed(object sender, EventArgs e) var result = await state.Target.Owner._codeFixService.GetMostSevereFixAsync( document, range.Span.ToTextSpan(), priorityProvider, fallbackOptions, cancellationToken).ConfigureAwait(false); - if (result.HasFix) + if (result != null) { Logger.Log(FunctionId.SuggestedActions_HasSuggestedActionsAsync); - return result.CodeFixCollection.FirstDiagnostic.Severity switch + return result.FirstDiagnostic.Severity switch { DiagnosticSeverity.Hidden or DiagnosticSeverity.Info or DiagnosticSeverity.Warning => PredefinedSuggestedActionCategoryNames.CodeFix, @@ -267,9 +267,6 @@ private void OnTextViewClosed(object sender, EventArgs e) _ => throw ExceptionUtilities.Unreachable(), }; } - - if (!result.UpToDate) - return null; } return null; diff --git a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb index d6722a2eee3cf..40ec9b0766318 100644 --- a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb +++ b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb @@ -2241,62 +2241,6 @@ class C End Using End Function - - - - - Friend Async Function TestTryAppendDiagnosticsForSpanAsync(category As DiagnosticAnalyzerCategory, isSpanBasedAnalyzer As Boolean) As Task - Dim test = - - - - - - - Using workspace = TestWorkspace.CreateWorkspace(test, composition:=s_compositionWithMockDiagnosticUpdateSourceRegistrationService) - Dim solution = workspace.CurrentSolution - Dim project = solution.Projects.Single() - - ' Add analyzer - Dim analyzer = New AnalyzerWithCustomDiagnosticCategory(category) - Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)) - project = project.AddAnalyzerReference(analyzerReference) - Assert.False(analyzer.ReceivedOperationCallback) - - ' Get span to analyze - Dim document = project.Documents.Single() - Dim root = Await document.GetSyntaxRootAsync(CancellationToken.None) - Dim localDecl = root.DescendantNodes().OfType(Of CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax).Single() - Dim span = localDecl.Span - - Dim mefExportProvider = DirectCast(workspace.Services.HostServices, IMefHostExportProvider) - Dim diagnosticService = Assert.IsType(Of DiagnosticAnalyzerService)(workspace.GetService(Of IDiagnosticAnalyzerService)()) - Dim incrementalAnalyzer = diagnosticService.CreateIncrementalAnalyzer(workspace) - - ' Verify available diagnostic descriptors - Dim descriptorsMap = solution.SolutionState.Analyzers.GetDiagnosticDescriptorsPerReference(diagnosticService.AnalyzerInfoCache, project) - Assert.Equal(1, descriptorsMap.Count) - Dim descriptors = descriptorsMap.First().Value - Assert.Equal(1, descriptors.Length) - Assert.Equal(analyzer.Descriptor.Id, descriptors.Single().Id) - - ' Try get diagnostics for span - Await diagnosticService.TryGetDiagnosticsForSpanAsync(document, span, shouldIncludeDiagnostic:=Nothing, includeSuppressedDiagnostics:=False, - priorityProvider:=New DefaultCodeActionRequestPriorityProvider(), - DiagnosticKind.All, isExplicit:=False, CancellationToken.None) - - ' Verify only existing cached diagnostics are returned with TryAppendDiagnosticsForSpanAsync, with no analyzer callbacks being made. - Assert.False(analyzer.ReceivedOperationCallback) - End Using - End Function - Friend Async Function TestGetDiagnosticsForDiagnosticKindAsync(diagnosticKind As DiagnosticKind) As Task diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/MockDiagnosticAnalyzerService.cs b/src/EditorFeatures/TestUtilities/Diagnostics/MockDiagnosticAnalyzerService.cs index 9074ca7ea1ec6..1d58ca00a5b09 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/MockDiagnosticAnalyzerService.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/MockDiagnosticAnalyzerService.cs @@ -69,8 +69,5 @@ public Task> GetDiagnosticsForSpanAsync(TextDocum public Task> GetProjectDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId, ImmutableHashSet? diagnosticIds, Func? shouldIncludeAnalyzer, bool includeSuppressedDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken) => throw new NotImplementedException(); - - public Task<(ImmutableArray diagnostics, bool upToDate)> TryGetDiagnosticsForSpanAsync(TextDocument document, TextSpan range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics, ICodeActionRequestPriorityProvider priorityProvider, DiagnosticKind diagnosticKind, bool isExplicit, CancellationToken cancellationToken) - => throw new NotImplementedException(); } } diff --git a/src/Features/Core/Portable/CodeFixes/FirstFixResult.cs b/src/Features/Core/Portable/CodeFixes/FirstFixResult.cs deleted file mode 100644 index 19f4fd158539f..0000000000000 --- a/src/Features/Core/Portable/CodeFixes/FirstFixResult.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics.CodeAnalysis; - -namespace Microsoft.CodeAnalysis.CodeFixes; - -internal readonly struct FirstFixResult(bool upToDate, CodeFixCollection? codeFixCollection) -{ - public readonly bool UpToDate = upToDate; - public readonly CodeFixCollection? CodeFixCollection = codeFixCollection; - - [MemberNotNullWhen(true, nameof(CodeFixCollection))] - public bool HasFix => CodeFixCollection != null; -} diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index 1321defaaf945..04ffcf80cab7a 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -97,26 +97,6 @@ internal interface IDiagnosticAnalyzerService /// Cancellation token. Task> GetProjectDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId, ImmutableHashSet? diagnosticIds, Func? shouldIncludeAnalyzer, bool includeSuppressedDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken); - /// - /// Try to return up to date diagnostics for the given span for the document. - /// - /// It will return true if it was able to return all up-to-date diagnostics. - /// otherwise, false indicating there are some missing diagnostics in the diagnostic list - /// - /// This API will only force complete analyzers that support span based analysis, i.e. compiler analyzer and - /// s that support . - /// For the rest of the analyzers, it will only return diagnostics if the analyzer has already been executed. - /// Use - /// if you want to force complete all analyzers and get up-to-date diagnostics for all analyzers for the given span. - /// - Task<(ImmutableArray diagnostics, bool upToDate)> TryGetDiagnosticsForSpanAsync( - TextDocument document, TextSpan range, Func? shouldIncludeDiagnostic, - bool includeSuppressedDiagnostics, - ICodeActionRequestPriorityProvider priorityProvider, - DiagnosticKind diagnosticKind, - bool isExplicit, - CancellationToken cancellationToken); - /// /// Return up to date diagnostics for the given span for the document /// diff --git a/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index f2f65827afd44..25f6545fb0441 100644 --- a/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -98,19 +98,18 @@ public CodeFixService( }; } - public async Task GetMostSevereFixAsync( + public async Task GetMostSevereFixAsync( TextDocument document, TextSpan range, ICodeActionRequestPriorityProvider priorityProvider, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using var _ = TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetMostSevereFixAsync)}"); ImmutableArray allDiagnostics; - bool upToDate; using (TelemetryLogging.LogBlockTimeAggregated(FunctionId.CodeFix_Summary, $"Pri{priorityProvider.Priority.GetPriorityInt()}.{nameof(GetMostSevereFixAsync)}.{nameof(_diagnosticService.GetDiagnosticsForSpanAsync)}")) { - (allDiagnostics, upToDate) = await _diagnosticService.TryGetDiagnosticsForSpanAsync( + allDiagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( document, range, GetShouldIncludeDiagnosticPredicate(document, priorityProvider), - includeSuppressedDiagnostics: false, priorityProvider, DiagnosticKind.All, isExplicit: false, cancellationToken).ConfigureAwait(false); + includeCompilerDiagnostics: true, includeSuppressedDiagnostics: false, priorityProvider, DiagnosticKind.All, isExplicit: false, cancellationToken).ConfigureAwait(false); } var copilotDiagnostics = await GetCopilotDiagnosticsAsync(document, range, priorityProvider.Priority, cancellationToken).ConfigureAwait(false); @@ -146,7 +145,7 @@ public async Task GetMostSevereFixAsync( await otherFixTask.ConfigureAwait(false); linkedTokenSource.Cancel(); - return new FirstFixResult(upToDate, collection); + return collection; async Task GetFirstFixAsync( SortedDictionary> spanToDiagnostics, diff --git a/src/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs b/src/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs index c1f71e6dcab82..30bbcb2d73e8b 100644 --- a/src/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs +++ b/src/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs @@ -22,7 +22,7 @@ internal interface ICodeFixService /// first. This will also attempt to return a fix for an error first, but will fall back to any fix if that /// does not succeed. /// - Task GetMostSevereFixAsync(TextDocument document, TextSpan range, ICodeActionRequestPriorityProvider priorityProvider, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task GetMostSevereFixAsync(TextDocument document, TextSpan range, ICodeActionRequestPriorityProvider priorityProvider, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); Task GetDocumentFixAllForIdInSpanAsync(TextDocument document, TextSpan textSpan, string diagnosticId, DiagnosticSeverity severity, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); Task ApplyCodeFixesForSpecificDiagnosticIdAsync(TDocument document, string diagnosticId, DiagnosticSeverity severity, IProgress progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs b/src/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs index b850e46ce9367..78a7e4266c53b 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs @@ -69,30 +69,6 @@ public static bool IsGlobalOptionAffectingDiagnostics(IOption2 option) public void RequestDiagnosticRefresh() => _diagnosticsRefresher?.RequestWorkspaceRefresh(); - public async Task<(ImmutableArray diagnostics, bool upToDate)> TryGetDiagnosticsForSpanAsync( - TextDocument document, - TextSpan range, - Func? shouldIncludeDiagnostic, - bool includeSuppressedDiagnostics, - ICodeActionRequestPriorityProvider priorityProvider, - DiagnosticKind diagnosticKinds, - bool isExplicit, - CancellationToken cancellationToken) - { - var analyzer = CreateIncrementalAnalyzer(document.Project.Solution.Workspace); - - // always make sure that analyzer is called on background thread. - await TaskScheduler.Default; - priorityProvider ??= new DefaultCodeActionRequestPriorityProvider(); - - using var _ = ArrayBuilder.GetInstance(out var diagnostics); - var upToDate = await analyzer.TryAppendDiagnosticsForSpanAsync( - document, range, diagnostics, shouldIncludeDiagnostic, - includeSuppressedDiagnostics, true, priorityProvider, blockForData: false, - diagnosticKinds, isExplicit, cancellationToken).ConfigureAwait(false); - return (diagnostics.ToImmutable(), upToDate); - } - public async Task> GetDiagnosticsForSpanAsync( TextDocument document, TextSpan? range, @@ -105,13 +81,14 @@ public async Task> GetDiagnosticsForSpanAsync( CancellationToken cancellationToken) { var analyzer = CreateIncrementalAnalyzer(document.Project.Solution.Workspace); - priorityProvider ??= new DefaultCodeActionRequestPriorityProvider(); // always make sure that analyzer is called on background thread. await TaskScheduler.Default; + priorityProvider ??= new DefaultCodeActionRequestPriorityProvider(); + return await analyzer.GetDiagnosticsForSpanAsync( document, range, shouldIncludeDiagnostic, includeSuppressedDiagnostics, includeCompilerDiagnostics, - priorityProvider, blockForData: true, diagnosticKinds, isExplicit, cancellationToken).ConfigureAwait(false); + priorityProvider, diagnosticKinds, isExplicit, cancellationToken).ConfigureAwait(false); } public Task> GetCachedDiagnosticsAsync(Workspace workspace, ProjectId? projectId, DocumentId? documentId, bool includeSuppressedDiagnostics, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken) diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs index 2b89fcb439082..9918f440a841d 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs @@ -23,17 +23,6 @@ namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2 { internal partial class DiagnosticIncrementalAnalyzer { - public async Task TryAppendDiagnosticsForSpanAsync( - TextDocument document, TextSpan? range, ArrayBuilder result, Func? shouldIncludeDiagnostic, - bool includeSuppressedDiagnostics, bool includeCompilerDiagnostics, ICodeActionRequestPriorityProvider priorityProvider, bool blockForData, - DiagnosticKind diagnosticKinds, bool isExplicit, CancellationToken cancellationToken) - { - var getter = await LatestDiagnosticsForSpanGetter.CreateAsync( - this, document, range, blockForData, includeSuppressedDiagnostics, includeCompilerDiagnostics, - priorityProvider, shouldIncludeDiagnostic, diagnosticKinds, isExplicit, cancellationToken).ConfigureAwait(false); - return await getter.TryGetAsync(result, cancellationToken).ConfigureAwait(false); - } - public async Task> GetDiagnosticsForSpanAsync( TextDocument document, TextSpan? range, @@ -41,16 +30,17 @@ public async Task> GetDiagnosticsForSpanAsync( bool includeSuppressedDiagnostics, bool includeCompilerDiagnostics, ICodeActionRequestPriorityProvider priorityProvider, - bool blockForData, DiagnosticKind diagnosticKinds, bool isExplicit, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var list); - var result = await TryAppendDiagnosticsForSpanAsync( - document, range, list, shouldIncludeDiagnostic, includeSuppressedDiagnostics, includeCompilerDiagnostics, - priorityProvider, blockForData, diagnosticKinds, isExplicit, cancellationToken).ConfigureAwait(false); - Debug.Assert(result); + + var getter = await LatestDiagnosticsForSpanGetter.CreateAsync( + this, document, range, includeSuppressedDiagnostics, includeCompilerDiagnostics, + priorityProvider, shouldIncludeDiagnostic, diagnosticKinds, isExplicit, cancellationToken).ConfigureAwait(false); + await getter.GetAsync(list, cancellationToken).ConfigureAwait(false); + return list.ToImmutableAndClear(); } @@ -72,7 +62,6 @@ private sealed class LatestDiagnosticsForSpanGetter private readonly CompilationWithAnalyzers? _compilationWithAnalyzers; private readonly TextSpan? _range; - private readonly bool _blockForData; private readonly bool _includeSuppressedDiagnostics; private readonly ICodeActionRequestPriorityProvider _priorityProvider; private readonly Func? _shouldIncludeDiagnostic; @@ -88,7 +77,6 @@ public static async Task CreateAsync( DiagnosticIncrementalAnalyzer owner, TextDocument document, TextSpan? range, - bool blockForData, bool includeSuppressedDiagnostics, bool includeCompilerDiagnostics, ICodeActionRequestPriorityProvider priorityProvider, @@ -111,8 +99,7 @@ public static async Task CreateAsync( range = null; // We log performance info when we are computing diagnostics for a span - // and also blocking for data, i.e. for lightbulb code path for "Ctrl + Dot" user command. - var logPerformanceInfo = range.HasValue && blockForData; + var logPerformanceInfo = range.HasValue; var compilationWithAnalyzers = await GetOrCreateCompilationWithAnalyzersAsync(document.Project, ideOptions, stateSets, includeSuppressedDiagnostics, cancellationToken).ConfigureAwait(false); // If we are computing full document diagnostics, we will attempt to perform incremental @@ -122,7 +109,7 @@ public static async Task CreateAsync( return new LatestDiagnosticsForSpanGetter( owner, compilationWithAnalyzers, document, text, stateSets, shouldIncludeDiagnostic, includeCompilerDiagnostics, - range, blockForData, includeSuppressedDiagnostics, priorityProvider, + range, includeSuppressedDiagnostics, priorityProvider, isExplicit, logPerformanceInfo, incrementalAnalysis, diagnosticKinds); } @@ -173,7 +160,6 @@ private LatestDiagnosticsForSpanGetter( Func? shouldIncludeDiagnostic, bool includeCompilerDiagnostics, TextSpan? range, - bool blockForData, bool includeSuppressedDiagnostics, ICodeActionRequestPriorityProvider priorityProvider, bool isExplicit, @@ -189,7 +175,6 @@ private LatestDiagnosticsForSpanGetter( _shouldIncludeDiagnostic = shouldIncludeDiagnostic; _includeCompilerDiagnostics = includeCompilerDiagnostics; _range = range; - _blockForData = blockForData; _includeSuppressedDiagnostics = includeSuppressedDiagnostics; _priorityProvider = priorityProvider; _isExplicit = isExplicit; @@ -198,12 +183,10 @@ private LatestDiagnosticsForSpanGetter( _diagnosticKind = diagnosticKind; } - public async Task TryGetAsync(ArrayBuilder list, CancellationToken cancellationToken) + public async Task GetAsync(ArrayBuilder list, CancellationToken cancellationToken) { try { - var containsFullResult = true; - // Try to get cached diagnostics, and also compute non-cached state sets that need diagnostic computation. using var _1 = ArrayBuilder.GetInstance(out var syntaxAnalyzers); @@ -254,16 +237,11 @@ public async Task TryGetAsync(ArrayBuilder list, Cancellat var existingData = state.GetAnalysisData(AnalysisKind.Semantic); if (!await TryAddCachedDocumentDiagnosticsAsync(stateSet.Analyzer, AnalysisKind.Semantic, existingData, list, cancellationToken).ConfigureAwait(false)) { - if (ShouldRunSemanticAnalysis(stateSet.Analyzer, _incrementalAnalysis, _blockForData, - semanticSpanBasedAnalyzers, semanticDocumentBasedAnalyzers, out var stateSets)) - { - stateSets.Add(new AnalyzerWithState(stateSet.Analyzer, state, existingData)); - } - else - { - Debug.Assert(!_blockForData); - containsFullResult = false; - } + var stateSets = GetSemanticAnalysisSelectedStates( + stateSet.Analyzer, _incrementalAnalysis, + semanticSpanBasedAnalyzers, semanticDocumentBasedAnalyzers); + + stateSets.Add(new AnalyzerWithState(stateSet.Analyzer, state, existingData)); } } } @@ -274,9 +252,7 @@ public async Task TryGetAsync(ArrayBuilder list, Cancellat await ComputeDocumentDiagnosticsAsync(semanticSpanBasedAnalyzers.ToImmutable(), AnalysisKind.Semantic, _range, list, _incrementalAnalysis, cancellationToken).ConfigureAwait(false); await ComputeDocumentDiagnosticsAsync(semanticDocumentBasedAnalyzers.ToImmutable(), AnalysisKind.Semantic, span: null, list, incrementalAnalysis: false, cancellationToken).ConfigureAwait(false); - // If we are blocked for data, then we should always have full result. - Debug.Assert(!_blockForData || containsFullResult); - return containsFullResult; + return; } catch (Exception e) when (FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken)) { @@ -317,38 +293,26 @@ static bool ShouldIncludeAnalyzer( return true; } - static bool ShouldRunSemanticAnalysis( + static ArrayBuilder GetSemanticAnalysisSelectedStates( DiagnosticAnalyzer analyzer, bool incrementalAnalysis, - bool blockForData, ArrayBuilder semanticSpanBasedAnalyzers, - ArrayBuilder semanticDocumentBasedAnalyzers, - [NotNullWhen(true)] out ArrayBuilder? selectedStateSets) + ArrayBuilder semanticDocumentBasedAnalyzers) { - // If the caller doesn't want us to force compute diagnostics, - // we don't run semantic analysis. - if (!blockForData) - { - selectedStateSets = null; - return false; - } - if (!incrementalAnalysis) { // For non-incremental analysis, we always attempt to compute all // analyzer diagnostics for the requested span. - selectedStateSets = semanticSpanBasedAnalyzers; + return semanticSpanBasedAnalyzers; } else { // We can perform incremental analysis only for analyzers that support // span-based semantic diagnostic analysis. - selectedStateSets = analyzer.SupportsSpanBasedSemanticDiagnosticAnalysis() + return analyzer.SupportsSpanBasedSemanticDiagnosticAnalysis() ? semanticSpanBasedAnalyzers : semanticDocumentBasedAnalyzers; } - - return true; } } diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index eb6f8d52ac77d..a0cd2d9fd0726 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -335,10 +335,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Public Function ForceAnalyzeProjectAsync(project As Project, cancellationToken As CancellationToken) As Task Implements IDiagnosticAnalyzerService.ForceAnalyzeProjectAsync Throw New NotImplementedException() End Function - - Public Function TryGetDiagnosticsForSpanAsync(document As TextDocument, range As TextSpan, shouldIncludeDiagnostic As Func(Of String, Boolean), includeSuppressedDiagnostics As Boolean, priority As ICodeActionRequestPriorityProvider, diagnosticKinds As DiagnosticKind, isExplicit As Boolean, cancellationToken As CancellationToken) As Task(Of (diagnostics As ImmutableArray(Of DiagnosticData), upToDate As Boolean)) Implements IDiagnosticAnalyzerService.TryGetDiagnosticsForSpanAsync - Return Task.FromResult((ImmutableArray(Of DiagnosticData).Empty, False)) - End Function End Class From 1874807a1fa6d3a6c10fce99215f2aa9e5c89636 Mon Sep 17 00:00:00 2001 From: Ankita Khera <40616383+akhera99@users.noreply.github.com> Date: Fri, 5 Jul 2024 12:10:24 -0700 Subject: [PATCH 35/59] fix (#74237) --- src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs | 2 +- .../Compiler/Core/Log/FunctionId.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs b/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs index f0f46e65d7e17..36edcf66005c0 100644 --- a/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs +++ b/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs @@ -41,7 +41,7 @@ internal static void LogOnTheFlyDocsResultsRequestedWithDocComments() public static void ReportTelemetry() { - Logger.Log(FunctionId.InheritanceMargin_GetInheritanceMemberItems, KeyValueLogMessage.Create(m => + Logger.Log(FunctionId.Copilot_On_The_Fly_Docs_Get_Counts, KeyValueLogMessage.Create(m => { foreach (var kv in s_countLogAggregator) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs index ab07429edd946..bae882174e5d4 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs @@ -631,5 +631,6 @@ internal enum FunctionId Copilot_On_The_Fly_Docs_Results_Displayed = 812, Copilot_On_The_Fly_Docs_Error_Displayed = 813, Copilot_On_The_Fly_Docs_Results_Canceled = 814, + Copilot_On_The_Fly_Docs_Get_Counts = 815, Copilot_Rename = 851 } From a1007090a49a4680eb7e47d72f17391644bfc2f3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Jul 2024 16:24:31 -0700 Subject: [PATCH 36/59] Remove more --- src/VisualStudio/Core/Def/ID.RoslynCommands.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/VisualStudio/Core/Def/ID.RoslynCommands.cs b/src/VisualStudio/Core/Def/ID.RoslynCommands.cs index 35b69bdf39809..3b35d239777e2 100644 --- a/src/VisualStudio/Core/Def/ID.RoslynCommands.cs +++ b/src/VisualStudio/Core/Def/ID.RoslynCommands.cs @@ -31,12 +31,6 @@ public static class RoslynCommands public const int SetActiveRuleSet = 0x0118; public const int SetSeverityDefault = 0x011b; - // Error list context menu command IDs for suppressions and setting severity - public const int AddSuppressions = 0x011d; - public const int AddSuppressionsInSource = 0x011f; - public const int AddSuppressionsInSuppressionFile = 0x0120; - public const int RemoveSuppressions = 0x0121; - // Analyze and Code Cleanup menu IDs public const int AnalysisScopeDefault = 0x0131; public const int AnalysisScopeCurrentDocument = 0x0132; From 269363694d9c2855c34d3106d4f2c7a6e10f9802 Mon Sep 17 00:00:00 2001 From: Ankita Khera <40616383+akhera99@users.noreply.github.com> Date: Mon, 8 Jul 2024 09:02:37 -0700 Subject: [PATCH 37/59] fix (#74276) --- src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs | 2 +- .../Compiler/Core/Log/FunctionId.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs b/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs index f0f46e65d7e17..36edcf66005c0 100644 --- a/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs +++ b/src/Features/Core/Portable/QuickInfo/OnTheFlyDocsLogger.cs @@ -41,7 +41,7 @@ internal static void LogOnTheFlyDocsResultsRequestedWithDocComments() public static void ReportTelemetry() { - Logger.Log(FunctionId.InheritanceMargin_GetInheritanceMemberItems, KeyValueLogMessage.Create(m => + Logger.Log(FunctionId.Copilot_On_The_Fly_Docs_Get_Counts, KeyValueLogMessage.Create(m => { foreach (var kv in s_countLogAggregator) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs index ab07429edd946..bae882174e5d4 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Log/FunctionId.cs @@ -631,5 +631,6 @@ internal enum FunctionId Copilot_On_The_Fly_Docs_Results_Displayed = 812, Copilot_On_The_Fly_Docs_Error_Displayed = 813, Copilot_On_The_Fly_Docs_Results_Canceled = 814, + Copilot_On_The_Fly_Docs_Get_Counts = 815, Copilot_Rename = 851 } From b5430a4483e94692ddacca1583b33a2d104accd8 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 8 Jul 2024 11:03:01 -0700 Subject: [PATCH 38/59] Localized file check-in by OneLocBuild Task: Build definition ID 327: Build ID 2490585 (#74287) --- .../Core/xlf/EditorFeaturesResources.zh-Hant.xlf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf index 2e6ed866c1573..e0d4a6621871d 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf @@ -29,17 +29,17 @@ Copilot - Copilot + Copilot Copilot thinking... - Copilot thinking... + Copilot 思考中... Describe with Copilot - Describe with Copilot + 使用 Copilot 加以描述 @@ -79,7 +79,7 @@ Generate summary with Copilot (might be inaccurate) - Generate summary with Copilot (might be inaccurate) + 使用 Copilot 產生摘要 (可能不準確) @@ -639,7 +639,7 @@ '{0}' intercepted locations - '{0}' intercepted locations + '{0}' 已攔截的位置 From f4fada16052e42ac91a33524fea91762ae8d826c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Mon, 8 Jul 2024 13:42:58 -0700 Subject: [PATCH 39/59] Syntax formatting options (#74223) --- .../CSharpCollectionExpressionRewriter.cs | 3 +- ...ctionExpressionForFluentCodeFixProvider.cs | 3 +- .../Core/Analyzers/AnalyzerOptionsProvider.cs | 2 +- .../AutomaticLineEnderCommandHandler.cs | 4 ++- .../ConvertNamespaceCommandHandler.cs | 2 +- .../CSharpFormattingInteractionService.cs | 6 ++-- .../RawStringLiteralCommandHandler_Return.cs | 2 +- .../SplitStringLiteralCommandHandler.cs | 2 +- .../StringCopyPasteCommandHandler.cs | 6 ++-- ...bstractAutomaticLineEnderCommandHandler.cs | 7 ++-- ...nSessionProvider.BraceCompletionSession.cs | 13 +++---- .../AbstractCommentSelectionBase.cs | 2 +- .../Options/EditorAnalyzerConfigOptions.cs | 4 +-- .../Core/Options/TextBufferOptionProviders.cs | 29 +++++++--------- .../OrganizeDocumentCommandHandler.cs | 2 +- .../Extensions/ITextSnapshotExtensions.cs | 2 +- .../Core/SmartIndent/SmartIndent.cs | 2 +- .../ChangeSignatureTestState.cs | 2 +- .../AbstractAutomaticBraceCompletionTests.cs | 3 +- .../ExtractInterfaceTestState.cs | 2 +- .../Formatting/CoreFormatterTestsBase.cs | 6 ++-- .../AutomaticLineEnderCommandHandler.vb | 3 +- .../EndConstructCommandHandler.vb | 2 +- .../VisualBasic/LineCommit/CommitFormatter.vb | 2 +- ...NavigationBarItemService_CodeGeneration.vb | 2 +- ...tringToRawStringCodeRefactoringProvider.cs | 13 ++++--- ...tructorParameterCodeRefactoringProvider.cs | 2 +- .../AbstractCSharpTypeSnippetProvider.cs | 2 +- .../Snippets/CSharpIntMainSnippetProvider.cs | 2 +- .../Portable/Snippets/CSharpSnippetHelpers.cs | 2 +- .../AbstractBraceCompletionService.cs | 5 +-- .../IBraceCompletionService.cs | 7 ++-- .../AbstractChangeSignatureService.cs | 2 +- ...ConfigureCodeStyleOptionCodeFixProvider.cs | 4 +-- .../ConfigureSeverityLevelCodeFixProvider.cs | 4 +-- ...rovider.GlobalSuppressMessageCodeAction.cs | 6 ++-- ...onCodeFixProvider.PragmaBatchFixHelpers.cs | 5 ++- ...ovider.PragmaWarningBatchFixAllProvider.cs | 2 +- ....RemoveSuppressionCodeAction.BatchFixer.cs | 4 +-- ...FixProvider.RemoveSuppressionCodeAction.cs | 3 +- .../AbstractSuppressionCodeFixProvider.cs | 24 ++++++------- .../Suppression/WrapperCodeFixProvider.cs | 4 +-- .../AbstractMoveTypeService.MoveTypeEditor.cs | 4 +-- .../AbstractChangeNamespaceService.cs | 4 +-- ...stractMemberInsertingCompletionProvider.cs | 2 +- .../AbstractImportCompletionProvider.cs | 2 +- ...ymousTypeToClassCodeRefactoringProvider.cs | 2 +- ...ertTupleToStructCodeRefactoringProvider.cs | 6 ++-- .../AbstractEncapsulateFieldService.cs | 2 +- .../AbstractExtractInterfaceService.cs | 2 +- .../GenerateEqualsAndGetHashCodeAction.cs | 2 +- ...erCodeRefactoringProviderMemberCreation.cs | 2 +- .../AbstractMoveToNamespaceService.cs | 2 +- .../AbstractSnippetProvider.cs | 2 +- .../AbstractUseAutoPropertyCodeFixProvider.cs | 10 +++--- .../AbstractSuppressionAllCodeTests.cs | 2 +- ...SharpDocumentationCommentOptionsWrapper.cs | 2 +- ...OmniSharpSyntaxFormattingOptionsWrapper.cs | 2 +- ...oadBaseCodeFixProvider.AddKeywordAction.vb | 6 ++-- .../OverloadBaseCodeFixProvider.vb | 4 +-- .../Extensions/ProtocolConversions.cs | 3 +- .../Razor/FormatNewFileHandler.cs | 2 +- .../CodeCleanup/AbstractCodeCleanupService.cs | 4 +-- .../Features/CodeFixes/CodeFixService.cs | 2 +- .../Options/IndentationOptionsStorage.cs | 2 +- .../Options/SyntaxFormattingOptionsStorage.cs | 20 ----------- .../AbstractFormatDocumentHandlerBase.cs | 3 +- .../Formatting/FormatDocumentHandler.cs | 15 +++----- .../Formatting/FormatDocumentOnTypeHandler.cs | 2 +- .../Formatting/FormatDocumentRangeHandler.cs | 15 +++----- .../InlineCompletionsHandler.cs | 2 +- .../OnAutoInsert/OnAutoInsertHandler.cs | 5 +-- .../VisualStudioExtractClassOptionsService.cs | 7 ++-- ...actLanguageService`2.IVsLanguageTextOps.cs | 2 +- .../Def/Snippets/SnippetExpansionClient.cs | 5 +-- .../Core/Def/Venus/ContainedDocument.cs | 2 +- .../CodeModel/AbstractCodeModelService.cs | 2 +- .../Core/Impl/CodeModel/FileCodeModel.cs | 2 +- .../Options/AbstractOptionPreviewViewModel.cs | 2 +- .../Supression/IConfigurationFixProvider.cs | 4 +-- .../Core/Portable/Formatting/Formatter.cs | 6 ++-- ...GlobalCodeActionOptionsWorkspaceService.cs | 2 +- .../Portable/Workspace/Solution/Project.cs | 6 ++++ .../Formatting/FormattingTestBase.cs | 2 +- .../Workspaces/TestWorkspace`1.cs | 34 ++++++++++++++----- .../Formatting/CSharpSyntaxFormatting.cs | 4 +-- .../Core/CodeCleanup/CodeCleanupOptions.cs | 2 +- .../Formatting/AbstractSyntaxFormatting.cs | 2 +- .../Core/Formatting/ISyntaxFormatting.cs | 2 +- .../Formatting/SyntaxFormattingOptions.cs | 11 +++--- .../CodeActions/CodeFixOptionsProvider.cs | 9 +---- .../Formatting/VisualBasicSyntaxFormatting.vb | 4 +-- 92 files changed, 210 insertions(+), 237 deletions(-) delete mode 100644 src/LanguageServer/Protocol/Features/Options/SyntaxFormattingOptionsStorage.cs diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs index 5de5853e93db8..4fbb6222312c9 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs @@ -50,8 +50,7 @@ public static async Task CreateCollectionExpressionA #if CODE_STYLE var formattingOptions = CSharpSyntaxFormattingOptions.Default; #else - var formattingOptions = (CSharpSyntaxFormattingOptions)await workspaceDocument.GetSyntaxFormattingOptionsAsync( - fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = (CSharpSyntaxFormattingOptions)await workspaceDocument.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); #endif var indentationOptions = new IndentationOptions(formattingOptions); diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs index fab7a804b6b76..d81166a7aea57 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs @@ -150,8 +150,7 @@ static async Task> GetArgumentsAsync( #if CODE_STYLE var formattingOptions = SyntaxFormattingOptions.CommonDefaults; #else - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync( - fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); #endif using var _ = ArrayBuilder.GetInstance(out var nodesAndTokens); diff --git a/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs b/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs index efa914b38a10b..868cb3b170b66 100644 --- a/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs +++ b/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs @@ -54,7 +54,7 @@ public SimplifierOptions GetSimplifierOptions(ISimplification simplification) // SyntaxFormattingOptions public SyntaxFormattingOptions GetSyntaxFormattingOptions(ISyntaxFormatting formatting) - => formatting.GetFormattingOptions(_options, _fallbackOptions.CleanupOptions?.FormattingOptions); + => formatting.GetFormattingOptions(_options); // CodeGenerationOptions diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs index c3fcbfbd57629..9636bd3fbb871 100644 --- a/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs +++ b/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs @@ -28,6 +28,7 @@ using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Diagnostics; namespace Microsoft.CodeAnalysis.Editor.CSharp.AutomaticCompletion; @@ -313,9 +314,10 @@ protected override void ModifySelectedNode( SyntaxNode selectedNode, bool addBrace, int caretPosition, + StructuredAnalyzerConfigOptions fallbackOptions, CancellationToken cancellationToken) { - var formattingOptions = args.SubjectBuffer.GetSyntaxFormattingOptions(EditorOptionsService, document.LanguageServices, explicitFormat: false); + var formattingOptions = args.SubjectBuffer.GetSyntaxFormattingOptions(EditorOptionsService, fallbackOptions, document.LanguageServices, explicitFormat: false); // Add braces for the selected node if (addBrace) diff --git a/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs b/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs index 4ad682630baff..76e1a337054ad 100644 --- a/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs @@ -141,7 +141,7 @@ public void ExecuteCommand(TypeCharCommandArgs args, Action nextCommandHandler, if (!ConvertNamespaceAnalysis.CanOfferUseFileScoped(s_fileScopedNamespacePreferenceOption, (CompilationUnitSyntax)parsedDocument.Root, namespaceDecl, forAnalyzer: true, LanguageVersion.CSharp10)) return default; - var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.Services, explicitFormat: false); + var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: false); return ConvertNamespaceTransform.ConvertNamespaceDeclaration(parsedDocument, namespaceDecl, formattingOptions, cancellationToken); } } diff --git a/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs b/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs index 0cb940aba6795..c51e8dd9b7c3f 100644 --- a/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs +++ b/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs @@ -86,7 +86,7 @@ public Task> GetFormattingChangesAsync( CancellationToken cancellationToken) { var parsedDocument = ParsedDocument.CreateSynchronously(document, cancellationToken); - var options = textBuffer.GetSyntaxFormattingOptions(_editorOptionsService, parsedDocument.LanguageServices, explicitFormat: true); + var options = textBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: true); var span = textSpan ?? new TextSpan(0, parsedDocument.Root.FullSpan.Length); var formattingSpan = CommonFormattingHelpers.GetFormattingSpan(parsedDocument.Root, span); @@ -97,7 +97,7 @@ public Task> GetFormattingChangesAsync( public Task> GetFormattingChangesOnPasteAsync(Document document, ITextBuffer textBuffer, TextSpan textSpan, CancellationToken cancellationToken) { var parsedDocument = ParsedDocument.CreateSynchronously(document, cancellationToken); - var options = textBuffer.GetSyntaxFormattingOptions(_editorOptionsService, parsedDocument.LanguageServices, explicitFormat: true); + var options = textBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: true); var service = parsedDocument.LanguageServices.GetRequiredService(); return Task.FromResult(service.GetFormattingChangesOnPaste(parsedDocument, textSpan, options, cancellationToken)); } @@ -112,7 +112,7 @@ public Task> GetFormattingChangesAsync(Document docum if (service.ShouldFormatOnTypedCharacter(parsedDocument, typedChar, position, cancellationToken)) { - var indentationOptions = textBuffer.GetIndentationOptions(_editorOptionsService, parsedDocument.LanguageServices, explicitFormat: false); + var indentationOptions = textBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: false); return Task.FromResult(service.GetFormattingChangesOnTypedCharacter(parsedDocument, position, indentationOptions, cancellationToken)); } diff --git a/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs b/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs index 8e163ffa7583d..0c66d57a8fa48 100644 --- a/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs +++ b/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs @@ -98,7 +98,7 @@ SyntaxKind.InterpolatedSingleLineRawStringStartToken or return false; } - var indentationOptions = subjectBuffer.GetIndentationOptions(_editorOptionsService, document.Project.Services, explicitFormat: false); + var indentationOptions = subjectBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: false); var indentation = token.GetPreferredIndentation(parsedDocument, indentationOptions, cancellationToken); var newLine = indentationOptions.FormattingOptions.NewLine; diff --git a/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.cs b/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.cs index aa0819766aa6e..d5cab6ad4a0d8 100644 --- a/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.cs +++ b/src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.cs @@ -80,7 +80,7 @@ public bool ExecuteCommandWorker(ReturnKeyCommandArgs args, CancellationToken ca return false; var parsedDocument = ParsedDocument.CreateSynchronously(document, CancellationToken.None); - var indentationOptions = subjectBuffer.GetIndentationOptions(_editorOptionsService, parsedDocument.LanguageServices, explicitFormat: false); + var indentationOptions = subjectBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: false); // We now go through the verified string literals and split each of them. // The list of spans is traversed in reverse order so we do not have to diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs index 592925bdef8ac..d1f7077462368 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.StringCopyPaste; @@ -186,7 +187,7 @@ ImmutableArray GetEdits(CancellationToken cancellationToken) { var newLine = textView.Options.GetNewLineCharacter(); var indentationWhitespace = DetermineIndentationWhitespace( - parsedDocumentBeforePaste, subjectBuffer, snapshotBeforePaste.AsText(), stringExpressionBeforePaste, cancellationToken); + parsedDocumentBeforePaste, subjectBuffer, snapshotBeforePaste.AsText(), stringExpressionBeforePaste, documentBeforePaste.Project.GetFallbackAnalyzerOptions(), cancellationToken); // See if this is a paste of the last copy that we heard about. var edits = TryGetEditsFromKnownCopySource(newLine, indentationWhitespace); @@ -235,6 +236,7 @@ private string DetermineIndentationWhitespace( ITextBuffer textBuffer, SourceText textBeforePaste, ExpressionSyntax stringExpressionBeforePaste, + StructuredAnalyzerConfigOptions fallbackOptions, CancellationToken cancellationToken) { // Only raw strings care about indentation. Don't bother computing if we don't need it. @@ -252,7 +254,7 @@ private string DetermineIndentationWhitespace( // Otherwise, we have a single-line raw string. Determine the default indentation desired here. // We'll use that if we have to convert this single-line raw string to a multi-line one. - var indentationOptions = textBuffer.GetIndentationOptions(_editorOptionsService, documentBeforePaste.LanguageServices, explicitFormat: false); + var indentationOptions = textBuffer.GetIndentationOptions(_editorOptionsService, fallbackOptions, documentBeforePaste.LanguageServices, explicitFormat: false); return stringExpressionBeforePaste.GetFirstToken().GetPreferredIndentation(documentBeforePaste, indentationOptions, cancellationToken); } diff --git a/src/EditorFeatures/Core/AutomaticCompletion/AbstractAutomaticLineEnderCommandHandler.cs b/src/EditorFeatures/Core/AutomaticCompletion/AbstractAutomaticLineEnderCommandHandler.cs index 9515c1e4ed9c9..04a34b24d239b 100644 --- a/src/EditorFeatures/Core/AutomaticCompletion/AbstractAutomaticLineEnderCommandHandler.cs +++ b/src/EditorFeatures/Core/AutomaticCompletion/AbstractAutomaticLineEnderCommandHandler.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Threading; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; @@ -61,7 +62,7 @@ protected AbstractAutomaticLineEnderCommandHandler( /// /// Add or remove the braces for . /// - protected abstract void ModifySelectedNode(AutomaticLineEnderCommandArgs args, ParsedDocument document, SyntaxNode selectedNode, bool addBrace, int caretPosition, CancellationToken cancellationToken); + protected abstract void ModifySelectedNode(AutomaticLineEnderCommandArgs args, ParsedDocument document, SyntaxNode selectedNode, bool addBrace, int caretPosition, StructuredAnalyzerConfigOptions fallbackOptions, CancellationToken cancellationToken); /// /// Get the syntax node needs add/remove braces. @@ -131,7 +132,7 @@ public void ExecuteCommand(AutomaticLineEnderCommandArgs args, Action nextHandle { var (selectedNode, addBrace) = selectNodeAndOperationKind.Value; using var transaction = args.TextView.CreateEditTransaction(EditorFeaturesResources.Automatic_Line_Ender, _undoRegistry, _editorOperationsFactoryService); - ModifySelectedNode(args, parsedDocument, selectedNode, addBrace, caretPosition, cancellationToken); + ModifySelectedNode(args, parsedDocument, selectedNode, addBrace, caretPosition, document.Project.GetFallbackAnalyzerOptions(), cancellationToken); NextAction(operations, nextHandler); transaction.Complete(); return; @@ -142,7 +143,7 @@ public void ExecuteCommand(AutomaticLineEnderCommandArgs args, Action nextHandle if (endingInsertionPosition != null) { using var transaction = args.TextView.CreateEditTransaction(EditorFeaturesResources.Automatic_Line_Ender, _undoRegistry, _editorOperationsFactoryService); - var formattingOptions = args.SubjectBuffer.GetSyntaxFormattingOptions(EditorOptionsService, parsedDocument.LanguageServices, explicitFormat: false); + var formattingOptions = args.SubjectBuffer.GetSyntaxFormattingOptions(EditorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: false); InsertEnding(args.TextView, args.SubjectBuffer, parsedDocument, endingInsertionPosition.Value, caretPosition, formattingOptions, cancellationToken); NextAction(operations, nextHandler); transaction.Complete(); diff --git a/src/EditorFeatures/Core/AutomaticCompletion/BraceCompletionSessionProvider.BraceCompletionSession.cs b/src/EditorFeatures/Core/AutomaticCompletion/BraceCompletionSessionProvider.BraceCompletionSession.cs index 3d520a1dc087d..3d9c496a7b667 100644 --- a/src/EditorFeatures/Core/AutomaticCompletion/BraceCompletionSessionProvider.BraceCompletionSession.cs +++ b/src/EditorFeatures/Core/AutomaticCompletion/BraceCompletionSessionProvider.BraceCompletionSession.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Threading; using Microsoft.CodeAnalysis.BraceCompletion; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; @@ -105,7 +106,7 @@ private bool TryStart(CancellationToken cancellationToken) } var parsedDocument = ParsedDocument.CreateSynchronously(document, cancellationToken); - var context = GetBraceCompletionContext(parsedDocument); + var context = GetBraceCompletionContext(parsedDocument, document.Project.GetFallbackAnalyzerOptions()); // Note: completes synchronously unless Semantic Model is needed to determine the result: if (!_service.HasBraceCompletionAsync(context, document, cancellationToken).WaitAndGetResult(cancellationToken)) @@ -125,7 +126,7 @@ private bool TryStart(CancellationToken cancellationToken) if (TryGetBraceCompletionContext(out var contextAfterStart, cancellationToken)) { - var indentationOptions = SubjectBuffer.GetIndentationOptions(_editorOptionsService, contextAfterStart.Document.LanguageServices, explicitFormat: false); + var indentationOptions = SubjectBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), contextAfterStart.Document.LanguageServices, explicitFormat: false); var changesAfterStart = _service.GetTextChangesAfterCompletion(contextAfterStart, indentationOptions, cancellationToken); if (changesAfterStart != null) { @@ -283,7 +284,7 @@ public void PostReturn() return; } - var indentationOptions = SubjectBuffer.GetIndentationOptions(_editorOptionsService, context.Document.LanguageServices, explicitFormat: false); + var indentationOptions = SubjectBuffer.GetIndentationOptions(_editorOptionsService, context.FallbackOptions, context.Document.LanguageServices, explicitFormat: false); var changesAfterReturn = _service.GetTextChangeAfterReturn(context, indentationOptions, CancellationToken.None); if (changesAfterReturn != null) { @@ -397,11 +398,11 @@ private bool TryGetBraceCompletionContext(out BraceCompletionContext context, Ca return false; } - context = GetBraceCompletionContext(ParsedDocument.CreateSynchronously(document, cancellationToken)); + context = GetBraceCompletionContext(ParsedDocument.CreateSynchronously(document, cancellationToken), document.Project.GetFallbackAnalyzerOptions()); return true; } - private BraceCompletionContext GetBraceCompletionContext(ParsedDocument document) + private BraceCompletionContext GetBraceCompletionContext(ParsedDocument document, StructuredAnalyzerConfigOptions fallbackOptions) { _threadingContext.ThrowIfNotOnUIThread(); var snapshot = SubjectBuffer.CurrentSnapshot; @@ -411,7 +412,7 @@ private BraceCompletionContext GetBraceCompletionContext(ParsedDocument document // The user is actively typing so the caret position should not be null. var caretPosition = this.GetCaretPosition().Value.Position; - return new BraceCompletionContext(document, openingSnapshotPoint, closingSnapshotPoint, caretPosition); + return new BraceCompletionContext(document, fallbackOptions, openingSnapshotPoint, closingSnapshotPoint, caretPosition); } private void ApplyBraceCompletionResult(BraceCompletionResult result) diff --git a/src/EditorFeatures/Core/CommentSelection/AbstractCommentSelectionBase.cs b/src/EditorFeatures/Core/CommentSelection/AbstractCommentSelectionBase.cs index 7609d2fc0377f..57a7ca49ceefa 100644 --- a/src/EditorFeatures/Core/CommentSelection/AbstractCommentSelectionBase.cs +++ b/src/EditorFeatures/Core/CommentSelection/AbstractCommentSelectionBase.cs @@ -149,7 +149,7 @@ private void ApplyEdits(Document document, ITextView textView, ITextBuffer subje var oldSyntaxTree = document.GetSyntaxTreeSynchronously(cancellationToken); var newRoot = oldSyntaxTree.WithChangedText(newText).GetRoot(cancellationToken); - var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.Services, explicitFormat: false); + var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: false); var formattingSpans = trackingSnapshotSpans.Select(change => CommonFormattingHelpers.GetFormattingSpan(newRoot, change.Span.ToTextSpan())); var formattedChanges = Formatter.GetFormattedTextChanges(newRoot, formattingSpans, document.Project.Solution.Services, formattingOptions, rules: default, cancellationToken); diff --git a/src/EditorFeatures/Core/Options/EditorAnalyzerConfigOptions.cs b/src/EditorFeatures/Core/Options/EditorAnalyzerConfigOptions.cs index 89086b1131b26..49a55053e7043 100644 --- a/src/EditorFeatures/Core/Options/EditorAnalyzerConfigOptions.cs +++ b/src/EditorFeatures/Core/Options/EditorAnalyzerConfigOptions.cs @@ -61,6 +61,6 @@ private static bool IsLowercase(string str) internal static partial class EditorOptionsExtensions { - public static StructuredAnalyzerConfigOptions ToAnalyzerConfigOptions(this IEditorOptions editorOptions) - => StructuredAnalyzerConfigOptions.Create(new EditorAnalyzerConfigOptions(editorOptions)); + public static StructuredAnalyzerConfigOptions ToAnalyzerConfigOptions(this IEditorOptions editorOptions, StructuredAnalyzerConfigOptions fallbackOptions) + => StructuredAnalyzerConfigOptions.Create(new EditorAnalyzerConfigOptions(editorOptions), fallbackOptions); } diff --git a/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs b/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs index ce61da12f9add..50ab0fb90a025 100644 --- a/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs +++ b/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs @@ -40,23 +40,22 @@ private static LineFormattingOptions GetLineFormattingOptionsImpl(ITextBuffer te }; } - public static SyntaxFormattingOptions GetSyntaxFormattingOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, LanguageServices languageServices, bool explicitFormat) - => GetSyntaxFormattingOptionsImpl(textBuffer, optionsProvider.Factory.GetOptions(textBuffer), optionsProvider.IndentationManager, optionsProvider.GlobalOptions, languageServices, explicitFormat); + public static SyntaxFormattingOptions GetSyntaxFormattingOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, StructuredAnalyzerConfigOptions fallbackOptions, LanguageServices languageServices, bool explicitFormat) + => GetSyntaxFormattingOptionsImpl(textBuffer, optionsProvider.Factory.GetOptions(textBuffer), fallbackOptions, optionsProvider.IndentationManager, languageServices, explicitFormat); - private static SyntaxFormattingOptions GetSyntaxFormattingOptionsImpl(ITextBuffer textBuffer, IEditorOptions editorOptions, IIndentationManagerService indentationManager, IGlobalOptionService globalOptions, LanguageServices languageServices, bool explicitFormat) + private static SyntaxFormattingOptions GetSyntaxFormattingOptionsImpl(ITextBuffer textBuffer, IEditorOptions editorOptions, StructuredAnalyzerConfigOptions fallbackOptions, IIndentationManagerService indentationManager, LanguageServices languageServices, bool explicitFormat) { - var configOptions = editorOptions.ToAnalyzerConfigOptions(); - var fallbackOptions = globalOptions.GetSyntaxFormattingOptions(languageServices); - var options = configOptions.GetSyntaxFormattingOptions(languageServices, fallbackOptions); + var configOptions = editorOptions.ToAnalyzerConfigOptions(fallbackOptions); + var options = configOptions.GetSyntaxFormattingOptions(languageServices); var lineFormattingOptions = GetLineFormattingOptionsImpl(textBuffer, editorOptions, indentationManager, explicitFormat); return options with { LineFormatting = lineFormattingOptions }; } - public static IndentationOptions GetIndentationOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, LanguageServices languageServices, bool explicitFormat) + public static IndentationOptions GetIndentationOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, StructuredAnalyzerConfigOptions fallbackOptions, LanguageServices languageServices, bool explicitFormat) { var editorOptions = optionsProvider.Factory.GetOptions(textBuffer); - var formattingOptions = GetSyntaxFormattingOptionsImpl(textBuffer, editorOptions, optionsProvider.IndentationManager, optionsProvider.GlobalOptions, languageServices, explicitFormat); + var formattingOptions = GetSyntaxFormattingOptionsImpl(textBuffer, editorOptions, fallbackOptions, optionsProvider.IndentationManager, languageServices, explicitFormat); return new IndentationOptions(formattingOptions) { @@ -66,21 +65,19 @@ public static IndentationOptions GetIndentationOptions(this ITextBuffer textBuff }; } - public static AddImportPlacementOptions GetAddImportPlacementOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, LanguageServices languageServices, bool allowInHiddenRegions) + public static AddImportPlacementOptions GetAddImportPlacementOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, StructuredAnalyzerConfigOptions fallbackOptions, LanguageServices languageServices, bool allowInHiddenRegions) { var editorOptions = optionsProvider.Factory.GetOptions(textBuffer); - var configOptions = editorOptions.ToAnalyzerConfigOptions(); - var fallbackOptions = optionsProvider.GlobalOptions.GetAddImportPlacementOptions(languageServices); - return configOptions.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions, fallbackOptions); + var configOptions = editorOptions.ToAnalyzerConfigOptions(fallbackOptions); + return configOptions.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions, fallbackOptions: null); } - public static CodeCleanupOptions GetCodeCleanupOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, LanguageServices languageServices, bool explicitFormat, bool allowImportsInHiddenRegions) + public static CodeCleanupOptions GetCodeCleanupOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, StructuredAnalyzerConfigOptions fallbackOptions, LanguageServices languageServices, bool explicitFormat, bool allowImportsInHiddenRegions) { var editorOptions = optionsProvider.Factory.GetOptions(textBuffer); - var configOptions = editorOptions.ToAnalyzerConfigOptions(); - var fallbackOptions = optionsProvider.GlobalOptions.GetCodeCleanupOptions(languageServices); + var configOptions = editorOptions.ToAnalyzerConfigOptions(fallbackOptions); - var options = configOptions.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions); + var options = configOptions.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions: null); var lineFormattingOptions = GetLineFormattingOptionsImpl(textBuffer, editorOptions, optionsProvider.IndentationManager, explicitFormat); return options with { FormattingOptions = options.FormattingOptions with { LineFormatting = lineFormattingOptions } }; diff --git a/src/EditorFeatures/Core/Organizing/OrganizeDocumentCommandHandler.cs b/src/EditorFeatures/Core/Organizing/OrganizeDocumentCommandHandler.cs index 6e14ab4d415b6..eb78e0649ee55 100644 --- a/src/EditorFeatures/Core/Organizing/OrganizeDocumentCommandHandler.cs +++ b/src/EditorFeatures/Core/Organizing/OrganizeDocumentCommandHandler.cs @@ -187,7 +187,7 @@ public bool ExecuteCommand(SortAndRemoveUnnecessaryImportsCommandArgs args, Comm async (document, cancellationToken) => { var formattingOptions = document.SupportsSyntaxTree - ? await document.GetSyntaxFormattingOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false) + ? await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false) : null; var removeImportsService = document.GetRequiredLanguageService(); diff --git a/src/EditorFeatures/Core/Shared/Extensions/ITextSnapshotExtensions.cs b/src/EditorFeatures/Core/Shared/Extensions/ITextSnapshotExtensions.cs index e9e3c5b7e0c9b..5b5b5b540f502 100644 --- a/src/EditorFeatures/Core/Shared/Extensions/ITextSnapshotExtensions.cs +++ b/src/EditorFeatures/Core/Shared/Extensions/ITextSnapshotExtensions.cs @@ -39,7 +39,7 @@ public static void FormatAndApplyToBuffer( var formatter = document.GetRequiredLanguageService(); - var options = textBuffer.GetSyntaxFormattingOptions(editorOptionsService, document.Project.Services, explicitFormat: false); + var options = textBuffer.GetSyntaxFormattingOptions(editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: false); var result = formatter.GetFormattingResult(documentSyntax.Root, [span], options, rules, cancellationToken); var changes = result.GetTextChanges(cancellationToken); diff --git a/src/EditorFeatures/Core/SmartIndent/SmartIndent.cs b/src/EditorFeatures/Core/SmartIndent/SmartIndent.cs index 335d0519d9661..7d573c4db7f21 100644 --- a/src/EditorFeatures/Core/SmartIndent/SmartIndent.cs +++ b/src/EditorFeatures/Core/SmartIndent/SmartIndent.cs @@ -42,7 +42,7 @@ public void Dispose() if (newService == null) return null; - var indentationOptions = line.Snapshot.TextBuffer.GetIndentationOptions(_editorOptionsService, document.Project.Services, explicitFormat: false); + var indentationOptions = line.Snapshot.TextBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: false); var parsedDocument = ParsedDocument.CreateSynchronously(document, cancellationToken); var result = newService.GetIndentation(parsedDocument, line.LineNumber, indentationOptions, cancellationToken); return result.GetIndentation(_textView, line); diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs b/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs index ec9853314c97e..9c7a3734976ca 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs @@ -38,7 +38,7 @@ public static ChangeSignatureTestState Create(string markup, string languageName _ => throw new ArgumentException("Invalid language name.") }; - options?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(options); return new ChangeSignatureTestState(workspace); } diff --git a/src/EditorFeatures/TestUtilities/AutomaticCompletion/AbstractAutomaticBraceCompletionTests.cs b/src/EditorFeatures/TestUtilities/AutomaticCompletion/AbstractAutomaticBraceCompletionTests.cs index d1b2607fc1a28..034d50afdbfaa 100644 --- a/src/EditorFeatures/TestUtilities/AutomaticCompletion/AbstractAutomaticBraceCompletionTests.cs +++ b/src/EditorFeatures/TestUtilities/AutomaticCompletion/AbstractAutomaticBraceCompletionTests.cs @@ -144,6 +144,8 @@ internal static void Type(IBraceCompletionSession session, string text) internal static Holder CreateSession(EditorTestWorkspace workspace, char opening, char closing, OptionsCollection globalOptions = null) { + workspace.SetAnalyzerFallbackAndGlobalOptions(globalOptions); + var document = workspace.Documents.First(); var provider = Assert.IsType(workspace.GetService()); @@ -151,7 +153,6 @@ internal static Holder CreateSession(EditorTestWorkspace workspace, char opening var openingPoint = new SnapshotPoint(document.GetTextBuffer().CurrentSnapshot, document.CursorPosition.Value); var textView = document.GetTextView(); - globalOptions?.SetGlobalOptions(workspace.GlobalOptions); workspace.GlobalOptions.SetEditorOptions(textView.Options.GlobalOptions, document.Project.Language); if (provider.TryCreateSession(textView, openingPoint, opening, closing, out var session)) diff --git a/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs b/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs index e10dfa5df6db2..c466125a9c7ac 100644 --- a/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs +++ b/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs @@ -42,7 +42,7 @@ public static ExtractInterfaceTestState Create( ? EditorTestWorkspace.CreateCSharp(markup, composition: Composition, compilationOptions: compilationOptions, parseOptions: parseOptions) : EditorTestWorkspace.CreateVisualBasic(markup, composition: Composition, compilationOptions: compilationOptions, parseOptions: parseOptions); - options?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(options); return new ExtractInterfaceTestState(workspace); } diff --git a/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs b/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs index 8334f80402998..f99a17ee49a6d 100644 --- a/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs +++ b/src/EditorFeatures/TestUtilities/Formatting/CoreFormatterTestsBase.cs @@ -131,7 +131,7 @@ private protected void AssertFormatWithView(string expectedWithMarker, string co { using var workspace = CreateWorkspace(codeWithMarker, parseOptions); - options?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(options); // set up caret position var testDocument = workspace.Documents.Single(); @@ -200,7 +200,7 @@ private protected async Task AssertFormatAsync(string expected, string code, IEn var formattingService = document.GetRequiredLanguageService(); var formattingOptions = (options != null) - ? formattingService.GetFormattingOptions(options, fallbackOptions: null) + ? formattingService.GetFormattingOptions(options) : formattingService.DefaultOptions; ImmutableArray rules = [formattingRuleProvider.CreateRule(documentSyntax, 0), .. Formatter.GetDefaultFormattingRules(document)]; @@ -286,7 +286,7 @@ protected static void AssertFormatOnArbitraryNode(SyntaxNode node, string expect { using var workspace = new AdhocWorkspace(); var formattingService = workspace.Services.GetLanguageServices(node.Language).GetRequiredService(); - var options = formattingService.GetFormattingOptions(StructuredAnalyzerConfigOptions.Empty, fallbackOptions: null); + var options = formattingService.GetFormattingOptions(StructuredAnalyzerConfigOptions.Empty); var result = Formatter.Format(node, workspace.Services.SolutionServices, options, CancellationToken.None); var actual = result.GetText().ToString(); diff --git a/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb b/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb index 3ff2273657ce8..aeae57260ace0 100644 --- a/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/AutomaticCompletion/AutomaticLineEnderCommandHandler.vb @@ -5,6 +5,7 @@ Imports System.ComponentModel.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.AutomaticCompletion +Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.Options @@ -46,7 +47,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.AutomaticCompletion Return False End Function - Protected Overrides Sub ModifySelectedNode(args As AutomaticLineEnderCommandArgs, document As ParsedDocument, selectedNode As SyntaxNode, addBrace As Boolean, caretPosition As Integer, cancellationToken As CancellationToken) + Protected Overrides Sub ModifySelectedNode(args As AutomaticLineEnderCommandArgs, document As ParsedDocument, selectedNode As SyntaxNode, addBrace As Boolean, caretPosition As Integer, fallbackOptions As StructuredAnalyzerConfigOptions, cancellationToken As CancellationToken) End Sub Protected Overrides Function GetValidNodeToModifyBraces(document As ParsedDocument, caretPosition As Integer, cancellationToken As CancellationToken) As (SyntaxNode, Boolean)? diff --git a/src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb b/src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb index b7e5fc83c4665..7d593f2862e37 100644 --- a/src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/EndConstructGeneration/EndConstructCommandHandler.vb @@ -140,7 +140,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EndConstructGeneration Return p.Name = PredefinedCodeCleanupProviderNames.NormalizeModifiersOrOperators End Function) - Dim options = buffer.GetCodeCleanupOptions(_editorOptionsService, document.Project.Services, explicitFormat:=False, allowImportsInHiddenRegions:=document.AllowImportsInHiddenRegions()) + Dim options = buffer.GetCodeCleanupOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat:=False, allowImportsInHiddenRegions:=document.AllowImportsInHiddenRegions()) Dim cleanDocument = CodeCleaner.CleanupAsync(document, GetSpanToCleanup(statement), Options, codeCleanups, cancellationToken:=cancellationToken).WaitAndGetResult(cancellationToken) Dim changes = cleanDocument.GetTextChangesAsync(document, cancellationToken).WaitAndGetResult(cancellationToken) diff --git a/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb b/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb index 6fa92b52053b2..89db5228db666 100644 --- a/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb +++ b/src/EditorFeatures/VisualBasic/LineCommit/CommitFormatter.vb @@ -72,7 +72,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.LineCommit End If ' create commit formatting cleanup provider that has line commit specific behavior - Dim cleanupOptions = buffer.GetCodeCleanupOptions(_editorOptionsService, document.Project.Services, isExplicitFormat, allowImportsInHiddenRegions:=document.AllowImportsInHiddenRegions()) + Dim cleanupOptions = buffer.GetCodeCleanupOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, isExplicitFormat, allowImportsInHiddenRegions:=document.AllowImportsInHiddenRegions()) Dim commitFormattingCleanup = GetCommitFormattingCleanupProvider( document.Id, document.Project.Services, diff --git a/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb b/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb index 3bd42bc2532c8..b98364b8ffbf6 100644 --- a/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb +++ b/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb @@ -61,7 +61,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar End If Dim simplifierOptions = Await newDocument.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(False) - Dim formattingOptions = Await newDocument.GetSyntaxFormattingOptionsAsync(globalOptions, cancellationToken).ConfigureAwait(False) + Dim formattingOptions = Await newDocument.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(False) newDocument = Await Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, simplifierOptions, cancellationToken).ConfigureAwait(False) diff --git a/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs index 3e001256b88f8..fb7e0ac174695 100644 --- a/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs @@ -77,7 +77,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; var options = context.Options; - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(options, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var parsedDocument = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); if (!CanConvert(parsedDocument, parentExpression, formattingOptions, out var convertParams, out var provider, cancellationToken)) @@ -90,7 +90,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( CSharpFeaturesResources.Convert_to_raw_string, - cancellationToken => UpdateDocumentAsync(document, parentExpression, ConvertToRawKind.SingleLine, options, provider, cancellationToken), + cancellationToken => UpdateDocumentAsync(document, parentExpression, ConvertToRawKind.SingleLine, provider, cancellationToken), s_kindToEquivalenceKeyMap[ConvertToRawKind.SingleLine], priority), token.Span); @@ -100,7 +100,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( CSharpFeaturesResources.Convert_to_raw_string, - cancellationToken => UpdateDocumentAsync(document, parentExpression, ConvertToRawKind.MultiLineIndented, options, provider, cancellationToken), + cancellationToken => UpdateDocumentAsync(document, parentExpression, ConvertToRawKind.MultiLineIndented, provider, cancellationToken), s_kindToEquivalenceKeyMap[ConvertToRawKind.MultiLineIndented], priority), token.Span); @@ -110,7 +110,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( CSharpFeaturesResources.without_leading_whitespace_may_change_semantics, - cancellationToken => UpdateDocumentAsync(document, parentExpression, ConvertToRawKind.MultiLineWithoutLeadingWhitespace, options, provider, cancellationToken), + cancellationToken => UpdateDocumentAsync(document, parentExpression, ConvertToRawKind.MultiLineWithoutLeadingWhitespace, provider, cancellationToken), s_kindToEquivalenceKeyMap[ConvertToRawKind.MultiLineWithoutLeadingWhitespace], priority), token.Span); @@ -122,11 +122,10 @@ private static async Task UpdateDocumentAsync( Document document, ExpressionSyntax expression, ConvertToRawKind kind, - CodeActionOptionsProvider optionsProvider, IConvertStringProvider provider, CancellationToken cancellationToken) { - var options = await document.GetSyntaxFormattingOptionsAsync(optionsProvider, cancellationToken).ConfigureAwait(false); + var options = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var parsedDocument = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); @@ -146,7 +145,7 @@ protected override async Task FixAllAsync( Debug.Assert(equivalenceKey != null); var kind = s_kindToEquivalenceKeyMap[equivalenceKey]; - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(optionsProvider, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var parsedDocument = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); foreach (var fixSpan in fixAllSpans) diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs index c7892f461d62a..bb0d0296fc386 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs @@ -74,7 +74,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (parameterNameParts.BaseName == "") return; - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var fieldOrProperty = TryFindMatchingUninitializedFieldOrPropertySymbol(); var refactorings = fieldOrProperty == null diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 5ba4d33c0368f..6569ef7bdd066 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -95,7 +95,7 @@ protected override async Task AddIndentationToDocumentAsync(Document d { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var indentationString = CSharpSnippetHelpers.GetBlockLikeIndentationString(document, typeDeclaration.OpenBraceToken.SpanStart, syntaxFormattingOptions, cancellationToken); var newTypeDeclaration = typeDeclaration.WithCloseBraceToken( diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs index 8016a03df0e8e..47f4954c017fa 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs @@ -54,7 +54,7 @@ protected override async Task AddIndentationToDocumentAsync(Document d var body = methodDeclaration.Body!; var returnStatement = body.Statements.First(); - var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var indentationString = CSharpSnippetHelpers.GetBlockLikeIndentationString(document, body.OpenBraceToken.SpanStart, syntaxFormattingOptions, cancellationToken); var updatedReturnStatement = returnStatement.WithPrependedLeadingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, indentationString)); diff --git a/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs b/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs index 40ee535b91968..9b6676458596c 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs @@ -49,7 +49,7 @@ public static async Task AddBlockIndentationToDocumentAsync - BraceCompletionContext? GetCompletedBraceContext(ParsedDocument document, int caretLocation); + BraceCompletionContext? GetCompletedBraceContext(ParsedDocument document, StructuredAnalyzerConfigOptions fallbackOptions, int caretLocation); /// /// Returns true if over typing should be allowed given the caret location and completed pair of braces. @@ -89,10 +90,12 @@ internal readonly struct BraceCompletionResult(ImmutableArray textCh public LinePosition CaretLocation { get; } = caretLocation; } -internal readonly struct BraceCompletionContext(ParsedDocument document, int openingPoint, int closingPoint, int caretLocation) +internal readonly struct BraceCompletionContext(ParsedDocument document, StructuredAnalyzerConfigOptions fallbackOptions, int openingPoint, int closingPoint, int caretLocation) { public ParsedDocument Document { get; } = document; + public StructuredAnalyzerConfigOptions FallbackOptions { get; } = fallbackOptions; + public int OpeningPoint { get; } = openingPoint; public int ClosingPoint { get; } = closingPoint; diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index 928e676f85863..440ae7946921c 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -401,7 +401,7 @@ private static async Task> FindChangeSignatureR }); var annotatedNodes = newRoot.GetAnnotatedNodes(syntaxAnnotation: changeSignatureFormattingAnnotation); - var formattingOptions = await doc.GetSyntaxFormattingOptionsAsync(context.FallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await doc.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var formattedRoot = Formatter.Format( newRoot, diff --git a/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureCodeStyle/ConfigureCodeStyleOptionCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureCodeStyle/ConfigureCodeStyleOptionCodeFixProvider.cs index 42e5660f87dac..2ce7630a16636 100644 --- a/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureCodeStyle/ConfigureCodeStyleOptionCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureCodeStyle/ConfigureCodeStyleOptionCodeFixProvider.cs @@ -53,10 +53,10 @@ public bool IsFixableDiagnostic(Diagnostic diagnostic) public FixAllProvider? GetFixAllProvider() => null; - public Task> GetFixesAsync(TextDocument document, TextSpan span, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public Task> GetFixesAsync(TextDocument document, TextSpan span, IEnumerable diagnostics, CancellationToken cancellationToken) => Task.FromResult(GetConfigurations(document.Project, diagnostics)); - public Task> GetFixesAsync(Project project, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public Task> GetFixesAsync(Project project, IEnumerable diagnostics, CancellationToken cancellationToken) => Task.FromResult(GetConfigurations(project, diagnostics)); private static ImmutableArray GetConfigurations(Project project, IEnumerable diagnostics) diff --git a/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureSeverity/ConfigureSeverityLevelCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureSeverity/ConfigureSeverityLevelCodeFixProvider.cs index 5d8e0d9cc85ee..3ae7001b1ec2d 100644 --- a/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureSeverity/ConfigureSeverityLevelCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Configuration/ConfigureSeverity/ConfigureSeverityLevelCodeFixProvider.cs @@ -44,10 +44,10 @@ public bool IsFixableDiagnostic(Diagnostic diagnostic) public FixAllProvider? GetFixAllProvider() => null; - public Task> GetFixesAsync(TextDocument document, TextSpan span, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public Task> GetFixesAsync(TextDocument document, TextSpan span, IEnumerable diagnostics, CancellationToken cancellationToken) => Task.FromResult(GetConfigurations(document.Project, diagnostics, cancellationToken)); - public Task> GetFixesAsync(Project project, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public Task> GetFixesAsync(Project project, IEnumerable diagnostics, CancellationToken cancellationToken) => Task.FromResult(GetConfigurations(project, diagnostics, cancellationToken)); private static ImmutableArray GetConfigurations(Project project, IEnumerable diagnostics, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageCodeAction.cs index c9df6009c13d7..4c5dcd72e5d3f 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageCodeAction.cs @@ -18,13 +18,11 @@ internal abstract partial class AbstractSuppressionCodeFixProvider : IConfigurat internal sealed class GlobalSuppressMessageCodeAction( ISymbol targetSymbol, INamedTypeSymbol suppressMessageAttribute, Project project, Diagnostic diagnostic, - AbstractSuppressionCodeFixProvider fixer, - CodeActionOptionsProvider fallbackOptions) : AbstractGlobalSuppressMessageCodeAction(fixer, project) + AbstractSuppressionCodeFixProvider fixer) : AbstractGlobalSuppressMessageCodeAction(fixer, project) { private readonly ISymbol _targetSymbol = targetSymbol; private readonly INamedTypeSymbol _suppressMessageAttribute = suppressMessageAttribute; private readonly Diagnostic _diagnostic = diagnostic; - private readonly CodeActionOptionsProvider _fallbackOptions = fallbackOptions; protected override async Task GetChangedSuppressionDocumentAsync(CancellationToken cancellationToken) { @@ -32,7 +30,7 @@ protected override async Task GetChangedSuppressionDocumentAsync(Cance var services = suppressionsDoc.Project.Solution.Services; var suppressionsRoot = await suppressionsDoc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var addImportsService = suppressionsDoc.GetRequiredLanguageService(); - var options = await suppressionsDoc.GetSyntaxFormattingOptionsAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await suppressionsDoc.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); suppressionsRoot = Fixer.AddGlobalSuppressMessageAttribute( suppressionsRoot, _targetSymbol, _suppressMessageAttribute, _diagnostic, services, options, addImportsService, cancellationToken); diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs index 81bd3002bced4..dd7aab504f8e2 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs @@ -34,7 +34,7 @@ public static CodeAction CreateBatchPragmaFix( return CodeAction.Create( ((CodeAction)pragmaActions[0]).Title, createChangedDocument: ct => - BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllState.CodeActionOptionsProvider, cancellationToken), + BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, cancellationToken), equivalenceKey: fixAllState.CodeActionEquivalenceKey); } @@ -43,7 +43,6 @@ private static async Task BatchPragmaFixesAsync( Document document, ImmutableArray pragmaActions, ImmutableArray diagnostics, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // We apply all the pragma suppression fixes sequentially. @@ -86,7 +85,7 @@ private static async Task BatchPragmaFixesAsync( properties: diagnostic.Properties, isSuppressed: diagnostic.IsSuppressed); - var newSuppressionFixes = await suppressionFixProvider.GetFixesAsync(currentDocument, currentDiagnosticSpan, [diagnostic], fallbackOptions, cancellationToken).ConfigureAwait(false); + var newSuppressionFixes = await suppressionFixProvider.GetFixesAsync(currentDocument, currentDiagnosticSpan, [diagnostic], cancellationToken).ConfigureAwait(false); var newSuppressionFix = newSuppressionFixes.SingleOrDefault(); if (newSuppressionFix != null) { diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs index 78695f9c6e311..40be76361e23a 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs @@ -35,7 +35,7 @@ protected override async Task AddDocumentFixesAsync( { var span = diagnostic.Location.SourceSpan; var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync( - document, span, [diagnostic], fixAllState.CodeActionOptionsProvider, cancellationToken).ConfigureAwait(false); + document, span, [diagnostic], cancellationToken).ConfigureAwait(false); var pragmaSuppression = pragmaSuppressions.SingleOrDefault(); if (pragmaSuppression != null) { diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs index 84ee578089529..ec1584616a016 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs @@ -44,7 +44,7 @@ protected override async Task AddDocumentFixesAsync( { var span = diagnostic.Location.SourceSpan; var removeSuppressionFixes = await _suppressionFixProvider.GetFixesAsync( - document, span, [diagnostic], fixAllState.CodeActionOptionsProvider, cancellationToken).ConfigureAwait(false); + document, span, [diagnostic], cancellationToken).ConfigureAwait(false); var removeSuppressionFix = removeSuppressionFixes.SingleOrDefault(); if (removeSuppressionFix != null) { @@ -89,7 +89,7 @@ protected override async Task AddProjectFixesAsync( foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed)) { var removeSuppressionFixes = await _suppressionFixProvider.GetFixesAsync( - project, [diagnostic], fixAllState.CodeActionOptionsProvider, cancellationToken).ConfigureAwait(false); + project, [diagnostic], cancellationToken).ConfigureAwait(false); if (removeSuppressionFixes.SingleOrDefault()?.Action is RemoveSuppressionCodeAction removeSuppressionCodeAction) { if (fixAllState.IsFixMultiple) diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs index 029be4d52cdea..b90e142d69b3b 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.cs @@ -27,7 +27,6 @@ public static async Task CreateAsync( Project project, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, - CodeActionOptionsProvider options, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); @@ -38,7 +37,7 @@ public static async Task CreateAsync( } else if (documentOpt != null && !SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(diagnostic)) { - var formattingOptions = await documentOpt.GetSyntaxFormattingOptionsAsync(options, cancellationToken).ConfigureAwait(false); + var formattingOptions = await documentOpt.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return PragmaRemoveAction.Create(suppressionTargetInfo, documentOpt, formattingOptions, diagnostic, fixer); } else diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs index 410c85da807df..7afb14e30a060 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs @@ -139,24 +139,24 @@ private SyntaxToken GetAdjustedTokenForPragmaRestore(SyntaxToken token, SyntaxNo } public Task> GetFixesAsync( - TextDocument textDocument, TextSpan span, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + TextDocument textDocument, TextSpan span, IEnumerable diagnostics, CancellationToken cancellationToken) { if (textDocument is not Document document) return Task.FromResult(ImmutableArray.Empty); - return GetSuppressionsAsync(document, span, diagnostics, fallbackOptions, skipSuppressMessage: false, skipUnsuppress: false, cancellationToken: cancellationToken); + return GetSuppressionsAsync(document, span, diagnostics, skipSuppressMessage: false, skipUnsuppress: false, cancellationToken: cancellationToken); } - internal async Task> GetPragmaSuppressionsAsync(Document document, TextSpan span, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + internal async Task> GetPragmaSuppressionsAsync(Document document, TextSpan span, IEnumerable diagnostics, CancellationToken cancellationToken) { - var codeFixes = await GetSuppressionsAsync(document, span, diagnostics, fallbackOptions, skipSuppressMessage: true, skipUnsuppress: true, cancellationToken: cancellationToken).ConfigureAwait(false); + var codeFixes = await GetSuppressionsAsync(document, span, diagnostics, skipSuppressMessage: true, skipUnsuppress: true, cancellationToken: cancellationToken).ConfigureAwait(false); return codeFixes.SelectMany(fix => fix.Action.NestedActions) .OfType() .ToImmutableArray(); } private async Task> GetSuppressionsAsync( - Document document, TextSpan span, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, bool skipSuppressMessage, bool skipUnsuppress, CancellationToken cancellationToken) + Document document, TextSpan span, IEnumerable diagnostics, bool skipSuppressMessage, bool skipUnsuppress, CancellationToken cancellationToken) { var suppressionTargetInfo = await GetSuppressionTargetInfoAsync(document, span, cancellationToken).ConfigureAwait(false); if (suppressionTargetInfo == null) @@ -165,11 +165,11 @@ private async Task> GetSuppressionsAsync( } return await GetSuppressionsAsync( - document, document.Project, diagnostics, suppressionTargetInfo, fallbackOptions, skipSuppressMessage, skipUnsuppress, cancellationToken).ConfigureAwait(false); + document, document.Project, diagnostics, suppressionTargetInfo, skipSuppressMessage, skipUnsuppress, cancellationToken).ConfigureAwait(false); } public async Task> GetFixesAsync( - Project project, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Project project, IEnumerable diagnostics, CancellationToken cancellationToken) { if (!project.SupportsCompilation) { @@ -180,12 +180,12 @@ public async Task> GetFixesAsync( var suppressionTargetInfo = new SuppressionTargetInfo() { TargetSymbol = compilation.Assembly }; return await GetSuppressionsAsync( documentOpt: null, project, diagnostics, suppressionTargetInfo, - fallbackOptions, skipSuppressMessage: false, skipUnsuppress: false, + skipSuppressMessage: false, skipUnsuppress: false, cancellationToken).ConfigureAwait(false); } private async Task> GetSuppressionsAsync( - Document documentOpt, Project project, IEnumerable diagnostics, SuppressionTargetInfo suppressionTargetInfo, CodeActionOptionsProvider fallbackOptions, bool skipSuppressMessage, bool skipUnsuppress, CancellationToken cancellationToken) + Document documentOpt, Project project, IEnumerable diagnostics, SuppressionTargetInfo suppressionTargetInfo, bool skipSuppressMessage, bool skipUnsuppress, CancellationToken cancellationToken) { // We only care about diagnostics that can be suppressed/unsuppressed. diagnostics = diagnostics.Where(IsFixableDiagnostic); @@ -212,7 +212,7 @@ private async Task> GetSuppressionsAsync( if (diagnostic.Location.IsInSource && documentOpt != null) { // pragma warning disable. - lazyFormattingOptions ??= await documentOpt.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + lazyFormattingOptions ??= await documentOpt.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); nestedActions.Add(PragmaWarningCodeAction.Create(suppressionTargetInfo, documentOpt, lazyFormattingOptions, diagnostic, this)); } @@ -221,7 +221,7 @@ private async Task> GetSuppressionsAsync( { // global assembly-level suppress message attribute. nestedActions.Add(new GlobalSuppressMessageCodeAction( - suppressionTargetInfo.TargetSymbol, suppressMessageAttribute, project, diagnostic, this, fallbackOptions)); + suppressionTargetInfo.TargetSymbol, suppressMessageAttribute, project, diagnostic, this)); // local suppress message attribute // please note that in order to avoid issues with existing unit tests referencing the code fix @@ -242,7 +242,7 @@ private async Task> GetSuppressionsAsync( } else if (!skipUnsuppress) { - var codeAction = await RemoveSuppressionCodeAction.CreateAsync(suppressionTargetInfo, documentOpt, project, diagnostic, this, fallbackOptions, cancellationToken).ConfigureAwait(false); + var codeAction = await RemoveSuppressionCodeAction.CreateAsync(suppressionTargetInfo, documentOpt, project, diagnostic, this, cancellationToken).ConfigureAwait(false); if (codeAction != null) { result.Add(new CodeFix(project, codeAction, diagnostic)); diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/WrapperCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/WrapperCodeFixProvider.cs index 3c3884d3c2899..027e2a48e2782 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/WrapperCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/WrapperCodeFixProvider.cs @@ -26,14 +26,14 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var documentDiagnostics = diagnostics.Where(d => d.Location.IsInSource).ToImmutableArray(); if (!documentDiagnostics.IsEmpty) { - var suppressionFixes = await _suppressionFixProvider.GetFixesAsync(context.Document, context.Span, documentDiagnostics, context.Options, context.CancellationToken).ConfigureAwait(false); + var suppressionFixes = await _suppressionFixProvider.GetFixesAsync(context.Document, context.Span, documentDiagnostics, context.CancellationToken).ConfigureAwait(false); RegisterSuppressionFixes(context, suppressionFixes); } var projectDiagnostics = diagnostics.Where(d => !d.Location.IsInSource).ToImmutableArray(); if (!projectDiagnostics.IsEmpty) { - var suppressionFixes = await _suppressionFixProvider.GetFixesAsync(context.Document.Project, projectDiagnostics, context.Options, context.CancellationToken).ConfigureAwait(false); + var suppressionFixes = await _suppressionFixProvider.GetFixesAsync(context.Document.Project, projectDiagnostics, context.CancellationToken).ConfigureAwait(false); RegisterSuppressionFixes(context, suppressionFixes); } } diff --git a/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs b/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs index fd88a578f05cf..7f687654b0529 100644 --- a/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs +++ b/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs @@ -76,7 +76,7 @@ private async Task RemoveUnnecessaryImportsAsync( Solution solution, DocumentId sourceDocumentId, DocumentId documentWithMovedTypeId) { var documentWithMovedType = solution.GetRequiredDocument(documentWithMovedTypeId); - var documentWithMovedTypeFormattingOptions = await documentWithMovedType.GetSyntaxFormattingOptionsAsync(State.FallbackOptions, CancellationToken).ConfigureAwait(false); + var documentWithMovedTypeFormattingOptions = await documentWithMovedType.GetSyntaxFormattingOptionsAsync(CancellationToken).ConfigureAwait(false); var syntaxFacts = documentWithMovedType.GetRequiredLanguageService(); var removeUnnecessaryImports = documentWithMovedType.GetRequiredLanguageService(); @@ -95,7 +95,7 @@ private async Task RemoveUnnecessaryImportsAsync( // Now remove any unnecessary imports from the original doc that moved to the new doc. var sourceDocument = solution.GetRequiredDocument(sourceDocumentId); - var sourceDocumentFormattingOptions = await sourceDocument.GetSyntaxFormattingOptionsAsync(State.FallbackOptions, CancellationToken).ConfigureAwait(false); + var sourceDocumentFormattingOptions = await sourceDocument.GetSyntaxFormattingOptionsAsync(CancellationToken).ConfigureAwait(false); sourceDocument = await removeUnnecessaryImports.RemoveUnnecessaryImportsAsync( sourceDocument, n => movedImports.Contains(i => syntaxFacts.AreEquivalent(i, n)), diff --git a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs index aa05c41fdfba2..f41600e751013 100644 --- a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs @@ -789,7 +789,6 @@ private static async Task RemoveUnnecessaryImportsAsync( var result = await RemoveUnnecessaryImportsWorkerAsync( doc, CreateImports(doc, names, withFormatterAnnotation: false), - fallbackOptions, cancellationToken).ConfigureAwait(false); callback((result.Id, await result.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false))); }, @@ -801,12 +800,11 @@ private static async Task RemoveUnnecessaryImportsAsync( async static Task RemoveUnnecessaryImportsWorkerAsync( Document doc, IEnumerable importsToRemove, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken token) { var removeImportService = doc.GetRequiredLanguageService(); var syntaxFacts = doc.GetRequiredLanguageService(); - var formattingOptions = await doc.GetSyntaxFormattingOptionsAsync(fallbackOptions, token).ConfigureAwait(false); + var formattingOptions = await doc.GetSyntaxFormattingOptionsAsync(token).ConfigureAwait(false); return await removeImportService.RemoveUnnecessaryImportsAsync( doc, diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs index 1a5dfd50d3ac5..0120aed951328 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs @@ -112,7 +112,7 @@ private async Task DetermineNewDocumentAsync( var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End)); document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation))); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return await Formatter.FormatAsync(document, _annotation, formattingOptions, cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs index 9e34d43f12d36..81edfcc979f8a 100644 --- a/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs @@ -154,7 +154,7 @@ public override async Task GetChangeAsync( var fallbackOptions = globalOptions?.Provider ?? CodeActionOptions.DefaultProvider; var addImportsOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var importNode = CreateImport(document, containingNamespace); diff --git a/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs index 138400c9c290f..64b091094e07e 100644 --- a/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs @@ -130,7 +130,7 @@ await ReplaceMatchingAnonymousTypesAsync( autoInsertionLocation: false); var info = await document.GetCodeGenerationInfoAsync(context, fallbackOptions, cancellationToken).ConfigureAwait(false); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); // Then, actually insert the new class in the appropriate container. var container = anonymousObject.GetAncestor() ?? root; diff --git a/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs index 83f8c53636c82..5a5864579ecad 100644 --- a/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs @@ -318,7 +318,7 @@ await GenerateStructIntoContainingNamespaceAsync( documentToEditorMap, fallbackOptions, cancellationToken).ConfigureAwait(false); var updatedSolution = await ApplyChangesAsync( - document, documentToEditorMap, fallbackOptions, cancellationToken).ConfigureAwait(false); + document, documentToEditorMap, cancellationToken).ConfigureAwait(false); return updatedSolution; } @@ -583,7 +583,7 @@ private static async Task GenerateStructIntoContainingNamespaceAsync( } private static async Task ApplyChangesAsync( - Document startingDocument, Dictionary documentToEditorMap, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document startingDocument, Dictionary documentToEditorMap, CancellationToken cancellationToken) { var currentSolution = startingDocument.Project.Solution; @@ -600,7 +600,7 @@ private static async Task ApplyChangesAsync( // so that our generated methods follow any special formatting rules specific to // them. var equalsAndGetHashCodeService = startingDocument.GetRequiredLanguageService(); - var formattingOptions = await updatedDocument.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await updatedDocument.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); updatedDocument = await equalsAndGetHashCodeService.FormatDocumentAsync( updatedDocument, formattingOptions, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs b/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs index e8e0cd659dab4..9649e4abbdde2 100644 --- a/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs +++ b/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs @@ -201,7 +201,7 @@ private async Task EncapsulateFieldAsync( var markFieldPrivate = field.DeclaredAccessibility != Accessibility.Private; var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibilityAsync(finalFieldName, markFieldPrivate, document, declarationAnnotation, fallbackOptions, cancellationToken).ConfigureAwait(false); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); document = await Formatter.FormatAsync(document.WithSyntaxRoot(rewrittenFieldDeclaration), Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index 12684fa5f487d..7db9025faab74 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -273,7 +273,7 @@ internal static async Task GetExtractInterfaceOpt var defaultInterfaceName = NameGenerator.GenerateUniqueName(candidateInterfaceName, name => !conflictingTypeNames.Contains(name)); var syntaxFactsService = document.GetLanguageService(); var notificationService = document.Project.Solution.Services.GetService(); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var generatedNameTypeParameterSuffix = ExtractTypeHelpers.GetTypeParameterSuffix(document, formattingOptions, type, extractableMembers, cancellationToken); var service = document.Project.Solution.Services.GetService(); diff --git a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs index 6811d69231553..89696ad7a4c93 100644 --- a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs +++ b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs @@ -73,7 +73,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke } var info = await _document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, _fallbackOptions, cancellationToken).ConfigureAwait(false); - var formattingOptions = await _document.GetSyntaxFormattingOptionsAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await _document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var newTypeDeclaration = info.Service.AddMembers(_typeDeclaration, methods, info, cancellationToken); diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs index 51b300ef0a504..6b9515fe627aa 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs @@ -118,7 +118,7 @@ private async Task> HandleNoExistingFieldOrPropertyAs // Offer to create new one and assign to that. using var _ = ArrayBuilder.GetInstance(out var allActions); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var (fieldAction, propertyAction) = AddSpecificParameterInitializationActions( document, parameter, constructorDeclaration, blockStatement, rules, formattingOptions.AccessibilityModifiersRequired, fallbackOptions); diff --git a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs index e9de1bd657dcb..37daf96bef5d4 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs @@ -262,7 +262,7 @@ private static async Task MoveTypeToNamespaceAsync( // Since MoveTypeService doesn't handle linked files, we need to merge the diff ourselves, // otherwise, we will end up with multiple linked documents with different content. - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var mergedSolution = await PropagateChangeToLinkedDocumentsAsync(modifiedDocument, formattingOptions, cancellationToken).ConfigureAwait(false); var mergedDocument = mergedSolution.GetDocument(document.Id); diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index 081bff40383e7..fa87099bef9d6 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -152,7 +152,7 @@ private async Task CleanupDocumentAsync( { var addImportPlacementOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); var simplifierOptions = await document.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(false); - var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); document = await ImportAdder.AddImportsFromSymbolAnnotationAsync( document, FindSnippetAnnotation, addImportPlacementOptions, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs index fdc3680c652ce..a6a50f11e9981 100644 --- a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs @@ -211,7 +211,7 @@ private async Task ProcessResultAsync(CodeFixContext context, Diagnost editor.RemoveNode(nodeToRemove, syntaxRemoveOptions); var newRoot = editor.GetChangedRoot(); - newRoot = await FormatAsync(newRoot, fieldDocument, context.Options, cancellationToken).ConfigureAwait(false); + newRoot = await FormatAsync(newRoot, fieldDocument, cancellationToken).ConfigureAwait(false); return solution.WithDocumentSyntaxRoot(fieldDocument.Id, newRoot); } @@ -225,8 +225,8 @@ private async Task ProcessResultAsync(CodeFixContext context, Diagnost Contract.ThrowIfNull(newFieldTreeRoot); var newPropertyTreeRoot = propertyTreeRoot.ReplaceNode(property, updatedProperty); - newFieldTreeRoot = await FormatAsync(newFieldTreeRoot, fieldDocument, context.Options, cancellationToken).ConfigureAwait(false); - newPropertyTreeRoot = await FormatAsync(newPropertyTreeRoot, propertyDocument, context.Options, cancellationToken).ConfigureAwait(false); + newFieldTreeRoot = await FormatAsync(newFieldTreeRoot, fieldDocument, cancellationToken).ConfigureAwait(false); + newPropertyTreeRoot = await FormatAsync(newPropertyTreeRoot, propertyDocument, cancellationToken).ConfigureAwait(false); var updatedSolution = solution.WithDocumentSyntaxRoot(fieldDocument.Id, newFieldTreeRoot); updatedSolution = updatedSolution.WithDocumentSyntaxRoot(propertyDocument.Id, newPropertyTreeRoot); @@ -277,13 +277,13 @@ private static bool CanEditDocument( return canEditDocument; } - private async Task FormatAsync(SyntaxNode newRoot, Document document, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private async Task FormatAsync(SyntaxNode newRoot, Document document, CancellationToken cancellationToken) { var formattingRules = GetFormattingRules(document); if (formattingRules.IsDefault) return newRoot; - var options = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return Formatter.Format(newRoot, SpecializedFormattingAnnotation, document.Project.Solution.Services, options, formattingRules, cancellationToken); } diff --git a/src/Features/DiagnosticsTestUtilities/Diagnostics/AbstractSuppressionAllCodeTests.cs b/src/Features/DiagnosticsTestUtilities/Diagnostics/AbstractSuppressionAllCodeTests.cs index ed3217dc8a698..a2d716ae40716 100644 --- a/src/Features/DiagnosticsTestUtilities/Diagnostics/AbstractSuppressionAllCodeTests.cs +++ b/src/Features/DiagnosticsTestUtilities/Diagnostics/AbstractSuppressionAllCodeTests.cs @@ -86,7 +86,7 @@ protected async Task TestPragmaOrAttributeAsync( continue; } - var fixes = fixer.GetFixesAsync(document, diagnostic.Location.SourceSpan, [diagnostic], CodeActionOptions.DefaultProvider, CancellationToken.None).GetAwaiter().GetResult(); + var fixes = fixer.GetFixesAsync(document, diagnostic.Location.SourceSpan, [diagnostic], CancellationToken.None).GetAwaiter().GetResult(); if (fixes == null || fixes.Count() <= 0) { continue; diff --git a/src/Features/ExternalAccess/OmniSharp/DocumentationComments/OmniSharpDocumentationCommentOptionsWrapper.cs b/src/Features/ExternalAccess/OmniSharp/DocumentationComments/OmniSharpDocumentationCommentOptionsWrapper.cs index 46da88e2699b7..e97f58dfcd72a 100644 --- a/src/Features/ExternalAccess/OmniSharp/DocumentationComments/OmniSharpDocumentationCommentOptionsWrapper.cs +++ b/src/Features/ExternalAccess/OmniSharp/DocumentationComments/OmniSharpDocumentationCommentOptionsWrapper.cs @@ -40,7 +40,7 @@ public static async ValueTask FromD bool autoXmlDocCommentGeneration, CancellationToken cancellationToken) { - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(CodeActionOptions.DefaultProvider, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return new(new() { LineFormatting = formattingOptions.LineFormatting, AutoXmlDocCommentGeneration = autoXmlDocCommentGeneration }); } diff --git a/src/Features/ExternalAccess/OmniSharp/Formatting/OmniSharpSyntaxFormattingOptionsWrapper.cs b/src/Features/ExternalAccess/OmniSharp/Formatting/OmniSharpSyntaxFormattingOptionsWrapper.cs index 3120877ca0262..2998a2a2bb754 100644 --- a/src/Features/ExternalAccess/OmniSharp/Formatting/OmniSharpSyntaxFormattingOptionsWrapper.cs +++ b/src/Features/ExternalAccess/OmniSharp/Formatting/OmniSharpSyntaxFormattingOptionsWrapper.cs @@ -34,7 +34,7 @@ public static async ValueTask FromDocum .Add(FormattingOptions2.NewLine.Definition.ConfigName, FormattingOptions2.NewLine.Definition.Serializer.Serialize(fallbackLineFormattingOptions.NewLine))))); return new OmniSharpSyntaxFormattingOptionsWrapper( - optionsWithFallback.GetSyntaxFormattingOptions(document.Project.Services, fallbackOptions: null)); + optionsWithFallback.GetSyntaxFormattingOptions(document.Project.Services)); } } } diff --git a/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.AddKeywordAction.vb b/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.AddKeywordAction.vb index 7c00a8abc3ddc..7291ecdb0064c 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.AddKeywordAction.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.AddKeywordAction.vb @@ -20,7 +20,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.OverloadBase Private ReadOnly _node As SyntaxNode Private ReadOnly _title As String Private ReadOnly _modifier As SyntaxKind - Private ReadOnly _fallbackOptions As SyntaxFormattingOptionsProvider Public Overrides ReadOnly Property Title As String Get @@ -34,17 +33,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.OverloadBase End Get End Property - Public Sub New(document As Document, node As SyntaxNode, title As String, modifier As SyntaxKind, fallbackOptions As SyntaxFormattingOptionsProvider) + Public Sub New(document As Document, node As SyntaxNode, title As String, modifier As SyntaxKind) _document = document _node = node _title = title _modifier = modifier - _fallbackOptions = fallbackOptions End Sub Protected Overrides Async Function GetChangedDocumentAsync(cancellationToken As CancellationToken) As Task(Of Document) Dim root = Await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) - Dim options = Await _document.GetSyntaxFormattingOptionsAsync(_fallbackOptions, cancellationToken).ConfigureAwait(False) + Dim options = Await _document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(False) Dim newNode = Await GetNewNodeAsync(_document, _node, options, cancellationToken).ConfigureAwait(False) Dim newRoot = root.ReplaceNode(_node, newNode) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb index 99cdd9589a84b..124357f4926d8 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/OverloadBase/OverloadBaseCodeFixProvider.vb @@ -46,9 +46,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.OverloadBase End If If diagnostic.Descriptor.Id = BC40003 Then - context.RegisterCodeFix(New AddKeywordAction(context.Document, token.Parent, VBFeaturesResources.Add_Overloads, SyntaxKind.OverloadsKeyword, context.Options), context.Diagnostics) + context.RegisterCodeFix(New AddKeywordAction(context.Document, token.Parent, VBFeaturesResources.Add_Overloads, SyntaxKind.OverloadsKeyword), context.Diagnostics) ElseIf diagnostic.Descriptor.Id = BC40004 Then - context.RegisterCodeFix(New AddKeywordAction(context.Document, token.Parent, VBFeaturesResources.Add_Shadows, SyntaxKind.ShadowsKeyword, context.Options), context.Diagnostics) + context.RegisterCodeFix(New AddKeywordAction(context.Document, token.Parent, VBFeaturesResources.Add_Shadows, SyntaxKind.ShadowsKeyword), context.Diagnostics) End If End Function End Class diff --git a/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs b/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs index 2f00c118bca7e..8a160dc30d3fc 100644 --- a/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs +++ b/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs @@ -849,10 +849,9 @@ public static LSP.VSProjectContext ProjectToProjectContext(Project project) public static async Task GetFormattingOptionsAsync( LSP.FormattingOptions? options, Document document, - IGlobalOptionService globalOptions, CancellationToken cancellationToken) { - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(globalOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); if (options != null) { diff --git a/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs b/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs index 5c40e875f7be4..6dfb370319944 100644 --- a/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs +++ b/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs @@ -69,7 +69,7 @@ public FormatNewFileHandler(IGlobalOptionService globalOptions) } // Unlike normal new file formatting, Razor also wants to remove unnecessary usings - var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false); + var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var removeImportsService = document.GetLanguageService(); if (removeImportsService is not null) { diff --git a/src/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 3b6da1a9e2f29..ae71e08efe42f 100644 --- a/src/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -89,7 +89,7 @@ public async Task CleanupAsync( if (enabledDiagnostics.FormatDocument) { - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); progressTracker.Report(CodeAnalysisProgress.Description(FeaturesResources.Formatting_document)); using (Logger.LogBlock(FunctionId.CodeCleanup_Format, cancellationToken)) @@ -116,7 +116,7 @@ private static async Task RemoveSortUsingsAsync( { using (Logger.LogBlock(FunctionId.CodeCleanup_RemoveUnusedImports, cancellationToken)) { - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); document = await removeUsingsService.RemoveUnnecessaryImportsAsync(document, formattingOptions, cancellationToken).ConfigureAwait(false); } } diff --git a/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index 5a47aae4b19a3..7ad0124d5fb6b 100644 --- a/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -725,7 +725,7 @@ private async IAsyncEnumerable StreamConfigurationFixesAsync( hasFix: d => provider.IsFixableDiagnostic(d), getFixes: async dxs => { - var fixes = await provider.GetFixesAsync(document, diagnosticsSpan, dxs, fallbackOptions, cancellationToken).ConfigureAwait(false); + var fixes = await provider.GetFixesAsync(document, diagnosticsSpan, dxs, cancellationToken).ConfigureAwait(false); return fixes.WhereAsArray(f => registeredConfigurationFixTitles.Add(f.Action.Title)); }, fallbackOptions, diff --git a/src/LanguageServer/Protocol/Features/Options/IndentationOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/IndentationOptionsStorage.cs index 9fd8f38c93dcc..5c18ca87fe454 100644 --- a/src/LanguageServer/Protocol/Features/Options/IndentationOptionsStorage.cs +++ b/src/LanguageServer/Protocol/Features/Options/IndentationOptionsStorage.cs @@ -13,7 +13,7 @@ internal static class IndentationOptionsStorage { public static async Task GetIndentationOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) { - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(globalOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return new IndentationOptions(formattingOptions) { diff --git a/src/LanguageServer/Protocol/Features/Options/SyntaxFormattingOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/SyntaxFormattingOptionsStorage.cs deleted file mode 100644 index 58c8c0aac714e..0000000000000 --- a/src/LanguageServer/Protocol/Features/Options/SyntaxFormattingOptionsStorage.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.Formatting; - -internal static class SyntaxFormattingOptionsStorage -{ - public static ValueTask GetSyntaxFormattingOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetSyntaxFormattingOptionsAsync(globalOptions.GetSyntaxFormattingOptions(document.Project.Services), cancellationToken); - - public static SyntaxFormattingOptions GetSyntaxFormattingOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) - => globalOptions.GetSyntaxFormattingOptions(languageServices, fallbackOptions: null); -} - diff --git a/src/LanguageServer/Protocol/Handler/Formatting/AbstractFormatDocumentHandlerBase.cs b/src/LanguageServer/Protocol/Handler/Formatting/AbstractFormatDocumentHandlerBase.cs index c9b1712f9d66a..45f13c67d6d03 100644 --- a/src/LanguageServer/Protocol/Handler/Formatting/AbstractFormatDocumentHandlerBase.cs +++ b/src/LanguageServer/Protocol/Handler/Formatting/AbstractFormatDocumentHandlerBase.cs @@ -23,7 +23,6 @@ internal abstract class AbstractFormatDocumentHandlerBase GetTextEditsAsync( RequestContext context, LSP.FormattingOptions options, - IGlobalOptionService globalOptions, CancellationToken cancellationToken, LSP.Range? range = null) { @@ -38,7 +37,7 @@ internal abstract class AbstractFormatDocumentHandlerBase + [method: ImportingConstructor] + [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + internal sealed class FormatDocumentHandler() : AbstractFormatDocumentHandlerBase { - private readonly IGlobalOptionService _globalOptions; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public FormatDocumentHandler(IGlobalOptionService globalOptions) - { - _globalOptions = globalOptions; - } - public override LSP.TextDocumentIdentifier GetTextDocumentIdentifier(LSP.DocumentFormattingParams request) => request.TextDocument; public override Task HandleRequestAsync( LSP.DocumentFormattingParams request, RequestContext context, CancellationToken cancellationToken) - => GetTextEditsAsync(context, request.Options, _globalOptions, cancellationToken); + => GetTextEditsAsync(context, request.Options, cancellationToken); } } diff --git a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentOnTypeHandler.cs b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentOnTypeHandler.cs index a3762bb7fe1ad..f15993645ca9c 100644 --- a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentOnTypeHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentOnTypeHandler.cs @@ -60,7 +60,7 @@ public FormatDocumentOnTypeHandler(IGlobalOptionService globalOptions) } // We should use the options passed in by LSP instead of the document's options. - var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(request.Options, document, _globalOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(request.Options, document, cancellationToken).ConfigureAwait(false); var indentationOptions = new IndentationOptions(formattingOptions) { AutoFormattingOptions = _globalOptions.GetAutoFormattingOptions(document.Project.Language) diff --git a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs index dce2297839510..6bb7432fde53f 100644 --- a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs @@ -14,23 +14,16 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler { [ExportCSharpVisualBasicStatelessLspService(typeof(FormatDocumentRangeHandler)), Shared] [Method(Methods.TextDocumentRangeFormattingName)] - internal sealed class FormatDocumentRangeHandler : AbstractFormatDocumentHandlerBase + [method: ImportingConstructor] + [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + internal sealed class FormatDocumentRangeHandler() : AbstractFormatDocumentHandlerBase { - private readonly IGlobalOptionService _globalOptions; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public FormatDocumentRangeHandler(IGlobalOptionService globalOptions) - { - _globalOptions = globalOptions; - } - public override TextDocumentIdentifier GetTextDocumentIdentifier(DocumentRangeFormattingParams request) => request.TextDocument; public override Task HandleRequestAsync( DocumentRangeFormattingParams request, RequestContext context, CancellationToken cancellationToken) - => GetTextEditsAsync(context, request.Options, _globalOptions, cancellationToken, range: request.Range); + => GetTextEditsAsync(context, request.Options, cancellationToken, range: request.Range); } } diff --git a/src/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs b/src/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs index 3704fdb11da52..4c10603b4f061 100644 --- a/src/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs +++ b/src/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs @@ -137,7 +137,7 @@ public TextDocumentIdentifier GetTextDocumentIdentifier(VSInternalInlineCompleti } // Use the formatting options specified by the client to format the snippet. - var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(request.Options, document, _globalOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(request.Options, document, cancellationToken).ConfigureAwait(false); var simplifierOptions = await document.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(false); var formattedLspSnippet = await GetFormattedLspSnippetAsync(parsedSnippet, wordOnLeft.Value, document, sourceText, formattingOptions, simplifierOptions, cancellationToken).ConfigureAwait(false); diff --git a/src/LanguageServer/Protocol/Handler/OnAutoInsert/OnAutoInsertHandler.cs b/src/LanguageServer/Protocol/Handler/OnAutoInsert/OnAutoInsertHandler.cs index b2d1e13496e6f..0e8cfb9fe6f41 100644 --- a/src/LanguageServer/Protocol/Handler/OnAutoInsert/OnAutoInsertHandler.cs +++ b/src/LanguageServer/Protocol/Handler/OnAutoInsert/OnAutoInsertHandler.cs @@ -69,7 +69,7 @@ internal sealed class OnAutoInsertHandler( var service = document.GetRequiredLanguageService(); // We should use the options passed in by LSP instead of the document's options. - var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(lspFormattingOptions, document, globalOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await ProtocolConversions.GetFormattingOptionsAsync(lspFormattingOptions, document, cancellationToken).ConfigureAwait(false); // The editor calls this handler for C# and VB comment characters, but we only need to process the one for the language that matches the document if (character == "\n" || character == service.DocumentationCommentCharacter) @@ -239,10 +239,11 @@ static string GetTextChangeTextWithCaretAtLocation(SourceText sourceText, TextCh private static async Task<(IBraceCompletionService Service, BraceCompletionContext Context)?> GetBraceCompletionContextAsync(ImmutableArray servicesForDocument, int caretLocation, Document document, CancellationToken cancellationToken) { var parsedDocument = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); + var fallbackOptions = document.Project.GetFallbackAnalyzerOptions(); foreach (var service in servicesForDocument) { - var context = service.GetCompletedBraceContext(parsedDocument, caretLocation); + var context = service.GetCompletedBraceContext(parsedDocument, fallbackOptions, caretLocation); if (context != null) { return (service, context.Value); diff --git a/src/VisualStudio/Core/Def/ExtractClass/VisualStudioExtractClassOptionsService.cs b/src/VisualStudio/Core/Def/ExtractClass/VisualStudioExtractClassOptionsService.cs index eb53373a3fd69..74e48a82e22d4 100644 --- a/src/VisualStudio/Core/Def/ExtractClass/VisualStudioExtractClassOptionsService.cs +++ b/src/VisualStudio/Core/Def/ExtractClass/VisualStudioExtractClassOptionsService.cs @@ -33,20 +33,17 @@ internal class VisualStudioExtractClassOptionsService : IExtractClassOptionsServ private readonly IThreadingContext _threadingContext; private readonly IGlyphService _glyphService; private readonly IUIThreadOperationExecutor _uiThreadOperationExecutor; - private readonly IGlobalOptionService _globalOptions; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public VisualStudioExtractClassOptionsService( IThreadingContext threadingContext, IGlyphService glyphService, - IUIThreadOperationExecutor uiThreadOperationExecutor, - IGlobalOptionService globalOptions) + IUIThreadOperationExecutor uiThreadOperationExecutor) { _threadingContext = threadingContext; _glyphService = glyphService; _uiThreadOperationExecutor = uiThreadOperationExecutor; - _globalOptions = globalOptions; } public async Task GetExtractClassOptionsAsync(Document document, INamedTypeSymbol selectedType, ImmutableArray selectedMembers, CancellationToken cancellationToken) @@ -77,7 +74,7 @@ public VisualStudioExtractClassOptionsService( ? string.Empty : selectedType.ContainingNamespace.ToDisplayString(); - var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var generatedNameTypeParameterSuffix = ExtractTypeHelpers.GetTypeParameterSuffix(document, formattingOptions, selectedType, membersInType, cancellationToken); var viewModel = new ExtractClassViewModel( diff --git a/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.IVsLanguageTextOps.cs b/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.IVsLanguageTextOps.cs index 186c4f4c72ec8..4f3ce55b5f064 100644 --- a/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.IVsLanguageTextOps.cs +++ b/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.IVsLanguageTextOps.cs @@ -56,7 +56,7 @@ private int FormatWorker(IVsTextLayer textLayer, TextSpan[] selections, Cancella var documentSyntax = ParsedDocument.CreateSynchronously(document, cancellationToken); var text = documentSyntax.Text; var root = documentSyntax.Root; - var formattingOptions = textBuffer.GetSyntaxFormattingOptions(EditorOptionsService, document.Project.Services, explicitFormat: true); + var formattingOptions = textBuffer.GetSyntaxFormattingOptions(EditorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: true); var ts = selections.Single(); var start = text.Lines[ts.iStartLine].Start + ts.iStartIndex; diff --git a/src/VisualStudio/Core/Def/Snippets/SnippetExpansionClient.cs b/src/VisualStudio/Core/Def/Snippets/SnippetExpansionClient.cs index 033fc59795f93..c8af6b722519b 100644 --- a/src/VisualStudio/Core/Def/Snippets/SnippetExpansionClient.cs +++ b/src/VisualStudio/Core/Def/Snippets/SnippetExpansionClient.cs @@ -1062,8 +1062,9 @@ private void AddReferencesAndImports( } var languageServices = documentWithImports.Project.Services; - var addImportOptions = SubjectBuffer.GetAddImportPlacementOptions(EditorOptionsService, languageServices, documentWithImports.AllowImportsInHiddenRegions()); - var formattingOptions = SubjectBuffer.GetSyntaxFormattingOptions(EditorOptionsService, languageServices, explicitFormat: false); + var fallbackOptions = documentWithImports.Project.GetFallbackAnalyzerOptions(); + var addImportOptions = SubjectBuffer.GetAddImportPlacementOptions(EditorOptionsService, fallbackOptions, languageServices, documentWithImports.AllowImportsInHiddenRegions()); + var formattingOptions = SubjectBuffer.GetSyntaxFormattingOptions(EditorOptionsService, fallbackOptions, languageServices, explicitFormat: false); documentWithImports = _languageHelper.AddImports(documentWithImports, addImportOptions, formattingOptions, position, snippetNode, cancellationToken); AddReferences(documentWithImports.Project, snippetNode); diff --git a/src/VisualStudio/Core/Def/Venus/ContainedDocument.cs b/src/VisualStudio/Core/Def/Venus/ContainedDocument.cs index ae479cb51a38d..494ec8edaad02 100644 --- a/src/VisualStudio/Core/Def/Venus/ContainedDocument.cs +++ b/src/VisualStudio/Core/Def/Venus/ContainedDocument.cs @@ -770,7 +770,7 @@ private void AdjustIndentation(IProjectionBuffer subjectBuffer, IEnumerable Debug.Assert(ReferenceEquals(parsedDocument.Text, subjectBuffer.CurrentSnapshot.AsText())); var editorOptionsService = _componentModel.GetService(); - var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(editorOptionsService, document.Project.Services, explicitFormat: false); + var formattingOptions = subjectBuffer.GetSyntaxFormattingOptions(editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), document.Project.Services, explicitFormat: false); using var pooledObject = SharedPools.Default>().GetPooledObject(); diff --git a/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs b/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs index 5a3744b54f520..0f8b0e399d1c6 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/AbstractCodeModelService.cs @@ -1042,7 +1042,7 @@ private Document FormatAnnotatedNode(Document document, SyntaxAnnotation annotat return _threadingContext.JoinableTaskFactory.Run(async () => { - var options = await document.GetSyntaxFormattingOptionsAsync(_editorOptionsService.GlobalOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return await Formatter.FormatAsync( document, diff --git a/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs b/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs index 62359b046a62e..6837a3f4123b7 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs @@ -347,7 +347,7 @@ internal void PerformEdit(Func action) var formatted = State.ThreadingContext.JoinableTaskFactory.Run(async () => { - var formattingOptions = await result.GetSyntaxFormattingOptionsAsync(GlobalOptions, CancellationToken.None).ConfigureAwait(false); + var formattingOptions = await result.GetSyntaxFormattingOptionsAsync(CancellationToken.None).ConfigureAwait(false); var formatted = await Formatter.FormatAsync(result, Formatter.Annotation, formattingOptions, CancellationToken.None).ConfigureAwait(true); formatted = await Formatter.FormatAsync(formatted, SyntaxAnnotation.ElasticAnnotation, formattingOptions, CancellationToken.None).ConfigureAwait(true); diff --git a/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs b/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs index 3ec296405e07d..71416ef4a42cb 100644 --- a/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs +++ b/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs @@ -137,7 +137,7 @@ public void UpdatePreview(string text) var document = project.AddDocument("document", SourceText.From(text, Encoding.UTF8)); var fallbackFormattingOptions = OptionStore.GlobalOptions.GetSyntaxFormattingOptions(document.Project.Services); var formattingService = document.GetRequiredLanguageService(); - var formattingOptions = formattingService.GetFormattingOptions(OptionStore, fallbackFormattingOptions); + var formattingOptions = formattingService.GetFormattingOptions(OptionStore); var formatted = Formatter.FormatAsync(document, formattingOptions, CancellationToken.None).WaitAndGetResult(CancellationToken.None); var textBuffer = _textBufferCloneService.Clone(formatted.GetTextSynchronously(CancellationToken.None), _contentType); diff --git a/src/Workspaces/Core/Portable/CodeFixes/Supression/IConfigurationFixProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/Supression/IConfigurationFixProvider.cs index 2fd5dfb0a34d1..1968fc91db5af 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/Supression/IConfigurationFixProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/Supression/IConfigurationFixProvider.cs @@ -25,13 +25,13 @@ internal interface IConfigurationFixProvider /// Gets one or more add suppression, remove suppression, or configuration fixes for the specified diagnostics represented as a list of 's. /// /// A list of zero or more potential 'es. It is also safe to return null if there are none. - Task> GetFixesAsync(TextDocument document, TextSpan span, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GetFixesAsync(TextDocument document, TextSpan span, IEnumerable diagnostics, CancellationToken cancellationToken); /// /// Gets one or more add suppression, remove suppression, or configuration fixes for the specified no-location diagnostics represented as a list of 's. /// /// A list of zero or more potential 'es. It is also safe to return null if there are none. - Task> GetFixesAsync(Project project, IEnumerable diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GetFixesAsync(Project project, IEnumerable diagnostics, CancellationToken cancellationToken); /// /// Gets an optional that can fix all/multiple occurrences of diagnostics fixed by this fix provider. diff --git a/src/Workspaces/Core/Portable/Formatting/Formatter.cs b/src/Workspaces/Core/Portable/Formatting/Formatter.cs index 9810d95a87592..8741477c480fe 100644 --- a/src/Workspaces/Core/Portable/Formatting/Formatter.cs +++ b/src/Workspaces/Core/Portable/Formatting/Formatter.cs @@ -90,7 +90,7 @@ public static async Task FormatAsync(Document document, IEnumerable FormatAsync(Document document, IEnumerable? spans, SyntaxFormattingOptions? options, ImmutableArray rules, CancellationToken cancellationToken) { - options ??= await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); + options ??= await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var services = document.Project.Solution.Services; return document.WithSyntaxRoot(Format(root, spans, services, options, rules, cancellationToken)); @@ -318,7 +318,7 @@ internal static IList GetFormattedTextChanges(SyntaxNode node, IEnum internal static SyntaxFormattingOptions GetFormattingOptions(Workspace workspace, OptionSet? optionSet, string language) { var syntaxFormattingService = workspace.Services.GetRequiredLanguageService(language); - return syntaxFormattingService.GetFormattingOptions(optionSet ?? workspace.CurrentSolution.Options, fallbackOptions: null); + return syntaxFormattingService.GetFormattingOptions(optionSet ?? workspace.CurrentSolution.Options); } #pragma warning disable RS0030 // Do not used banned APIs (backwards compatibility) @@ -332,7 +332,7 @@ internal static SyntaxFormattingOptions GetFormattingOptions(Workspace workspace var syntaxFormattingService = document.GetLanguageService(); if (syntaxFormattingService != null) { - syntaxFormattingOptions = syntaxFormattingService.GetFormattingOptions(optionSet, fallbackOptions: null); + syntaxFormattingOptions = syntaxFormattingService.GetFormattingOptions(optionSet); lineFormattingOptions = syntaxFormattingOptions.LineFormatting; } else diff --git a/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs b/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs index ff2967895982c..586ca3474750a 100644 --- a/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs +++ b/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs @@ -38,7 +38,7 @@ ValueTask OptionsProvider. => ValueTaskFactory.FromResult(options.GetDocumentFormattingOptions(fallbackOptions: null)); ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetSyntaxFormattingOptions(languageServices, fallbackOptions: null)); + => ValueTaskFactory.FromResult(options.GetSyntaxFormattingOptions(languageServices)); ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) => ValueTaskFactory.FromResult(options.GetSimplifierOptions(languageServices)); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs index d5775d1b4f502..cb6832d8646bc 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs @@ -802,6 +802,12 @@ private void CheckIdsContainedInProject(ImmutableArray documentIds) internal AnalyzerConfigData? GetAnalyzerConfigOptions() => _projectState.GetAnalyzerConfigOptions(); + /// + /// Retrieves fallback analyzer options for this project's language. + /// + internal StructuredAnalyzerConfigOptions GetFallbackAnalyzerOptions() + => _solution.FallbackAnalyzerOptions.GetValueOrDefault(Language, StructuredAnalyzerConfigOptions.Empty); + private string GetDebuggerDisplay() => this.Name; diff --git a/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs b/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs index 53491c70ed86d..fc2f16633463e 100644 --- a/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs +++ b/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs @@ -54,7 +54,7 @@ private protected async Task AssertFormatAsync( var formattingService = document.GetRequiredLanguageService(); var formattingOptions = changedOptions != null - ? formattingService.GetFormattingOptions(changedOptions, fallbackOptions: null) + ? formattingService.GetFormattingOptions(changedOptions) : formattingService.DefaultOptions; var syntaxTree = await document.GetRequiredSyntaxTreeAsync(CancellationToken.None); diff --git a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs index 3d20103db09f8..4313e5532c122 100644 --- a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs +++ b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs @@ -116,21 +116,37 @@ internal TestWorkspace( } } - public void SetAnalyzerFallbackOptions(string language, params (string name, string value)[] options) + /// + /// Use to set specified editorconfig options as . + /// + internal void SetAnalyzerFallbackOptions(OptionsCollection? options) { + if (options == null) + { + return; + } + SetCurrentSolution( - s => s.WithFallbackAnalyzerOptions(s.FallbackAnalyzerOptions.SetItem(language, - StructuredAnalyzerConfigOptions.Create( - new DictionaryAnalyzerConfigOptions( - options.Select(static o => KeyValuePairUtil.Create(o.name, o.value)).ToImmutableDictionary())))), + s => s.WithFallbackAnalyzerOptions(s.FallbackAnalyzerOptions.SetItem(options.LanguageName, options.ToAnalyzerConfigOptions())), changeKind: WorkspaceChangeKind.SolutionChanged); } - internal void SetAnalyzerFallbackOptions(OptionsCollection options) + /// + /// Use to set specified options both as global options and as . + /// Only editorconfig options listed in will be set to the latter. + /// + internal void SetAnalyzerFallbackAndGlobalOptions(OptionsCollection? options) { - SetCurrentSolution( - s => s.WithFallbackAnalyzerOptions(s.FallbackAnalyzerOptions.SetItem(options.LanguageName, options.ToAnalyzerConfigOptions())), - changeKind: WorkspaceChangeKind.SolutionChanged); + if (options == null) + { + return; + } + + var configOptions = new OptionsCollection(options.LanguageName); + configOptions.AddRange(options.Where(entry => entry.Key.Option.Definition.IsEditorConfigOption)); + SetAnalyzerFallbackOptions(configOptions); + + options.SetGlobalOptions(GlobalOptions); } private static HostServices GetHostServices([NotNull] ref TestComposition? composition, bool hasWorkspaceConfigurationOptions) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs index 19b67ce8243ab..d8572dffba6c5 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs @@ -39,8 +39,8 @@ public override ImmutableArray GetDefaultFormattingRules public override SyntaxFormattingOptions DefaultOptions => CSharpSyntaxFormattingOptions.Default; - public override SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options, SyntaxFormattingOptions? fallbackOptions) - => new CSharpSyntaxFormattingOptions(options, (CSharpSyntaxFormattingOptions?)fallbackOptions); + public override SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options) + => new CSharpSyntaxFormattingOptions(options, fallbackOptions: null); protected override IFormattingResult CreateAggregatedFormattingResult(SyntaxNode node, IList results, TextSpanMutableIntervalTree? formattingSpans = null) => new AggregatedFormattingResult(node, results, formattingSpans); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs index 658ddb186f855..6ea3b329423cb 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs @@ -87,7 +87,7 @@ internal static class CodeCleanupOptionsProviders public static CodeCleanupOptions GetCodeCleanupOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowImportsInHiddenRegions, CodeCleanupOptions? fallbackOptions) => new() { - FormattingOptions = options.GetSyntaxFormattingOptions(languageServices, fallbackOptions?.FormattingOptions), + FormattingOptions = options.GetSyntaxFormattingOptions(languageServices), SimplifierOptions = options.GetSimplifierOptions(languageServices), AddImportOptions = options.GetAddImportPlacementOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions?.AddImportOptions), DocumentFormattingOptions = options.GetDocumentFormattingOptions(fallbackOptions?.DocumentFormattingOptions), diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormatting.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormatting.cs index 8817da296f1b2..1c78cb66e3e6c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormatting.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/AbstractSyntaxFormatting.cs @@ -21,7 +21,7 @@ internal abstract class AbstractSyntaxFormatting : ISyntaxFormatting private static readonly Func s_notEmpty = s => !s.IsEmpty; public abstract SyntaxFormattingOptions DefaultOptions { get; } - public abstract SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options, SyntaxFormattingOptions? fallbackOptions); + public abstract SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options); public abstract ImmutableArray GetDefaultFormattingRules(); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormatting.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormatting.cs index aa3bf201c3742..6542f10269a5b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormatting.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/ISyntaxFormatting.cs @@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.Formatting; internal interface ISyntaxFormatting { SyntaxFormattingOptions DefaultOptions { get; } - SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options, SyntaxFormattingOptions? fallbackOptions); + SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options); ImmutableArray GetDefaultFormattingRules(); IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerable? spans, SyntaxFormattingOptions options, ImmutableArray rules, CancellationToken cancellationToken); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs index 69a0415ff71d1..28fa9f8675fc6 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs @@ -64,16 +64,13 @@ internal interface SyntaxFormattingOptionsProvider : internal static partial class SyntaxFormattingOptionsProviders { #if !CODE_STYLE - public static SyntaxFormattingOptions GetSyntaxFormattingOptions(this IOptionsReader options, LanguageServices languageServices, SyntaxFormattingOptions? fallbackOptions) - => languageServices.GetRequiredService().GetFormattingOptions(options, fallbackOptions); + public static SyntaxFormattingOptions GetSyntaxFormattingOptions(this IOptionsReader options, LanguageServices languageServices) + => languageServices.GetRequiredService().GetFormattingOptions(options); - public static async ValueTask GetSyntaxFormattingOptionsAsync(this Document document, SyntaxFormattingOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetSyntaxFormattingOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetSyntaxFormattingOptions(document.Project.Services, fallbackOptions); + return configOptions.GetSyntaxFormattingOptions(document.Project.Services); } - - public static async ValueTask GetSyntaxFormattingOptionsAsync(this Document document, SyntaxFormattingOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await GetSyntaxFormattingOptionsAsync(document, await ((OptionsProvider)fallbackOptionsProvider).GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); #endif } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs index 1f572ec2cd76c..39bcea51a4d08 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs @@ -54,7 +54,7 @@ public LineFormattingOptions GetLineFormattingOptions() // SyntaxFormattingOptions public SyntaxFormattingOptions GetFormattingOptions(ISyntaxFormatting formatting) - => formatting.GetFormattingOptions(_options, FallbackSyntaxFormattingOptions); + => formatting.GetFormattingOptions(_options); public AccessibilityModifiersRequired AccessibilityModifiersRequired => _options.GetOptionValue(CodeStyleOptions2.AccessibilityModifiersRequired, _languageServices.Language, FallbackCommonSyntaxFormattingOptions.AccessibilityModifiersRequired); @@ -68,13 +68,6 @@ private LineFormattingOptions FallbackLineFormattingOptions => _fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.FormattingOptions.LineFormatting; #endif - private SyntaxFormattingOptions? FallbackSyntaxFormattingOptions -#if CODE_STYLE - => null; -#else - => _fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.FormattingOptions; -#endif - private SyntaxFormattingOptions FallbackCommonSyntaxFormattingOptions #if CODE_STYLE => SyntaxFormattingOptions.CommonDefaults; diff --git a/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb b/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb index 9ab542e29c0ce..9a13c1e0b8da1 100644 --- a/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb +++ b/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb @@ -35,8 +35,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting End Get End Property - Public Overrides Function GetFormattingOptions(options As IOptionsReader, fallbackOptions As SyntaxFormattingOptions) As SyntaxFormattingOptions - Return New VisualBasicSyntaxFormattingOptions(options, DirectCast(fallbackOptions, VisualBasicSyntaxFormattingOptions)) + Public Overrides Function GetFormattingOptions(options As IOptionsReader) As SyntaxFormattingOptions + Return New VisualBasicSyntaxFormattingOptions(options, fallbackOptions:=Nothing) End Function Protected Overrides Function CreateAggregatedFormattingResult(node As SyntaxNode, results As IList(Of AbstractFormattingResult), Optional formattingSpans As TextSpanMutableIntervalTree = Nothing) As IFormattingResult From 21fd45be332b22b81d9953be98eead183eb8537c Mon Sep 17 00:00:00 2001 From: DoctorKrolic <70431552+DoctorKrolic@users.noreply.github.com> Date: Tue, 9 Jul 2024 00:36:52 +0300 Subject: [PATCH 40/59] Improve parser recovery around nullable types in patterns (#72805) --- .../CSharp/Portable/Parser/LanguageParser.cs | 79 +- .../Parser/LanguageParser_Patterns.cs | 51 +- .../Emit2/Semantics/PatternMatchingTests.cs | 18 +- .../Emit2/Semantics/PatternMatchingTests2.cs | 27 +- .../Emit2/Semantics/PatternMatchingTests4.cs | 35 +- .../PatternMatchingTests_NullableTypes.cs | 675 ++++++++++++++++++ .../Test/Semantic/Semantics/NullableTests.cs | 16 +- .../Test/Syntax/Parsing/AsyncParsingTests.cs | 194 ++++- .../Test/Syntax/Parsing/AwaitParsingTests.cs | 359 ++++++++++ .../Parsing/DeclarationExpressionTests.cs | 61 +- .../Syntax/Parsing/NullableParsingTests.cs | 582 +++++++++++++++ .../Syntax/Parsing/PatternParsingTests2.cs | 384 ++++++++++ .../PatternParsingTests_ListPatterns.cs | 507 ++++++++++++- .../Syntax/Parsing/StatementParsingTests.cs | 323 +++++++++ .../Parsing/SwitchExpressionParsingTests.cs | 654 +++++++++++++++++ 15 files changed, 3851 insertions(+), 114 deletions(-) create mode 100644 src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests_NullableTypes.cs diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 31c2e242c1c8e..887dfabee8fb7 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -7223,18 +7223,79 @@ bool canFollowNullableType() case ParseTypeMode.AfterIs: case ParseTypeMode.DefinitePattern: case ParseTypeMode.AsExpression: - // These contexts might be a type that is at the end of an expression. In these contexts we only - // permit the nullable qualifier if it is followed by a token that could not start an - // expression, because for backward compatibility we want to consider a `?` token as part of the - // `?:` operator if possible. + // We are currently after `?` token after a nullable type pattern and need to decide how to + // parse what we see next. In the case of an identifier (e.g. `x ? a` there are two ways we can + // see things // - // Similarly, if we have `T?[]` we do want to treat that as an array of nullables (following - // existing parsing), not a conditional that returns a list. + // 1. As a start of conditional expression, e.g. `var a = obj is string ? a : b` + // 2. As a designation of a nullable-typed pattern, e.g. `if (obj is string? str)` + // + // Since nullable types (no matter reference or value types) are not valid in patterns by + // default we are biased towards the first option and consider case 2 only for error recovery + // purposes (if we parse here as nullable type pattern an error will be reported during + // binding). This condition checks for simple cases, where we better use option 2 and parse a + // nullable-typed pattern + if (IsTrueIdentifier(this.CurrentToken)) + { + // In a non-async method, `await` is a simple identifier. However, if we see `x ? await` + // it's almost certainly the start of an `await expression` in a conditional expression + // (e.g. `x is Y ? await ...`), not a nullable type pattern (since users would not use + // 'await' as the name of a variable). So just treat this as a conditional expression. + // Similarly, `async` can start a simple lambda in a conditional expression + // (e.g. `x is Y ? async a => ...`). The correct behavior is to treat `async` as a keyword + if (this.CurrentToken.ContextualKind is SyntaxKind.AsyncKeyword or SyntaxKind.AwaitKeyword) + return false; + + var nextTokenKind = PeekToken(1).Kind; + + // These token either 100% end a pattern or start a new one: + + // A literal token starts a new pattern. Can occur in list pattern with missing separation + // `,`. For example, in `x is [int[]? arr 5]` we'd prefer to parse this as a missing `,` + // after `arr` + if (SyntaxFacts.IsLiteral(nextTokenKind)) + return true; + + // A predefined type is basically the same case: `x is [string[]? slice char ch]`. We'd + // prefer to parse this as a missing `,` after `slice`. + if (SyntaxFacts.IsPredefinedType(nextTokenKind)) + return true; + + // `)`, `]` and `}` obviously end a pattern. For example: + // `if (x is int? i)`, `indexable[x is string? s]`, `x is { Prop: Type? typeVar }` + if (nextTokenKind is SyntaxKind.CloseParenToken or SyntaxKind.CloseBracketToken or SyntaxKind.CloseBraceToken) + return true; + + // `{` starts a new pattern. For example: `x is A? { ...`. Note, that `[` and `(` are not + // in the list because they can start an invocation/indexer + if (nextTokenKind == SyntaxKind.OpenBraceToken) + return true; + + // `,` ends a pattern in list/property pattern. For example `x is { Prop1: Type1? type, Prop2: Type2 }` or + // `x is [Type1? type, ...]` + if (nextTokenKind == SyntaxKind.CommaToken) + return true; + + // `;` ends a pattern if it finishes an expression statement: var y = x is bool? b; + if (nextTokenKind == SyntaxKind.SemicolonToken) + return true; + + // EndOfFileToken is obviously the end of parsing. We are better parsing a pattern rather + // than an unfinished conditional expression + if (nextTokenKind == SyntaxKind.EndOfFileToken) + return true; + + return false; + } + + // If nothing from above worked permit the nullable qualifier if it is followed by a token that + // could not start an expression. If we have `T?[]` we do want to treat that as an array of + // nullables (following existing parsing), not a conditional that returns a list. return !CanStartExpression() || this.CurrentToken.Kind is SyntaxKind.OpenBracketToken; case ParseTypeMode.NewExpression: - // A nullable qualifier is permitted as part of the type in a `new` expression. - // e.g. `new int?()` is allowed. It creates a null value of type `Nullable`. - // Similarly `new int? {}` is allowed. + // A nullable qualifier is permitted as part of the type in a `new` expression. e.g. `new + // int?()` is allowed. It creates a null value of type `Nullable`. Similarly `new int? {}` + // is allowed. return this.CurrentToken.Kind is SyntaxKind.OpenParenToken or // ctor parameters SyntaxKind.OpenBracketToken or // array type diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs index e9b3e9a56cb83..ad961242a9386 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser_Patterns.cs @@ -50,21 +50,21 @@ when ConvertExpressionToType(expr, out var leftType): }; } - private PatternSyntax ParsePattern(Precedence precedence, bool afterIs = false, bool whenIsKeyword = false) + private PatternSyntax ParsePattern(Precedence precedence, bool afterIs = false, bool inSwitchArmPattern = false) { - return ParseDisjunctivePattern(precedence, afterIs, whenIsKeyword); + return ParseDisjunctivePattern(precedence, afterIs, inSwitchArmPattern); } - private PatternSyntax ParseDisjunctivePattern(Precedence precedence, bool afterIs, bool whenIsKeyword) + private PatternSyntax ParseDisjunctivePattern(Precedence precedence, bool afterIs, bool inSwitchArmPattern) { - PatternSyntax result = ParseConjunctivePattern(precedence, afterIs, whenIsKeyword); + PatternSyntax result = ParseConjunctivePattern(precedence, afterIs, inSwitchArmPattern); while (this.CurrentToken.ContextualKind == SyntaxKind.OrKeyword) { result = _syntaxFactory.BinaryPattern( SyntaxKind.OrPattern, result, ConvertToKeyword(this.EatToken()), - ParseConjunctivePattern(precedence, afterIs, whenIsKeyword)); + ParseConjunctivePattern(precedence, afterIs, inSwitchArmPattern)); } return result; @@ -101,16 +101,16 @@ private bool LooksLikeTypeOfPattern() return false; } - private PatternSyntax ParseConjunctivePattern(Precedence precedence, bool afterIs, bool whenIsKeyword) + private PatternSyntax ParseConjunctivePattern(Precedence precedence, bool afterIs, bool inSwitchArmPattern) { - PatternSyntax result = ParseNegatedPattern(precedence, afterIs, whenIsKeyword); + PatternSyntax result = ParseNegatedPattern(precedence, afterIs, inSwitchArmPattern); while (this.CurrentToken.ContextualKind == SyntaxKind.AndKeyword) { result = _syntaxFactory.BinaryPattern( SyntaxKind.AndPattern, result, ConvertToKeyword(this.EatToken()), - ParseNegatedPattern(precedence, afterIs, whenIsKeyword)); + ParseNegatedPattern(precedence, afterIs, inSwitchArmPattern)); } return result; @@ -155,21 +155,21 @@ private bool ScanDesignation(bool permitTuple) } } - private PatternSyntax ParseNegatedPattern(Precedence precedence, bool afterIs, bool whenIsKeyword) + private PatternSyntax ParseNegatedPattern(Precedence precedence, bool afterIs, bool inSwitchArmPattern) { if (this.CurrentToken.ContextualKind == SyntaxKind.NotKeyword) { return _syntaxFactory.UnaryPattern( ConvertToKeyword(this.EatToken()), - ParseNegatedPattern(precedence, afterIs, whenIsKeyword)); + ParseNegatedPattern(precedence, afterIs, inSwitchArmPattern)); } else { - return ParsePrimaryPattern(precedence, afterIs, whenIsKeyword); + return ParsePrimaryPattern(precedence, afterIs, inSwitchArmPattern); } } - private PatternSyntax ParsePrimaryPattern(Precedence precedence, bool afterIs, bool whenIsKeyword) + private PatternSyntax ParsePrimaryPattern(Precedence precedence, bool afterIs, bool inSwitchArmPattern) { // handle common error recovery situations during typing var tk = this.CurrentToken.Kind; @@ -192,10 +192,10 @@ private PatternSyntax ParsePrimaryPattern(Precedence precedence, bool afterIs, b switch (CurrentToken.Kind) { case SyntaxKind.OpenBracketToken: - return this.ParseListPattern(whenIsKeyword); + return this.ParseListPattern(inSwitchArmPattern); case SyntaxKind.DotDotToken: return _syntaxFactory.SlicePattern(EatToken(), - IsPossibleSubpatternElement() ? ParsePattern(precedence, afterIs: false, whenIsKeyword) : null); + IsPossibleSubpatternElement() ? ParsePattern(precedence, afterIs: false, inSwitchArmPattern) : null); case SyntaxKind.LessThanToken: case SyntaxKind.LessThanEqualsToken: case SyntaxKind.GreaterThanToken: @@ -214,7 +214,8 @@ private PatternSyntax ParsePrimaryPattern(Precedence precedence, bool afterIs, b TypeSyntax? type = null; if (LooksLikeTypeOfPattern()) { - type = this.ParseType(afterIs ? ParseTypeMode.AfterIs : ParseTypeMode.DefinitePattern); + type = this.ParseType( + afterIs ? ParseTypeMode.AfterIs : ParseTypeMode.DefinitePattern); if (type.IsMissing || !CanTokenFollowTypeInPattern(precedence)) { // either it is not shaped like a type, or it is a constant expression. @@ -223,7 +224,7 @@ private PatternSyntax ParsePrimaryPattern(Precedence precedence, bool afterIs, b } } - var pattern = ParsePatternContinued(type, precedence, whenIsKeyword); + var pattern = ParsePatternContinued(type, precedence, inSwitchArmPattern); if (pattern != null) return pattern; @@ -262,14 +263,14 @@ bool CanTokenFollowTypeInPattern(Precedence precedence) } } - private PatternSyntax? ParsePatternContinued(TypeSyntax? type, Precedence precedence, bool whenIsKeyword) + private PatternSyntax? ParsePatternContinued(TypeSyntax? type, Precedence precedence, bool inSwitchArmPattern) { if (type?.Kind == SyntaxKind.IdentifierName) { var typeIdentifier = (IdentifierNameSyntax)type; var typeIdentifierToken = typeIdentifier.Identifier; if (typeIdentifierToken.ContextualKind == SyntaxKind.VarKeyword && - (this.CurrentToken.Kind == SyntaxKind.OpenParenToken || this.IsValidPatternDesignation(whenIsKeyword))) + (this.CurrentToken.Kind == SyntaxKind.OpenParenToken || this.IsValidPatternDesignation(inSwitchArmPattern))) { // we have a "var" pattern; "var" is not permitted to be a stand-in for a type (or a constant) in a pattern. var varToken = ConvertToKeyword(typeIdentifierToken); @@ -295,7 +296,7 @@ bool CanTokenFollowTypeInPattern(Precedence precedence) var closeParenToken = this.EatToken(SyntaxKind.CloseParenToken); parsePropertyPatternClause(out PropertyPatternClauseSyntax? propertyPatternClause0); - var designation0 = TryParseSimpleDesignation(whenIsKeyword); + var designation0 = TryParseSimpleDesignation(inSwitchArmPattern); if (type == null && propertyPatternClause0 == null && @@ -333,12 +334,12 @@ bool CanTokenFollowTypeInPattern(Precedence precedence) { return _syntaxFactory.RecursivePattern( type, positionalPatternClause: null, propertyPatternClause, - TryParseSimpleDesignation(whenIsKeyword)); + TryParseSimpleDesignation(inSwitchArmPattern)); } if (type != null) { - var designation = TryParseSimpleDesignation(whenIsKeyword); + var designation = TryParseSimpleDesignation(inSwitchArmPattern); if (designation != null) return _syntaxFactory.DeclarationPattern(type, designation); @@ -431,7 +432,7 @@ private CSharpSyntaxNode ParseExpressionOrPatternForSwitchStatement() { var savedState = _termState; _termState |= TerminatorState.IsExpressionOrPatternInCaseLabelOfSwitchStatement; - var pattern = ParsePattern(Precedence.Conditional, whenIsKeyword: true); + var pattern = ParsePattern(Precedence.Conditional, inSwitchArmPattern: true); _termState = savedState; return ConvertPatternToExpressionIfPossible(pattern); } @@ -589,7 +590,7 @@ SeparatedSyntaxList parseSwitchExpressionArms() var savedState = _termState; _termState |= TerminatorState.IsPatternInSwitchExpressionArm; - var pattern = ParsePattern(Precedence.Coalescing, whenIsKeyword: true); + var pattern = ParsePattern(Precedence.Coalescing, inSwitchArmPattern: true); _termState = savedState; // We use a precedence that excludes lambdas, assignments, and a conditional which could have a @@ -628,7 +629,7 @@ SeparatedSyntaxList parseSwitchExpressionArms() } } - private ListPatternSyntax ParseListPattern(bool whenIsKeyword) + private ListPatternSyntax ParseListPattern(bool inSwitchArmPattern) { var openBracket = this.EatToken(SyntaxKind.OpenBracketToken); var list = this.ParseCommaSeparatedSyntaxList( @@ -645,7 +646,7 @@ private ListPatternSyntax ParseListPattern(bool whenIsKeyword) openBracket, list, this.EatToken(SyntaxKind.CloseBracketToken), - TryParseSimpleDesignation(whenIsKeyword)); + TryParseSimpleDesignation(inSwitchArmPattern)); } } } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs index ac537827d6664..2e6c81c785b24 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs @@ -4773,26 +4773,28 @@ public static void Main(object o) private static object M() => null; }"; var compilation = CreateCompilation(program).VerifyDiagnostics( - // (9,32): error CS1525: Invalid expression term 'break' - // case Color? Color2: - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "").WithArguments("break").WithLocation(9, 32), - // (9,32): error CS1003: Syntax error, ':' expected - // case Color? Color2: - Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(9, 32), // (8,18): error CS0118: 'Color' is a variable but is used like a type // case Color Color: Diagnostic(ErrorCode.ERR_BadSKknown, "Color").WithArguments("Color", "variable", "type").WithLocation(8, 18), // (9,25): error CS0103: The name 'Color2' does not exist in the current context // case Color? Color2: - Diagnostic(ErrorCode.ERR_NameNotInContext, "Color2").WithArguments("Color2").WithLocation(9, 25) - ); + Diagnostic(ErrorCode.ERR_NameNotInContext, "Color2").WithArguments("Color2").WithLocation(9, 25), + // (9,32): error CS1525: Invalid expression term 'break' + // case Color? Color2: + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "").WithArguments("break").WithLocation(9, 32), + // (9,32): error CS1003: Syntax error, ':' expected + // case Color? Color2: + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(9, 32)); + var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); var colorDecl = GetPatternDeclarations(tree, "Color").ToArray(); var colorRef = GetReferences(tree, "Color").ToArray(); + Assert.Equal(1, colorDecl.Length); Assert.Equal(2, colorRef.Length); + Assert.Null(model.GetSymbolInfo(colorRef[0]).Symbol); VerifyModelForDeclarationOrVarSimplePattern(model, colorDecl[0], colorRef[1]); } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests2.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests2.cs index 8b28cfd8f6468..3cf79e3499614 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests2.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests2.cs @@ -4,11 +4,7 @@ #nullable disable -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; @@ -2680,7 +2676,7 @@ public void M(string s) ); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] public void IsNullableReferenceType_01() { var source = @@ -2712,25 +2708,12 @@ public void M5(object o) { // (10,22): error CS8650: It is not legal to use nullable reference type 'string?' in an is-type expression; use the underlying type 'string' instead. // var t = o is string?; Diagnostic(ErrorCode.ERR_IsNullableType, "string?").WithArguments("string").WithLocation(10, 22), - // (13,30): error CS0103: The name '_' does not exist in the current context - // var t = o is string? _; - Diagnostic(ErrorCode.ERR_NameNotInContext, "_").WithArguments("_").WithLocation(13, 30), - // (13,31): error CS1003: Syntax error, ':' expected - // var t = o is string? _; - Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments(":").WithLocation(13, 31), - // (13,31): error CS1525: Invalid expression term ';' + // (13,22): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. // var t = o is string? _; - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(13, 31), - // (16,22): error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'object', with 2 out parameters and a void return type. + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(13, 22), + // (16,23): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. // var t = o is (string? _); - Diagnostic(ErrorCode.ERR_MissingDeconstruct, "(string? _)").WithArguments("object", "2").WithLocation(16, 22), - // (16,29): error CS1003: Syntax error, ',' expected - // var t = o is (string? _); - Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(",").WithLocation(16, 29), - // (16,31): error CS1003: Syntax error, ',' expected - // var t = o is (string? _); - Diagnostic(ErrorCode.ERR_SyntaxError, "_").WithArguments(",").WithLocation(16, 31) - ); + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(16, 23)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests4.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests4.cs index 9f8814f4ecf8b..4665233220ada 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests4.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests4.cs @@ -3759,11 +3759,11 @@ public class A static void M(object o, bool c) { if (o is A?) { } // error 1 (can't test for is nullable reference type) - if (o is A? b1) { } // error 2 (missing :) + if (o is A? b1) { } // error 2 (can't test for is nullable reference type) if (o is A? b2 && c) { } // error 3 (missing :) - if (o is A[]? b5) { } // error 4 (missing :) + if (o is A[]? b5) { } // error 4 (can't test for is nullable reference type) if (o is A[]? b6 && c) { } // error 5 (missing :) - if (o is A[][]? b7) { } // error 6 (missing :) + if (o is A[][]? b7) { } // error 6 (can't test for is nullable reference type) if (o is A[][]? b8 && c) { } // error 7 (missing :) if (o is A? && c) { } // error 8 (can't test for is nullable reference type) _ = o is A[][]?; // error 9 (can't test for is nullable reference type) @@ -3776,36 +3776,27 @@ static void M(object o, bool c) // (7,18): error CS8650: It is not legal to use nullable reference type 'A?' in an is-type expression; use the underlying type 'A' instead. // if (o is A?) { } // error 1 (can't test for is nullable reference type) Diagnostic(ErrorCode.ERR_IsNullableType, "A?").WithArguments("A").WithLocation(7, 18), - // (8,23): error CS1003: Syntax error, ':' expected - // if (o is A? b1) { } // error 2 (missing :) - Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(8, 23), - // (8,23): error CS1525: Invalid expression term ')' - // if (o is A? b1) { } // error 2 (missing :) - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(8, 23), - // (9,28): error CS1003: Syntax error, ':' expected + // 0.cs(8,18): error CS8116: It is not legal to use nullable reference type 'A?' in an is-type expression; use the underlying type 'A' instead. + // if (o is A? b1) { } // error 2 (can't test for is nullable reference type) + Diagnostic(ErrorCode.ERR_PatternNullableType, "A?").WithArguments("A").WithLocation(8, 18), + // 0.cs(9,28): error CS1003: Syntax error, ':' expected // if (o is A? b2 && c) { } // error 3 (missing :) Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(9, 28), // (9,28): error CS1525: Invalid expression term ')' // if (o is A? b2 && c) { } // error 3 (missing :) Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(9, 28), - // (10,25): error CS1003: Syntax error, ':' expected - // if (o is A[]? b5) { } // error 4 (missing :) - Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(10, 25), - // (10,25): error CS1525: Invalid expression term ')' - // if (o is A[]? b5) { } // error 4 (missing :) - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(10, 25), + // (10,18): error CS8116: It is not legal to use nullable reference type 'A[]?' in an is-type expression; use the underlying type 'A[]' instead. + // if (o is A[]? b5) { } // error 4 (can't test for is nullable reference type) + Diagnostic(ErrorCode.ERR_PatternNullableType, "A[]?").WithArguments("A[]").WithLocation(10, 18), // (11,30): error CS1003: Syntax error, ':' expected // if (o is A[]? b6 && c) { } // error 5 (missing :) Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(11, 30), // (11,30): error CS1525: Invalid expression term ')' // if (o is A[]? b6 && c) { } // error 5 (missing :) Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(11, 30), - // (12,27): error CS1003: Syntax error, ':' expected - // if (o is A[][]? b7) { } // error 6 (missing :) - Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(12, 27), - // (12,27): error CS1525: Invalid expression term ')' - // if (o is A[][]? b7) { } // error 6 (missing :) - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(12, 27), + // (12,18): error CS8116: It is not legal to use nullable reference type 'A[][]?' in an is-type expression; use the underlying type 'A[][]' instead. + // if (o is A[][]? b7) { } // error 6 (can't test for is nullable reference type) + Diagnostic(ErrorCode.ERR_PatternNullableType, "A[][]?").WithArguments("A[][]").WithLocation(12, 18), // (13,32): error CS1003: Syntax error, ':' expected // if (o is A[][]? b8 && c) { } // error 7 (missing :) Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(13, 32), diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests_NullableTypes.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests_NullableTypes.cs new file mode 100644 index 0000000000000..ecfa3b7758616 --- /dev/null +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests_NullableTypes.cs @@ -0,0 +1,675 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests; + +public class PatternMatchingTests_NullableTypes : PatternMatchingTestBase +{ + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PatternCombinations() + { + var source = """ + #nullable enable + + class C + { + void M(object obj) + { + if (obj is int? or string?) { } + if (obj is int? i1 or string? s) { } + if (obj is int? and { }) { } + if (obj is int? i2 and { }) { } + if (obj is int? i3 and (1, 2)) { } + if (obj is int? i4 and []) { } + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (7,20): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (obj is int? or string?) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(7, 20), + // (7,28): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (obj is int? or string?) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(7, 28), + // (8,20): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (obj is int? i1 or string? s) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(8, 20), + // (8,25): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (obj is int? i1 or string? s) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "i1").WithLocation(8, 25), + // (8,31): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (obj is int? i1 or string? s) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(8, 31), + // (8,39): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (obj is int? i1 or string? s) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "s").WithLocation(8, 39), + // (9,20): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (obj is int? and { }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(9, 20), + // (10,20): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (obj is int? i2 and { }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(10, 20), + // (11,20): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (obj is int? i3 and (1, 2)) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(11, 20), + // (11,32): error CS1061: 'int' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) + // if (obj is int? i3 and (1, 2)) { } + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "(1, 2)").WithArguments("int", "Deconstruct").WithLocation(11, 32), + // (11,32): error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'int', with 2 out parameters and a void return type. + // if (obj is int? i3 and (1, 2)) { } + Diagnostic(ErrorCode.ERR_MissingDeconstruct, "(1, 2)").WithArguments("int", "2").WithLocation(11, 32), + // (12,20): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (obj is int? i4 and []) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(12, 20), + // (12,32): error CS8985: List patterns may not be used for a value of type 'int'. No suitable 'Length' or 'Count' property was found. + // if (obj is int? i4 and []) { } + Diagnostic(ErrorCode.ERR_ListPatternRequiresLength, "[]").WithArguments("int").WithLocation(12, 32), + // (12,32): error CS0518: Predefined type 'System.Index' is not defined or imported + // if (obj is int? i4 and []) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "[]").WithArguments("System.Index").WithLocation(12, 32), + // (12,32): error CS0021: Cannot apply indexing with [] to an expression of type 'int' + // if (obj is int? i4 and []) { } + Diagnostic(ErrorCode.ERR_BadIndexLHS, "[]").WithArguments("int").WithLocation(12, 32)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PatternCombinations_Arrays() + { + var source = """ + #nullable enable + + class C + { + void M(object obj) + { + if (obj is int[]? or string[]?) { } + if (obj is int[]? i1 or string[]? s) { } + if (obj is int[]? and { }) { } + if (obj is int[]? i2 and { }) { } + if (obj is int[]? i3 and (1, 2)) { } + if (obj is int[]? i4 and []) { } + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (7,20): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (obj is int[]? or string[]?) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(7, 20), + // (7,30): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (obj is int[]? or string[]?) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(7, 30), + // (8,20): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (obj is int[]? i1 or string[]? s) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(8, 20), + // (8,27): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (obj is int[]? i1 or string[]? s) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "i1").WithLocation(8, 27), + // (8,33): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (obj is int[]? i1 or string[]? s) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(8, 33), + // (8,43): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (obj is int[]? i1 or string[]? s) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "s").WithLocation(8, 43), + // (9,20): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (obj is int[]? and { }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(9, 20), + // (10,20): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (obj is int[]? i2 and { }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(10, 20), + // (11,20): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (obj is int[]? i3 and (1, 2)) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(11, 20), + // (11,34): error CS1061: 'int[]' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?) + // if (obj is int[]? i3 and (1, 2)) { } + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "(1, 2)").WithArguments("int[]", "Deconstruct").WithLocation(11, 34), + // (11,34): error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'int[]', with 2 out parameters and a void return type. + // if (obj is int[]? i3 and (1, 2)) { } + Diagnostic(ErrorCode.ERR_MissingDeconstruct, "(1, 2)").WithArguments("int[]", "2").WithLocation(11, 34), + // (12,20): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (obj is int[]? i4 and []) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(12, 20), + // (12,34): error CS0518: Predefined type 'System.Index' is not defined or imported + // if (obj is int[]? i4 and []) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "[]").WithArguments("System.Index").WithLocation(12, 34)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PatternsInSwitchStatement() + { + var source = """ + using System.Threading.Tasks; + + #nullable enable + + class C + { + void M(object obj) + { + var x = 0; + switch (obj) + { + case int?: + break; + case Task?: + break; + case int? i1: + break; + case Task? t1: + break; + case int? when x > 0: + break; + case Task? when x > 0: + break; + case int? i2 when x > 0: + break; + case Task? t2 when x > 0: + break; + case (int? when) when x > 0: + break; + case (Task? when) when x > 0: + break; + } + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (12,18): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // case int?: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(12, 18), + // (14,18): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // case Task?: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(14, 18), + // (16,21): error CS1003: Syntax error, ':' expected + // case int? i1: + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(":").WithLocation(16, 21), + // (16,21): error CS1513: } expected + // case int? i1: + Diagnostic(ErrorCode.ERR_RbraceExpected, "?").WithLocation(16, 21), + // (16,23): warning CS0164: This label has not been referenced + // case int? i1: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "i1").WithLocation(16, 23), + // (18,18): error CS0119: 'Task' is a type, which is not valid in the given context + // case Task? t1: + Diagnostic(ErrorCode.ERR_BadSKunknown, "Task").WithArguments("System.Threading.Tasks.Task", "type").WithLocation(18, 18), + // (18,24): error CS0103: The name 't1' does not exist in the current context + // case Task? t1: + Diagnostic(ErrorCode.ERR_NameNotInContext, "t1").WithArguments("t1").WithLocation(18, 24), + // (18,27): error CS1525: Invalid expression term 'break' + // case Task? t1: + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "").WithArguments("break").WithLocation(18, 27), + // (18,27): error CS1003: Syntax error, ':' expected + // case Task? t1: + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(18, 27), + // (20,18): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // case int? when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(20, 18), + // (22,18): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // case Task? when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(22, 18), + // (24,18): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // case int? i2 when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(24, 18), + // (26,18): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // case Task? t2 when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(26, 18), + // (28,19): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // case (int? when) when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(28, 19), + // (30,19): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // case (Task? when) when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(30, 19)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PatternsInSwitchStatement_Arrays() + { + var source = """ + using System.Threading.Tasks; + + #nullable enable + + class C + { + void M(object obj) + { + var x = 0; + switch (obj) + { + case int[]?: + break; + case Task[]?: + break; + case int[]? i1: + break; + case Task[]? t1: + break; + case int[]? when x > 0: + break; + case Task[]? when x > 0: + break; + case int[]? i2 when x > 0: + break; + case Task[]? t2 when x > 0: + break; + case (int[]? when) when x > 0: + break; + case (Task[]? when) when x > 0: + break; + } + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (12,18): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // case int[]?: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(12, 18), + // (14,18): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // case Task[]?: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(14, 18), + // (16,23): error CS1003: Syntax error, ':' expected + // case int[]? i1: + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(":").WithLocation(16, 23), + // (16,23): error CS1513: } expected + // case int[]? i1: + Diagnostic(ErrorCode.ERR_RbraceExpected, "?").WithLocation(16, 23), + // (16,25): warning CS0164: This label has not been referenced + // case int[]? i1: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "i1").WithLocation(16, 25), + // (18,24): error CS1003: Syntax error, ':' expected + // case Task[]? t1: + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(":").WithLocation(18, 24), + // (18,24): error CS1513: } expected + // case Task[]? t1: + Diagnostic(ErrorCode.ERR_RbraceExpected, "?").WithLocation(18, 24), + // (18,26): warning CS0164: This label has not been referenced + // case Task[]? t1: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "t1").WithLocation(18, 26), + // (20,18): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // case int[]? when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(20, 18), + // (22,18): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // case Task[]? when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(22, 18), + // (24,18): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // case int[]? i2 when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(24, 18), + // (26,18): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // case Task[]? t2 when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(26, 18), + // (28,19): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // case (int[]? when) when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(28, 19), + // (30,19): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // case (Task[]? when) when x > 0: + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(30, 19)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PatternsInSwitchExpression() + { + var source = """ + using System.Threading.Tasks; + + #nullable enable + + class C + { + void M(object obj) + { + var x = 0; + _ = obj switch + { + int? => 1, + Task? => 2, + int? i1 => 3, + Task? t1 => 4, + int? when x > 0 => 5, + Task? when x > 0 => 6, + int? i2 when x > 0 => 7, + Task? t2 when x > 0 => 8, + (int? when) when x > 0 => 9, + (Task? when) when x > 0 => 10 + }; + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (12,13): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // int? => 1, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(12, 13), + // (13,13): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // Task? => 2, + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(13, 13), + // (14,16): error CS1003: Syntax error, '=>' expected + // int? i1 => 3, + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments("=>").WithLocation(14, 16), + // (14,16): error CS1525: Invalid expression term '?' + // int? i1 => 3, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "?").WithArguments("?").WithLocation(14, 16), + // (14,25): error CS1003: Syntax error, ':' expected + // int? i1 => 3, + Diagnostic(ErrorCode.ERR_SyntaxError, ",").WithArguments(":").WithLocation(14, 25), + // (14,25): error CS1525: Invalid expression term ',' + // int? i1 => 3, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ",").WithArguments(",").WithLocation(14, 25), + // (15,17): error CS1003: Syntax error, '=>' expected + // Task? t1 => 4, + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments("=>").WithLocation(15, 17), + // (15,17): error CS1525: Invalid expression term '?' + // Task? t1 => 4, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "?").WithArguments("?").WithLocation(15, 17), + // (15,26): error CS1003: Syntax error, ':' expected + // Task? t1 => 4, + Diagnostic(ErrorCode.ERR_SyntaxError, ",").WithArguments(":").WithLocation(15, 26), + // (15,26): error CS1525: Invalid expression term ',' + // Task? t1 => 4, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ",").WithArguments(",").WithLocation(15, 26), + // (16,13): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // int? when x > 0 => 5, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(16, 13), + // (17,13): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // Task? when x > 0 => 6, + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(17, 13), + // (18,13): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // int? i2 when x > 0 => 7, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(18, 13), + // (19,13): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // Task? t2 when x > 0 => 8, + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(19, 13), + // (20,14): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // (int? when) when x > 0 => 9, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(20, 14), + // (21,14): error CS8116: It is not legal to use nullable type 'Task?' in a pattern; use the underlying type 'Task' instead. + // (Task? when) when x > 0 => 10 + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task?").WithArguments("System.Threading.Tasks.Task").WithLocation(21, 14)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PatternsInSwitchExpression_Arrays() + { + var source = """ + using System.Threading.Tasks; + + #nullable enable + + class C + { + void M(object obj) + { + var x = 0; + _ = obj switch + { + int[]? => 1, + Task[]? => 2, + int[]? i1 => 3, + Task[]? t1 => 4, + int[]? when x > 0 => 5, + Task[]? when x > 0 => 6, + int[]? i2 when x > 0 => 7, + Task[]? t2 when x > 0 => 8, + (int[]? when) when x > 0 => 9, + (Task[]? when) when x > 0 => 10 + }; + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (12,13): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // int[]? => 1, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(12, 13), + // (13,13): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // Task[]? => 2, + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(13, 13), + // (14,18): error CS1003: Syntax error, '=>' expected + // int[]? i1 => 3, + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments("=>").WithLocation(14, 18), + // (14,18): error CS1525: Invalid expression term '?' + // int[]? i1 => 3, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "?").WithArguments("?").WithLocation(14, 18), + // (14,27): error CS1003: Syntax error, ':' expected + // int[]? i1 => 3, + Diagnostic(ErrorCode.ERR_SyntaxError, ",").WithArguments(":").WithLocation(14, 27), + // (14,27): error CS1525: Invalid expression term ',' + // int[]? i1 => 3, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ",").WithArguments(",").WithLocation(14, 27), + // (15,19): error CS1003: Syntax error, '=>' expected + // Task[]? t1 => 4, + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments("=>").WithLocation(15, 19), + // (15,19): error CS1525: Invalid expression term '?' + // Task[]? t1 => 4, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "?").WithArguments("?").WithLocation(15, 19), + // (15,28): error CS1003: Syntax error, ':' expected + // Task[]? t1 => 4, + Diagnostic(ErrorCode.ERR_SyntaxError, ",").WithArguments(":").WithLocation(15, 28), + // (15,28): error CS1525: Invalid expression term ',' + // Task[]? t1 => 4, + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ",").WithArguments(",").WithLocation(15, 28), + // (16,13): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // int[]? when x > 0 => 5, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(16, 13), + // (17,13): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // Task[]? when x > 0 => 6, + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(17, 13), + // (18,13): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // int[]? i2 when x > 0 => 7, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(18, 13), + // (19,13): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // Task[]? t2 when x > 0 => 8, + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(19, 13), + // (20,14): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // (int[]? when) when x > 0 => 9, + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(20, 14), + // (21,14): error CS8116: It is not legal to use nullable type 'Task[]?' in a pattern; use the underlying type 'Task[]' instead. + // (Task[]? when) when x > 0 => 10 + Diagnostic(ErrorCode.ERR_PatternNullableType, "Task[]?").WithArguments("System.Threading.Tasks.Task[]").WithLocation(21, 14)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PropertySubpatterns() + { + var source = """ + #nullable enable + + class E + { + public object? Prop { get; set; } + public object? Prop2 { get; set; } + } + + class C + { + void M(E e) + { + if (e is { Prop: int? }) { } + if (e is { Prop: int? i1 }) { } + if (e is { Prop: int? or string? }) { } + if (e is { Prop: int? i2 or string? s1 }) { } + if (e is { Prop: int?, Prop2: string? }) { } + if (e is { Prop: int? i3, Prop2: string? s2 }) { } + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (13,26): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (e is { Prop: int? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(13, 26), + // (14,26): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (e is { Prop: int? i1 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(14, 26), + // (15,26): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (e is { Prop: int? or string? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(15, 26), + // (15,34): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (e is { Prop: int? or string? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(15, 34), + // (16,26): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (e is { Prop: int? i2 or string? s1 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(16, 26), + // (16,31): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (e is { Prop: int? i2 or string? s1 }) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "i2").WithLocation(16, 31), + // (16,37): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (e is { Prop: int? i2 or string? s1 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(16, 37), + // (16,45): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (e is { Prop: int? i2 or string? s1 }) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "s1").WithLocation(16, 45), + // (17,26): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (e is { Prop: int?, Prop2: string? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(17, 26), + // (17,39): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (e is { Prop: int?, Prop2: string? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(17, 39), + // (18,26): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. + // if (e is { Prop: int? i3, Prop2: string? s2 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(18, 26), + // (18,42): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (e is { Prop: int? i3, Prop2: string? s2 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(18, 42)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void PropertySubpatterns_Arrays() + { + var source = """ + #nullable enable + + class E + { + public object? Prop { get; set; } + public object? Prop2 { get; set; } + } + + class C + { + void M(E e) + { + if (e is { Prop: int[]? }) { } + if (e is { Prop: int[]? i1 }) { } + if (e is { Prop: int[]? or string[]? }) { } + if (e is { Prop: int[]? i2 or string[]? s1 }) { } + if (e is { Prop: int[]?, Prop2: string[]? }) { } + if (e is { Prop: int[]? i3, Prop2: string[]? s2 }) { } + } + } + """; + + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (13,26): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (e is { Prop: int[]? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(13, 26), + // (14,26): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (e is { Prop: int[]? i1 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(14, 26), + // (15,26): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (e is { Prop: int[]? or string[]? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(15, 26), + // (15,36): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (e is { Prop: int[]? or string[]? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(15, 36), + // (16,26): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (e is { Prop: int[]? i2 or string[]? s1 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(16, 26), + // (16,33): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (e is { Prop: int[]? i2 or string[]? s1 }) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "i2").WithLocation(16, 33), + // (16,39): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (e is { Prop: int[]? i2 or string[]? s1 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(16, 39), + // (16,49): error CS8780: A variable may not be declared within a 'not' or 'or' pattern. + // if (e is { Prop: int[]? i2 or string[]? s1 }) { } + Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "s1").WithLocation(16, 49), + // (17,26): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (e is { Prop: int[]?, Prop2: string[]? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(17, 26), + // (17,41): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (e is { Prop: int[]?, Prop2: string[]? }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(17, 41), + // (18,26): error CS8116: It is not legal to use nullable type 'int[]?' in a pattern; use the underlying type 'int[]' instead. + // if (e is { Prop: int[]? i3, Prop2: string[]? s2 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "int[]?").WithArguments("int[]").WithLocation(18, 26), + // (18,44): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (e is { Prop: int[]? i3, Prop2: string[]? s2 }) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(18, 44)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ListPatterns() + { + var source = """ + #nullable enable + + class C + { + void M2(string s) + { + if (s is [.. string?]) { } + if (s is [.. string? slice1]) { } + if (s is [.. string? slice2, ')']) { } + } + } + """; + + var comp = CreateCompilationWithIndexAndRange(source); + comp.VerifyDiagnostics( + // (7,22): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (s is [.. string?]) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(7, 22), + // (8,22): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (s is [.. string? slice1]) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(8, 22), + // (9,22): error CS8116: It is not legal to use nullable type 'string?' in a pattern; use the underlying type 'string' instead. + // if (s is [.. string? slice2, ')']) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string?").WithArguments("string").WithLocation(9, 22)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ListPatterns_Arrays() + { + var source = """ + #nullable enable + + class C + { + void M(string[] s) + { + if (s is [.. string[]?]) { } + if (s is [.. string[]? slice1]) { } + if (s is [.. string[]? slice2, ")"]) { } + } + } + """; + + var comp = CreateCompilationWithIndexAndRange([source, TestSources.GetSubArray]); + comp.VerifyDiagnostics( + // (7,22): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (s is [.. string[]?]) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(7, 22), + // (8,22): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (s is [.. string[]? slice1]) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(8, 22), + // (9,22): error CS8116: It is not legal to use nullable type 'string[]?' in a pattern; use the underlying type 'string[]' instead. + // if (s is [.. string[]? slice2, ')']) { } + Diagnostic(ErrorCode.ERR_PatternNullableType, "string[]?").WithArguments("string[]").WithLocation(9, 22)); + } +} diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableTests.cs index 73ba7b40eccba..602da008a3af4 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableTests.cs @@ -6,11 +6,7 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; using System.Text; -using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; @@ -2133,7 +2129,7 @@ struct S ); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] public void TestIsNullable1() { var source = @" @@ -2149,15 +2145,9 @@ void M(object o) "; CreateCompilation(source).VerifyDiagnostics( - // (6,23): error CS0103: The name 'i' does not exist in the current context - // if (o is int? i) - Diagnostic(ErrorCode.ERR_NameNotInContext, "i").WithArguments("i").WithLocation(6, 23), - // (6,24): error CS1003: Syntax error, ':' expected - // if (o is int? i) - Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(6, 24), - // (6,24): error CS1525: Invalid expression term ')' + // (6,18): error CS8116: It is not legal to use nullable type 'int?' in a pattern; use the underlying type 'int' instead. // if (o is int? i) - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(6, 24)); + Diagnostic(ErrorCode.ERR_PatternNullableType, "int?").WithArguments("int").WithLocation(6, 18)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/AsyncParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/AsyncParsingTests.cs index 91a5bf720bf4b..90944462784b9 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/AsyncParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/AsyncParsingTests.cs @@ -4,9 +4,9 @@ #nullable disable +using System; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Roslyn.Test.Utilities; -using System; using Xunit; using Xunit.Abstractions; @@ -2658,5 +2658,197 @@ public void AsyncAsType_Property_ExplicitInterface() } EOF(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AsyncLambdaInConditionalExpressionAfterPattern1() + { + UsingExpression("x is A ? async b => 0 : null"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.SimpleLambdaExpression); + { + N(SyntaxKind.AsyncKeyword); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "b"); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AsyncLambdaInConditionalExpressionAfterPattern2() + { + UsingExpression("x is A a ? async b => 0 : null"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "a"); + } + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.SimpleLambdaExpression); + { + N(SyntaxKind.AsyncKeyword); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "b"); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AsyncLambdaInConditionalExpressionAfterPattern3() + { + UsingExpression("x is A ? async (b) => 0 : null"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.AsyncKeyword); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "b"); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AsyncLambdaInConditionalExpressionAfterPattern4() + { + UsingExpression("x is A a ? async (b) => 0 : null"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "A"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "a"); + } + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.ParenthesizedLambdaExpression); + { + N(SyntaxKind.AsyncKeyword); + N(SyntaxKind.ParameterList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "b"); + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.NullLiteralExpression); + { + N(SyntaxKind.NullKeyword); + } + } + EOF(); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/AwaitParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/AwaitParsingTests.cs index 56c40064345ad..3479451b547ab 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/AwaitParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/AwaitParsingTests.cs @@ -4,6 +4,7 @@ #nullable disable +using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -1147,6 +1148,364 @@ public void AwaitUsingTest() } } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitInConditionalExpressionAfterPattern1() + { + UsingExpression("x is int ? await y : z"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.AwaitExpression); + { + N(SyntaxKind.AwaitKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "y"); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "z"); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitInConditionalExpressionAfterPattern2() + { + UsingExpression("x is int ? await this.SomeMethodAsync() : z"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.AwaitExpression); + { + N(SyntaxKind.AwaitKeyword); + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.SimpleMemberAccessExpression); + { + N(SyntaxKind.ThisExpression); + { + N(SyntaxKind.ThisKeyword); + } + N(SyntaxKind.DotToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "SomeMethodAsync"); + } + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "z"); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitInConditionalExpressionAfterPattern3() + { + UsingExpression("x is int ? await base.SomeMethodAsync() : z"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.AwaitExpression); + { + N(SyntaxKind.AwaitKeyword); + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.SimpleMemberAccessExpression); + { + N(SyntaxKind.BaseExpression); + { + N(SyntaxKind.BaseKeyword); + } + N(SyntaxKind.DotToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "SomeMethodAsync"); + } + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "z"); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitInConditionalExpressionAfterPattern4() + { + UsingExpression("x is int ? await (myTask) : z"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "await"); + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "myTask"); + } + } + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "z"); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitAsStartOfExpressionInConditional1() + { + UsingExpression("f(x is int? await)", + // (1,18): error CS1003: Syntax error, ':' expected + // f(x is int? await) + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(1, 18), + // (1,18): error CS1525: Invalid expression term ')' + // f(x is int? await) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(1, 18)); + + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "f"); + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "await"); + } + M(SyntaxKind.ColonToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.CloseParenToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitAsStartOfExpressionInConditional2() + { + UsingExpression("dict[x is int? await]", + // (1,21): error CS1003: Syntax error, ':' expected + // dict[x is int? await] + Diagnostic(ErrorCode.ERR_SyntaxError, "]").WithArguments(":").WithLocation(1, 21), + // (1,21): error CS1525: Invalid expression term ']' + // dict[x is int? await] + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "]").WithArguments("]").WithLocation(1, 21)); + + N(SyntaxKind.ElementAccessExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "dict"); + } + N(SyntaxKind.BracketedArgumentList); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "await"); + } + M(SyntaxKind.ColonToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void AwaitAsStartOfExpressionInConditional3() + { + UsingExpression("x is { Prop: int? await }", + // (1,17): error CS1003: Syntax error, ',' expected + // x is { Prop: int? await } + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments(",").WithLocation(1, 17), + // (1,19): error CS1003: Syntax error, ',' expected + // x is { Prop: int? await } + Diagnostic(ErrorCode.ERR_SyntaxError, "await").WithArguments(",").WithLocation(1, 19)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "await"); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } + #region AwaitExpressionInSyncContext [Fact] diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationExpressionTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationExpressionTests.cs index a8dc74a200040..cce90916c45e4 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationExpressionTests.cs @@ -5,6 +5,7 @@ #nullable disable using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -134,17 +135,53 @@ public void NullableTypeTest_02() EOF(); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] public void NullableTypeTest_03() { - UsingStatement("if (e is int? x) {}", - // (1,16): error CS1003: Syntax error, ':' expected - // if (e is int? x) {} - Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(":").WithLocation(1, 16), - // (1,16): error CS1525: Invalid expression term ')' - // if (e is int? x) {} - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(1, 16) - ); + UsingStatement("if (e is int? x) {}"); + + N(SyntaxKind.IfStatement); + { + N(SyntaxKind.IfKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); + } + } + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.Block); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void NullableTypeTest_03_2() + { + UsingStatement("if (e is int ? x : y) {}"); + N(SyntaxKind.IfStatement); { N(SyntaxKind.IfKeyword); @@ -168,10 +205,10 @@ public void NullableTypeTest_03() { N(SyntaxKind.IdentifierToken, "x"); } - M(SyntaxKind.ColonToken); - M(SyntaxKind.IdentifierName); + N(SyntaxKind.ColonToken); + N(SyntaxKind.IdentifierName); { - M(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "y"); } } N(SyntaxKind.CloseParenToken); diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/NullableParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/NullableParsingTests.cs index aaacbfe16dcc9..be7321a78f231 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/NullableParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/NullableParsingTests.cs @@ -688,6 +688,7 @@ public void DeclarationPattern_NullableType() // (1,25): error CS1003: Syntax error, ':' expected // switch (e) { case T? t: break; } Diagnostic(ErrorCode.ERR_SyntaxError, "break").WithArguments(":").WithLocation(1, 25)); + N(SyntaxKind.SwitchStatement); { N(SyntaxKind.SwitchKeyword); @@ -836,6 +837,7 @@ public void DeclarationPattern_NullableArray() // (1,22): error CS1513: } expected // switch (e) { case T[]? t: break; } Diagnostic(ErrorCode.ERR_RbraceExpected, "?").WithLocation(1, 22)); + N(SyntaxKind.SwitchStatement); { N(SyntaxKind.SwitchKeyword); @@ -1774,5 +1776,585 @@ public void CreateNullableArray_07() } EOF(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void IsExpressionOfNullableTypeInStatement() + { + UsingStatement("_ = x is Type?;"); + + N(SyntaxKind.ExpressionStatement); + { + N(SyntaxKind.SimpleAssignmentExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "_"); + } + N(SyntaxKind.EqualsToken); + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + } + N(SyntaxKind.SemicolonToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void DeclarationPatternOfNullableTypeInStatement() + { + UsingStatement("_ = x is Type? t;"); + + N(SyntaxKind.ExpressionStatement); + { + N(SyntaxKind.SimpleAssignmentExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "_"); + } + N(SyntaxKind.EqualsToken); + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "t"); + } + } + } + } + N(SyntaxKind.SemicolonToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void DisjunctivePattern_NullableType1() + { + UsingExpression("x is int? or string?"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.OrPattern); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.OrKeyword); + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.QuestionToken); + } + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void DisjunctivePattern_NullableType2() + { + UsingExpression("x is int? i or string? s"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.OrPattern); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "i"); + } + } + N(SyntaxKind.OrKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "s"); + } + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_NullableType1() + { + UsingExpression("x is Type? and { }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.AndPattern); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.AndKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_NullableType2() + { + UsingExpression("x is Type? t and { }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.AndPattern); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "t"); + } + } + N(SyntaxKind.AndKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_ConditionalExpressionInsteadOfNullableType3() + { + UsingExpression("x is Type? and (1, 2)", + // (1,22): error CS1003: Syntax error, ':' expected + // x is Type? and (1, 2) + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(1, 22), + // (1,22): error CS1733: Expected expression + // x is Type? and (1, 2) + Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 22)); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "and"); + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "2"); + } + } + N(SyntaxKind.CloseParenToken); + } + } + M(SyntaxKind.ColonToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_ConditionalExpressionInsteadOfNullableType3_2() + { + UsingExpression("x is Type ? f(1, 2) : 0"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.InvocationExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "f"); + } + N(SyntaxKind.ArgumentList); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "2"); + } + } + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_NullableType4() + { + UsingExpression("x is Type? t and (1, 2)"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.AndPattern); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "t"); + } + } + N(SyntaxKind.AndKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PositionalPatternClause); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "2"); + } + } + } + N(SyntaxKind.CloseParenToken); + } + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_ConditionalExpressionInsteadOfNullableType5() + { + UsingExpression("x is Type? and []", + // (1,17): error CS0443: Syntax error; value expected + // x is Type? and [] + Diagnostic(ErrorCode.ERR_ValueExpected, "]").WithLocation(1, 17), + // (1,18): error CS1003: Syntax error, ':' expected + // x is Type? and [] + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(1, 18), + // (1,18): error CS1733: Expected expression + // x is Type? and [] + Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 18)); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.ElementAccessExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "and"); + } + N(SyntaxKind.BracketedArgumentList); + { + N(SyntaxKind.OpenBracketToken); + M(SyntaxKind.Argument); + { + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + M(SyntaxKind.ColonToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_ConditionalExpressionInsteadOfNullableType5_2() + { + UsingExpression("x is Type ? dict[key] : default"); + + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.ElementAccessExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "dict"); + } + N(SyntaxKind.BracketedArgumentList); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "key"); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.DefaultLiteralExpression); + { + N(SyntaxKind.DefaultKeyword); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ConjunctivePattern_NullableType6() + { + UsingExpression("x is Type? t and []"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.AndPattern); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "t"); + } + } + N(SyntaxKind.AndKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.CloseBracketToken); + } + } + } + EOF(); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests2.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests2.cs index ddc8174b9dbe3..df04aa31a3fa9 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests2.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests2.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -1361,5 +1362,388 @@ public void MissingClosingAngleBracket07() } #endregion + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ExtendedPropertySubpattern_NullableType1() + { + UsingExpression("e is { Prop: Type? }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ExtendedPropertySubpattern_NullableType2() + { + UsingExpression("e is { Prop: Type? propVal }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "propVal"); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ExtendedPropertySubpattern_NullableType3() + { + UsingExpression("e is { Prop: Type? propVal, Prop2: int? val2 }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "propVal"); + } + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop2"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "val2"); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ExtendedPropertySubpattern_NullableType4() + { + UsingExpression("e is { Prop: Type? propVal Prop2: int? val2 }", + // (1,28): error CS1003: Syntax error, ',' expected + // e is { Prop: Type? propVal Prop2: int? val2 } + Diagnostic(ErrorCode.ERR_SyntaxError, "Prop2").WithArguments(",").WithLocation(1, 28)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "propVal"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop2"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "val2"); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ExtendedPropertySubpattern_NullableType5() + { + UsingExpression("e is { Prop: Type? or AnotherType? }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.OrPattern); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.OrKeyword); + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "AnotherType"); + } + N(SyntaxKind.QuestionToken); + } + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void ExtendedPropertySubpattern_NullableType6() + { + UsingExpression("e is { Prop: Type? t or AnotherType? a }"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.RecursivePattern); + { + N(SyntaxKind.PropertyPatternClause); + { + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.Subpattern); + { + N(SyntaxKind.NameColon); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Prop"); + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.OrPattern); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "t"); + } + } + N(SyntaxKind.OrKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "AnotherType"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "a"); + } + } + } + } + N(SyntaxKind.CloseBraceToken); + } + } + } + EOF(); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs index 0bcd4870ba5af..422e1f3cb456f 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/PatternParsingTests_ListPatterns.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -767,7 +768,7 @@ public void SlicePattern_11() { UsingExpression(@"c is [var x ..]", // (1,13): error CS1003: Syntax error, ',' expected - // c is {var x ..} + // c is [var x ..] Diagnostic(ErrorCode.ERR_SyntaxError, "..").WithArguments(",").WithLocation(1, 13)); N(SyntaxKind.IsPatternExpression); @@ -835,7 +836,7 @@ public void SlicePattern_13() { UsingExpression(@"c is [[]..]", // (1,9): error CS1003: Syntax error, ',' expected - // c is {{}..} + // c is [[]..] Diagnostic(ErrorCode.ERR_SyntaxError, "..").WithArguments(",").WithLocation(1, 9)); N(SyntaxKind.IsPatternExpression); @@ -1098,6 +1099,508 @@ public void SlicePattern_19() } EOF(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_20() + { + UsingExpression(@"c is [.. string?]"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.QuestionToken); + } + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_21() + { + UsingExpression(@"c is [.. string? slice]"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_22() + { + UsingExpression(@"c is [.. string? slice, ')']"); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.CharacterLiteralExpression); + { + N(SyntaxKind.CharacterLiteralToken); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_23() + { + UsingExpression(@"c is [.. string? slice ')']", + // (1,24): error CS1003: Syntax error, ',' expected + // c is [.. string? slice ')'] + Diagnostic(ErrorCode.ERR_SyntaxError, "')'").WithArguments(",").WithLocation(1, 24)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.CharacterLiteralExpression); + { + N(SyntaxKind.CharacterLiteralToken); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_24() + { + UsingExpression(@"c is [.. string[]? slice "")""]", + // (1,26): error CS1003: Syntax error, ',' expected + // c is [.. string[]? slice ")"] + Diagnostic(ErrorCode.ERR_SyntaxError, @""")""").WithArguments(",").WithLocation(1, 26)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.ArrayType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.ArrayRankSpecifier); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.OmittedArraySizeExpression); + { + N(SyntaxKind.OmittedArraySizeExpressionToken); + } + N(SyntaxKind.CloseBracketToken); + } + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.StringLiteralExpression); + { + N(SyntaxKind.StringLiteralToken, "\")\""); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_25() + { + UsingExpression(@"c is [.. int[]? slice 5]", + // (1,23): error CS1003: Syntax error, ',' expected + // c is [.. int[]? slice 5] + Diagnostic(ErrorCode.ERR_SyntaxError, "5").WithArguments(",").WithLocation(1, 23)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.ArrayType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.ArrayRankSpecifier); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.OmittedArraySizeExpression); + { + N(SyntaxKind.OmittedArraySizeExpressionToken); + } + N(SyntaxKind.CloseBracketToken); + } + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "5"); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_26() + { + UsingExpression(@"c is [.. int[]? slice int i]", + // (1,23): error CS1003: Syntax error, ',' expected + // c is [.. int[]? slice int i] + Diagnostic(ErrorCode.ERR_SyntaxError, "int").WithArguments(",").WithLocation(1, 23)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.ArrayType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.ArrayRankSpecifier); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.OmittedArraySizeExpression); + { + N(SyntaxKind.OmittedArraySizeExpressionToken); + } + N(SyntaxKind.CloseBracketToken); + } + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "i"); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_27() + { + UsingExpression(@"c is [.. string[]? slice string s]", + // (1,26): error CS1003: Syntax error, ',' expected + // c is [.. string[]? slice string s] + Diagnostic(ErrorCode.ERR_SyntaxError, "string").WithArguments(",").WithLocation(1, 26)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.ArrayType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.ArrayRankSpecifier); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.OmittedArraySizeExpression); + { + N(SyntaxKind.OmittedArraySizeExpressionToken); + } + N(SyntaxKind.CloseBracketToken); + } + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.StringKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "s"); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void SlicePattern_28() + { + UsingExpression(@"c is [.. char[]? slice char ch]", + // (1,24): error CS1003: Syntax error, ',' expected + // c is [.. char[]? slice char ch] + Diagnostic(ErrorCode.ERR_SyntaxError, "char").WithArguments(",").WithLocation(1, 24)); + + N(SyntaxKind.IsPatternExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "c"); + } + N(SyntaxKind.IsKeyword); + N(SyntaxKind.ListPattern); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.SlicePattern); + { + N(SyntaxKind.DotDotToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.ArrayType); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.CharKeyword); + } + N(SyntaxKind.ArrayRankSpecifier); + { + N(SyntaxKind.OpenBracketToken); + N(SyntaxKind.OmittedArraySizeExpression); + { + N(SyntaxKind.OmittedArraySizeExpressionToken); + } + N(SyntaxKind.CloseBracketToken); + } + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "slice"); + } + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.CharKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "ch"); + } + } + N(SyntaxKind.CloseBracketToken); + } + } + EOF(); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs index d94f42dd3cfed..1ca8465151f27 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/StatementParsingTests.cs @@ -5488,6 +5488,329 @@ public void ParseSwitchStatementWithUnclosedPatternAndArrow() EOF(); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestSwitchStatementWithNullableTypeInPattern1() + { + UsingStatement(""" + switch (obj) + { + case Type?: + break; + } + """); + + N(SyntaxKind.SwitchStatement); + { + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchSection); + { + N(SyntaxKind.CasePatternSwitchLabel); + { + N(SyntaxKind.CaseKeyword); + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.BreakStatement); + { + N(SyntaxKind.BreakKeyword); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestSwitchStatementWithNullableTypeInPattern2() + { + UsingStatement(""" + switch (obj) + { + case Type? varName: + break; + } + """, + // (3,24): error CS1525: Invalid expression term 'break' + // case Type? varName: + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "").WithArguments("break").WithLocation(3, 24), + // (3,24): error CS1003: Syntax error, ':' expected + // case Type? varName: + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(3, 24)); + + N(SyntaxKind.SwitchStatement); + { + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchSection); + { + N(SyntaxKind.CaseSwitchLabel); + { + N(SyntaxKind.CaseKeyword); + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "varName"); + } + N(SyntaxKind.ColonToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + M(SyntaxKind.ColonToken); + } + N(SyntaxKind.BreakStatement); + { + N(SyntaxKind.BreakKeyword); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestSwitchStatementWithNullableTypeInPattern3() + { + UsingStatement(""" + switch (obj) + { + case Type? when x > 0: + break; + } + """); + + N(SyntaxKind.SwitchStatement); + { + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchSection); + { + N(SyntaxKind.CasePatternSwitchLabel); + { + N(SyntaxKind.CaseKeyword); + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.BreakStatement); + { + N(SyntaxKind.BreakKeyword); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestSwitchStatementWithNullableTypeInPattern4() + { + UsingStatement(""" + switch (obj) + { + case Type? varName when x > 0: + break; + } + """); + + N(SyntaxKind.SwitchStatement); + { + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchSection); + { + N(SyntaxKind.CasePatternSwitchLabel); + { + N(SyntaxKind.CaseKeyword); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "varName"); + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.BreakStatement); + { + N(SyntaxKind.BreakKeyword); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestSwitchStatementWithNullableTypeInPattern5() + { + UsingStatement(""" + switch (obj) + { + case (Type? when) when x > 0: + break; + } + """); + + N(SyntaxKind.SwitchStatement); + { + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchSection); + { + N(SyntaxKind.CasePatternSwitchLabel); + { + N(SyntaxKind.CaseKeyword); + N(SyntaxKind.ParenthesizedPattern); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "when"); + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.BreakStatement); + { + N(SyntaxKind.BreakKeyword); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + private sealed class TokenAndTriviaWalker : CSharpSyntaxWalker { public int Tokens; diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/SwitchExpressionParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/SwitchExpressionParsingTests.cs index 0f33ab868b05d..77f90db34eb36 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/SwitchExpressionParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/SwitchExpressionParsingTests.cs @@ -4231,4 +4231,658 @@ public void TestIncompleteSwitchExpression() } EOF(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern1() + { + UsingExpression(""" + obj switch + { + Type? => 1 + } + """); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern1_Colon() + { + UsingExpression(""" + obj switch + { + Type? : 1 + } + """, + // (3,11): error CS1003: Syntax error, '=>' expected + // Type? : 1 + Diagnostic(ErrorCode.ERR_SyntaxError, ":").WithArguments("=>").WithLocation(3, 11)); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + M(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern2() + { + UsingExpression(""" + obj switch + { + Type? varName => 1 + } + """, + // (3,9): error CS1003: Syntax error, '=>' expected + // Type? varName => 1 + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments("=>").WithLocation(3, 9), + // (3,9): error CS1525: Invalid expression term '?' + // Type? varName => 1 + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "?").WithArguments("?").WithLocation(3, 9), + // (3,23): error CS1003: Syntax error, ':' expected + // Type? varName => 1 + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments(":").WithLocation(3, 23), + // (3,23): error CS1525: Invalid expression term '}' + // Type? varName => 1 + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "").WithArguments("}").WithLocation(3, 23)); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + } + M(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.ConditionalExpression); + { + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.SimpleLambdaExpression); + { + N(SyntaxKind.Parameter); + { + N(SyntaxKind.IdentifierToken, "varName"); + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + M(SyntaxKind.ColonToken); + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern2_Colon() + { + UsingExpression(""" + obj switch + { + Type? varName : 1 + } + """, + // (3,9): error CS1003: Syntax error, '=>' expected + // Type? varName : 1 + Diagnostic(ErrorCode.ERR_SyntaxError, "?").WithArguments("=>").WithLocation(3, 9), + // (3,9): error CS1525: Invalid expression term '?' + // Type? varName : 1 + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "?").WithArguments("?").WithLocation(3, 9)); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + } + M(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.ConditionalExpression); + { + M(SyntaxKind.IdentifierName); + { + M(SyntaxKind.IdentifierToken); + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "varName"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern3() + { + UsingExpression(""" + obj switch + { + Type? when x > 0 => 1 + } + """); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern3_Colon() + { + UsingExpression(""" + obj switch + { + Type? when x > 0 : 1 + } + """, + // (3,22): error CS1003: Syntax error, '=>' expected + // Type? when x > 0 : 1 + Diagnostic(ErrorCode.ERR_SyntaxError, ":").WithArguments("=>").WithLocation(3, 22)); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.TypePattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + M(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern4() + { + UsingExpression(""" + obj switch + { + Type? varName when x > 0 => 1 + } + """); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "varName"); + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern4_Colon() + { + UsingExpression(""" + obj switch + { + Type? varName when x > 0 : 1 + } + """, + // (3,30): error CS1003: Syntax error, '=>' expected + // Type? varName when x > 0 : 1 + Diagnostic(ErrorCode.ERR_SyntaxError, ":").WithArguments("=>").WithLocation(3, 30)); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "varName"); + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + M(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern5() + { + UsingExpression(""" + obj switch + { + (Type? when) when x > 0 => 1 + } + """); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.ParenthesizedPattern); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "when"); + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestNullableTypeInPattern5_Colon() + { + UsingExpression(""" + obj switch + { + (Type? when) when x > 0 : 1 + } + """, + // (3,29): error CS1003: Syntax error, '=>' expected + // (Type? when) when x > 0 : 1 + Diagnostic(ErrorCode.ERR_SyntaxError, ":").WithArguments("=>").WithLocation(3, 29)); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.ParenthesizedPattern); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.DeclarationPattern); + { + N(SyntaxKind.NullableType); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Type"); + } + N(SyntaxKind.QuestionToken); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "when"); + } + } + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.GreaterThanExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "x"); + } + N(SyntaxKind.GreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "0"); + } + } + } + M(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72720")] + public void TestConditionalExpressionAsPattern() + { + UsingExpression(""" + obj switch + { + (flag ? a : b) => 1 + } + """); + + N(SyntaxKind.SwitchExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "obj"); + } + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchExpressionArm); + { + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.ParenthesizedExpression); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.ConditionalExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "flag"); + } + N(SyntaxKind.QuestionToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "a"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "b"); + } + } + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.EqualsGreaterThanToken); + N(SyntaxKind.NumericLiteralExpression); + { + N(SyntaxKind.NumericLiteralToken, "1"); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } } From 5704d856945422b670f5686098ec768f66e0689d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 8 Jul 2024 14:44:48 -0700 Subject: [PATCH 41/59] Fix msbuild issue --- Directory.Build.rsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.rsp b/Directory.Build.rsp index d2d2d1d2f4e8e..424936667b087 100644 --- a/Directory.Build.rsp +++ b/Directory.Build.rsp @@ -1 +1 @@ -# This file intentionally left blank to avoid accidental import during build. +-p:_IsDisjointMSBuildVersion=false \ No newline at end of file From a873d9b7a8817eb5e5bd2d8cbb0ea8ffbd678537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Mon, 8 Jul 2024 15:15:05 -0700 Subject: [PATCH 42/59] Remove fallback options from IdeAnalyzerOptions (#74235) --- .../CSharpAnalyzerOptionsProvider.cs | 131 +++++++---------- .../Core/Analyzers/AnalyzerOptionsProvider.cs | 136 ++++++------------ .../CodeFixes/AnalyzerOptionsProviders.cs | 5 +- .../VisualBasicAnalyzerOptionsProvider.vb | 46 ++---- .../CSharpTest/Formatting/CodeCleanupTests.cs | 13 +- .../DiagnosticIncrementalAnalyzer.Executor.cs | 4 +- ...alyzer.InProcOrRemoteHostAnalyzerRunner.cs | 2 +- ...IncrementalAnalyzer_IncrementalAnalyzer.cs | 2 +- .../Options/IdeAnalyzerOptionsStorage.cs | 6 +- .../Formatting/FormatDocumentHandler.cs | 1 - .../Formatting/FormatDocumentRangeHandler.cs | 1 - ...alStudioDiagnosticAnalyzerExecutorTests.cs | 53 ++----- .../Diagnostics/WorkspaceAnalyzerOptions.cs | 5 + .../Workspaces/TestWorkspace`1.cs | 10 ++ .../Core/Diagnostics/IdeAnalyzerOptions.cs | 21 +-- 15 files changed, 155 insertions(+), 281 deletions(-) diff --git a/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs b/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs index dedfa4b189a42..4413bf53ca539 100644 --- a/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs +++ b/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs @@ -6,7 +6,6 @@ using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.CodeStyle; -using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.CSharp.Simplification; using Microsoft.CodeAnalysis.Options; @@ -15,115 +14,87 @@ namespace Microsoft.CodeAnalysis.Diagnostics; /// /// Provides C# analyzers a convenient access to editorconfig options with fallback to IDE default values. /// -internal readonly struct CSharpAnalyzerOptionsProvider(IOptionsReader options, IdeAnalyzerOptions fallbackOptions) +internal readonly struct CSharpAnalyzerOptionsProvider(IOptionsReader options) { - /// - /// Document editorconfig options. - /// - private readonly IOptionsReader _options = options; - - /// - /// Fallback options - the default options in Code Style layer. - /// - private readonly IdeAnalyzerOptions _fallbackOptions = fallbackOptions; - - public CSharpAnalyzerOptionsProvider(IOptionsReader options, AnalyzerOptions fallbackOptions) - : this(options, fallbackOptions.GetIdeOptions()) - { - } + private IOptionsReader Options => options; // SimplifierOptions - public CodeStyleOption2 VarForBuiltInTypes => GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes, FallbackSimplifierOptions.VarForBuiltInTypes); - public CodeStyleOption2 VarWhenTypeIsApparent => GetOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent, FallbackSimplifierOptions.VarWhenTypeIsApparent); - public CodeStyleOption2 VarElsewhere => GetOption(CSharpCodeStyleOptions.VarElsewhere, FallbackSimplifierOptions.VarElsewhere); - public CodeStyleOption2 PreferSimpleDefaultExpression => GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression, FallbackSimplifierOptions.PreferSimpleDefaultExpression); - public CodeStyleOption2 AllowEmbeddedStatementsOnSameLine => GetOption(CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, FallbackSimplifierOptions.AllowEmbeddedStatementsOnSameLine); - public CodeStyleOption2 PreferThrowExpression => GetOption(CSharpCodeStyleOptions.PreferThrowExpression, FallbackSimplifierOptions.PreferThrowExpression); - public CodeStyleOption2 PreferBraces => GetOption(CSharpCodeStyleOptions.PreferBraces, FallbackSimplifierOptions.PreferBraces); + public CodeStyleOption2 VarForBuiltInTypes => GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes); + public CodeStyleOption2 VarWhenTypeIsApparent => GetOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent); + public CodeStyleOption2 VarElsewhere => GetOption(CSharpCodeStyleOptions.VarElsewhere); + public CodeStyleOption2 PreferSimpleDefaultExpression => GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression); + public CodeStyleOption2 AllowEmbeddedStatementsOnSameLine => GetOption(CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine); + public CodeStyleOption2 PreferThrowExpression => GetOption(CSharpCodeStyleOptions.PreferThrowExpression); + public CodeStyleOption2 PreferBraces => GetOption(CSharpCodeStyleOptions.PreferBraces); internal CSharpSimplifierOptions GetSimplifierOptions() - => new(_options, FallbackSimplifierOptions); + => new(options, fallbackOptions: null); // SyntaxFormattingOptions - public CodeStyleOption2 NamespaceDeclarations => GetOption(CSharpCodeStyleOptions.NamespaceDeclarations, FallbackSyntaxFormattingOptions.NamespaceDeclarations); - public CodeStyleOption2 PreferTopLevelStatements => GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements, FallbackSyntaxFormattingOptions.PreferTopLevelStatements); + public CodeStyleOption2 NamespaceDeclarations => GetOption(CSharpCodeStyleOptions.NamespaceDeclarations); + public CodeStyleOption2 PreferTopLevelStatements => GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements); // AddImportPlacementOptions - public CodeStyleOption2 UsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, FallbackAddImportPlacementOptions.UsingDirectivePlacement); + public CodeStyleOption2 UsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement); // CodeStyleOptions - public CodeStyleOption2 ImplicitObjectCreationWhenTypeIsApparent => GetOption(CSharpCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent, FallbackCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent); - public CodeStyleOption2 PreferNullCheckOverTypeCheck => GetOption(CSharpCodeStyleOptions.PreferNullCheckOverTypeCheck, FallbackCodeStyleOptions.PreferNullCheckOverTypeCheck); - public CodeStyleOption2 AllowBlankLinesBetweenConsecutiveBraces => GetOption(CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, FallbackCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces); - public CodeStyleOption2 AllowBlankLineAfterColonInConstructorInitializer => GetOption(CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, FallbackCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer); - public CodeStyleOption2 AllowBlankLineAfterTokenInArrowExpressionClause => GetOption(CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, FallbackCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause); - public CodeStyleOption2 AllowBlankLineAfterTokenInConditionalExpression => GetOption(CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, FallbackCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression); - public CodeStyleOption2 PreferConditionalDelegateCall => GetOption(CSharpCodeStyleOptions.PreferConditionalDelegateCall, FallbackCodeStyleOptions.PreferConditionalDelegateCall); - public CodeStyleOption2 PreferSwitchExpression => GetOption(CSharpCodeStyleOptions.PreferSwitchExpression, FallbackCodeStyleOptions.PreferSwitchExpression); - public CodeStyleOption2 PreferPatternMatching => GetOption(CSharpCodeStyleOptions.PreferPatternMatching, FallbackCodeStyleOptions.PreferPatternMatching); - public CodeStyleOption2 PreferPatternMatchingOverAsWithNullCheck => GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck, FallbackCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck); - public CodeStyleOption2 PreferPatternMatchingOverIsWithCastCheck => GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck, FallbackCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck); - public CodeStyleOption2 PreferNotPattern => GetOption(CSharpCodeStyleOptions.PreferNotPattern, FallbackCodeStyleOptions.PreferNotPattern); - public CodeStyleOption2 PreferExtendedPropertyPattern => GetOption(CSharpCodeStyleOptions.PreferExtendedPropertyPattern, FallbackCodeStyleOptions.PreferExtendedPropertyPattern); - public CodeStyleOption2 PreferInlinedVariableDeclaration => GetOption(CSharpCodeStyleOptions.PreferInlinedVariableDeclaration, FallbackCodeStyleOptions.PreferInlinedVariableDeclaration); - public CodeStyleOption2 PreferDeconstructedVariableDeclaration => GetOption(CSharpCodeStyleOptions.PreferDeconstructedVariableDeclaration, FallbackCodeStyleOptions.PreferDeconstructedVariableDeclaration); - public CodeStyleOption2 PreferIndexOperator => GetOption(CSharpCodeStyleOptions.PreferIndexOperator, FallbackCodeStyleOptions.PreferIndexOperator); - public CodeStyleOption2 PreferRangeOperator => GetOption(CSharpCodeStyleOptions.PreferRangeOperator, FallbackCodeStyleOptions.PreferRangeOperator); - public CodeStyleOption2 PreferUtf8StringLiterals => GetOption(CSharpCodeStyleOptions.PreferUtf8StringLiterals, FallbackCodeStyleOptions.PreferUtf8StringLiterals); - public CodeStyleOption2 PreferredModifierOrder => GetOption(CSharpCodeStyleOptions.PreferredModifierOrder, FallbackCodeStyleOptions.PreferredModifierOrder); - public CodeStyleOption2 PreferSimpleUsingStatement => GetOption(CSharpCodeStyleOptions.PreferSimpleUsingStatement, FallbackCodeStyleOptions.PreferSimpleUsingStatement); - public CodeStyleOption2 PreferLocalOverAnonymousFunction => GetOption(CSharpCodeStyleOptions.PreferLocalOverAnonymousFunction, FallbackCodeStyleOptions.PreferLocalOverAnonymousFunction); - public CodeStyleOption2 PreferTupleSwap => GetOption(CSharpCodeStyleOptions.PreferTupleSwap, FallbackCodeStyleOptions.PreferTupleSwap); - public CodeStyleOption2 UnusedValueExpressionStatement => GetOption(CSharpCodeStyleOptions.UnusedValueExpressionStatement, FallbackCodeStyleOptions.UnusedValueExpressionStatement); - public CodeStyleOption2 UnusedValueAssignment => GetOption(CSharpCodeStyleOptions.UnusedValueAssignment, FallbackCodeStyleOptions.UnusedValueAssignment); - public CodeStyleOption2 PreferMethodGroupConversion => GetOption(CSharpCodeStyleOptions.PreferMethodGroupConversion, FallbackCodeStyleOptions.PreferMethodGroupConversion); - public CodeStyleOption2 PreferPrimaryConstructors => GetOption(CSharpCodeStyleOptions.PreferPrimaryConstructors, FallbackCodeStyleOptions.PreferPrimaryConstructors); - public CodeStyleOption2 PreferSystemThreadingLock => GetOption(CSharpCodeStyleOptions.PreferSystemThreadingLock, FallbackCodeStyleOptions.PreferSystemThreadingLock); + public CodeStyleOption2 ImplicitObjectCreationWhenTypeIsApparent => GetOption(CSharpCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent); + public CodeStyleOption2 PreferNullCheckOverTypeCheck => GetOption(CSharpCodeStyleOptions.PreferNullCheckOverTypeCheck); + public CodeStyleOption2 AllowBlankLinesBetweenConsecutiveBraces => GetOption(CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces); + public CodeStyleOption2 AllowBlankLineAfterColonInConstructorInitializer => GetOption(CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer); + public CodeStyleOption2 AllowBlankLineAfterTokenInArrowExpressionClause => GetOption(CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause); + public CodeStyleOption2 AllowBlankLineAfterTokenInConditionalExpression => GetOption(CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression); + public CodeStyleOption2 PreferConditionalDelegateCall => GetOption(CSharpCodeStyleOptions.PreferConditionalDelegateCall); + public CodeStyleOption2 PreferSwitchExpression => GetOption(CSharpCodeStyleOptions.PreferSwitchExpression); + public CodeStyleOption2 PreferPatternMatching => GetOption(CSharpCodeStyleOptions.PreferPatternMatching); + public CodeStyleOption2 PreferPatternMatchingOverAsWithNullCheck => GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck); + public CodeStyleOption2 PreferPatternMatchingOverIsWithCastCheck => GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck); + public CodeStyleOption2 PreferNotPattern => GetOption(CSharpCodeStyleOptions.PreferNotPattern); + public CodeStyleOption2 PreferExtendedPropertyPattern => GetOption(CSharpCodeStyleOptions.PreferExtendedPropertyPattern); + public CodeStyleOption2 PreferInlinedVariableDeclaration => GetOption(CSharpCodeStyleOptions.PreferInlinedVariableDeclaration); + public CodeStyleOption2 PreferDeconstructedVariableDeclaration => GetOption(CSharpCodeStyleOptions.PreferDeconstructedVariableDeclaration); + public CodeStyleOption2 PreferIndexOperator => GetOption(CSharpCodeStyleOptions.PreferIndexOperator); + public CodeStyleOption2 PreferRangeOperator => GetOption(CSharpCodeStyleOptions.PreferRangeOperator); + public CodeStyleOption2 PreferUtf8StringLiterals => GetOption(CSharpCodeStyleOptions.PreferUtf8StringLiterals); + public CodeStyleOption2 PreferredModifierOrder => GetOption(CSharpCodeStyleOptions.PreferredModifierOrder); + public CodeStyleOption2 PreferSimpleUsingStatement => GetOption(CSharpCodeStyleOptions.PreferSimpleUsingStatement); + public CodeStyleOption2 PreferLocalOverAnonymousFunction => GetOption(CSharpCodeStyleOptions.PreferLocalOverAnonymousFunction); + public CodeStyleOption2 PreferTupleSwap => GetOption(CSharpCodeStyleOptions.PreferTupleSwap); + public CodeStyleOption2 UnusedValueExpressionStatement => GetOption(CSharpCodeStyleOptions.UnusedValueExpressionStatement); + public CodeStyleOption2 UnusedValueAssignment => GetOption(CSharpCodeStyleOptions.UnusedValueAssignment); + public CodeStyleOption2 PreferMethodGroupConversion => GetOption(CSharpCodeStyleOptions.PreferMethodGroupConversion); + public CodeStyleOption2 PreferPrimaryConstructors => GetOption(CSharpCodeStyleOptions.PreferPrimaryConstructors); + public CodeStyleOption2 PreferSystemThreadingLock => GetOption(CSharpCodeStyleOptions.PreferSystemThreadingLock); // CodeGenerationOptions internal CSharpCodeGenerationOptions GetCodeGenerationOptions() - => new(_options, FallbackCodeGenerationOptions); - - public CodeStyleOption2 PreferExpressionBodiedLambdas => GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, FallbackCodeStyleOptions.PreferExpressionBodiedLambdas); - public CodeStyleOption2 PreferReadOnlyStruct => GetOption(CSharpCodeStyleOptions.PreferReadOnlyStruct, FallbackCodeStyleOptions.PreferReadOnlyStruct); - public CodeStyleOption2 PreferReadOnlyStructMember => GetOption(CSharpCodeStyleOptions.PreferReadOnlyStructMember, FallbackCodeStyleOptions.PreferReadOnlyStructMember); - public CodeStyleOption2 PreferStaticLocalFunction => GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction, FallbackCodeStyleOptions.PreferStaticLocalFunction); - public CodeStyleOption2 PreferStaticAnonymousFunction => GetOption(CSharpCodeStyleOptions.PreferStaticAnonymousFunction, FallbackCodeStyleOptions.PreferStaticAnonymousFunction); - - private TValue GetOption(Option2 option, TValue defaultValue) - => _options.GetOption(option, defaultValue); - - private CSharpIdeCodeStyleOptions FallbackCodeStyleOptions - => (CSharpIdeCodeStyleOptions?)_fallbackOptions.CodeStyleOptions ?? CSharpIdeCodeStyleOptions.Default; - - private CSharpSimplifierOptions FallbackSimplifierOptions - => (CSharpSimplifierOptions?)_fallbackOptions.CleanupOptions?.SimplifierOptions ?? CSharpSimplifierOptions.Default; - - private CSharpSyntaxFormattingOptions FallbackSyntaxFormattingOptions - => (CSharpSyntaxFormattingOptions?)_fallbackOptions.CleanupOptions?.FormattingOptions ?? CSharpSyntaxFormattingOptions.Default; + => new(options, fallbackOptions: null); - private AddImportPlacementOptions FallbackAddImportPlacementOptions - => _fallbackOptions.CleanupOptions?.AddImportOptions ?? AddImportPlacementOptions.Default; + public CodeStyleOption2 PreferExpressionBodiedLambdas => GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas); + public CodeStyleOption2 PreferReadOnlyStruct => GetOption(CSharpCodeStyleOptions.PreferReadOnlyStruct); + public CodeStyleOption2 PreferReadOnlyStructMember => GetOption(CSharpCodeStyleOptions.PreferReadOnlyStructMember); + public CodeStyleOption2 PreferStaticLocalFunction => GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction); + public CodeStyleOption2 PreferStaticAnonymousFunction => GetOption(CSharpCodeStyleOptions.PreferStaticAnonymousFunction); - private CSharpCodeGenerationOptions FallbackCodeGenerationOptions - => (CSharpCodeGenerationOptions?)_fallbackOptions.GenerationOptions ?? CSharpCodeGenerationOptions.Default; + private TValue GetOption(Option2 option) + => options.GetOption(option); public static explicit operator CSharpAnalyzerOptionsProvider(AnalyzerOptionsProvider provider) - => new(provider.GetAnalyzerConfigOptions(), provider.GetFallbackOptions()); + => new(provider.GetAnalyzerConfigOptions()); public static implicit operator AnalyzerOptionsProvider(CSharpAnalyzerOptionsProvider provider) - => new(provider._options, LanguageNames.CSharp, provider._fallbackOptions); + => new(provider.Options, LanguageNames.CSharp); } internal static class CSharpAnalyzerOptionsProviders { public static CSharpAnalyzerOptionsProvider GetCSharpAnalyzerOptions(this AnalyzerOptions options, SyntaxTree syntaxTree) - => new(options.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader(), options); + => new(options.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader()); public static CSharpAnalyzerOptionsProvider GetCSharpAnalyzerOptions(this SemanticModelAnalysisContext context) => GetCSharpAnalyzerOptions(context.Options, context.SemanticModel.SyntaxTree); diff --git a/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs b/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs index 868cb3b170b66..9ff472e4bf746 100644 --- a/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs +++ b/src/Analyzers/Core/Analyzers/AnalyzerOptionsProvider.cs @@ -2,118 +2,83 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.CodeStyle; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; namespace Microsoft.CodeAnalysis.Diagnostics; /// -/// Provides C# and VB analyzers a convenient access to common editorconfig options with fallback to IDE default values. +/// Provides C# and VB analyzers a convenient access to common editorconfig options. /// -internal readonly struct AnalyzerOptionsProvider(IOptionsReader options, string language, IdeAnalyzerOptions fallbackOptions) +internal readonly struct AnalyzerOptionsProvider(IOptionsReader options, string language) { - /// - /// Document editorconfig options. - /// - private readonly IOptionsReader _options = options; - - /// - /// Fallback options - the default options in Code Style layer. - /// - private readonly IdeAnalyzerOptions _fallbackOptions = fallbackOptions; - - private readonly string _language = language; - - public AnalyzerOptionsProvider(IOptionsReader options, string language, AnalyzerOptions fallbackOptions) - : this(options, language, fallbackOptions.GetIdeOptions()) - { - } - // SimplifierOptions - public CodeStyleOption2 QualifyFieldAccess => GetOption(CodeStyleOptions2.QualifyFieldAccess, FallbackSimplifierOptions.QualifyFieldAccess); - public CodeStyleOption2 QualifyPropertyAccess => GetOption(CodeStyleOptions2.QualifyPropertyAccess, FallbackSimplifierOptions.QualifyPropertyAccess); - public CodeStyleOption2 QualifyMethodAccess => GetOption(CodeStyleOptions2.QualifyMethodAccess, FallbackSimplifierOptions.QualifyMethodAccess); - public CodeStyleOption2 QualifyEventAccess => GetOption(CodeStyleOptions2.QualifyEventAccess, FallbackSimplifierOptions.QualifyEventAccess); - public CodeStyleOption2 PreferPredefinedTypeKeywordInMemberAccess => GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, FallbackSimplifierOptions.PreferPredefinedTypeKeywordInMemberAccess); - public CodeStyleOption2 PreferPredefinedTypeKeywordInDeclaration => GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, FallbackSimplifierOptions.PreferPredefinedTypeKeywordInDeclaration); + public CodeStyleOption2 QualifyFieldAccess => GetOption(CodeStyleOptions2.QualifyFieldAccess); + public CodeStyleOption2 QualifyPropertyAccess => GetOption(CodeStyleOptions2.QualifyPropertyAccess); + public CodeStyleOption2 QualifyMethodAccess => GetOption(CodeStyleOptions2.QualifyMethodAccess); + public CodeStyleOption2 QualifyEventAccess => GetOption(CodeStyleOptions2.QualifyEventAccess); + public CodeStyleOption2 PreferPredefinedTypeKeywordInMemberAccess => GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess); + public CodeStyleOption2 PreferPredefinedTypeKeywordInDeclaration => GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration); public SimplifierOptions GetSimplifierOptions(ISimplification simplification) - => simplification.GetSimplifierOptions(_options); + => simplification.GetSimplifierOptions(options); // SyntaxFormattingOptions public SyntaxFormattingOptions GetSyntaxFormattingOptions(ISyntaxFormatting formatting) - => formatting.GetFormattingOptions(_options); + => formatting.GetFormattingOptions(options); // CodeGenerationOptions - public NamingStylePreferences NamingPreferences => GetOption(NamingStyleOptions.NamingPreferences, _fallbackOptions.GenerationOptions?.NamingStyle ?? NamingStylePreferences.Default); + public NamingStylePreferences NamingPreferences => GetOption(NamingStyleOptions.NamingPreferences); // CodeStyleOptions - public CodeStyleOption2 PreferObjectInitializer => GetOption(CodeStyleOptions2.PreferObjectInitializer, FallbackCodeStyleOptions.PreferObjectInitializer); - public CodeStyleOption2 PreferCollectionExpression => GetOption(CodeStyleOptions2.PreferCollectionExpression, FallbackCodeStyleOptions.PreferCollectionExpression); - public CodeStyleOption2 PreferCollectionInitializer => GetOption(CodeStyleOptions2.PreferCollectionInitializer, FallbackCodeStyleOptions.PreferCollectionInitializer); - public CodeStyleOption2 PreferSimplifiedBooleanExpressions => GetOption(CodeStyleOptions2.PreferSimplifiedBooleanExpressions, FallbackCodeStyleOptions.PreferSimplifiedBooleanExpressions); - public OperatorPlacementWhenWrappingPreference OperatorPlacementWhenWrapping => GetOption(CodeStyleOptions2.OperatorPlacementWhenWrapping, FallbackCodeStyleOptions.OperatorPlacementWhenWrapping); - public CodeStyleOption2 PreferCoalesceExpression => GetOption(CodeStyleOptions2.PreferCoalesceExpression, FallbackCodeStyleOptions.PreferCoalesceExpression); - public CodeStyleOption2 PreferNullPropagation => GetOption(CodeStyleOptions2.PreferNullPropagation, FallbackCodeStyleOptions.PreferNullPropagation); - public CodeStyleOption2 PreferExplicitTupleNames => GetOption(CodeStyleOptions2.PreferExplicitTupleNames, FallbackCodeStyleOptions.PreferExplicitTupleNames); - public CodeStyleOption2 PreferAutoProperties => GetOption(CodeStyleOptions2.PreferAutoProperties, FallbackCodeStyleOptions.PreferAutoProperties); - public CodeStyleOption2 PreferInferredTupleNames => GetOption(CodeStyleOptions2.PreferInferredTupleNames, FallbackCodeStyleOptions.PreferInferredTupleNames); - public CodeStyleOption2 PreferInferredAnonymousTypeMemberNames => GetOption(CodeStyleOptions2.PreferInferredAnonymousTypeMemberNames, FallbackCodeStyleOptions.PreferInferredAnonymousTypeMemberNames); - public CodeStyleOption2 PreferIsNullCheckOverReferenceEqualityMethod => GetOption(CodeStyleOptions2.PreferIsNullCheckOverReferenceEqualityMethod, FallbackCodeStyleOptions.PreferIsNullCheckOverReferenceEqualityMethod); - public CodeStyleOption2 PreferConditionalExpressionOverAssignment => GetOption(CodeStyleOptions2.PreferConditionalExpressionOverAssignment, FallbackCodeStyleOptions.PreferConditionalExpressionOverAssignment); - public CodeStyleOption2 PreferConditionalExpressionOverReturn => GetOption(CodeStyleOptions2.PreferConditionalExpressionOverReturn, FallbackCodeStyleOptions.PreferConditionalExpressionOverReturn); - public CodeStyleOption2 PreferCompoundAssignment => GetOption(CodeStyleOptions2.PreferCompoundAssignment, FallbackCodeStyleOptions.PreferCompoundAssignment); - public CodeStyleOption2 PreferSimplifiedInterpolation => GetOption(CodeStyleOptions2.PreferSimplifiedInterpolation, FallbackCodeStyleOptions.PreferSimplifiedInterpolation); + public CodeStyleOption2 PreferObjectInitializer => GetOption(CodeStyleOptions2.PreferObjectInitializer); + public CodeStyleOption2 PreferCollectionExpression => GetOption(CodeStyleOptions2.PreferCollectionExpression); + public CodeStyleOption2 PreferCollectionInitializer => GetOption(CodeStyleOptions2.PreferCollectionInitializer); + public CodeStyleOption2 PreferSimplifiedBooleanExpressions => GetOption(CodeStyleOptions2.PreferSimplifiedBooleanExpressions); + public OperatorPlacementWhenWrappingPreference OperatorPlacementWhenWrapping => GetOption(CodeStyleOptions2.OperatorPlacementWhenWrapping); + public CodeStyleOption2 PreferCoalesceExpression => GetOption(CodeStyleOptions2.PreferCoalesceExpression); + public CodeStyleOption2 PreferNullPropagation => GetOption(CodeStyleOptions2.PreferNullPropagation); + public CodeStyleOption2 PreferExplicitTupleNames => GetOption(CodeStyleOptions2.PreferExplicitTupleNames); + public CodeStyleOption2 PreferAutoProperties => GetOption(CodeStyleOptions2.PreferAutoProperties); + public CodeStyleOption2 PreferInferredTupleNames => GetOption(CodeStyleOptions2.PreferInferredTupleNames); + public CodeStyleOption2 PreferInferredAnonymousTypeMemberNames => GetOption(CodeStyleOptions2.PreferInferredAnonymousTypeMemberNames); + public CodeStyleOption2 PreferIsNullCheckOverReferenceEqualityMethod => GetOption(CodeStyleOptions2.PreferIsNullCheckOverReferenceEqualityMethod); + public CodeStyleOption2 PreferConditionalExpressionOverAssignment => GetOption(CodeStyleOptions2.PreferConditionalExpressionOverAssignment); + public CodeStyleOption2 PreferConditionalExpressionOverReturn => GetOption(CodeStyleOptions2.PreferConditionalExpressionOverReturn); + public CodeStyleOption2 PreferCompoundAssignment => GetOption(CodeStyleOptions2.PreferCompoundAssignment); + public CodeStyleOption2 PreferSimplifiedInterpolation => GetOption(CodeStyleOptions2.PreferSimplifiedInterpolation); public CodeStyleOption2 PreferSystemHashCode => GetOption(CodeStyleOptions2.PreferSystemHashCode); - public CodeStyleOption2 UnusedParameters => GetOption(CodeStyleOptions2.UnusedParameters, FallbackCodeStyleOptions.UnusedParameters); - public CodeStyleOption2 RequireAccessibilityModifiers => GetOption(CodeStyleOptions2.AccessibilityModifiersRequired, FallbackCodeStyleOptions.AccessibilityModifiersRequired); - public CodeStyleOption2 PreferReadonly => GetOption(CodeStyleOptions2.PreferReadonly, FallbackCodeStyleOptions.PreferReadonly); - public CodeStyleOption2 ArithmeticBinaryParentheses => GetOption(CodeStyleOptions2.ArithmeticBinaryParentheses, FallbackCodeStyleOptions.ArithmeticBinaryParentheses); - public CodeStyleOption2 OtherBinaryParentheses => GetOption(CodeStyleOptions2.OtherBinaryParentheses, FallbackCodeStyleOptions.OtherBinaryParentheses); - public CodeStyleOption2 RelationalBinaryParentheses => GetOption(CodeStyleOptions2.RelationalBinaryParentheses, FallbackCodeStyleOptions.RelationalBinaryParentheses); - public CodeStyleOption2 OtherParentheses => GetOption(CodeStyleOptions2.OtherParentheses, FallbackCodeStyleOptions.OtherParentheses); - public CodeStyleOption2 ForEachExplicitCastInSource => GetOption(CodeStyleOptions2.ForEachExplicitCastInSource, FallbackCodeStyleOptions.ForEachExplicitCastInSource); - public CodeStyleOption2 PreferNamespaceAndFolderMatchStructure => GetOption(CodeStyleOptions2.PreferNamespaceAndFolderMatchStructure, FallbackCodeStyleOptions.PreferNamespaceAndFolderMatchStructure); - public CodeStyleOption2 AllowMultipleBlankLines => GetOption(CodeStyleOptions2.AllowMultipleBlankLines, FallbackCodeStyleOptions.AllowMultipleBlankLines); - public CodeStyleOption2 AllowStatementImmediatelyAfterBlock => GetOption(CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, FallbackCodeStyleOptions.AllowStatementImmediatelyAfterBlock); - public string RemoveUnnecessarySuppressionExclusions => GetOption(CodeStyleOptions2.RemoveUnnecessarySuppressionExclusions, FallbackCodeStyleOptions.RemoveUnnecessarySuppressionExclusions); - - public string FileHeaderTemplate => GetOption(CodeStyleOptions2.FileHeaderTemplate, defaultValue: string.Empty); // no fallback IDE option - - private TValue GetOption(Option2 option, TValue defaultValue) - => _options.GetOption(option, defaultValue); + public CodeStyleOption2 UnusedParameters => GetOption(CodeStyleOptions2.UnusedParameters); + public CodeStyleOption2 RequireAccessibilityModifiers => GetOption(CodeStyleOptions2.AccessibilityModifiersRequired); + public CodeStyleOption2 PreferReadonly => GetOption(CodeStyleOptions2.PreferReadonly); + public CodeStyleOption2 ArithmeticBinaryParentheses => GetOption(CodeStyleOptions2.ArithmeticBinaryParentheses); + public CodeStyleOption2 OtherBinaryParentheses => GetOption(CodeStyleOptions2.OtherBinaryParentheses); + public CodeStyleOption2 RelationalBinaryParentheses => GetOption(CodeStyleOptions2.RelationalBinaryParentheses); + public CodeStyleOption2 OtherParentheses => GetOption(CodeStyleOptions2.OtherParentheses); + public CodeStyleOption2 ForEachExplicitCastInSource => GetOption(CodeStyleOptions2.ForEachExplicitCastInSource); + public CodeStyleOption2 PreferNamespaceAndFolderMatchStructure => GetOption(CodeStyleOptions2.PreferNamespaceAndFolderMatchStructure); + public CodeStyleOption2 AllowMultipleBlankLines => GetOption(CodeStyleOptions2.AllowMultipleBlankLines); + public CodeStyleOption2 AllowStatementImmediatelyAfterBlock => GetOption(CodeStyleOptions2.AllowStatementImmediatelyAfterBlock); + public string RemoveUnnecessarySuppressionExclusions => GetOption(CodeStyleOptions2.RemoveUnnecessarySuppressionExclusions); + + public string FileHeaderTemplate => GetOption(CodeStyleOptions2.FileHeaderTemplate); public TValue GetOption(PerLanguageOption2 option) - => _options.GetOption(option, _language); + => options.GetOption(option, language); - private TValue GetOption(PerLanguageOption2 option, TValue defaultValue) - => _options.GetOption(option, _language, defaultValue); - - private IdeCodeStyleOptions FallbackCodeStyleOptions - => _fallbackOptions.CodeStyleOptions ?? IdeCodeStyleOptions.CommonDefaults; - - private SimplifierOptions FallbackSimplifierOptions - => _fallbackOptions.CleanupOptions?.SimplifierOptions ?? SimplifierOptions.CommonDefaults; + private TValue GetOption(Option2 option) + => options.GetOption(option); internal IOptionsReader GetAnalyzerConfigOptions() - => _options; - - internal IdeAnalyzerOptions GetFallbackOptions() - => _fallbackOptions; + => options; } internal static partial class AnalyzerOptionsProviders @@ -126,7 +91,7 @@ public static IdeAnalyzerOptions GetIdeOptions(this AnalyzerOptions options) #endif public static AnalyzerOptionsProvider GetAnalyzerOptions(this AnalyzerOptions analyzerOptions, SyntaxTree syntaxTree) - => new(analyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader(), syntaxTree.Options.Language, analyzerOptions); + => new(analyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader(), syntaxTree.Options.Language); public static AnalyzerOptionsProvider GetAnalyzerOptions(this SemanticModelAnalysisContext context) => GetAnalyzerOptions(context.Options, context.SemanticModel.SyntaxTree); @@ -148,13 +113,4 @@ public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this SemanticModelAnalysi public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this SyntaxNodeAnalysisContext context) => context.Options.GetIdeOptions(); - - public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this SyntaxTreeAnalysisContext context) - => context.Options.GetIdeOptions(); - - public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this OperationAnalysisContext context) - => context.Options.GetIdeOptions(); - - public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this CodeBlockAnalysisContext context) - => context.Options.GetIdeOptions(); } diff --git a/src/Analyzers/Core/CodeFixes/AnalyzerOptionsProviders.cs b/src/Analyzers/Core/CodeFixes/AnalyzerOptionsProviders.cs index c799a31e569e9..e270d3156c84e 100644 --- a/src/Analyzers/Core/CodeFixes/AnalyzerOptionsProviders.cs +++ b/src/Analyzers/Core/CodeFixes/AnalyzerOptionsProviders.cs @@ -2,11 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Threading; using System.Threading.Tasks; -using System.Collections.Generic; -using System.Text; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Options; @@ -20,6 +17,6 @@ public static async ValueTask GetAnalyzerOptionsProvide var analyzerOptions = document.Project.AnalyzerOptions; var configOptions = analyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader(); - return new AnalyzerOptionsProvider(configOptions, document.Project.Language, analyzerOptions); + return new AnalyzerOptionsProvider(configOptions, document.Project.Language); } } diff --git a/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb b/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb index 8e24a0c492cd1..324ccd7641048 100644 --- a/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb +++ b/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb @@ -18,83 +18,61 @@ Namespace Microsoft.CodeAnalysis.Diagnostics ''' Private ReadOnly _options As IOptionsReader - ''' - ''' Fallback options - the default options in Code Style layer. - ''' - Private ReadOnly _fallbackOptions As IdeAnalyzerOptions - - Public Sub New(options As IOptionsReader, fallbackOptions As IdeAnalyzerOptions) + Public Sub New(options As IOptionsReader) _options = options - _fallbackOptions = fallbackOptions - End Sub - - Public Sub New(options As IOptionsReader, fallbackOptions As AnalyzerOptions) - MyClass.New(options, fallbackOptions.GetIdeOptions()) End Sub Public Function GetSimplifierOptions() As VisualBasicSimplifierOptions - Return New VisualBasicSimplifierOptions(_options, FallbackSimplifierOptions) + Return New VisualBasicSimplifierOptions(_options, fallbackOptions:=Nothing) End Function Public ReadOnly Property PreferredModifierOrder As CodeStyleOption2(Of String) Get - Return GetOption(VisualBasicCodeStyleOptions.PreferredModifierOrder, FallbackCodeStyleOptions.PreferredModifierOrder) + Return GetOption(VisualBasicCodeStyleOptions.PreferredModifierOrder) End Get End Property Public ReadOnly Property PreferIsNotExpression As CodeStyleOption2(Of Boolean) Get - Return GetOption(VisualBasicCodeStyleOptions.PreferIsNotExpression, FallbackCodeStyleOptions.PreferIsNotExpression) + Return GetOption(VisualBasicCodeStyleOptions.PreferIsNotExpression) End Get End Property Public ReadOnly Property PreferSimplifiedObjectCreation As CodeStyleOption2(Of Boolean) Get - Return GetOption(VisualBasicCodeStyleOptions.PreferSimplifiedObjectCreation, FallbackCodeStyleOptions.PreferSimplifiedObjectCreation) + Return GetOption(VisualBasicCodeStyleOptions.PreferSimplifiedObjectCreation) End Get End Property Public ReadOnly Property UnusedValueExpressionStatement As CodeStyleOption2(Of UnusedValuePreference) Get - Return GetOption(VisualBasicCodeStyleOptions.UnusedValueExpressionStatement, FallbackCodeStyleOptions.UnusedValueExpressionStatement) + Return GetOption(VisualBasicCodeStyleOptions.UnusedValueExpressionStatement) End Get End Property Public ReadOnly Property UnusedValueAssignment As CodeStyleOption2(Of UnusedValuePreference) Get - Return GetOption(VisualBasicCodeStyleOptions.UnusedValueAssignment, FallbackCodeStyleOptions.UnusedValueAssignment) + Return GetOption(VisualBasicCodeStyleOptions.UnusedValueAssignment) End Get End Property - Private Function GetOption(Of TValue)([option] As Option2(Of CodeStyleOption2(Of TValue)), defaultValue As CodeStyleOption2(Of TValue)) As CodeStyleOption2(Of TValue) - Return _options.GetOption([option], defaultValue) + Private Function GetOption(Of TValue)([option] As Option2(Of CodeStyleOption2(Of TValue))) As CodeStyleOption2(Of TValue) + Return _options.GetOption([option]) End Function - Private ReadOnly Property FallbackSimplifierOptions As VisualBasicSimplifierOptions - Get - Return If(DirectCast(_fallbackOptions.CleanupOptions?.SimplifierOptions, VisualBasicSimplifierOptions), VisualBasicSimplifierOptions.Default) - End Get - End Property - - Private ReadOnly Property FallbackCodeStyleOptions As VisualBasicIdeCodeStyleOptions - Get - Return If(DirectCast(_fallbackOptions.CodeStyleOptions, VisualBasicIdeCodeStyleOptions), VisualBasicIdeCodeStyleOptions.Default) - End Get - End Property - Public Shared Narrowing Operator CType(provider As AnalyzerOptionsProvider) As VisualBasicAnalyzerOptionsProvider - Return New VisualBasicAnalyzerOptionsProvider(provider.GetAnalyzerConfigOptions(), provider.GetFallbackOptions()) + Return New VisualBasicAnalyzerOptionsProvider(provider.GetAnalyzerConfigOptions()) End Operator Public Shared Widening Operator CType(provider As VisualBasicAnalyzerOptionsProvider) As AnalyzerOptionsProvider - Return New AnalyzerOptionsProvider(provider._options, LanguageNames.VisualBasic, provider._fallbackOptions) + Return New AnalyzerOptionsProvider(provider._options, LanguageNames.VisualBasic) End Operator End Structure Friend Module VisualBasicAnalyzerOptionsProviders Public Function GetVisualBasicAnalyzerOptions(options As AnalyzerOptions, syntaxTree As SyntaxTree) As VisualBasicAnalyzerOptionsProvider - Return New VisualBasicAnalyzerOptionsProvider(options.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader(), options) + Return New VisualBasicAnalyzerOptionsProvider(options.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader()) End Function diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index a4ab425197cd9..df7f3b889c6ed 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -21,6 +21,7 @@ using Microsoft.CodeAnalysis.Diagnostics.CSharp; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editor.UnitTests; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; @@ -886,10 +887,12 @@ private protected static async Task AssertCodeCleanupResult(string expected, str using var workspace = EditorTestWorkspace.CreateCSharp(code, composition: EditorTestCompositions.EditorFeaturesWpf); // must set global options since incremental analyzer infra reads from global options - var globalOptions = workspace.GlobalOptions; - globalOptions.SetGlobalOption(GenerationOptions.SeparateImportDirectiveGroups, LanguageNames.CSharp, separateUsingGroups); - globalOptions.SetGlobalOption(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp, systemUsingsFirst); - globalOptions.SetGlobalOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredImportPlacement); + workspace.SetAnalyzerFallbackAndGlobalOptions(new OptionsCollection(LanguageNames.CSharp) + { + { GenerationOptions.SeparateImportDirectiveGroups, separateUsingGroups }, + { GenerationOptions.PlaceSystemNamespaceFirst, systemUsingsFirst }, + { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredImportPlacement }, + }); var solution = workspace.CurrentSolution.WithAnalyzerReferences(new[] { @@ -923,7 +926,7 @@ private protected static async Task AssertCodeCleanupResult(string expected, str enabledDiagnostics = VisualStudio.LanguageServices.Implementation.CodeCleanup.AbstractCodeCleanUpFixer.AdjustDiagnosticOptions(enabledDiagnostics, enabledFixIdsFilter); var newDoc = await codeCleanupService.CleanupAsync( - document, enabledDiagnostics, CodeAnalysisProgress.None, globalOptions.CreateProvider(), CancellationToken.None); + document, enabledDiagnostics, CodeAnalysisProgress.None, workspace.GlobalOptions.CreateProvider(), CancellationToken.None); var actual = await newDoc.GetTextAsync(); diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs index 789e2ef71f0cd..260baa5f17f93 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs @@ -35,7 +35,7 @@ private async Task GetProjectAnalysisDataAsync( // We can't return here if we have open file only analyzers since saved data for open file only analyzer // is incomplete -- it only contains info on open files rather than whole project. - if (existingData.Version == version && !CompilationHasOpenFileOnlyAnalyzers(compilationWithAnalyzers, ideOptions.CleanupOptions?.SimplifierOptions)) + if (existingData.Version == version && !CompilationHasOpenFileOnlyAnalyzers(compilationWithAnalyzers, ideOptions.SimplifierOptions)) { return existingData; } @@ -214,7 +214,7 @@ private static bool TryReduceAnalyzersToRun( { if (existing.TryGetValue(analyzer, out var analysisResult) && analysisResult.Version == version && - !analyzer.IsOpenFileOnly(ideOptions.CleanupOptions?.SimplifierOptions)) + !analyzer.IsOpenFileOnly(ideOptions.SimplifierOptions)) { // we already have up to date result. continue; diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs index 88214593ae6d4..e507a0b07d2bb 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.InProcOrRemoteHostAnalyzerRunner.cs @@ -196,7 +196,7 @@ private static async Task forceExecuteAllAnalyzers || !a.IsOpenFileOnly(ideOptions.CleanupOptions?.SimplifierOptions)); + compilationWithAnalyzers.Analyzers.Where(a => forceExecuteAllAnalyzers || !a.IsOpenFileOnly(ideOptions.SimplifierOptions)); analyzerMap.AppendAnalyzerMap(analyzers); diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs index 041715c46a099..5b9c64754eec5 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs @@ -32,7 +32,7 @@ public async Task> ForceAnalyzeProjectAsync(Proje // this is perf optimization. we cache these result since we know the result. (no diagnostics) var activeAnalyzers = stateSets .Select(s => s.Analyzer) - .Where(a => !a.IsOpenFileOnly(ideOptions.CleanupOptions?.SimplifierOptions)); + .Where(a => !a.IsOpenFileOnly(ideOptions.SimplifierOptions)); CompilationWithAnalyzers? compilationWithAnalyzers = null; diff --git a/src/LanguageServer/Protocol/Features/Options/IdeAnalyzerOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/IdeAnalyzerOptionsStorage.cs index d4cb86c44517e..c3b84c406891e 100644 --- a/src/LanguageServer/Protocol/Features/Options/IdeAnalyzerOptionsStorage.cs +++ b/src/LanguageServer/Protocol/Features/Options/IdeAnalyzerOptionsStorage.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Simplification; namespace Microsoft.CodeAnalysis.Diagnostics; @@ -17,16 +18,13 @@ public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this IGlobalOptionService public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) { - var language = languageServices.Language; - // avoid throwing for languages other than C# and VB: var supportsLanguageSpecificOptions = languageServices.GetService() != null; return new() { CrashOnAnalyzerException = globalOptions.GetOption(CrashOnAnalyzerException), - CleanCodeGenerationOptions = supportsLanguageSpecificOptions ? globalOptions.GetCleanCodeGenerationOptions(languageServices) : null, - CodeStyleOptions = supportsLanguageSpecificOptions ? globalOptions.GetCodeStyleOptions(languageServices) : null, + SimplifierOptions = supportsLanguageSpecificOptions ? globalOptions.GetSimplifierOptions(languageServices) : null, }; } diff --git a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentHandler.cs b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentHandler.cs index 6ba5da7b3afb5..543f18d5ef3b4 100644 --- a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentHandler.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; using LSP = Roslyn.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.LanguageServer.Handler diff --git a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs index 6bb7432fde53f..c5b7205715520 100644 --- a/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Formatting/FormatDocumentRangeHandler.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; using Roslyn.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.LanguageServer.Handler diff --git a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs index 5e7ab4334dded..06f09db296468 100644 --- a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs @@ -11,11 +11,8 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeStyle; -using Microsoft.CodeAnalysis.CSharp.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.Diagnostics.TypeStyle; -using Microsoft.CodeAnalysis.CSharp.Formatting; -using Microsoft.CodeAnalysis.CSharp.Simplification; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Remote; @@ -24,7 +21,6 @@ using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.VisualBasic.CodeStyle; using Microsoft.CodeAnalysis.VisualBasic.UseNullPropagation; using Microsoft.CodeAnalysis.Workspaces.Diagnostics; using Roslyn.Test.Utilities; @@ -50,30 +46,15 @@ void Method() using var workspace = CreateWorkspace(LanguageNames.CSharp, code); var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer); - var analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType, - IdeAnalyzerOptions.GetDefault(workspace.Services.SolutionServices.GetLanguageServices(LanguageNames.CSharp))); + var analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType); var diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); Assert.Equal(DiagnosticSeverity.Hidden, diagnostics[0].Severity); - var ideOptions = new IdeAnalyzerOptions() - { - CleanCodeGenerationOptions = new() - { - GenerationOptions = CSharpCodeGenerationOptions.Default, - CleanupOptions = new() - { - FormattingOptions = CSharpSyntaxFormattingOptions.Default, - SimplifierOptions = new CSharpSimplifierOptions() - { - VarWhenTypeIsApparent = new CodeStyleOption2(false, NotificationOption2.Suggestion) - } - } - } - }; + workspace.SetAnalyzerFallbackOptions(LanguageNames.CSharp, ("csharp_style_var_when_type_is_apparent", "false:suggestion")); - analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType, ideOptions); + analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType); diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id); @@ -91,30 +72,17 @@ End Sub End Class"; using var workspace = CreateWorkspace(LanguageNames.VisualBasic, code); - var ideAnalyzerOptions = IdeAnalyzerOptions.GetDefault(workspace.Services.SolutionServices.GetLanguageServices(LanguageNames.VisualBasic)); - ideAnalyzerOptions = ideAnalyzerOptions with - { - CodeStyleOptions = new VisualBasicIdeCodeStyleOptions() - { - PreferNullPropagation = new CodeStyleOption2(false, NotificationOption2.Silent) - } - }; + workspace.SetAnalyzerFallbackOptions(LanguageNames.VisualBasic, ("dotnet_style_null_propagation", "false:silent")); var analyzerType = typeof(VisualBasicUseNullPropagationDiagnosticAnalyzer); - var analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType, ideAnalyzerOptions); + var analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType); Assert.True(analyzerResult.IsEmpty); - ideAnalyzerOptions = ideAnalyzerOptions with - { - CodeStyleOptions = new VisualBasicIdeCodeStyleOptions() - { - PreferNullPropagation = new CodeStyleOption2(true, NotificationOption2.Error) - } - }; + workspace.SetAnalyzerFallbackOptions(LanguageNames.VisualBasic, ("dotnet_style_null_propagation", "true:error")); - analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType, ideAnalyzerOptions); + analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType); var diagnostics = analyzerResult.GetDocumentDiagnostics(analyzerResult.DocumentIds.First(), AnalysisKind.Semantic); Assert.Equal(IDEDiagnosticIds.UseNullPropagationDiagnosticId, diagnostics[0].Id); @@ -126,7 +94,6 @@ public async Task TestCancellation() var code = @"class Test { void Method() { } }"; using var workspace = CreateWorkspace(LanguageNames.CSharp, code); - var ideAnalyzerOptions = IdeAnalyzerOptions.GetDefault(workspace.Services.SolutionServices.GetLanguageServices(LanguageNames.CSharp)); var analyzerType = typeof(MyAnalyzer); @@ -136,7 +103,7 @@ public async Task TestCancellation() try { - var task = Task.Run(() => AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType, ideAnalyzerOptions, source.Token)); + var task = Task.Run(() => AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType, source.Token)); // wait random milli-second var random = new Random(Environment.TickCount); @@ -235,7 +202,7 @@ void Method() private static InProcOrRemoteHostAnalyzerRunner CreateAnalyzerRunner() => new(enabled: true, new DiagnosticAnalyzerInfoCache()); - private static async Task AnalyzeAsync(TestWorkspace workspace, ProjectId projectId, Type analyzerType, IdeAnalyzerOptions ideOptions, CancellationToken cancellationToken = default) + private static async Task AnalyzeAsync(TestWorkspace workspace, ProjectId projectId, Type analyzerType, CancellationToken cancellationToken = default) { var executor = CreateAnalyzerRunner(); @@ -244,7 +211,7 @@ private static async Task AnalyzeAsync(TestWorkspace w var analyzerDriver = (await project.GetCompilationAsync()).WithAnalyzers( analyzerReference.GetAnalyzers(project.Language).Where(a => a.GetType() == analyzerType).ToImmutableArray(), - new WorkspaceAnalyzerOptions(project.AnalyzerOptions, ideOptions)); + new WorkspaceAnalyzerOptions(project.AnalyzerOptions, IdeAnalyzerOptions.GetDefault(project.Services))); var result = await executor.AnalyzeProjectAsync( project, analyzerDriver, logPerformanceInfo: false, getTelemetryInfo: false, cancellationToken); diff --git a/src/Workspaces/Core/Portable/Diagnostics/WorkspaceAnalyzerOptions.cs b/src/Workspaces/Core/Portable/Diagnostics/WorkspaceAnalyzerOptions.cs index ca42a234a37be..d29fd966eba69 100644 --- a/src/Workspaces/Core/Portable/Diagnostics/WorkspaceAnalyzerOptions.cs +++ b/src/Workspaces/Core/Portable/Diagnostics/WorkspaceAnalyzerOptions.cs @@ -4,6 +4,7 @@ #nullable disable +using Microsoft.CodeAnalysis.Simplification; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics; @@ -14,6 +15,10 @@ namespace Microsoft.CodeAnalysis.Diagnostics; /// internal sealed class WorkspaceAnalyzerOptions(AnalyzerOptions options, IdeAnalyzerOptions ideOptions) : AnalyzerOptions(options.AdditionalFiles, options.AnalyzerConfigOptionsProvider) { + /// + /// Currently needed to implement . + /// Should be removed: https://github.com/dotnet/roslyn/issues/74048 + /// public IdeAnalyzerOptions IdeOptions { get; } = ideOptions; public override bool Equals(object obj) diff --git a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs index 4313e5532c122..e6c461f6aa2af 100644 --- a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs +++ b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs @@ -116,6 +116,16 @@ internal TestWorkspace( } } + public void SetAnalyzerFallbackOptions(string language, params (string name, string value)[] options) + { + SetCurrentSolution( + s => s.WithFallbackAnalyzerOptions(s.FallbackAnalyzerOptions.SetItem(language, + StructuredAnalyzerConfigOptions.Create( + new DictionaryAnalyzerConfigOptions( + options.Select(static o => KeyValuePairUtil.Create(o.name, o.value)).ToImmutableDictionary())))), + changeKind: WorkspaceChangeKind.SolutionChanged); + } + /// /// Use to set specified editorconfig options as . /// diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Diagnostics/IdeAnalyzerOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Diagnostics/IdeAnalyzerOptions.cs index 61ed91c84206c..51c1700a6a48c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Diagnostics/IdeAnalyzerOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Diagnostics/IdeAnalyzerOptions.cs @@ -3,12 +3,11 @@ // See the LICENSE file in the project root for more information. using System.Runtime.Serialization; -using Microsoft.CodeAnalysis.CodeCleanup; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CodeStyle; #if !CODE_STYLE using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Simplification; #endif namespace Microsoft.CodeAnalysis.Diagnostics; @@ -23,25 +22,17 @@ internal sealed record class IdeAnalyzerOptions [DataMember] public bool CrashOnAnalyzerException { get; init; } = false; +#if !CODE_STYLE /// - /// Default values for , or null if not available (the project language does not support these options). - /// - [DataMember] public CleanCodeGenerationOptions? CleanCodeGenerationOptions { get; init; } = null; - - /// - /// Default values for , or null if not available (the project language does not support these options). + /// Currently needed to implement . + /// Should be removed: https://github.com/dotnet/roslyn/issues/74048 /// - [DataMember] public IdeCodeStyleOptions? CodeStyleOptions { get; init; } = null; - - public CodeCleanupOptions? CleanupOptions => CleanCodeGenerationOptions?.CleanupOptions; - public CodeGenerationOptions? GenerationOptions => CleanCodeGenerationOptions?.GenerationOptions; + [DataMember] public SimplifierOptions? SimplifierOptions { get; init; } = null; -#if !CODE_STYLE public static IdeAnalyzerOptions GetDefault(LanguageServices languageServices) => new() { - CleanCodeGenerationOptions = CodeGeneration.CleanCodeGenerationOptions.GetDefault(languageServices), - CodeStyleOptions = IdeCodeStyleOptions.GetDefault(languageServices), + SimplifierOptions = SimplifierOptions.GetDefault(languageServices), }; #endif } From 7cc4ff4e0a84f420d29a9610dbb74468c445c2c6 Mon Sep 17 00:00:00 2001 From: Arun Chander Date: Mon, 8 Jul 2024 15:18:02 -0700 Subject: [PATCH 43/59] Update Directory.Build.rsp --- Directory.Build.rsp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.rsp b/Directory.Build.rsp index 424936667b087..37bf61d3487f8 100644 --- a/Directory.Build.rsp +++ b/Directory.Build.rsp @@ -1 +1,2 @@ --p:_IsDisjointMSBuildVersion=false \ No newline at end of file +# Workaround for https://github.com/dotnet/sdk/issues/41791 +-p:_IsDisjointMSBuildVersion=false From 0971b49f5852a2ed2d091c3e5343a43e909b10ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Mon, 8 Jul 2024 15:52:17 -0700 Subject: [PATCH 44/59] Allow Document.FilePath to be set to null (#74290) --- .../Portable/Workspace/Solution/Document.cs | 18 ++--- .../Workspace/Solution/DocumentState.cs | 59 ++++++--------- .../Portable/Workspace/Solution/Solution.cs | 11 +-- .../Core/Portable/Workspace/Workspace.cs | 5 +- .../CoreTest/SolutionTests/SolutionTests.cs | 71 +++++++++++++++++-- 5 files changed, 98 insertions(+), 66 deletions(-) diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs index ba601240cab4c..0d7fa9786fed0 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Document.cs @@ -383,41 +383,37 @@ async Task GetSemanticModelWorkerAsync() /// Creates a new instance of this document updated to have the source code kind specified. /// public Document WithSourceCodeKind(SourceCodeKind kind) - => this.Project.Solution.WithDocumentSourceCodeKind(this.Id, kind).GetDocument(this.Id)!; + => this.Project.Solution.WithDocumentSourceCodeKind(this.Id, kind).GetRequiredDocument(Id); /// /// Creates a new instance of this document updated to have the text specified. /// public Document WithText(SourceText text) - => this.Project.Solution.WithDocumentText(this.Id, text, PreservationMode.PreserveIdentity).GetDocument(this.Id)!; + => this.Project.Solution.WithDocumentText(this.Id, text, PreservationMode.PreserveIdentity).GetRequiredDocument(Id); /// /// Creates a new instance of this document updated to have a syntax tree rooted by the specified syntax node. /// public Document WithSyntaxRoot(SyntaxNode root) - => this.Project.Solution.WithDocumentSyntaxRoot(this.Id, root, PreservationMode.PreserveIdentity).GetDocument(this.Id)!; + => this.Project.Solution.WithDocumentSyntaxRoot(this.Id, root, PreservationMode.PreserveIdentity).GetRequiredDocument(Id); /// /// Creates a new instance of this document updated to have the specified name. /// public Document WithName(string name) - => this.Project.Solution.WithDocumentName(this.Id, name).GetDocument(this.Id)!; + => this.Project.Solution.WithDocumentName(this.Id, name).GetRequiredDocument(Id); /// /// Creates a new instance of this document updated to have the specified folders. /// public Document WithFolders(IEnumerable folders) - => this.Project.Solution.WithDocumentFolders(this.Id, folders).GetDocument(this.Id)!; + => this.Project.Solution.WithDocumentFolders(this.Id, folders).GetRequiredDocument(Id); /// /// Creates a new instance of this document updated to have the specified file path. /// - /// - // TODO (https://github.com/dotnet/roslyn/issues/37125): Solution.WithDocumentFilePath will throw if - // filePath is null, but it's odd because we *do* support null file paths. Why can't you switch a - // document back to null? - public Document WithFilePath(string filePath) - => this.Project.Solution.WithDocumentFilePath(this.Id, filePath).GetDocument(this.Id)!; + public Document WithFilePath(string? filePath) + => this.Project.Solution.WithDocumentFilePath(this.Id, filePath).GetRequiredDocument(Id); /// /// Get the text changes between this document and a prior version of the same document. diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs index 5eaacf839d0b6..285e12ba49633 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/DocumentState.cs @@ -350,15 +350,7 @@ public DocumentState UpdateParseOptions(ParseOptions options, bool onlyPreproces private DocumentState SetParseOptions(ParseOptions options, bool onlyPreprocessorDirectiveChange) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (!SupportsSyntaxTree) - { - throw new InvalidOperationException(); - } + Contract.ThrowIfFalse(SupportsSyntaxTree); ITreeAndVersionSource? newTreeSource = null; @@ -413,42 +405,37 @@ public DocumentState UpdateSourceCodeKind(SourceCodeKind kind) return this.SetParseOptions(this.ParseOptions.WithKind(kind), onlyPreprocessorDirectiveChange: false); } - // TODO: https://github.com/dotnet/roslyn/issues/37125 - // if FilePath is null, then this will change the name of the underlying tree, but we aren't producing a new tree in that case. public DocumentState UpdateName(string name) => UpdateAttributes(Attributes.With(name: name)); + public DocumentState UpdateFilePath(string? path) + => UpdateAttributes(Attributes.With(filePath: path)); + public DocumentState UpdateFolders(IReadOnlyList folders) => UpdateAttributes(Attributes.With(folders: folders)); - private DocumentState UpdateAttributes(DocumentInfo.DocumentAttributes attributes) - { - Debug.Assert(attributes != Attributes); - - return new DocumentState( - LanguageServices, - Services, - attributes, - _options, - TextAndVersionSource, - LoadTextOptions, - _treeSource); - } - - public DocumentState UpdateFilePath(string? filePath) + private DocumentState UpdateAttributes(DocumentInfo.DocumentAttributes newAttributes) { - var newAttributes = Attributes.With(filePath: filePath); Debug.Assert(newAttributes != Attributes); - // TODO: it's overkill to fully reparse the tree if we had the tree already; all we have to do is update the - // file path and diagnostic options for that tree. - var newTreeSource = SupportsSyntaxTree ? - CreateLazyFullyParsedTree( - TextAndVersionSource, - LoadTextOptions, - newAttributes.SyntaxTreeFilePath, - _options, - LanguageServices) : null; + ITreeAndVersionSource? newTreeSource; + + if (newAttributes.SyntaxTreeFilePath != Attributes.SyntaxTreeFilePath) + { + // TODO: it's overkill to fully reparse the tree if we had the tree already; all we have to do is update the + // file path and diagnostic options for that tree. + newTreeSource = SupportsSyntaxTree ? + CreateLazyFullyParsedTree( + TextAndVersionSource, + LoadTextOptions, + newAttributes.SyntaxTreeFilePath, + _options, + LanguageServices) : null; + } + else + { + newTreeSource = _treeSource; + } return new DocumentState( LanguageServices, diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs index e102e911df007..438640169d706 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs @@ -1169,18 +1169,9 @@ public Solution WithDocumentFolders(DocumentId documentId, IEnumerable? /// /// Creates a new solution instance with the document specified updated to have the specified file path. /// - public Solution WithDocumentFilePath(DocumentId documentId, string filePath) + public Solution WithDocumentFilePath(DocumentId documentId, string? filePath) { CheckContainsDocument(documentId); - - // TODO (https://github.com/dotnet/roslyn/issues/37125): - // We *do* support null file paths. Why can't you switch a document back to null? - // See DocumentState.GetSyntaxTreeFilePath - if (filePath == null) - { - throw new ArgumentNullException(nameof(filePath)); - } - return WithCompilationState(_compilationState.WithDocumentFilePath(documentId, filePath)); } diff --git a/src/Workspaces/Core/Portable/Workspace/Workspace.cs b/src/Workspaces/Core/Portable/Workspace/Workspace.cs index 6bf7e5efe4372..7f7e86d82952e 100644 --- a/src/Workspaces/Core/Portable/Workspace/Workspace.cs +++ b/src/Workspaces/Core/Portable/Workspace/Workspace.cs @@ -1088,10 +1088,7 @@ protected internal void OnDocumentInfoChanged(DocumentId documentId, DocumentInf if (oldAttributes.FilePath != newInfo.FilePath) { - // TODO (https://github.com/dotnet/roslyn/issues/37125): Solution.WithDocumentFilePath will throw if - // filePath is null, but it's odd because we *do* support null file paths. The suppression here is to silence it - // but should be removed when the bug is fixed. - newSolution = newSolution.WithDocumentFilePath(documentId, newInfo.FilePath!); + newSolution = newSolution.WithDocumentFilePath(documentId, newInfo.FilePath); } if (oldAttributes.SourceCodeKind != newInfo.SourceCodeKind) diff --git a/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs b/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs index 2bf869fa41587..b068688cc7798 100644 --- a/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs +++ b/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs @@ -226,19 +226,19 @@ public void WithDocumentFilePath() var path = "new path"; var newSolution1 = solution.WithDocumentFilePath(documentId, path); - Assert.Equal(path, newSolution1.GetDocument(documentId)!.FilePath); + Assert.Equal(path, newSolution1.GetRequiredDocument(documentId).FilePath); AssertEx.Equal(new[] { documentId }, newSolution1.GetDocumentIdsWithFilePath(path)); var newSolution2 = newSolution1.WithDocumentFilePath(documentId, path); Assert.Same(newSolution1, newSolution2); - // empty path (TODO https://github.com/dotnet/roslyn/issues/37125): var newSolution3 = solution.WithDocumentFilePath(documentId, ""); - Assert.Equal("", newSolution3.GetDocument(documentId)!.FilePath); + Assert.Equal("", newSolution3.GetRequiredDocument(documentId).FilePath); Assert.Empty(newSolution3.GetDocumentIdsWithFilePath("")); - // TODO: https://github.com/dotnet/roslyn/issues/37125 - Assert.Throws(() => solution.WithDocumentFilePath(documentId, filePath: null!)); + var newSolution4 = solution.WithDocumentFilePath(documentId, null); + Assert.Null(newSolution4.GetRequiredDocument(documentId).FilePath); + Assert.Empty(newSolution4.GetDocumentIdsWithFilePath(null)); Assert.Throws(() => solution.WithDocumentFilePath(null!, path)); Assert.Throws(() => solution.WithDocumentFilePath(s_unrelatedDocumentId, path)); @@ -1341,6 +1341,67 @@ public async Task ChangingPreprocessorDirectivesMayReparse(string source, bool e Assert.Equal(expectReuse, oldRoot.IsIncrementallyIdenticalTo(newTree.GetRoot())); } + [Theory] + [InlineData(null, "test.cs")] + [InlineData("test.cs", null)] + [InlineData("", null)] + [InlineData("test.cs", "")] + public async Task ChangingFilePathReparses(string oldPath, string newPath) + { + var projectId = ProjectId.CreateNewId(); + var documentId = DocumentId.CreateNewId(projectId); + + using var workspace = CreateWorkspace(); + var document = workspace.CurrentSolution + .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp) + .AddDocument(documentId, name: "Test.cs", text: "// File", filePath: oldPath) + .GetRequiredDocument(documentId); + + var oldTree = await document.GetRequiredSyntaxTreeAsync(CancellationToken.None); + var newDocument = document.WithFilePath(newPath); + var newTree = await newDocument.GetRequiredSyntaxTreeAsync(CancellationToken.None); + + Assert.False(oldTree.GetRoot().IsIncrementallyIdenticalTo(newTree.GetRoot())); + } + + [Fact] + public async Task ChangingName_ReparsesWhenPathIsNull() + { + var projectId = ProjectId.CreateNewId(); + var documentId = DocumentId.CreateNewId(projectId); + + using var workspace = CreateWorkspace(); + var document = workspace.CurrentSolution + .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp) + .AddDocument(documentId, name: "name1", text: "// File", filePath: null) + .GetRequiredDocument(documentId); + + var oldTree = await document.GetRequiredSyntaxTreeAsync(CancellationToken.None); + var newDocument = document.WithName("name2"); + var newTree = await newDocument.GetRequiredSyntaxTreeAsync(CancellationToken.None); + + Assert.False(oldTree.GetRoot().IsIncrementallyIdenticalTo(newTree.GetRoot())); + } + + [Fact] + public async Task ChangingName_NoReparse() + { + var projectId = ProjectId.CreateNewId(); + var documentId = DocumentId.CreateNewId(projectId); + + using var workspace = CreateWorkspace(); + var document = workspace.CurrentSolution + .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp) + .AddDocument(documentId, name: "name1", text: "// File", filePath: "") + .GetRequiredDocument(documentId); + + var oldTree = await document.GetRequiredSyntaxTreeAsync(CancellationToken.None); + var newDocument = document.WithName("name2"); + var newTree = await newDocument.GetRequiredSyntaxTreeAsync(CancellationToken.None); + + Assert.True(oldTree.GetRoot().IsIncrementallyIdenticalTo(newTree.GetRoot())); + } + [Fact] public void WithProjectReferences() { From 296e94e60ea6ec7b361e1505f87540c951f4bd2c Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Mon, 8 Jul 2024 22:34:49 -0700 Subject: [PATCH 45/59] Revert "Remove semantic model keep-alive code in completion (#73844)" This reverts commit 5aeb42b891093c9442b6f9f12454447326a4f8b3. --- .../IntelliSense/AsyncCompletion/CommitManager.cs | 13 +++---------- .../Core/Portable/Completion/CompletionService.cs | 10 ++++++---- .../Completion/CompletionService_GetCompletions.cs | 14 ++++++++------ 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/CommitManager.cs b/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/CommitManager.cs index 7c4c8d68f732e..7d4b4c67a47bc 100644 --- a/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/CommitManager.cs +++ b/src/EditorFeatures/Core/IntelliSense/AsyncCompletion/CommitManager.cs @@ -212,7 +212,7 @@ private AsyncCompletionData.CommitResult Commit( // This might be an item promoted by us, make sure we restore it to the original state first. roslynItem = Helpers.DemoteItem(roslynItem); - CompletionChange change = null!; + CompletionChange change; // We met an issue when external code threw an OperationCanceledException and the cancellationToken is not canceled. // Catching this scenario for further investigations. @@ -229,10 +229,7 @@ private AsyncCompletionData.CommitResult Commit( if (_textView is IDebuggerTextView) roslynItem = ImportCompletionItem.MarkItemToAlwaysFullyQualify(roslynItem); - _threadingContext.JoinableTaskFactory.Run(async () => - { - change = await completionService.GetChangeAsync(document, roslynItem, commitCharacter, cancellationToken).ConfigureAwait(true); - }); + change = completionService.GetChangeAsync(document, roslynItem, commitCharacter, cancellationToken).WaitAndGetResult(cancellationToken); } catch (OperationCanceledException e) when (e.CancellationToken != cancellationToken && FatalError.ReportAndCatch(e)) { @@ -322,11 +319,7 @@ private AsyncCompletionData.CommitResult Commit( var spanToFormat = triggerSnapshotSpan.TranslateTo(subjectBuffer.CurrentSnapshot, SpanTrackingMode.EdgeInclusive); // Note: C# always completes synchronously, TypeScript is async - var changes = ImmutableArray.Empty; - _threadingContext.JoinableTaskFactory.Run(async () => - { - changes = await formattingService.GetFormattingChangesAsync(currentDocument, subjectBuffer, spanToFormat.Span.ToTextSpan(), cancellationToken).ConfigureAwait(true); - }); + var changes = formattingService.GetFormattingChangesAsync(currentDocument, subjectBuffer, spanToFormat.Span.ToTextSpan(), cancellationToken).WaitAndGetResult(cancellationToken); subjectBuffer.ApplyChanges(changes); } } diff --git a/src/Features/Core/Portable/Completion/CompletionService.cs b/src/Features/Core/Portable/Completion/CompletionService.cs index 5eae73ebce122..6ecbfa300daf4 100644 --- a/src/Features/Core/Portable/Completion/CompletionService.cs +++ b/src/Features/Core/Portable/Completion/CompletionService.cs @@ -214,14 +214,14 @@ public virtual TextSpan GetDefaultCompletionListSpan(SourceText text, int caretP var extensionManager = document.Project.Solution.Workspace.Services.GetRequiredService(); - document = await GetDocumentWithFrozenPartialSemanticsAsync(document, cancellationToken).ConfigureAwait(false); - + // We don't need SemanticModel here, just want to make sure it won't get GC'd before CompletionProviders are able to get it. + (document, var semanticModel) = await GetDocumentWithFrozenPartialSemanticsAsync(document, cancellationToken).ConfigureAwait(false); var description = await extensionManager.PerformFunctionAsync( provider, cancellationToken => provider.GetDescriptionAsync(document, item, options, displayOptions, cancellationToken), defaultValue: null, cancellationToken).ConfigureAwait(false); - + GC.KeepAlive(semanticModel); return description; } @@ -245,7 +245,8 @@ public virtual async Task GetChangeAsync( { var extensionManager = document.Project.Solution.Workspace.Services.GetRequiredService(); - document = await GetDocumentWithFrozenPartialSemanticsAsync(document, cancellationToken).ConfigureAwait(false); + // We don't need SemanticModel here, just want to make sure it won't get GC'd before CompletionProviders are able to get it. + (document, var semanticModel) = await GetDocumentWithFrozenPartialSemanticsAsync(document, cancellationToken).ConfigureAwait(false); var change = await extensionManager.PerformFunctionAsync( provider, @@ -255,6 +256,7 @@ public virtual async Task GetChangeAsync( if (change == null) return CompletionChange.Create(new TextChange(new TextSpan(), "")); + GC.KeepAlive(semanticModel); Debug.Assert(item.Span == change.TextChange.Span || item.IsComplexTextEdit); return change; } diff --git a/src/Features/Core/Portable/Completion/CompletionService_GetCompletions.cs b/src/Features/Core/Portable/Completion/CompletionService_GetCompletions.cs index 604fbf2a78cd4..178d6758b87e3 100644 --- a/src/Features/Core/Portable/Completion/CompletionService_GetCompletions.cs +++ b/src/Features/Core/Portable/Completion/CompletionService_GetCompletions.cs @@ -68,7 +68,8 @@ internal virtual async Task GetCompletionsAsync( ImmutableHashSet? roles = null, CancellationToken cancellationToken = default) { - document = await GetDocumentWithFrozenPartialSemanticsAsync(document, cancellationToken).ConfigureAwait(false); + // We don't need SemanticModel here, just want to make sure it won't get GC'd before CompletionProviders are able to get it. + (document, var semanticModel) = await GetDocumentWithFrozenPartialSemanticsAsync(document, cancellationToken).ConfigureAwait(false); var text = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false); var completionListSpan = GetDefaultCompletionListSpan(text, caretPosition); @@ -114,6 +115,8 @@ internal virtual async Task GetCompletionsAsync( var augmentingContexts = await ComputeNonEmptyCompletionContextsAsync( document, caretPosition, trigger, options, completionListSpan, augmentingProviders, sharedContext, cancellationToken).ConfigureAwait(false); + GC.KeepAlive(semanticModel); + // Providers are ordered, but we processed them in our own order. Ensure that the // groups are properly ordered based on the original providers. var completionProviderToIndex = GetCompletionProviderToIndex(providers); @@ -169,20 +172,19 @@ static async Task> GetAugmentingProvidersAsyn } /// - /// Returns a document with frozen partial semantic model unless caller is test code require full semantics. + /// Returns a document with frozen partial semantic unless we already have a complete compilation available. /// Getting full semantic could be costly in certain scenarios and would cause significant delay in completion. /// In most cases we'd still end up with complete document, but we'd consider it an acceptable trade-off even when /// we get into this transient state. /// - private async Task GetDocumentWithFrozenPartialSemanticsAsync(Document document, CancellationToken cancellationToken) + private async Task<(Document document, SemanticModel? semanticModel)> GetDocumentWithFrozenPartialSemanticsAsync(Document document, CancellationToken cancellationToken) { if (_suppressPartialSemantics) { - var _ = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); - return document; + return (document, await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false)); } - return document.WithFrozenPartialSemantics(cancellationToken); + return await document.GetFullOrPartialSemanticModelAsync(cancellationToken).ConfigureAwait(false); } private static bool ValidatePossibleTriggerCharacterSet(CompletionTriggerKind completionTriggerKind, IEnumerable triggeredProviders, From 7866265ebf3bfa5b72f521d3e628ac08d7ab7e8c Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 9 Jul 2024 08:57:38 +0200 Subject: [PATCH 46/59] Consolidate test Span sources (#74281) --- .../Test/Emit2/Emit/NumericIntPtrTests.cs | 2 +- .../IOperationTests_IForEachLoopStatement.cs | 8 +- .../Semantics/NullableReferenceTypesTests.cs | 2 +- .../Test/Semantic/Semantics/RefFieldTests.cs | 8 +- .../Test/Utilities/CSharp/CSharpTestBase.cs | 289 +----------------- .../Test/Utilities/CSharp/TestSources.cs | 103 ++++++- 6 files changed, 101 insertions(+), 311 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs index fdd5fed1ee0de..14e4d23beed4b 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs @@ -11742,7 +11742,7 @@ static void Main() } }"; - var comp = CreateCompilation(new[] { SpanSource, source }, options: TestOptions.UnsafeReleaseExe); + var comp = CreateCompilation(new[] { TestSources.Span, source }, options: TestOptions.UnsafeReleaseExe); verify(comp); comp = CreateCompilation(new[] { source }, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.Net70); diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs index 11a9f7482ab8f..b6701cc8eefe6 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs @@ -3120,7 +3120,7 @@ void M(in System.Span e, int result) Predecessors: [B2] Statements (0) "; - VerifyFlowGraphAndDiagnosticsForTest(source + SpanSource, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); + VerifyFlowGraphAndDiagnosticsForTest(source + TestSources.Span, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); } [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)] @@ -3209,7 +3209,7 @@ void M(in System.Span e, int result) Predecessors: [B2] Statements (0) "; - VerifyFlowGraphAndDiagnosticsForTest(source + SpanSource, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); + VerifyFlowGraphAndDiagnosticsForTest(source + TestSources.Span, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); } [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)] @@ -3298,7 +3298,7 @@ void M(in System.ReadOnlySpan e, int result) Predecessors: [B2] Statements (0) "; - VerifyFlowGraphAndDiagnosticsForTest(source + SpanSource, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); + VerifyFlowGraphAndDiagnosticsForTest(source + TestSources.Span, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); } [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)] @@ -3387,7 +3387,7 @@ void M(in System.ReadOnlySpan e, int result) Predecessors: [B2] Statements (0) "; - VerifyFlowGraphAndDiagnosticsForTest(source + SpanSource, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); + VerifyFlowGraphAndDiagnosticsForTest(source + TestSources.Span, expectedFlowGraph, expectedDiagnostics, TestOptions.ReleaseDll.WithAllowUnsafe(true)); } [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 4b416fa579944..bee789b7f2230 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -142546,7 +142546,7 @@ public class B : IEquatable<(B?, B?)> public bool Equals((B?, B?) l) => false; } "; - var spanRef = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll) + var spanRef = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll) .EmitToImageReference(); var comp = CreateCompilation(def + @" class C diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index fa8b87aff98a1..30d0a4332e765 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -1483,7 +1483,7 @@ unsafe void M() } "; - var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var spanReference = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll); var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( // (16,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') @@ -1539,7 +1539,7 @@ unsafe C M2() } "; - var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var spanReference = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll); var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( // (16,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') @@ -1591,7 +1591,7 @@ unsafe void M() } "; - var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var spanReference = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll); var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( // (16,29): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') @@ -1647,7 +1647,7 @@ unsafe void M() } "; - var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var spanReference = CreateCompilation(TestSources.Span, options: TestOptions.UnsafeReleaseDll); var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( // (16,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 8388968457fb4..2c22b59dac227 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -2211,7 +2211,7 @@ protected static MetadataReference VerifyOperationTreeAndDiagnosticsForTestWithI protected static CSharpCompilation CreateCompilationWithSpan(CSharpTestSource tree, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null) { var reference = CreateCompilation( - SpanSource, + TestSources.Span, options: TestOptions.UnsafeReleaseDll); reference.VerifyDiagnostics(); @@ -2228,7 +2228,7 @@ protected static CSharpCompilation CreateCompilationWithSpan(CSharpTestSource tr protected static CSharpCompilation CreateCompilationWithMscorlibAndSpan(CSharpTestSource text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null) { var reference = CreateEmptyCompilation( - SpanSource, + TestSources.Span, references: new List() { Net451.mscorlib, Net451.SystemCore, Net451.MicrosoftCSharp }, options: TestOptions.UnsafeReleaseDll); @@ -2245,7 +2245,7 @@ protected static CSharpCompilation CreateCompilationWithMscorlibAndSpan(CSharpTe protected static CSharpCompilation CreateCompilationWithMscorlibAndSpanSrc(string text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null) { - var textWitSpan = new string[] { text, SpanSource }; + var textWitSpan = new string[] { text, TestSources.Span }; var comp = CreateEmptyCompilation( textWitSpan, references: new List() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef }, @@ -2254,289 +2254,6 @@ protected static CSharpCompilation CreateCompilationWithMscorlibAndSpanSrc(strin return comp; } - - protected static readonly string SpanSource = @" -namespace System - { - public readonly ref struct Span - { - private readonly T[] arr; - - public ref T this[int i] => ref arr[i]; - public override int GetHashCode() => 1; - public int Length { get; } - public bool IsEmpty => Length == 0; - - unsafe public Span(void* pointer, int length) - { - this.arr = Helpers.ToArray(pointer, length); - this.Length = length; - } - - public Span(T[] arr) - { - this.arr = arr; - this.Length = arr.Length; - } - - public Span(T[] arr, int start, int length) - { - this.arr = new T[length]; - Array.Copy(arr, start, this.arr, 0, length); - this.Length = length; - } - - public void CopyTo(Span other) { } - - /// Gets an enumerator for this span. - public Enumerator GetEnumerator() => new Enumerator(this); - - /// Enumerates the elements of a . - public ref struct Enumerator - { - /// The span being enumerated. - private readonly Span _span; - /// The next index to yield. - private int _index; - - /// Initialize the enumerator. - /// The span to enumerate. - internal Enumerator(Span span) - { - _span = span; - _index = -1; - } - - /// Advances the enumerator to the next element of the span. - public bool MoveNext() - { - int index = _index + 1; - if (index < _span.Length) - { - _index = index; - return true; - } - - return false; - } - - /// Gets the element at the current position of the enumerator. - public ref T Current - { - get => ref _span[_index]; - } - } - - public static implicit operator Span(T[] array) => new Span(array); - } - - public readonly ref struct ReadOnlySpan - { - private readonly T[] arr; - - public ref readonly T this[int i] => ref arr[i]; - public override int GetHashCode() => 2; - public int Length { get; } - public bool IsEmpty => Length == 0; - - unsafe public ReadOnlySpan(void* pointer, int length) - { - this.arr = Helpers.ToArray(pointer, length); - this.Length = length; - } - - public ReadOnlySpan(T[] arr) - { - this.arr = arr; - this.Length = arr.Length; - } - - public ReadOnlySpan(T[] arr, int start, int length) - { - this.arr = new T[length]; - Array.Copy(arr, start, this.arr, 0, length); - this.Length = length; - } - - public void CopyTo(Span other) { } - - /// Gets an enumerator for this span. - public Enumerator GetEnumerator() => new Enumerator(this); - - /// Enumerates the elements of a . - public ref struct Enumerator - { - /// The span being enumerated. - private readonly ReadOnlySpan _span; - /// The next index to yield. - private int _index; - - /// Initialize the enumerator. - /// The span to enumerate. - internal Enumerator(ReadOnlySpan span) - { - _span = span; - _index = -1; - } - - /// Advances the enumerator to the next element of the span. - public bool MoveNext() - { - int index = _index + 1; - if (index < _span.Length) - { - _index = index; - return true; - } - - return false; - } - - /// Gets the element at the current position of the enumerator. - public ref readonly T Current - { - get => ref _span[_index]; - } - } - - public static implicit operator ReadOnlySpan(T[] array) => array == null ? default : new ReadOnlySpan(array); - } - - public readonly ref struct SpanLike - { - public readonly Span field; - } - - public enum Color: sbyte - { - Red, - Green, - Blue - } - - public static unsafe class Helpers - { - public static T[] ToArray(void* ptr, int count) - { - if (ptr == null) - { - return null; - } - - if (typeof(T) == typeof(sbyte)) - { - var arr = new sbyte[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((sbyte*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(byte)) - { - var arr = new byte[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((byte*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(short)) - { - var arr = new short[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((short*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(ushort)) - { - var arr = new ushort[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((ushort*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(int)) - { - var arr = new int[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((int*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(uint)) - { - var arr = new uint[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((uint*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(long)) - { - var arr = new long[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((long*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(ulong)) - { - var arr = new ulong[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((ulong*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(char)) - { - var arr = new char[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((char*)ptr)[i]; - } - - return (T[])(object)arr; - } - - if (typeof(T) == typeof(Color)) - { - var arr = new Color[count]; - for(int i = 0; i < count; i++) - { - arr[i] = ((Color*)ptr)[i]; - } - - return (T[])(object)arr; - } - - throw new Exception(""add a case for: "" + typeof(T)); - } - } - }"; #endregion #region Index and Range diff --git a/src/Compilers/Test/Utilities/CSharp/TestSources.cs b/src/Compilers/Test/Utilities/CSharp/TestSources.cs index f550ea7be6781..62efa9495c6ae 100644 --- a/src/Compilers/Test/Utilities/CSharp/TestSources.cs +++ b/src/Compilers/Test/Utilities/CSharp/TestSources.cs @@ -18,6 +18,7 @@ public readonly ref struct Span public ref T this[int i] => ref arr[i]; public override int GetHashCode() => 1; public int Length { get; } + public bool IsEmpty => Length == 0; unsafe public Span(void* pointer, int length) { @@ -31,6 +32,13 @@ public Span(T[] arr) this.Length = arr is null ? 0 : arr.Length; } + public Span(T[] arr, int start, int length) + { + this.arr = new T[length]; + Array.Copy(arr, start, this.arr, 0, length); + this.Length = length; + } + public void CopyTo(Span other) { } /// Gets an enumerator for this span. @@ -76,12 +84,7 @@ public ref T Current public static implicit operator ReadOnlySpan(Span span) => new ReadOnlySpan(span.arr); - public Span Slice(int offset, int length) - { - var copy = new T[length]; - Array.Copy(arr, offset, copy, 0, length); - return new Span(copy); - } + public Span Slice(int offset, int length) => new Span(this.arr, offset, length); } public readonly ref struct ReadOnlySpan @@ -91,6 +94,7 @@ public readonly ref struct ReadOnlySpan public ref readonly T this[int i] => ref arr[i]; public override int GetHashCode() => 2; public int Length { get; } + public bool IsEmpty => Length == 0; unsafe public ReadOnlySpan(void* pointer, int length) { @@ -104,6 +108,13 @@ public ReadOnlySpan(T[] arr) this.Length = arr is null ? 0 : arr.Length; } + public ReadOnlySpan(T[] arr, int start, int length) + { + this.arr = new T[length]; + Array.Copy(arr, start, this.arr, 0, length); + this.Length = length; + } + public void CopyTo(Span other) { } /// Gets an enumerator for this span. @@ -147,14 +158,10 @@ public ref readonly T Current public static implicit operator ReadOnlySpan(T[] array) => array == null ? default : new ReadOnlySpan(array); + // NOTE: This is defined on String in the BCL (and the target type is non-generic ReadOnlySpan). public static implicit operator ReadOnlySpan(string stringValue) => string.IsNullOrEmpty(stringValue) ? default : new ReadOnlySpan((T[])(object)stringValue.ToCharArray()); - public ReadOnlySpan Slice(int offset, int length) - { - var copy = new T[length]; - Array.Copy(arr, offset, copy, 0, length); - return new ReadOnlySpan(copy); - } + public ReadOnlySpan Slice(int offset, int length) => new ReadOnlySpan(this.arr, offset, length); } public readonly ref struct SpanLike @@ -178,12 +185,12 @@ public static T[] ToArray(void* ptr, int count) return null; } - if (typeof(T) == typeof(int)) + if (typeof(T) == typeof(sbyte)) { - var arr = new int[count]; + var arr = new sbyte[count]; for(int i = 0; i < count; i++) { - arr[i] = ((int*)ptr)[i]; + arr[i] = ((sbyte*)ptr)[i]; } return (T[])(object)arr; @@ -200,6 +207,72 @@ public static T[] ToArray(void* ptr, int count) return (T[])(object)arr; } + if (typeof(T) == typeof(short)) + { + var arr = new short[count]; + for(int i = 0; i < count; i++) + { + arr[i] = ((short*)ptr)[i]; + } + + return (T[])(object)arr; + } + + if (typeof(T) == typeof(ushort)) + { + var arr = new ushort[count]; + for(int i = 0; i < count; i++) + { + arr[i] = ((ushort*)ptr)[i]; + } + + return (T[])(object)arr; + } + + if (typeof(T) == typeof(int)) + { + var arr = new int[count]; + for(int i = 0; i < count; i++) + { + arr[i] = ((int*)ptr)[i]; + } + + return (T[])(object)arr; + } + + if (typeof(T) == typeof(uint)) + { + var arr = new uint[count]; + for(int i = 0; i < count; i++) + { + arr[i] = ((uint*)ptr)[i]; + } + + return (T[])(object)arr; + } + + if (typeof(T) == typeof(long)) + { + var arr = new long[count]; + for(int i = 0; i < count; i++) + { + arr[i] = ((long*)ptr)[i]; + } + + return (T[])(object)arr; + } + + if (typeof(T) == typeof(ulong)) + { + var arr = new ulong[count]; + for(int i = 0; i < count; i++) + { + arr[i] = ((ulong*)ptr)[i]; + } + + return (T[])(object)arr; + } + if (typeof(T) == typeof(char)) { var arr = new char[count]; From 2e8737848930501cede2b394458e72702d72e6d0 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Tue, 9 Jul 2024 04:24:47 -0700 Subject: [PATCH 47/59] Adjust lowering of a string interpolation in an expression lambda to not use expanded non-array `params` collection in Format/Create calls. (#74274) Fixes #74163. --- .../Portable/Binder/Binder_Expressions.cs | 4 +- .../Portable/Binder/Binder_Invocation.cs | 20 +- .../OverloadResolution/OverloadResolution.cs | 31 +- .../ExpressionLambdaRewriter.cs | 4 +- .../LocalRewriter_StringInterpolation.cs | 4 +- .../Lowering/SyntheticBoundNodeFactory.cs | 29 +- .../Test/Emit3/ParamsCollectionTests.cs | 554 ++++++++++++++++++ 7 files changed, 602 insertions(+), 44 deletions(-) create mode 100644 src/Compilers/CSharp/Test/Emit3/ParamsCollectionTests.cs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 3beeb46f46c26..d7ca3622909d8 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -8248,6 +8248,7 @@ protected MethodGroupResolution BindExtensionMethod( OverloadResolution.Options.IsFunctionPointerResolution | OverloadResolution.Options.InferWithDynamic | OverloadResolution.Options.IgnoreNormalFormIfHasValidParamsParameter | + OverloadResolution.Options.DisallowExpandedNonArrayParams | OverloadResolution.Options.DynamicResolution | OverloadResolution.Options.DynamicConvertsToAnything)) == 0); @@ -10282,6 +10283,7 @@ private MethodGroupResolution ResolveDefaultMethodGroup( OverloadResolution.Options.IsFunctionPointerResolution | OverloadResolution.Options.InferWithDynamic | OverloadResolution.Options.IgnoreNormalFormIfHasValidParamsParameter | + OverloadResolution.Options.DisallowExpandedNonArrayParams | OverloadResolution.Options.DynamicResolution | OverloadResolution.Options.DynamicConvertsToAnything)) == 0); @@ -10607,7 +10609,7 @@ bool satisfiesConstraintChecks(MethodSymbol method) parameters.SelectAsArray(p => p.ExplicitDefaultConstantValue) : default; - var hasParams = OverloadResolution.IsValidParams(this, methodSymbol, out _); + var hasParams = OverloadResolution.IsValidParams(this, methodSymbol, disallowExpandedNonArrayParams: false, out _); Debug.Assert(ContainingMemberOrLambda is { }); Debug.Assert(parameterRefKinds.IsDefault || parameterRefKinds.Length == parameterTypes.Length); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index 6ede6b11be4f9..b5885aa1e4af0 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -86,7 +86,8 @@ internal BoundExpression MakeInvocationExpression( CSharpSyntaxNode? queryClause = null, bool allowFieldsAndProperties = false, bool ignoreNormalFormIfHasValidParamsParameter = false, - bool searchExtensionMethodsIfNecessary = true) + bool searchExtensionMethodsIfNecessary = true, + bool disallowExpandedNonArrayParams = false) { // // !!! ATTENTION !!! @@ -137,7 +138,8 @@ internal BoundExpression MakeInvocationExpression( BoundExpression result = BindInvocationExpression( node, node, methodName, boundExpression, analyzedArguments, diagnostics, queryClause, - ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter); + ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter, + disallowExpandedNonArrayParams: disallowExpandedNonArrayParams); // Query operator can't be called dynamically. if (queryClause != null && result.Kind == BoundKind.DynamicInvocation) @@ -323,7 +325,8 @@ private BoundExpression BindInvocationExpression( AnalyzedArguments analyzedArguments, BindingDiagnosticBag diagnostics, CSharpSyntaxNode queryClause = null, - bool ignoreNormalFormIfHasValidParamsParameter = false) + bool ignoreNormalFormIfHasValidParamsParameter = false, + bool disallowExpandedNonArrayParams = false) { // // !!! ATTENTION !!! @@ -349,7 +352,10 @@ private BoundExpression BindInvocationExpression( ReportSuppressionIfNeeded(boundExpression, diagnostics); result = BindMethodGroupInvocation( node, expression, methodName, (BoundMethodGroup)boundExpression, analyzedArguments, - diagnostics, queryClause, ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter, anyApplicableCandidates: out _); + diagnostics, queryClause, + ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter, + disallowExpandedNonArrayParams: disallowExpandedNonArrayParams, + anyApplicableCandidates: out _); } else if ((object)(delegateType = GetDelegateType(boundExpression)) != null) { @@ -689,7 +695,8 @@ private BoundExpression BindMethodGroupInvocation( BindingDiagnosticBag diagnostics, CSharpSyntaxNode queryClause, bool ignoreNormalFormIfHasValidParamsParameter, - out bool anyApplicableCandidates) + out bool anyApplicableCandidates, + bool disallowExpandedNonArrayParams = false) { // // !!! ATTENTION !!! @@ -705,6 +712,7 @@ private BoundExpression BindMethodGroupInvocation( methodGroup, expression, methodName, analyzedArguments, useSiteInfo: ref useSiteInfo, options: (ignoreNormalFormIfHasValidParamsParameter ? OverloadResolution.Options.IgnoreNormalFormIfHasValidParamsParameter : OverloadResolution.Options.None) | + (disallowExpandedNonArrayParams ? OverloadResolution.Options.DisallowExpandedNonArrayParams : OverloadResolution.Options.None) | (analyzedArguments.HasDynamicArgument ? OverloadResolution.Options.DynamicResolution : OverloadResolution.Options.None)); diagnostics.Add(expression, useSiteInfo); anyApplicableCandidates = resolution.ResultKind == LookupResultKind.Viable && resolution.OverloadResolutionResult.HasAnyApplicableMember; @@ -848,7 +856,7 @@ private void ReportDynamicInvocationWarnings(SyntaxNode syntax, BoundMethodGroup private bool IsAmbiguousDynamicParamsArgument(ArrayBuilder arguments, MemberResolutionResult candidate, out SyntaxNode argumentSyntax) where TMethodOrPropertySymbol : Symbol { - if (OverloadResolution.IsValidParams(this, candidate.LeastOverriddenMember, out _) && + if (OverloadResolution.IsValidParams(this, candidate.LeastOverriddenMember, disallowExpandedNonArrayParams: false, out _) && candidate.Result.Kind == MemberResolutionKind.ApplicableInNormalForm) { var parameters = candidate.Member.GetParameters(); diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index 5acde0dfa8f0a..b25e5c915b670 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -116,17 +116,18 @@ public void ObjectCreationOverloadResolution(ImmutableArray constr } [Flags] - public enum Options : byte + public enum Options : ushort { None = 0, - IsMethodGroupConversion = 0b_00000001, - AllowRefOmittedArguments = 0b_00000010, - InferWithDynamic = 0b_00000100, - IgnoreNormalFormIfHasValidParamsParameter = 0b_00001000, - IsFunctionPointerResolution = 0b_00010000, - IsExtensionMethodResolution = 0b_00100000, - DynamicResolution = 0b_01000000, - DynamicConvertsToAnything = 0b_10000000, + IsMethodGroupConversion = 1 << 0, + AllowRefOmittedArguments = 1 << 1, + InferWithDynamic = 1 << 2, + IgnoreNormalFormIfHasValidParamsParameter = 1 << 3, + IsFunctionPointerResolution = 1 << 4, + IsExtensionMethodResolution = 1 << 5, + DynamicResolution = 1 << 6, + DynamicConvertsToAnything = 1 << 7, + DisallowExpandedNonArrayParams = 1 << 8, } // Perform overload resolution on the given method group, with the given arguments and @@ -817,7 +818,7 @@ private void AddConstructorToCandidateSet(MethodSymbol constructor, ArrayBuilder var result = normalResult; if (!normalResult.IsValid) { - if (IsValidParams(_binder, constructor, out TypeWithAnnotations definitionElementType)) + if (IsValidParams(_binder, constructor, disallowExpandedNonArrayParams: false, out TypeWithAnnotations definitionElementType)) { var expandedResult = IsConstructorApplicableInExpandedForm(constructor, arguments, definitionElementType, completeResults, ref useSiteInfo); if (expandedResult.IsValid || completeResults) @@ -1040,8 +1041,8 @@ private void AddMemberToCandidateSet( Debug.Assert(typeArguments.Count == 0 || typeArguments.Count == member.GetMemberArity()); // Second, we need to determine if the method is applicable in its normal form or its expanded form. - - var normalResult = ((options & Options.IgnoreNormalFormIfHasValidParamsParameter) != 0 && IsValidParams(_binder, leastOverriddenMember, out _)) + bool disallowExpandedNonArrayParams = (options & Options.DisallowExpandedNonArrayParams) != 0; + var normalResult = ((options & Options.IgnoreNormalFormIfHasValidParamsParameter) != 0 && IsValidParams(_binder, leastOverriddenMember, disallowExpandedNonArrayParams, out _)) ? default(MemberResolutionResult) : IsMemberApplicableInNormalForm( member, @@ -1060,7 +1061,7 @@ private void AddMemberToCandidateSet( // tricks you can pull to make overriding methods [indexers] inconsistent with overridden // methods [indexers] (or implementing methods [indexers] inconsistent with interfaces). - if ((options & Options.IsMethodGroupConversion) == 0 && IsValidParams(_binder, leastOverriddenMember, out TypeWithAnnotations definitionElementType)) + if ((options & Options.IsMethodGroupConversion) == 0 && IsValidParams(_binder, leastOverriddenMember, disallowExpandedNonArrayParams, out TypeWithAnnotations definitionElementType)) { var expandedResult = IsMemberApplicableInExpandedForm( member, @@ -1160,7 +1161,7 @@ static bool haveBadArgumentForLastParameter(MemberResolutionResult resu // We need to know if this is a valid formal parameter list with a parameter array // as the final formal parameter. We might be in an error recovery scenario // where the params array is not an array type. - public static bool IsValidParams(Binder binder, Symbol member, out TypeWithAnnotations definitionElementType) + public static bool IsValidParams(Binder binder, Symbol member, bool disallowExpandedNonArrayParams, out TypeWithAnnotations definitionElementType) { // A varargs method is never a valid params method. if (member.GetIsVararg()) @@ -1178,7 +1179,7 @@ public static bool IsValidParams(Binder binder, Symbol member, out TypeWithAnnot ParameterSymbol final = member.GetParameters().Last(); if ((final.IsParamsArray && final.Type.IsSZArray()) || - (final.IsParamsCollection && !final.Type.IsSZArray() && + (final.IsParamsCollection && !final.Type.IsSZArray() && !disallowExpandedNonArrayParams && (binder.Compilation.LanguageVersion > LanguageVersion.CSharp12 || member.ContainingModule == binder.Compilation.SourceModule))) { return TryInferParamsCollectionIterationType(binder, final.OriginalDefinition.Type, out definitionElementType); diff --git a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ExpressionLambdaRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ExpressionLambdaRewriter.cs index 37849dc7d66ff..561404bb2771f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ExpressionLambdaRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ExpressionLambdaRewriter.cs @@ -1094,12 +1094,12 @@ private BoundExpression VisitUnaryOperator(BoundUnaryOperator node) private BoundExpression ExprFactory(string name, params BoundExpression[] arguments) { - return _bound.StaticCall(ExpressionType, name, arguments); + return _bound.StaticCall(ExpressionType, name, disallowExpandedNonArrayParams: true, arguments); } private BoundExpression ExprFactory(string name, ImmutableArray typeArgs, params BoundExpression[] arguments) { - return _bound.StaticCall(_ignoreAccessibility ? BinderFlags.IgnoreAccessibility : BinderFlags.None, ExpressionType, name, typeArgs, arguments); + return _bound.StaticCall(_ignoreAccessibility ? BinderFlags.IgnoreAccessibility : BinderFlags.None, ExpressionType, name, disallowExpandedNonArrayParams: true, typeArgs, arguments); } private BoundExpression Constant(BoundExpression node) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringInterpolation.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringInterpolation.cs index a148a9ee88dd6..ce47533644585 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringInterpolation.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringInterpolation.cs @@ -26,7 +26,7 @@ private BoundExpression RewriteInterpolatedStringConversion(BoundConversion conv // the arguments first in this situation because we do not know what conversions will be // produced for the arguments until after we've done overload resolution. So we produce the invocation // and then lower it along with its arguments. - var result = _factory.StaticCall(stringFactory, "Create", expressions.ToImmutableAndFree(), + var result = _factory.StaticCall(stringFactory, "Create", disallowExpandedNonArrayParams: _inExpressionLambda, expressions.ToImmutableAndFree(), ignoreNormalFormIfHasValidParamsParameter: true // if an interpolation expression is the null literal, it should not match a params parameter. ); if (!result.HasAnyErrors) @@ -351,7 +351,7 @@ public override BoundNode VisitInterpolatedString(BoundInterpolatedString node) // and then lower it along with its arguments. expressions.Insert(0, format); var stringType = node.Type; - result = _factory.StaticCall(stringType, "Format", expressions.ToImmutableAndFree(), + result = _factory.StaticCall(stringType, "Format", disallowExpandedNonArrayParams: _inExpressionLambda, expressions.ToImmutableAndFree(), ignoreNormalFormIfHasValidParamsParameter: true // if an interpolation expression is the null literal, it should not match a params parameter. ); } diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs index cb28b923999b7..c0a2ac0cbd438 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs @@ -96,11 +96,12 @@ private set /// private Binder? _binder; - internal BoundExpression MakeInvocationExpression( + private BoundExpression MakeInvocationExpression( BinderFlags flags, SyntaxNode node, BoundExpression receiver, string methodName, + bool disallowExpandedNonArrayParams, ImmutableArray args, BindingDiagnosticBag diagnostics, ImmutableArray typeArgs = default(ImmutableArray), @@ -119,7 +120,8 @@ internal BoundExpression MakeInvocationExpression( diagnostics, typeArgs: typeArgs.IsDefault ? default(ImmutableArray) : typeArgs.SelectAsArray(t => TypeWithAnnotations.Create(t)), allowFieldsAndProperties: false, - ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter); + ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter, + disallowExpandedNonArrayParams: disallowExpandedNonArrayParams); } /// @@ -831,29 +833,20 @@ public BoundExpression MakeIsNotANumberTest(BoundExpression input) } } - public BoundExpression InstanceCall(BoundExpression receiver, string name, BoundExpression arg) + public BoundExpression StaticCall(TypeSymbol receiver, string name, bool disallowExpandedNonArrayParams, params BoundExpression[] args) { - return MakeInvocationExpression(BinderFlags.None, this.Syntax, receiver, name, ImmutableArray.Create(arg), this.Diagnostics); + return MakeInvocationExpression(BinderFlags.None, this.Syntax, this.Type(receiver), name, disallowExpandedNonArrayParams, args.ToImmutableArray(), this.Diagnostics); } - public BoundExpression InstanceCall(BoundExpression receiver, string name) + public BoundExpression StaticCall(TypeSymbol receiver, string name, bool disallowExpandedNonArrayParams, ImmutableArray args, bool ignoreNormalFormIfHasValidParamsParameter) { - return MakeInvocationExpression(BinderFlags.None, this.Syntax, receiver, name, ImmutableArray.Empty, this.Diagnostics); + return MakeInvocationExpression( + BinderFlags.None, this.Syntax, this.Type(receiver), name, disallowExpandedNonArrayParams, args, this.Diagnostics, ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter); } - public BoundExpression StaticCall(TypeSymbol receiver, string name, params BoundExpression[] args) + public BoundExpression StaticCall(BinderFlags flags, TypeSymbol receiver, string name, bool disallowExpandedNonArrayParams, ImmutableArray typeArgs, params BoundExpression[] args) { - return MakeInvocationExpression(BinderFlags.None, this.Syntax, this.Type(receiver), name, args.ToImmutableArray(), this.Diagnostics); - } - - public BoundExpression StaticCall(TypeSymbol receiver, string name, ImmutableArray args, bool ignoreNormalFormIfHasValidParamsParameter) - { - return MakeInvocationExpression(BinderFlags.None, this.Syntax, this.Type(receiver), name, args, this.Diagnostics, ignoreNormalFormIfHasValidParamsParameter: ignoreNormalFormIfHasValidParamsParameter); - } - - public BoundExpression StaticCall(BinderFlags flags, TypeSymbol receiver, string name, ImmutableArray typeArgs, params BoundExpression[] args) - { - return MakeInvocationExpression(flags, this.Syntax, this.Type(receiver), name, args.ToImmutableArray(), this.Diagnostics, typeArgs); + return MakeInvocationExpression(flags, this.Syntax, this.Type(receiver), name, disallowExpandedNonArrayParams, args.ToImmutableArray(), this.Diagnostics, typeArgs); } public BoundExpression StaticCall(TypeSymbol receiver, MethodSymbol method, params BoundExpression[] args) diff --git a/src/Compilers/CSharp/Test/Emit3/ParamsCollectionTests.cs b/src/Compilers/CSharp/Test/Emit3/ParamsCollectionTests.cs new file mode 100644 index 0000000000000..7d2ce4528690c --- /dev/null +++ b/src/Compilers/CSharp/Test/Emit3/ParamsCollectionTests.cs @@ -0,0 +1,554 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#nullable disable + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics +{ + public class ParamsCollectionTests : CompilingTestBase + { + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73743")] + public void ParamsSpanInExpression_01() + { + string source = """ +class Program +{ + public static void Test() + { + System.Linq.Expressions.Expression> e = (s) => M(s, s, s); + } + + static void M(params string[] p) {} + static void M(params System.Span p) {} +} +"""; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); + + comp.VerifyEmitDiagnostics( + // (5,78): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'. + // System.Linq.Expressions.Expression> e = (s) => M(s, s, s); + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "M(s, s, s)").WithArguments("Span").WithLocation(5, 78), + // (5,78): error CS9226: An expression tree may not contain an expanded form of non-array params collection parameter. + // System.Linq.Expressions.Expression> e = (s) => M(s, s, s); + Diagnostic(ErrorCode.ERR_ParamsCollectionExpressionTree, "M(s, s, s)").WithLocation(5, 78) + ); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73743")] + public void ParamsSpanInExpression_02() + { + string source = """ +class Program +{ + public static void Test() + { + System.Linq.Expressions.Expression> e = (s) => M(s, s, s); + } + + static void M(params System.Span p) {} +} +"""; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); + + comp.VerifyEmitDiagnostics( + // (5,78): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Span'. + // System.Linq.Expressions.Expression> e = (s) => M(s, s, s); + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "M(s, s, s)").WithArguments("Span").WithLocation(5, 78), + // (5,78): error CS9226: An expression tree may not contain an expanded form of non-array params collection parameter. + // System.Linq.Expressions.Expression> e = (s) => M(s, s, s); + Diagnostic(ErrorCode.ERR_ParamsCollectionExpressionTree, "M(s, s, s)").WithLocation(5, 78) + ); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/74163")] + public void StringInterpolation_01() + { + string source1 = """ +class Program +{ + public static void Test1() + { + System.Linq.Expressions.Expression> e = (s) => $"{s} {2} {s} {4}"; + } + + public static void Test2() + { + System.Linq.Expressions.Expression> e = (s) => $"{s} {2} {s} {4}"; + } +} +"""; + string core = """ +namespace System +{ + public class Object {} + + public class ValueType {} + public abstract partial class Enum {} + + public struct Void {} + public struct Boolean {} + public struct Byte {} + public struct Int16 {} + public struct Int32 {} + public struct Int64 {} + public struct IntPtr {} + + public partial class Exception {} + + public class String + { + public static string Format(string format, params object[] args) => null; + public static string Format(string format, params ReadOnlySpan args) => null; + } + + public abstract class FormattableString {} + + public abstract partial class Attribute {} + public sealed class ParamArrayAttribute : Attribute {} + + public enum AttributeTargets + { + Assembly = 1, + Module = 2, + Class = 4, + Struct = 8, + Enum = 16, + Constructor = 32, + Method = 64, + Property = 128, + Field = 256, + Event = 512, + Interface = 1024, + Parameter = 2048, + Delegate = 4096, + ReturnValue = 8192, + GenericParameter = 16384, + All = 32767 + } + + public sealed class AttributeUsageAttribute : Attribute + { + public AttributeUsageAttribute(AttributeTargets validOn) + { + } + + internal AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited) + { + } + + public AttributeTargets ValidOn {get; set;} + + public bool AllowMultiple {get; set;} + + public bool Inherited {get; set;} + } + + public abstract partial class Delegate {} + public abstract partial class MulticastDelegate : Delegate {} + + public delegate TResult Func(T arg); + + public interface IDisposable + { + void Dispose(); + } + + public partial struct Nullable where T : struct {} + + public unsafe partial struct RuntimeTypeHandle {} + public unsafe partial struct RuntimeMethodHandle {} + public abstract partial class Type + { + public static Type GetTypeFromHandle(RuntimeTypeHandle handle) => null; + } + + public ref struct ReadOnlySpan + { + public ReadOnlySpan(T[] array) + { + } + + public ReadOnlySpan(T[] array, int start, int length) + { + } + + public unsafe ReadOnlySpan(void* pointer, int length) + { + } + } +} + +namespace System.Collections +{ + public interface IEnumerator + { + object Current { get; } + bool MoveNext(); + void Reset(); + } + + public interface IEnumerable + { + IEnumerator GetEnumerator(); + } +} + +namespace System.Collections.Generic +{ + public interface IEnumerator : IEnumerator, IDisposable + { + new T Current { get; } + } + + public interface IEnumerable : IEnumerable + { + new IEnumerator GetEnumerator(); + } +} + +namespace System.Reflection +{ + public abstract unsafe partial class MethodBase + { + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle) => null; + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) => null; + } + + public abstract partial class MethodInfo : MethodBase {} + + public abstract partial class ConstructorInfo : MethodBase {} +} + +namespace System.Linq.Expressions +{ + using System.Collections.Generic; + using System.Reflection; + + public partial class Expression + { + public static ParameterExpression Parameter(Type type) => null; + public static ParameterExpression Parameter(Type type, string name) => null; + public static ConstantExpression Constant(object value) => null; + public static ConstantExpression Constant(object value, Type type) => null; + + public static Expression Lambda(Expression body, params ParameterExpression[] parameters) => null; + public static NewArrayExpression NewArrayInit(Type type, params Expression[] initializers) => null; + public static NewExpression New(ConstructorInfo constructor, IEnumerable arguments) => null; + public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments) => null; + public static UnaryExpression Convert(Expression expression, Type type) => null; + } + + public abstract class LambdaExpression : Expression {} + + public class Expression : LambdaExpression {} + + public class ParameterExpression : Expression {} + public class ConstantExpression : Expression {} + public class NewArrayExpression : Expression {} + public class NewExpression : Expression {} + public class MethodCallExpression : Expression {} + public class UnaryExpression : Expression {} +} + +namespace System.Runtime.CompilerServices +{ + public sealed class InlineArrayAttribute : Attribute + { + public InlineArrayAttribute(int length) + { + } + } + + public sealed class IsReadOnlyAttribute : Attribute + {} + + public static class FormattableStringFactory + { + public static FormattableString Create(string format, params object[] arguments) => null; + public static FormattableString Create(string format, params ReadOnlySpan arguments) => null; + } + + public static unsafe partial class Unsafe + { + public static ref TTo As(ref TFrom source) => throw null; + public static ref T AsRef(scoped ref readonly T source) => throw null; + public static ref T Add(ref T source, int elementOffset) => throw null; + } +} + +namespace System.Runtime.InteropServices +{ + public static partial class MemoryMarshal + { + public static ReadOnlySpan CreateReadOnlySpan(ref readonly T reference, int length) => default; + } +} +"""; + + var comp = CreateEmptyCompilation([source1, core], options: TestOptions.ReleaseDll.WithAllowUnsafe(true)); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics( + // warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options. + Diagnostic(ErrorCode.WRN_NoRuntimeMetadataVersion).WithLocation(1, 1) + ); + + verifier.VerifyIL("Program.Test1", +@" +{ + // Code size 198 (0xc6) + .maxstack 11 + .locals init (System.Linq.Expressions.ParameterExpression V_0) + IL_0000: ldtoken ""string"" + IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_000a: ldstr ""s"" + IL_000f: call ""System.Linq.Expressions.ParameterExpression System.Linq.Expressions.Expression.Parameter(System.Type, string)"" + IL_0014: stloc.0 + IL_0015: ldnull + IL_0016: ldtoken ""string string.Format(string, params object[])"" + IL_001b: call ""System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"" + IL_0020: castclass ""System.Reflection.MethodInfo"" + IL_0025: ldc.i4.2 + IL_0026: newarr ""System.Linq.Expressions.Expression"" + IL_002b: dup + IL_002c: ldc.i4.0 + IL_002d: ldstr ""{0} {1} {2} {3}"" + IL_0032: ldtoken ""string"" + IL_0037: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_003c: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" + IL_0041: stelem.ref + IL_0042: dup + IL_0043: ldc.i4.1 + IL_0044: ldtoken ""object"" + IL_0049: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_004e: ldc.i4.4 + IL_004f: newarr ""System.Linq.Expressions.Expression"" + IL_0054: dup + IL_0055: ldc.i4.0 + IL_0056: ldloc.0 + IL_0057: stelem.ref + IL_0058: dup + IL_0059: ldc.i4.1 + IL_005a: ldc.i4.2 + IL_005b: box ""int"" + IL_0060: ldtoken ""int"" + IL_0065: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_006a: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" + IL_006f: ldtoken ""object"" + IL_0074: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_0079: call ""System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type)"" + IL_007e: stelem.ref + IL_007f: dup + IL_0080: ldc.i4.2 + IL_0081: ldloc.0 + IL_0082: stelem.ref + IL_0083: dup + IL_0084: ldc.i4.3 + IL_0085: ldc.i4.4 + IL_0086: box ""int"" + IL_008b: ldtoken ""int"" + IL_0090: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_0095: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" + IL_009a: ldtoken ""object"" + IL_009f: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_00a4: call ""System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type)"" + IL_00a9: stelem.ref + IL_00aa: call ""System.Linq.Expressions.NewArrayExpression System.Linq.Expressions.Expression.NewArrayInit(System.Type, params System.Linq.Expressions.Expression[])"" + IL_00af: stelem.ref + IL_00b0: call ""System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"" + IL_00b5: ldc.i4.1 + IL_00b6: newarr ""System.Linq.Expressions.ParameterExpression"" + IL_00bb: dup + IL_00bc: ldc.i4.0 + IL_00bd: ldloc.0 + IL_00be: stelem.ref + IL_00bf: call ""System.Linq.Expressions.Expression> System.Linq.Expressions.Expression.Lambda>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"" + IL_00c4: pop + IL_00c5: ret +} +"); + + verifier.VerifyIL("Program.Test2", +@" +{ + // Code size 198 (0xc6) + .maxstack 11 + .locals init (System.Linq.Expressions.ParameterExpression V_0) + IL_0000: ldtoken ""string"" + IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_000a: ldstr ""s"" + IL_000f: call ""System.Linq.Expressions.ParameterExpression System.Linq.Expressions.Expression.Parameter(System.Type, string)"" + IL_0014: stloc.0 + IL_0015: ldnull + IL_0016: ldtoken ""System.FormattableString System.Runtime.CompilerServices.FormattableStringFactory.Create(string, params object[])"" + IL_001b: call ""System.Reflection.MethodBase System.Reflection.MethodBase.GetMethodFromHandle(System.RuntimeMethodHandle)"" + IL_0020: castclass ""System.Reflection.MethodInfo"" + IL_0025: ldc.i4.2 + IL_0026: newarr ""System.Linq.Expressions.Expression"" + IL_002b: dup + IL_002c: ldc.i4.0 + IL_002d: ldstr ""{0} {1} {2} {3}"" + IL_0032: ldtoken ""string"" + IL_0037: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_003c: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" + IL_0041: stelem.ref + IL_0042: dup + IL_0043: ldc.i4.1 + IL_0044: ldtoken ""object"" + IL_0049: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_004e: ldc.i4.4 + IL_004f: newarr ""System.Linq.Expressions.Expression"" + IL_0054: dup + IL_0055: ldc.i4.0 + IL_0056: ldloc.0 + IL_0057: stelem.ref + IL_0058: dup + IL_0059: ldc.i4.1 + IL_005a: ldc.i4.2 + IL_005b: box ""int"" + IL_0060: ldtoken ""int"" + IL_0065: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_006a: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" + IL_006f: ldtoken ""object"" + IL_0074: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_0079: call ""System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type)"" + IL_007e: stelem.ref + IL_007f: dup + IL_0080: ldc.i4.2 + IL_0081: ldloc.0 + IL_0082: stelem.ref + IL_0083: dup + IL_0084: ldc.i4.3 + IL_0085: ldc.i4.4 + IL_0086: box ""int"" + IL_008b: ldtoken ""int"" + IL_0090: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_0095: call ""System.Linq.Expressions.ConstantExpression System.Linq.Expressions.Expression.Constant(object, System.Type)"" + IL_009a: ldtoken ""object"" + IL_009f: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_00a4: call ""System.Linq.Expressions.UnaryExpression System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type)"" + IL_00a9: stelem.ref + IL_00aa: call ""System.Linq.Expressions.NewArrayExpression System.Linq.Expressions.Expression.NewArrayInit(System.Type, params System.Linq.Expressions.Expression[])"" + IL_00af: stelem.ref + IL_00b0: call ""System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression, System.Reflection.MethodInfo, params System.Linq.Expressions.Expression[])"" + IL_00b5: ldc.i4.1 + IL_00b6: newarr ""System.Linq.Expressions.ParameterExpression"" + IL_00bb: dup + IL_00bc: ldc.i4.0 + IL_00bd: ldloc.0 + IL_00be: stelem.ref + IL_00bf: call ""System.Linq.Expressions.Expression> System.Linq.Expressions.Expression.Lambda>(System.Linq.Expressions.Expression, params System.Linq.Expressions.ParameterExpression[])"" + IL_00c4: pop + IL_00c5: ret + +} +"); + + string source2 = """ +class Program +{ + public static string Test1(string s) => $"{s} {2} {s} {4}"; + + public static System.FormattableString Test2(string s) => $"{s} {2} {s} {4}"; +} +"""; + comp = CreateEmptyCompilation([source2, core], options: TestOptions.ReleaseDll.WithAllowUnsafe(true)); + verifier = CompileAndVerify(comp, verify: Verification.Skipped).VerifyDiagnostics( + // warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options. + Diagnostic(ErrorCode.WRN_NoRuntimeMetadataVersion).WithLocation(1, 1) + ); + + verifier.VerifyIL("Program.Test1", +@" +{ + // Code size 77 (0x4d) + .maxstack 3 + .locals init (<>y__InlineArray4 V_0) + IL_0000: ldstr ""{0} {1} {2} {3}"" + IL_0005: ldloca.s V_0 + IL_0007: initobj ""<>y__InlineArray4"" + IL_000d: ldloca.s V_0 + IL_000f: ldc.i4.0 + IL_0010: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_0015: ldarg.0 + IL_0016: stind.ref + IL_0017: ldloca.s V_0 + IL_0019: ldc.i4.1 + IL_001a: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_001f: ldc.i4.2 + IL_0020: box ""int"" + IL_0025: stind.ref + IL_0026: ldloca.s V_0 + IL_0028: ldc.i4.2 + IL_0029: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_002e: ldarg.0 + IL_002f: stind.ref + IL_0030: ldloca.s V_0 + IL_0032: ldc.i4.3 + IL_0033: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_0038: ldc.i4.4 + IL_0039: box ""int"" + IL_003e: stind.ref + IL_003f: ldloca.s V_0 + IL_0041: ldc.i4.4 + IL_0042: call ""System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray4, object>(in <>y__InlineArray4, int)"" + IL_0047: call ""string string.Format(string, params System.ReadOnlySpan)"" + IL_004c: ret +} +"); + + verifier.VerifyIL("Program.Test2", +@" +{ + // Code size 77 (0x4d) + .maxstack 3 + .locals init (<>y__InlineArray4 V_0) + IL_0000: ldstr ""{0} {1} {2} {3}"" + IL_0005: ldloca.s V_0 + IL_0007: initobj ""<>y__InlineArray4"" + IL_000d: ldloca.s V_0 + IL_000f: ldc.i4.0 + IL_0010: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_0015: ldarg.0 + IL_0016: stind.ref + IL_0017: ldloca.s V_0 + IL_0019: ldc.i4.1 + IL_001a: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_001f: ldc.i4.2 + IL_0020: box ""int"" + IL_0025: stind.ref + IL_0026: ldloca.s V_0 + IL_0028: ldc.i4.2 + IL_0029: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_002e: ldarg.0 + IL_002f: stind.ref + IL_0030: ldloca.s V_0 + IL_0032: ldc.i4.3 + IL_0033: call ""ref object .InlineArrayElementRef<<>y__InlineArray4, object>(ref <>y__InlineArray4, int)"" + IL_0038: ldc.i4.4 + IL_0039: box ""int"" + IL_003e: stind.ref + IL_003f: ldloca.s V_0 + IL_0041: ldc.i4.4 + IL_0042: call ""System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray4, object>(in <>y__InlineArray4, int)"" + IL_0047: call ""System.FormattableString System.Runtime.CompilerServices.FormattableStringFactory.Create(string, params System.ReadOnlySpan)"" + IL_004c: ret +} +"); + } + } +} From b3a18bb0274a94c3d7ceae057cb9bb7c83f3a326 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 9 Jul 2024 15:52:06 +0200 Subject: [PATCH 48/59] Avoid using constants for large string literals (#74305) --- src/Compilers/Test/Utilities/CSharp/TestSources.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Compilers/Test/Utilities/CSharp/TestSources.cs b/src/Compilers/Test/Utilities/CSharp/TestSources.cs index 62efa9495c6ae..efa80e45830aa 100644 --- a/src/Compilers/Test/Utilities/CSharp/TestSources.cs +++ b/src/Compilers/Test/Utilities/CSharp/TestSources.cs @@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities { internal static class TestSources { - internal const string Span = @" + internal static readonly string Span = @" namespace System { public readonly ref struct Span @@ -300,7 +300,7 @@ public static T[] ToArray(void* ptr, int count) } }"; - internal const string Index = @" + internal static readonly string Index = @" namespace System { @@ -396,7 +396,7 @@ public int GetOffset(int length) } }"; - internal const string Range = @" + internal static readonly string Range = @" namespace System { using System.Runtime.CompilerServices; @@ -466,7 +466,7 @@ public void Deconstruct(out int offset, out int length) } }"; - public const string GetSubArray = @" + public static readonly string GetSubArray = @" namespace System.Runtime.CompilerServices { public static class RuntimeHelpers @@ -483,7 +483,7 @@ public static T[] GetSubArray(T[] array, Range range) } }"; - public const string ITuple = @" + public static readonly string ITuple = @" namespace System.Runtime.CompilerServices { public interface ITuple @@ -493,7 +493,7 @@ public interface ITuple } }"; - public const string MemoryExtensions = @" + public static readonly string MemoryExtensions = @" namespace System { public static class MemoryExtensions From 5c2d76c890d6974aa8c3b955965dc49b1c73bb43 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Tue, 9 Jul 2024 19:18:48 +0200 Subject: [PATCH 49/59] Disable BuildWithNetFrameworkHostedCompiler (#74299) --- eng/targets/Settings.props | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props index 3598b4bdc7671..4e8a4b0c1b6b2 100644 --- a/eng/targets/Settings.props +++ b/eng/targets/Settings.props @@ -60,6 +60,12 @@ <_SkipUpgradeNetAnalyzersNuGetWarning>true + + + false From fdaf58df81d92f4de5b1cd5c56fe05657af4bab2 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Mon, 8 Jul 2024 22:34:36 -0700 Subject: [PATCH 50/59] Move determination of language for an LSP request into the serialized queue to avoid race --- .../Mocks/TestMethodHandlers.cs | 76 ++--- .../RequestExecutionQueueTests.cs | 27 +- .../AbstractHandlerProvider.cs | 4 +- .../AbstractLanguageServer.cs | 73 +---- .../AbstractRequestScope.cs | 10 + .../HandlerProvider.cs | 4 +- .../IQueueItem.cs | 32 +-- .../IRequestExecutionQueue.cs | 3 +- .../NewtonsoftLanguageServer.cs | 72 ++--- .../QueueItem.cs | 78 ++++-- .../RequestExecutionQueue.cs | 264 ++++++++++++------ .../SystemTextJsonLanguageServer.cs | 71 ++--- .../Handler/RequestTelemetryLogger.cs | 10 +- .../ExecuteWorkspaceCommandHandler.cs | 11 +- .../LspServices/RequestTelemetryScope.cs | 2 +- .../Protocol/RoslynLanguageServer.cs | 15 +- .../Protocol/RoslynRequestExecutionQueue.cs | 8 +- .../ProtocolUnitTests/HandlerTests.cs | 36 ++- .../LspMiscellaneousFilesWorkspaceTests.cs | 64 ++++- .../XamlRequestExecutionQueue.cs | 1 - 20 files changed, 495 insertions(+), 366 deletions(-) diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/Mocks/TestMethodHandlers.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/Mocks/TestMethodHandlers.cs index c9716bc9a7935..b1fd010ce20c9 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/Mocks/TestMethodHandlers.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/Mocks/TestMethodHandlers.cs @@ -9,47 +9,50 @@ namespace Microsoft.CommonLanguageServerProtocol.Framework.UnitTests; +internal record class MockRequest(int Param); +internal record class MockResponse(string Response); + [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class TestMethodHandler : IRequestHandler +internal class TestMethodHandler : IRequestHandler { public const string Name = "Method"; public static readonly IMethodHandler Instance = new TestMethodHandler(); public bool MutatesSolutionState => true; - public static TypeRef RequestType = TypeRef.Of(); - public static TypeRef ResponseType = TypeRef.Of(); + public static TypeRef RequestType = TypeRef.Of(); + public static TypeRef ResponseType = TypeRef.Of(); public static RequestHandlerMetadata Metadata = new(Name, RequestType, ResponseType, LanguageServerConstants.DefaultLanguageName); - public Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) - => Task.FromResult("stuff"); + public Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) + => Task.FromResult(new("stuff")); } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class TestParameterlessMethodHandler : IRequestHandler +internal class TestParameterlessMethodHandler : IRequestHandler { public const string Name = "ParameterlessMethod"; public static readonly IMethodHandler Instance = new TestParameterlessMethodHandler(); public bool MutatesSolutionState => true; - public static TypeRef ResponseTypeRef = TypeRef.Of(); + public static TypeRef ResponseTypeRef = TypeRef.Of(); public static RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: null, ResponseTypeRef, LanguageServerConstants.DefaultLanguageName); - public Task HandleRequestAsync(TestRequestContext context, CancellationToken cancellationToken) - => Task.FromResult(true); + public Task HandleRequestAsync(TestRequestContext context, CancellationToken cancellationToken) + => Task.FromResult(new MockResponse("true")); } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class TestNotificationHandler : INotificationHandler +internal class TestNotificationHandler : INotificationHandler { public const string Name = "Notification"; public static readonly IMethodHandler Instance = new TestNotificationHandler(); public bool MutatesSolutionState => true; - public static TypeRef RequestTypeRef = TypeRef.Of(); + public static TypeRef RequestTypeRef = TypeRef.Of(); public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef, ResponseTypeRef: null, LanguageServerConstants.DefaultLanguageName); - public Task HandleNotificationAsync(bool request, TestRequestContext context, CancellationToken cancellationToken) + public Task HandleNotificationAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) => Task.FromResult(true); } @@ -77,11 +80,12 @@ public Task HandleNotificationAsync(TestRequestContext requestContext, Cancellat } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class MutatingHandler : IRequestHandler +internal class MutatingHandler : IRequestHandler { public const string Name = "MutatingMethod"; public static readonly IMethodHandler Instance = new MutatingHandler(); - public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); + + public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); public MutatingHandler() { @@ -89,28 +93,28 @@ public MutatingHandler() public bool MutatesSolutionState => true; - public Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) + public Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) { - return Task.FromResult(string.Empty); + return Task.FromResult(new MockResponse(string.Empty)); } } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class CompletingHandler : IRequestHandler +internal class CompletingHandler : IRequestHandler { public const string Name = "CompletingMethod"; public static readonly IMethodHandler Instance = new CompletingHandler(); - public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); + public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); public bool MutatesSolutionState => false; - public async Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) + public async Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) { while (true) { if (cancellationToken.IsCancellationRequested) { - return "I completed!"; + return new("I completed!"); } await Task.Delay(100, cancellationToken).NoThrowAwaitable(); } @@ -118,15 +122,15 @@ public async Task HandleRequestAsync(int request, TestRequestContext con } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class CancellingHandler : IRequestHandler +internal class CancellingHandler : IRequestHandler { public const string Name = "CancellingMethod"; public static readonly IMethodHandler Instance = new CancellingHandler(); - public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); + public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); public bool MutatesSolutionState => false; - public async Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) + public async Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) { while (true) { @@ -137,48 +141,48 @@ public async Task HandleRequestAsync(int request, TestRequestContext con } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class ThrowingHandler : IRequestHandler +internal class ThrowingHandler : IRequestHandler { public const string Name = "ThrowingMethod"; public static readonly IMethodHandler Instance = new ThrowingHandler(); - public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); + public static readonly RequestHandlerMetadata Metadata = new(Name, RequestTypeRef: TypeRef.Of(), ResponseTypeRef: TypeRef.Of(), LanguageServerConstants.DefaultLanguageName); public bool MutatesSolutionState => false; - public Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) + public Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) { throw new NotImplementedException(); } } [LanguageServerEndpoint(Name, LanguageServerConstants.DefaultLanguageName)] -internal class TestDefaultLanguageHandler : IRequestHandler +internal class TestDefaultLanguageHandler : IRequestHandler { public const string Name = "Language"; public static readonly IMethodHandler Instance = new TestDefaultLanguageHandler(); public bool MutatesSolutionState => true; - public static TypeRef RequestType = TypeRef.Of(); - public static TypeRef ResponseType = TypeRef.Of(); + public static TypeRef RequestType = TypeRef.Of(); + public static TypeRef ResponseType = TypeRef.Of(); public static RequestHandlerMetadata Metadata = new(Name, RequestType, ResponseType, LanguageServerConstants.DefaultLanguageName); - public Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) - => Task.FromResult(string.Empty); + public Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) + => Task.FromResult(new MockResponse(string.Empty)); } [LanguageServerEndpoint(Name, Language)] -internal class TestXamlLanguageHandler : IRequestHandler +internal class TestXamlLanguageHandler : IRequestHandler { public const string Name = TestDefaultLanguageHandler.Name; public const string Language = "xaml"; public static readonly IMethodHandler Instance = new TestXamlLanguageHandler(); public bool MutatesSolutionState => true; - public static TypeRef RequestType = TypeRef.Of(); - public static TypeRef ResponseType = TypeRef.Of(); + public static TypeRef RequestType = TypeRef.Of(); + public static TypeRef ResponseType = TypeRef.Of(); public static RequestHandlerMetadata Metadata = new(Name, RequestType, ResponseType, Language); - public Task HandleRequestAsync(int request, TestRequestContext context, CancellationToken cancellationToken) - => Task.FromResult("xaml"); + public Task HandleRequestAsync(MockRequest request, TestRequestContext context, CancellationToken cancellationToken) + => Task.FromResult(new MockResponse("xaml")); } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/RequestExecutionQueueTests.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/RequestExecutionQueueTests.cs index 77e7b6cfe6b13..7547505b2f97a 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/RequestExecutionQueueTests.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework.UnitTests/RequestExecutionQueueTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Nerdbank.Streams; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using StreamJsonRpc; using Xunit; @@ -51,7 +52,7 @@ public async Task ExecuteAsync_ThrowCompletes() var lspServices = GetLspServices(); // Act & Assert - await Assert.ThrowsAsync(() => requestExecutionQueue.ExecuteAsync(1, ThrowingHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None)); + await Assert.ThrowsAsync(() => requestExecutionQueue.ExecuteAsync(JToken.FromObject(new MockRequest(1)), ThrowingHandler.Name, lspServices, CancellationToken.None)); } [Fact] @@ -72,12 +73,12 @@ public async Task ExecuteAsync_WithCancelInProgressWork_CancelsInProgressWorkWhe var cancellingRequestCancellationToken = new CancellationToken(); var completingRequestCancellationToken = new CancellationToken(); - var _ = requestExecutionQueue.ExecuteAsync(1, CancellingHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, cancellingRequestCancellationToken); - var _1 = requestExecutionQueue.ExecuteAsync(1, CompletingHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, completingRequestCancellationToken); + var _ = requestExecutionQueue.ExecuteAsync(JToken.FromObject(new MockRequest(1)), CancellingHandler.Name, lspServices, cancellingRequestCancellationToken); + var _1 = requestExecutionQueue.ExecuteAsync(JToken.FromObject(new MockRequest(1)), CompletingHandler.Name, lspServices, completingRequestCancellationToken); // Act & Assert // A Debug.Assert would throw if the tasks hadn't completed when the mutating request is called. - await requestExecutionQueue.ExecuteAsync(1, MutatingHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); + await requestExecutionQueue.ExecuteAsync(JToken.FromObject(new MockRequest(1)), MutatingHandler.Name, lspServices, CancellationToken.None); } } @@ -100,8 +101,8 @@ public async Task ExecuteAsync_CompletesTask() var requestExecutionQueue = GetRequestExecutionQueue(false, (TestMethodHandler.Metadata, TestMethodHandler.Instance)); var lspServices = GetLspServices(); - var response = await requestExecutionQueue.ExecuteAsync(request: 1, TestMethodHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); - Assert.Equal("stuff", response); + var response = (MockResponse?)await requestExecutionQueue.ExecuteAsync(JToken.FromObject(new MockRequest(1)), TestMethodHandler.Name, lspServices, CancellationToken.None); + Assert.Equal("stuff", response?.Response); } [Fact] @@ -110,8 +111,8 @@ public async Task ExecuteAsync_CompletesTask_Parameterless() var requestExecutionQueue = GetRequestExecutionQueue(false, (TestParameterlessMethodHandler.Metadata, TestParameterlessMethodHandler.Instance)); var lspServices = GetLspServices(); - var response = await requestExecutionQueue.ExecuteAsync(request: NoValue.Instance, TestParameterlessMethodHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); - Assert.True(response); + var response = (MockResponse?)await requestExecutionQueue.ExecuteAsync(serializedRequest: null, TestParameterlessMethodHandler.Name, lspServices, CancellationToken.None); + Assert.Equal("true", response?.Response); } [Fact] @@ -120,7 +121,7 @@ public async Task ExecuteAsync_CompletesTask_Notification() var requestExecutionQueue = GetRequestExecutionQueue(false, (TestNotificationHandler.Metadata, TestNotificationHandler.Instance)); var lspServices = GetLspServices(); - var response = await requestExecutionQueue.ExecuteAsync(request: true, TestNotificationHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); + var response = await requestExecutionQueue.ExecuteAsync(JToken.FromObject(new MockRequest(1)), TestNotificationHandler.Name, lspServices, CancellationToken.None); Assert.Same(NoValue.Instance, response); } @@ -130,7 +131,7 @@ public async Task ExecuteAsync_CompletesTask_Notification_Parameterless() var requestExecutionQueue = GetRequestExecutionQueue(false, (TestParameterlessNotificationHandler.Metadata, TestParameterlessNotificationHandler.Instance)); var lspServices = GetLspServices(); - var response = await requestExecutionQueue.ExecuteAsync(request: NoValue.Instance, TestParameterlessNotificationHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); + var response = await requestExecutionQueue.ExecuteAsync(serializedRequest: null, TestParameterlessNotificationHandler.Name, lspServices, CancellationToken.None); Assert.Same(NoValue.Instance, response); } @@ -138,11 +139,11 @@ public async Task ExecuteAsync_CompletesTask_Notification_Parameterless() public async Task Queue_DrainsOnShutdown() { var requestExecutionQueue = GetRequestExecutionQueue(false, (TestMethodHandler.Metadata, TestMethodHandler.Instance)); - var request = 1; + var request = JToken.FromObject(new MockRequest(1)); var lspServices = GetLspServices(); - var task1 = requestExecutionQueue.ExecuteAsync(request, TestMethodHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); - var task2 = requestExecutionQueue.ExecuteAsync(request, TestMethodHandler.Name, LanguageServerConstants.DefaultLanguageName, lspServices, CancellationToken.None); + var task1 = requestExecutionQueue.ExecuteAsync(request, TestMethodHandler.Name, lspServices, CancellationToken.None); + var task2 = requestExecutionQueue.ExecuteAsync(request, TestMethodHandler.Name, lspServices, CancellationToken.None); await requestExecutionQueue.DisposeAsync(); diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractHandlerProvider.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractHandlerProvider.cs index d7cb25405b026..14516ad074984 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractHandlerProvider.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractHandlerProvider.cs @@ -29,8 +29,8 @@ internal abstract class AbstractHandlerProvider /// The language for the request. /// The handler for the request. /// - /// If the handler for the given language is not found, the default handler is returned. - /// If the default handler is not found, an exception is thrown. + /// If the handler for the given language is not found, an exception is thrown. + /// Callers are expected to only request handlers for methods and languages that exist. /// public abstract IMethodHandler GetMethodHandler(string method, TypeRef? requestTypeRef, TypeRef? responseTypeRef, string language); } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractLanguageServer.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractLanguageServer.cs index 3c07c01a746e8..90492b7d7fa00 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractLanguageServer.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractLanguageServer.cs @@ -6,7 +6,6 @@ #nullable enable using System; -using System.Collections.Frozen; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -20,7 +19,6 @@ internal abstract class AbstractLanguageServer { private readonly JsonRpc _jsonRpc; protected readonly ILspLogger Logger; - protected readonly AbstractTypeRefResolver TypeRefResolver; /// /// These are lazy to allow implementations to define custom variables that are used by @@ -53,6 +51,8 @@ internal abstract class AbstractLanguageServer /// private readonly TaskCompletionSource _serverExitedSource = new(); + public AbstractTypeRefResolver TypeRefResolver { get; } + protected AbstractLanguageServer( JsonRpc jsonRpc, ILspLogger logger, @@ -123,7 +123,7 @@ protected virtual void SetupRequestDispatcher(AbstractHandlerProvider handlerPro throw new InvalidOperationException($"Language specific handlers for {methodGroup.Key} have mis-matched number of returns:{Environment.NewLine}{string.Join(Environment.NewLine, methodGroup)}"); } - var delegatingEntryPoint = CreateDelegatingEntryPoint(methodGroup.Key, methodGroup); + var delegatingEntryPoint = CreateDelegatingEntryPoint(methodGroup.Key); var methodAttribute = new JsonRpcMethodAttribute(methodGroup.Key) { UseSingleObjectParameterDeserialization = true, @@ -137,12 +137,7 @@ protected virtual void SetupRequestDispatcher(AbstractHandlerProvider handlerPro static bool AllTypesMatch(IEnumerable typeRefs) { - if (typeRefs.All(r => r is null)) - { - return true; - } - - if (typeRefs.All(r => r is not null)) + if (typeRefs.All(r => r is null) || typeRefs.All(r => r is not null)) { return true; } @@ -177,67 +172,34 @@ protected IRequestExecutionQueue GetRequestExecutionQueue() return _queue.Value; } - protected abstract DelegatingEntryPoint CreateDelegatingEntryPoint(string method, IGrouping handlersForMethod); + public virtual string GetLanguageForRequest(string methodName, object? serializedRequest) + { + Logger.LogInformation($"Using default language handler for {methodName}"); + return LanguageServerConstants.DefaultLanguageName; + } + + protected abstract DelegatingEntryPoint CreateDelegatingEntryPoint(string method); + + public abstract TRequest DeserializeRequest(object? serializedRequest, RequestHandlerMetadata metadata); protected abstract class DelegatingEntryPoint { protected readonly string _method; - protected readonly AbstractTypeRefResolver _typeRefResolver; - protected readonly Lazy> _languageEntryPoint; - - private static readonly MethodInfo s_queueExecuteAsyncMethod = typeof(RequestExecutionQueue).GetMethod(nameof(RequestExecutionQueue.ExecuteAsync))!; - public DelegatingEntryPoint(string method, AbstractTypeRefResolver typeRefResolver, IGrouping handlersForMethod) + public DelegatingEntryPoint(string method) { _method = method; - _typeRefResolver = typeRefResolver; - _languageEntryPoint = new Lazy>(() => - { - var handlerEntryPoints = new Dictionary(); - foreach (var metadata in handlersForMethod) - { - var noValueType = NoValue.Instance.GetType(); - - var requestType = metadata.RequestTypeRef is TypeRef requestTypeRef - ? _typeRefResolver.Resolve(requestTypeRef) ?? noValueType - : noValueType; - var responseType = metadata.ResponseTypeRef is TypeRef responseTypeRef - ? _typeRefResolver.Resolve(responseTypeRef) ?? noValueType - : noValueType; - var methodInfo = s_queueExecuteAsyncMethod.MakeGenericMethod(requestType, responseType); - handlerEntryPoints[metadata.Language] = (methodInfo, metadata); - } - - return handlerEntryPoints.ToFrozenDictionary(); - }); } public abstract MethodInfo GetEntryPoint(bool hasParameter); - protected (MethodInfo MethodInfo, RequestHandlerMetadata Metadata) GetMethodInfo(string language) - { - if (!_languageEntryPoint.Value.TryGetValue(language, out var requestInfo) - && !_languageEntryPoint.Value.TryGetValue(LanguageServerConstants.DefaultLanguageName, out requestInfo)) - { - throw new InvalidOperationException($"No default or language specific handler was found for {_method} and document with language {language}"); - } - - return requestInfo; - } - protected async Task InvokeAsync( - MethodInfo methodInfo, IRequestExecutionQueue queue, object? requestObject, - string language, ILspServices lspServices, CancellationToken cancellationToken) { - var task = methodInfo.Invoke(queue, [requestObject, _method, language, lspServices, cancellationToken]) as Task - ?? throw new InvalidOperationException($"Queue result task cannot be null"); - await task.ConfigureAwait(false); - var resultProperty = task.GetType().GetProperty("Result") ?? throw new InvalidOperationException("Result property on task cannot be null"); - var result = resultProperty.GetValue(task); + var result = await queue.ExecuteAsync(requestObject, _method, lspServices, cancellationToken).ConfigureAwait(false); if (result == NoValue.Instance) { return null; @@ -394,11 +356,6 @@ internal TestAccessor(AbstractLanguageServer server) return null; } - internal Task ExecuteRequestAsync(string methodName, string languageName, TRequest request, CancellationToken cancellationToken) - { - return _server._queue.Value.ExecuteAsync(request, methodName, languageName, _server._lspServices.Value, cancellationToken); - } - internal JsonRpc GetServerRpc() => _server._jsonRpc; internal bool HasShutdownStarted() diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs index 27762af48782d..1ab7c81174844 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs @@ -12,11 +12,21 @@ internal abstract class AbstractRequestScope(string name) : IDisposable { public string Name { get; } = name; + public string? Language { get; private set; } + public abstract void RecordCancellation(); public abstract void RecordException(Exception exception); public abstract void RecordWarning(string message); public abstract void RecordExecutionStart(); + /// + /// Sets the language for the request once it has been determined + /// + public void UpdateLanguage(string language) + { + Language = language; + } + public abstract void Dispose(); } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/HandlerProvider.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/HandlerProvider.cs index 5ad6c8267b9db..1d258ecb80b93 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/HandlerProvider.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/HandlerProvider.cs @@ -26,11 +26,9 @@ public IMethodHandler GetMethodHandler(string method, TypeRef? requestTypeRef, T public override IMethodHandler GetMethodHandler(string method, TypeRef? requestTypeRef, TypeRef? responseTypeRef, string language) { var requestHandlerMetadata = new RequestHandlerMetadata(method, requestTypeRef, responseTypeRef, language); - var defaultHandlerMetadata = new RequestHandlerMetadata(method, requestTypeRef, responseTypeRef, LanguageServerConstants.DefaultLanguageName); var requestHandlers = GetRequestHandlers(); - if (!requestHandlers.TryGetValue(requestHandlerMetadata, out var lazyHandler) && - !requestHandlers.TryGetValue(defaultHandlerMetadata, out lazyHandler)) + if (!requestHandlers.TryGetValue(requestHandlerMetadata, out var lazyHandler)) { throw new InvalidOperationException($"Missing handler for {requestHandlerMetadata.MethodName}"); } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs index 23f1ea4cd188e..60c78f614788d 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Threading; using System.Threading.Tasks; @@ -20,19 +19,27 @@ internal interface IQueueItem /// /// Executes the work specified by this queue item. /// - /// the context created by + /// The request parameters. + /// The context created by . /// The handler to use to execute the request. + /// The language for the request. /// /// A which completes when the request has finished. - Task StartRequestAsync(TRequestContext requestContext, IMethodHandler handler, CancellationToken cancellationToken); + Task StartRequestAsync(TRequest request, TRequestContext? context, IMethodHandler handler, string language, CancellationToken cancellationToken); /// /// Creates the context that is sent to the handler for this queue item. /// Note - this method is always called serially inside the queue before - /// running the actual request in + /// running the actual request in /// Throwing in this method will cause the server to shutdown. /// - Task CreateRequestContextAsync(IMethodHandler handler, CancellationToken cancellationToken); + Task CreateRequestContextAsync(TRequest deserializedRequest, IMethodHandler handler, CancellationToken cancellationToken); + + /// + /// Attempts to deserialize the request. If the request cannot be deserialized, ensures that the exception is returned as the result. + /// If the request is mutating, the exception will bubble up so the queue can handle it and shutdown. + /// + public TRequest? TryDeserializeRequest(AbstractLanguageServer languageServer, RequestHandlerMetadata requestHandlerMetadata, bool isMutating); /// /// Provides access to LSP services. @@ -44,18 +51,5 @@ internal interface IQueueItem /// string MethodName { get; } - /// - /// The language of the request. The default is - /// - string Language { get; } - - /// - /// The type of the request. - /// - Type? RequestType { get; } - - /// - /// The type of the response. - /// - Type? ResponseType { get; } + object? SerializedRequest { get; } } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IRequestExecutionQueue.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IRequestExecutionQueue.cs index 463e597c70cf3..084293272ded8 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IRequestExecutionQueue.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IRequestExecutionQueue.cs @@ -6,6 +6,7 @@ #nullable enable using System; +using System.Collections.Frozen; using System.Threading; using System.Threading.Tasks; @@ -21,7 +22,7 @@ internal interface IRequestExecutionQueue : IAsyncDisposable /// Queue a request. /// /// A task that completes when the handler execution is done. - Task ExecuteAsync(TRequest request, string methodName, string languageName, ILspServices lspServices, CancellationToken cancellationToken); + Task ExecuteAsync(object? serializedRequest, string methodName, ILspServices lspServices, CancellationToken cancellationToken); /// /// Start the queue accepting requests once any event handlers have been attached. diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/NewtonsoftLanguageServer.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/NewtonsoftLanguageServer.cs index 9747129144462..59c45026e2543 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/NewtonsoftLanguageServer.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/NewtonsoftLanguageServer.cs @@ -25,21 +25,41 @@ internal abstract class NewtonsoftLanguageServer( { private readonly JsonSerializer _jsonSerializer = jsonSerializer; - protected override DelegatingEntryPoint CreateDelegatingEntryPoint(string method, IGrouping handlersForMethod) + public override TRequest DeserializeRequest(object? serializedRequest, RequestHandlerMetadata metadata) { - return new NewtonsoftDelegatingEntryPoint(method, handlersForMethod, this); + var requestTypeRef = metadata.RequestTypeRef; + + if (serializedRequest is null) + { + if (requestTypeRef is not null) + { + throw new InvalidOperationException($"Handler {metadata.HandlerDescription} requires request parameters but received none"); + } + + // We checked that TRequest is typeof(NoValue). + return (TRequest)(object)NoValue.Instance; + } + + // request is not null + if (requestTypeRef is null) + { + throw new InvalidOperationException($"Handler {metadata.HandlerDescription} does not accept parameters, but received some."); + } + + var request = (JToken)serializedRequest; + + return request.ToObject(_jsonSerializer) + ?? throw new InvalidOperationException($"Unable to deserialize {request} into {requestTypeRef} for {metadata.HandlerDescription}"); } - protected virtual string GetLanguageForRequest(string methodName, JToken? parameters) + protected override DelegatingEntryPoint CreateDelegatingEntryPoint(string method) { - Logger.LogInformation($"Using default language handler for {methodName}"); - return LanguageServerConstants.DefaultLanguageName; + return new NewtonsoftDelegatingEntryPoint(method, this); } private class NewtonsoftDelegatingEntryPoint( string method, - IGrouping handlersForMethod, - NewtonsoftLanguageServer target) : DelegatingEntryPoint(method, target.TypeRefResolver, handlersForMethod) + NewtonsoftLanguageServer target) : DelegatingEntryPoint(method) { private static readonly MethodInfo s_entryPoint = typeof(NewtonsoftDelegatingEntryPoint).GetMethod(nameof(NewtonsoftDelegatingEntryPoint.ExecuteRequestAsync), BindingFlags.NonPublic | BindingFlags.Instance)!; @@ -57,16 +77,7 @@ public override MethodInfo GetEntryPoint(bool hasParameter) var queue = target.GetRequestExecutionQueue(); var lspServices = target.GetLspServices(); - // Retrieve the language of the request so we know how to deserialize it. - var language = target.GetLanguageForRequest(_method, request); - - // Find the correct request and response types for the given request and language. - var requestInfo = GetMethodInfo(language); - - // Deserialize the request parameters (if any). - var requestObject = DeserializeRequest(request, requestInfo.Metadata, target._jsonSerializer); - - var result = await InvokeAsync(requestInfo.MethodInfo, queue, requestObject, language, lspServices, cancellationToken).ConfigureAwait(false); + var result = await InvokeAsync(queue, request, lspServices, cancellationToken).ConfigureAwait(false); if (result is null) { return null; @@ -74,32 +85,5 @@ public override MethodInfo GetEntryPoint(bool hasParameter) return JToken.FromObject(result, target._jsonSerializer); } - - private object DeserializeRequest(JToken? request, RequestHandlerMetadata metadata, JsonSerializer jsonSerializer) - { - var requestTypeRef = metadata.RequestTypeRef; - - if (request is null) - { - if (requestTypeRef is not null) - { - throw new InvalidOperationException($"Handler {metadata.HandlerDescription} requires request parameters but received none"); - } - - return NoValue.Instance; - } - - // request is not null - if (requestTypeRef is null) - { - throw new InvalidOperationException($"Handler {metadata.HandlerDescription} does not accept parameters, but received some."); - } - - var requestType = _typeRefResolver.Resolve(requestTypeRef) - ?? throw new InvalidOperationException($"Could not resolve type: '{requestTypeRef}'"); - - return request.ToObject(requestType, jsonSerializer) - ?? throw new InvalidOperationException($"Unable to deserialize {request} into {requestTypeRef} for {metadata.HandlerDescription}"); - } } } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs index 6d276eb61bd16..b037e60610fd4 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs @@ -6,7 +6,10 @@ #nullable enable using System; +using System.Collections.Frozen; +using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.Threading; @@ -21,10 +24,8 @@ internal sealed class NoValue public static NoValue Instance = new(); } -internal class QueueItem : IQueueItem +internal class QueueItem : IQueueItem { - private readonly TRequest _request; - private readonly ILspLogger _logger; private readonly AbstractRequestScope? _requestTelemetryScope; @@ -32,22 +33,17 @@ internal class QueueItem : IQueueItem - private readonly TaskCompletionSource _completionSource = new(); + private readonly TaskCompletionSource _completionSource = new(); public ILspServices LspServices { get; } public string MethodName { get; } - public string Language { get; } - - public Type? RequestType => typeof(TRequest) == typeof(NoValue) ? null : typeof(TRequest); - - public Type? ResponseType => typeof(TResponse) == typeof(NoValue) ? null : typeof(TResponse); + public object? SerializedRequest { get; } private QueueItem( string methodName, - string language, - TRequest request, + object? serializedRequest, ILspServices lspServices, ILspLogger logger, CancellationToken cancellationToken) @@ -56,29 +52,26 @@ private QueueItem( cancellationToken.Register(() => _completionSource.TrySetCanceled(cancellationToken)); _logger = logger; - _request = request; + SerializedRequest = serializedRequest; LspServices = lspServices; MethodName = methodName; - Language = language; var telemetryService = lspServices.GetService(); _requestTelemetryScope = telemetryService?.CreateRequestScope(methodName); } - public static (IQueueItem, Task) Create( + public static (IQueueItem, Task) Create( string methodName, - string language, - TRequest request, + object? serializedRequest, ILspServices lspServices, ILspLogger logger, CancellationToken cancellationToken) { - var queueItem = new QueueItem( + var queueItem = new QueueItem( methodName, - language, - request, + serializedRequest, lspServices, logger, cancellationToken); @@ -86,29 +79,58 @@ public static (IQueueItem, Task) Create( return (queueItem, queueItem._completionSource.Task); } - public async Task CreateRequestContextAsync(IMethodHandler handler, CancellationToken cancellationToken) + public async Task CreateRequestContextAsync(TRequest request, IMethodHandler handler, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _requestTelemetryScope?.RecordExecutionStart(); var requestContextFactory = LspServices.GetRequiredService>(); - var context = await requestContextFactory.CreateRequestContextAsync(this, handler, _request, cancellationToken).ConfigureAwait(false); + var context = await requestContextFactory.CreateRequestContextAsync(this, handler, request, cancellationToken).ConfigureAwait(false); return context; } + public TRequest? TryDeserializeRequest(AbstractLanguageServer languageServer, RequestHandlerMetadata requestHandlerMetadata, bool isMutating) + { + try + { + return languageServer.DeserializeRequest(SerializedRequest, requestHandlerMetadata); + } + catch (Exception ex) + { + // Report the exception to logs / telemetry + _requestTelemetryScope?.RecordException(ex); + _logger.LogException(ex); + + // Set the task result to the exception + _completionSource.TrySetException(ex); + + // End the request - the caller will return immediately if it cannot deserialize. + _requestTelemetryScope?.Dispose(); + _logger.LogEndContext($"{MethodName}"); + + // If the request is mutating, bubble the exception out so the queue shutsdown. + if (isMutating) + { + throw; + } + else + { + return default; + } + } + } + /// /// Processes the queued request. Exceptions will be sent to the task completion source /// representing the task that the client is waiting for, then re-thrown so that /// the queue can correctly handle them depending on the type of request. /// - /// Context used for the request. - /// The handler to execute. - /// - /// The result of the request. - public async Task StartRequestAsync(TRequestContext? context, IMethodHandler handler, CancellationToken cancellationToken) + public async Task StartRequestAsync(TRequest request, TRequestContext? context, IMethodHandler handler, string language, CancellationToken cancellationToken) { _logger.LogStartContext($"{MethodName}"); + _requestTelemetryScope?.UpdateLanguage(language); + try { cancellationToken.ThrowIfCancellationRequested(); @@ -133,7 +155,7 @@ public async Task StartRequestAsync(TRequestContext? context, IMethodHandler han } else if (handler is IRequestHandler requestHandler) { - var result = await requestHandler.HandleRequestAsync(_request, context, cancellationToken).ConfigureAwait(false); + var result = await requestHandler.HandleRequestAsync(request, context, cancellationToken).ConfigureAwait(false); _completionSource.TrySetResult(result); } @@ -145,7 +167,7 @@ public async Task StartRequestAsync(TRequestContext? context, IMethodHandler han } else if (handler is INotificationHandler notificationHandler) { - await notificationHandler.HandleNotificationAsync(_request, context, cancellationToken).ConfigureAwait(false); + await notificationHandler.HandleNotificationAsync(request, context, cancellationToken).ConfigureAwait(false); // We know that the return type of will always be even if the compiler doesn't. _completionSource.TrySetResult((TResponse)(object)NoValue.Instance); diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs index ea352e408be4e..13ccb40530c94 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs @@ -7,11 +7,15 @@ using System; using System.Collections.Concurrent; +using System.Collections.Frozen; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.Threading; +using StreamJsonRpc; namespace Microsoft.CommonLanguageServerProtocol.Framework; @@ -36,7 +40,7 @@ namespace Microsoft.CommonLanguageServerProtocol.Framework; /// /// Regardless of whether a request is mutating or not, or blocking or not, is an implementation detail of this class /// and any consumers observing the results of the task returned from -/// +/// /// will see the results of the handling of the request, whenever it occurred. /// /// @@ -51,6 +55,9 @@ namespace Microsoft.CommonLanguageServerProtocol.Framework; /// internal class RequestExecutionQueue : IRequestExecutionQueue { + private static readonly MethodInfo s_processQueueCoreAsync = typeof(RequestExecutionQueue) + .GetMethod(nameof(RequestExecutionQueue.ProcessQueueCoreAsync), BindingFlags.NonPublic | BindingFlags.Instance)!; + protected readonly ILspLogger _logger; protected readonly AbstractHandlerProvider _handlerProvider; private readonly AbstractLanguageServer _languageServer; @@ -62,6 +69,13 @@ internal class RequestExecutionQueue : IRequestExecutionQueue queueItem, Guid ActivityId, CancellationToken cancellationToken)> _queue = new(); private readonly CancellationTokenSource _cancelSource = new(); + /// + /// Map of method to the handler info for each language. + /// The handler info is created lazily to avoid instantiating any types or handlers until a request is recieved for + /// that particular method and language. + /// + private readonly FrozenDictionary>> _handlerInfoMap; + /// /// For test purposes only. /// A task that completes when the queue processing stops. @@ -75,6 +89,40 @@ public RequestExecutionQueue(AbstractLanguageServer languageSer _languageServer = languageServer; _logger = logger; _handlerProvider = handlerProvider; + _handlerInfoMap = BuildHandlerMap(handlerProvider, languageServer.TypeRefResolver); + } + + private static FrozenDictionary>> BuildHandlerMap(AbstractHandlerProvider handlerProvider, AbstractTypeRefResolver typeRefResolver) + { + var genericMethodMap = new Dictionary>>(); + var noValueType = NoValue.Instance.GetType(); + // Get unique set of methods from the handler provider for the default language. + foreach (var methodGroup in handlerProvider + .GetRegisteredMethods() + .GroupBy(m => m.MethodName)) + { + var languages = new Dictionary>(); + foreach (var metadata in methodGroup) + { + languages.Add(metadata.Language, new(() => + { + var requestType = metadata.RequestTypeRef is TypeRef requestTypeRef + ? typeRefResolver.Resolve(requestTypeRef) ?? noValueType + : noValueType; + var responseType = metadata.ResponseTypeRef is TypeRef responseTypeRef + ? typeRefResolver.Resolve(responseTypeRef) ?? noValueType + : noValueType; + + var method = s_processQueueCoreAsync.MakeGenericMethod(requestType, responseType); + var handler = handlerProvider.GetMethodHandler(metadata.MethodName, metadata.RequestTypeRef, metadata.ResponseTypeRef, metadata.Language); + return (metadata, handler, method); + })); + } + + genericMethodMap.Add(methodGroup.Key, languages.ToFrozenDictionary()); + } + + return genericMethodMap.ToFrozenDictionary(); } public void Start() @@ -100,16 +148,15 @@ public void Start() /// Queues a request to be handled by the specified handler, with mutating requests blocking subsequent requests /// from starting until the mutation is complete. /// - /// The request to handle. + /// The serialized request to handle. /// The name of the LSP method. /// The set of LSP services to use. /// A cancellation token that will cancel the handing of this request. /// The request could also be cancelled by the queue shutting down. /// A task that can be awaited to observe the results of the handing of this request. - public virtual Task ExecuteAsync( - TRequest request, + public virtual Task ExecuteAsync( + object? serializedRequest, string methodName, - string languageName, ILspServices lspServices, CancellationToken requestCancellationToken) { @@ -119,11 +166,11 @@ public virtual Task ExecuteAsync( // shutting down cancels the request. var combinedTokenSource = _cancelSource.Token.CombineWith(requestCancellationToken); var combinedCancellationToken = combinedTokenSource.Token; - var (item, resultTask) = CreateQueueItem( + var (item, resultTask) = QueueItem.Create( methodName, - languageName, - request, + serializedRequest, lspServices, + _logger, combinedCancellationToken); // Run a continuation to ensure the cts is disposed of. @@ -136,26 +183,11 @@ public virtual Task ExecuteAsync( // If the queue has been shut down the enqueue will fail, so we just fault the task immediately. // The queue itself is threadsafe (_queue.TryEnqueue and _queue.Complete use the same lock). if (!didEnqueue) - return Task.FromException(new InvalidOperationException("Server was requested to shut down.")); + return Task.FromException(new InvalidOperationException("Server was requested to shut down.")); return resultTask; } - internal (IQueueItem, Task) CreateQueueItem( - string methodName, - string languageName, - TRequest request, - ILspServices lspServices, - CancellationToken cancellationToken) - { - return QueueItem.Create(methodName, - languageName, - request, - lspServices, - _logger, - cancellationToken); - } - private async Task ProcessQueueAsync() { ILspServices? lspServices = null; @@ -206,62 +238,15 @@ private async Task ProcessQueueAsync() // Restore our activity id so that logging/tracking works across asynchronous calls. Trace.CorrelationManager.ActivityId = activityId; - // The request context must be created serially inside the queue to so that requests always run - // on the correct snapshot as of the last request. - var handler = GetHandlerForRequest(work); - var context = await work.CreateRequestContextAsync(handler, cancellationToken).ConfigureAwait(false); - if (handler.MutatesSolutionState) - { - if (CancelInProgressWorkUponMutatingRequest) - { - // Cancel all concurrently executing tasks - var concurrentlyExecutingTasksArray = concurrentlyExecutingTasks.ToArray(); - for (var i = 0; i < concurrentlyExecutingTasksArray.Length; i++) - { - concurrentlyExecutingTasksArray[i].Value.Cancel(); - } - - // wait for all pending tasks to complete their cancellation, ignoring any exceptions - await Task.WhenAll(concurrentlyExecutingTasksArray.Select(kvp => kvp.Key)).NoThrowAwaitable(captureContext: false); - } - Debug.Assert(!concurrentlyExecutingTasks.Any(t => !t.Key.IsCompleted), "The tasks should have all been drained before continuing"); - // Mutating requests block other requests from starting to ensure an up to date snapshot is used. - // Since we're explicitly awaiting exceptions to mutating requests will bubble up here. - await WrapStartRequestTaskAsync(work.StartRequestAsync(context, handler, cancellationToken), rethrowExceptions: true).ConfigureAwait(false); - } - else - { - // Non mutating are fire-and-forget because they are by definition read-only. Any errors - // will be sent back to the client but they can also be captured via HandleNonMutatingRequestError, - // though these errors don't put us into a bad state as far as the rest of the queue goes. - // Furthermore we use Task.Run here to protect ourselves against synchronous execution of work - // blocking the request queue for longer periods of time (it enforces parallelizability). - var currentWorkTask = WrapStartRequestTaskAsync(Task.Run(() => work.StartRequestAsync(context, handler, cancellationToken), cancellationToken), rethrowExceptions: false); - - if (CancelInProgressWorkUponMutatingRequest) - { - if (currentWorkCts is null) - { - throw new InvalidOperationException($"unexpected null value for {nameof(currentWorkCts)}"); - } - - if (!concurrentlyExecutingTasks.TryAdd(currentWorkTask, currentWorkCts)) - { - throw new InvalidOperationException($"unable to add {nameof(currentWorkTask)} into {nameof(concurrentlyExecutingTasks)}"); - } - - _ = currentWorkTask.ContinueWith(t => - { - if (!concurrentlyExecutingTasks.TryRemove(t, out var concurrentlyExecutingTaskCts)) - { - throw new InvalidOperationException($"unexpected failure to remove task from {nameof(concurrentlyExecutingTasks)}"); - } - - concurrentlyExecutingTaskCts.Dispose(); - }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); - } - } + // Determine which language is appropriate for handling the request. + var language = _languageServer.GetLanguageForRequest(work.MethodName, work.SerializedRequest); + + // Now that we know the actual language, we can deserialize the request and start creating the request context. + var (metadata, handler, methodInfo) = GetHandlerForRequest(work, language); + + // We now have the actual handler and language, so we can process the work item using the concrete types defined by the metadata. + await InvokeProcessCoreAsync(work, metadata, handler, methodInfo, concurrentlyExecutingTasks, currentWorkCts, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -290,24 +275,121 @@ private async Task ProcessQueueAsync() } /// - /// Allows XAML to inspect the request before its dispatched. - /// Should not generally be used, this will be replaced by the OOP XAML server. + /// Reflection invokes + /// using the concrete types defined by the handler's metadata. /// - [Obsolete("Only for use by legacy XAML LSP")] - protected internal virtual void BeforeRequest(TRequest request) + private async Task InvokeProcessCoreAsync( + IQueueItem work, + RequestHandlerMetadata metadata, + IMethodHandler handler, + MethodInfo methodInfo, + ConcurrentDictionary concurrentlyExecutingTasks, + CancellationTokenSource? currentWorkCts, + CancellationToken cancellationToken) { - return; + var task = methodInfo.Invoke(this, [work, handler, metadata, concurrentlyExecutingTasks, currentWorkCts, cancellationToken]) as Task + ?? throw new InvalidOperationException($"ProcessQueueCoreAsync result task cannot be null"); + await task.ConfigureAwait(false); + } + + /// + /// Given a concrete handler and types, this dispatches the current work item to the appropriate handler, + /// waiting or not waiting on results as defined by the handler. + /// + private async Task ProcessQueueCoreAsync( + IQueueItem work, + IMethodHandler handler, + RequestHandlerMetadata metadata, + ConcurrentDictionary concurrentlyExecutingTasks, + CancellationTokenSource? currentWorkCts, + CancellationToken cancellationToken) + { + var deserializedRequest = work.TryDeserializeRequest(_languageServer, metadata, handler.MutatesSolutionState); + if (deserializedRequest == null) + { + return; + } + + // The request context must be created serially inside the queue to so that requests always run + // on the correct snapshot as of the last request. + var context = await work.CreateRequestContextAsync(deserializedRequest, handler, cancellationToken).ConfigureAwait(false); + + // Run anything in before request before we start handliung the request (for example setting the UI culture). + BeforeRequest(deserializedRequest); + + if (handler.MutatesSolutionState) + { + if (CancelInProgressWorkUponMutatingRequest) + { + // Cancel all concurrently executing tasks + var concurrentlyExecutingTasksArray = concurrentlyExecutingTasks.ToArray(); + for (var i = 0; i < concurrentlyExecutingTasksArray.Length; i++) + { + concurrentlyExecutingTasksArray[i].Value.Cancel(); + } + + // wait for all pending tasks to complete their cancellation, ignoring any exceptions + await Task.WhenAll(concurrentlyExecutingTasksArray.Select(kvp => kvp.Key)).NoThrowAwaitable(captureContext: false); + } + + Debug.Assert(!concurrentlyExecutingTasks.Any(t => !t.Key.IsCompleted), "The tasks should have all been drained before continuing"); + // Mutating requests block other requests from starting to ensure an up to date snapshot is used. + // Since we're explicitly awaiting exceptions to mutating requests will bubble up here. + await WrapStartRequestTaskAsync(work.StartRequestAsync(deserializedRequest, context, handler, metadata.Language, cancellationToken), rethrowExceptions: true).ConfigureAwait(false); + } + else + { + // Non mutating are fire-and-forget because they are by definition read-only. Any errors + // will be sent back to the client but they can also be captured via HandleNonMutatingRequestError, + // though these errors don't put us into a bad state as far as the rest of the queue goes. + // Furthermore we use Task.Run here to protect ourselves against synchronous execution of work + // blocking the request queue for longer periods of time (it enforces parallelizability). + var currentWorkTask = WrapStartRequestTaskAsync(Task.Run(() => work.StartRequestAsync(deserializedRequest, context, handler, metadata.Language, cancellationToken), cancellationToken), rethrowExceptions: false); + + if (CancelInProgressWorkUponMutatingRequest) + { + if (currentWorkCts is null) + { + throw new InvalidOperationException($"unexpected null value for {nameof(currentWorkCts)}"); + } + + if (!concurrentlyExecutingTasks.TryAdd(currentWorkTask, currentWorkCts)) + { + throw new InvalidOperationException($"unable to add {nameof(currentWorkTask)} into {nameof(concurrentlyExecutingTasks)}"); + } + + _ = currentWorkTask.ContinueWith(t => + { + if (!concurrentlyExecutingTasks.TryRemove(t, out var concurrentlyExecutingTaskCts)) + { + throw new InvalidOperationException($"unexpected failure to remove task from {nameof(concurrentlyExecutingTasks)}"); + } + + concurrentlyExecutingTaskCts.Dispose(); + }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); + } + } } /// - /// Choose the method handler for the given request. By default this calls the . + /// Allows an action to happen before the request runs, for example setting the current thread culture. /// - protected virtual IMethodHandler GetHandlerForRequest(IQueueItem work) - => _handlerProvider.GetMethodHandler( - work.MethodName, - TypeRef.FromOrNull(work.RequestType), - TypeRef.FromOrNull(work.ResponseType), - work.Language); + protected internal virtual void BeforeRequest(TRequest request) + { + return; + } + + private (RequestHandlerMetadata Metadata, IMethodHandler Handler, MethodInfo MethodInfo) GetHandlerForRequest(IQueueItem work, string language) + { + var handlersForMethod = _handlerInfoMap[work.MethodName]; + if (handlersForMethod.TryGetValue(language, out var lazyData) || + handlersForMethod.TryGetValue(LanguageServerConstants.DefaultLanguageName, out lazyData)) + { + return lazyData.Value; + } + + throw new InvalidOperationException($"Missing default or language handler for {work.MethodName} and language {language}"); + } /// /// Provides an extensibility point to log or otherwise inspect errors thrown from non-mutating requests, diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs index caac57fb85f96..8006a68d0c905 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs @@ -25,21 +25,40 @@ internal abstract class SystemTextJsonLanguageServer( /// private readonly JsonSerializerOptions _jsonSerializerOptions = options; - protected override DelegatingEntryPoint CreateDelegatingEntryPoint(string method, IGrouping handlersForMethod) + public override TRequest DeserializeRequest(object? serializedRequest, RequestHandlerMetadata metadata) { - return new SystemTextJsonDelegatingEntryPoint(method, handlersForMethod, this); + if (serializedRequest is null) + { + if (metadata.RequestTypeRef is not null) + { + throw new InvalidOperationException($"Handler {metadata.HandlerDescription} requires request parameters but received none"); + } + else + { + // We checked that TRequest is typeof(NoValue). + return (TRequest)(object)NoValue.Instance; + } + } + + if (metadata.RequestTypeRef is null) + { + throw new InvalidOperationException($"Handler {metadata.HandlerDescription} does not accept parameters, but received some."); + } + + var request = (JsonElement)serializedRequest; + + return JsonSerializer.Deserialize(request, _jsonSerializerOptions) + ?? throw new InvalidOperationException($"Unable to deserialize {request} into {typeof(TRequest)} for {metadata.HandlerDescription}"); } - protected virtual string GetLanguageForRequest(string methodName, JsonElement? parameters) + protected override DelegatingEntryPoint CreateDelegatingEntryPoint(string method) { - Logger.LogInformation($"Using default language handler for {methodName}"); - return LanguageServerConstants.DefaultLanguageName; + return new SystemTextJsonDelegatingEntryPoint(method, this); } private sealed class SystemTextJsonDelegatingEntryPoint( string method, - IGrouping handlersForMethod, - SystemTextJsonLanguageServer target) : DelegatingEntryPoint(method, target.TypeRefResolver, handlersForMethod) + SystemTextJsonLanguageServer target) : DelegatingEntryPoint(method) { private static readonly MethodInfo s_parameterlessEntryPoint = typeof(SystemTextJsonDelegatingEntryPoint).GetMethod(nameof(SystemTextJsonDelegatingEntryPoint.ExecuteRequest0Async), BindingFlags.NonPublic | BindingFlags.Instance)!; private static readonly MethodInfo s_entryPoint = typeof(SystemTextJsonDelegatingEntryPoint).GetMethod(nameof(SystemTextJsonDelegatingEntryPoint.ExecuteRequestAsync), BindingFlags.NonPublic | BindingFlags.Instance)!; @@ -66,16 +85,7 @@ public override MethodInfo GetEntryPoint(bool hasParameter) var queue = target.GetRequestExecutionQueue(); var lspServices = target.GetLspServices(); - // Retrieve the language of the request so we know how to deserialize it. - var language = target.GetLanguageForRequest(_method, request); - - // Find the correct request and response types for the given request and language. - var requestInfo = GetMethodInfo(language); - - // Deserialize the request parameters (if any). - var requestObject = DeserializeRequest(request, requestInfo.Metadata, target._jsonSerializerOptions); - - var result = await InvokeAsync(requestInfo.MethodInfo, queue, requestObject, language, lspServices, cancellationToken).ConfigureAwait(false); + var result = await InvokeAsync(queue, request, lspServices, cancellationToken).ConfigureAwait(false); if (result is null) { return null; @@ -84,32 +94,5 @@ public override MethodInfo GetEntryPoint(bool hasParameter) var serializedResult = JsonSerializer.SerializeToElement(result, target._jsonSerializerOptions); return serializedResult; } - - private object DeserializeRequest(JsonElement? request, RequestHandlerMetadata metadata, JsonSerializerOptions options) - { - var requestTypeRef = metadata.RequestTypeRef; - - if (request is null) - { - if (requestTypeRef is not null) - { - throw new InvalidOperationException($"Handler {metadata.HandlerDescription} requires request parameters but received none"); - } - - return NoValue.Instance; - } - - // request is not null - if (requestTypeRef is null) - { - throw new InvalidOperationException($"Handler {metadata.HandlerDescription} does not accept parameters, but received some."); - } - - var requestType = _typeRefResolver.Resolve(requestTypeRef) - ?? throw new InvalidOperationException($"Could not resolve type: '{requestTypeRef}'"); - - return JsonSerializer.Deserialize(request.Value, requestType, options) - ?? throw new InvalidOperationException($"Unable to deserialize {request} into {requestTypeRef} for {metadata.HandlerDescription}"); - } } } diff --git a/src/LanguageServer/Protocol/Handler/RequestTelemetryLogger.cs b/src/LanguageServer/Protocol/Handler/RequestTelemetryLogger.cs index 72db45075c156..4a2be60dae256 100644 --- a/src/LanguageServer/Protocol/Handler/RequestTelemetryLogger.cs +++ b/src/LanguageServer/Protocol/Handler/RequestTelemetryLogger.cs @@ -22,7 +22,7 @@ internal sealed class RequestTelemetryLogger : IDisposable, ILspService /// Store request counters in a concurrent dictionary as non-mutating LSP requests can /// run alongside other non-mutating requests. /// - private readonly ConcurrentDictionary _requestCounters; + private readonly ConcurrentDictionary<(string Method, string? Language), Counter> _requestCounters; private readonly CountLogAggregator _findDocumentResults; @@ -57,6 +57,7 @@ public void UpdateUsedForkedSolutionCounter(bool usedForkedSolution) public void UpdateTelemetryData( string methodName, + string? language, TimeSpan queuedDuration, TimeSpan requestDuration, Result result) @@ -69,6 +70,7 @@ public void UpdateTelemetryData( m[TelemetryLogging.KeyMetricName] = "TimeInQueue"; m["server"] = _serverTypeName; m["method"] = methodName; + m["language"] = language; })); TelemetryLogging.LogAggregated(FunctionId.LSP_RequestDuration, KeyValueLogMessage.Create(m => @@ -78,9 +80,10 @@ public void UpdateTelemetryData( m[TelemetryLogging.KeyMetricName] = "RequestDuration"; m["server"] = _serverTypeName; m["method"] = methodName; + m["language"] = language; })); - _requestCounters.GetOrAdd(methodName, (_) => new Counter()).IncrementCount(result); + _requestCounters.GetOrAdd((methodName, language), (_) => new Counter()).IncrementCount(result); } /// @@ -107,7 +110,8 @@ private void OnFlushed(object? sender, EventArgs e) TelemetryLogging.Log(FunctionId.LSP_RequestCounter, KeyValueLogMessage.Create(LogType.Trace, m => { m["server"] = _serverTypeName; - m["method"] = kvp.Key; + m["method"] = kvp.Key.Method; + m["language"] = kvp.Key.Language; m["successful"] = kvp.Value.SucceededCount; m["failed"] = kvp.Value.FailedCount; m["cancelled"] = kvp.Value.CancelledCount; diff --git a/src/LanguageServer/Protocol/Handler/WorkspaceCommand/ExecuteWorkspaceCommandHandler.cs b/src/LanguageServer/Protocol/Handler/WorkspaceCommand/ExecuteWorkspaceCommandHandler.cs index 04397fc1bf4d4..6ad5c5f940515 100644 --- a/src/LanguageServer/Protocol/Handler/WorkspaceCommand/ExecuteWorkspaceCommandHandler.cs +++ b/src/LanguageServer/Protocol/Handler/WorkspaceCommand/ExecuteWorkspaceCommandHandler.cs @@ -29,17 +29,14 @@ public ExecuteWorkspaceCommandHandler() public async Task HandleRequestAsync(ExecuteCommandParams request, RequestContext context, CancellationToken cancellationToken) { - var requestExecutionQueue = context.GetRequiredService>(); + var handlerProvider = context.GetRequiredService(); var lspServices = context.GetRequiredService(); var requestMethod = AbstractExecuteWorkspaceCommandHandler.GetRequestNameForCommandName(request.Command); - var result = await requestExecutionQueue.ExecuteAsync( - request, - LanguageServerConstants.DefaultLanguageName, - requestMethod, - lspServices, - cancellationToken).ConfigureAwait(false); + var handler = (AbstractExecuteWorkspaceCommandHandler)handlerProvider.GetMethodHandler(requestMethod, TypeRef.FromOrNull(typeof(ExecuteCommandParams)), TypeRef.FromOrNull(typeof(object)), LanguageServerConstants.DefaultLanguageName); + + var result = await handler.HandleRequestAsync(request, context, cancellationToken).ConfigureAwait(false); return result; } diff --git a/src/LanguageServer/Protocol/LspServices/RequestTelemetryScope.cs b/src/LanguageServer/Protocol/LspServices/RequestTelemetryScope.cs index 9c4798d119d42..7cc25cf9e74ba 100644 --- a/src/LanguageServer/Protocol/LspServices/RequestTelemetryScope.cs +++ b/src/LanguageServer/Protocol/LspServices/RequestTelemetryScope.cs @@ -41,6 +41,6 @@ public override void Dispose() { var requestDuration = _stopwatch.Elapsed; - _telemetryLogger.UpdateTelemetryData(Name, _queuedDuration, requestDuration, _result); + _telemetryLogger.UpdateTelemetryData(Name, Language, _queuedDuration, requestDuration, _result); } } diff --git a/src/LanguageServer/Protocol/RoslynLanguageServer.cs b/src/LanguageServer/Protocol/RoslynLanguageServer.cs index 0898b09d3cfae..6aa1623551766 100644 --- a/src/LanguageServer/Protocol/RoslynLanguageServer.cs +++ b/src/LanguageServer/Protocol/RoslynLanguageServer.cs @@ -86,8 +86,8 @@ private FrozenDictionary> GetBaseServices( AddService(lifeCycleManager); AddService(new ServerInfoProvider(serverKind, supportedLanguages)); AddLazyService>((lspServices) => new RequestContextFactory(lspServices)); - AddLazyService>((_) => GetRequestExecutionQueue()); AddLazyService((lspServices) => new TelemetryService(lspServices)); + AddLazyService((_) => HandlerProvider); AddService(new InitializeManager()); AddService(new InitializeHandler()); AddService(new InitializedHandler()); @@ -164,14 +164,17 @@ public Task OnInitializedAsync(ClientCapabilities clientCapabilities, RequestCon return Task.CompletedTask; } - protected override string GetLanguageForRequest(string methodName, JsonElement? parameters) + public override string GetLanguageForRequest(string methodName, object? serializedParameters) { - if (parameters == null) + if (serializedParameters == null) { Logger.LogInformation("No request parameters given, using default language handler"); return LanguageServerConstants.DefaultLanguageName; } + // We implement the STJ language server so this must be a JsonElement. + var parameters = (JsonElement)serializedParameters; + // For certain requests like text syncing we'll always use the default language handler // as we do not want languages to be able to override them. if (ShouldUseDefaultLanguage(methodName)) @@ -185,8 +188,8 @@ protected override string GetLanguageForRequest(string methodName, JsonElement? // { "textDocument": { "uri": "" ... } ... } // // We can easily identify the URI for the request by looking for this structure - if (parameters.Value.TryGetProperty("textDocument", out var textDocumentToken) || - parameters.Value.TryGetProperty("_vs_textDocument", out textDocumentToken)) + if (parameters.TryGetProperty("textDocument", out var textDocumentToken) || + parameters.TryGetProperty("_vs_textDocument", out textDocumentToken)) { var uriToken = textDocumentToken.GetProperty("uri"); var uri = JsonSerializer.Deserialize(uriToken, ProtocolConversions.LspJsonSerializerOptions); @@ -201,7 +204,7 @@ protected override string GetLanguageForRequest(string methodName, JsonElement? // // We can deserialize the data object using our unified DocumentResolveData. //var dataToken = parameters["data"]; - if (parameters.Value.TryGetProperty("data", out var dataToken)) + if (parameters.TryGetProperty("data", out var dataToken)) { var data = JsonSerializer.Deserialize(dataToken, ProtocolConversions.LspJsonSerializerOptions); Contract.ThrowIfNull(data, "Failed to document resolve data object"); diff --git a/src/LanguageServer/Protocol/RoslynRequestExecutionQueue.cs b/src/LanguageServer/Protocol/RoslynRequestExecutionQueue.cs index 291c908c88242..72796e0783a89 100644 --- a/src/LanguageServer/Protocol/RoslynRequestExecutionQueue.cs +++ b/src/LanguageServer/Protocol/RoslynRequestExecutionQueue.cs @@ -27,8 +27,6 @@ public RoslynRequestExecutionQueue(AbstractLanguageServer langua public override Task WrapStartRequestTaskAsync(Task nonMutatingRequestTask, bool rethrowExceptions) { - // Update the locale for this request to the desired LSP locale. - CultureInfo.CurrentUICulture = GetCultureForRequest(); if (rethrowExceptions) { return nonMutatingRequestTask; @@ -39,6 +37,12 @@ public override Task WrapStartRequestTaskAsync(Task nonMutatingRequestTask, bool } } + protected internal override void BeforeRequest(TRequest request) + { + // Update the locale for this request to the desired LSP locale. + CultureInfo.CurrentUICulture = GetCultureForRequest(); + } + /// /// Serial access is guaranteed by the queue. /// diff --git a/src/LanguageServer/ProtocolUnitTests/HandlerTests.cs b/src/LanguageServer/ProtocolUnitTests/HandlerTests.cs index 4eeaea3b54dcb..86d9c2446c33e 100644 --- a/src/LanguageServer/ProtocolUnitTests/HandlerTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/HandlerTests.cs @@ -27,6 +27,7 @@ public HandlerTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) protected override TestComposition Composition => base.Composition.AddParts( typeof(TestDocumentHandler), + typeof(TestNonMutatingDocumentHandler), typeof(TestRequestHandlerWithNoParams), typeof(TestNotificationHandlerFactory), typeof(TestNotificationWithoutParamsHandlerFactory), @@ -120,7 +121,18 @@ public async Task ThrowsIfDeserializationFails(bool mutatingLspWorkspace) await using var server = await CreateTestLspServerAsync("", mutatingLspWorkspace); var request = new TestRequestTypeThree("value"); - await Assert.ThrowsAsync(async () => await server.ExecuteRequestAsync(TestDocumentHandler.MethodName, request, CancellationToken.None)); + await Assert.ThrowsAsync(async () => await server.ExecuteRequestAsync(TestNonMutatingDocumentHandler.MethodName, request, CancellationToken.None)); + Assert.False(server.GetServerAccessor().HasShutdownStarted()); + } + + [Theory, CombinatorialData] + public async Task ShutsdownIfDeserializationFailsOnMutatingRequest(bool mutatingLspWorkspace) + { + await using var server = await CreateTestLspServerAsync("", mutatingLspWorkspace); + + var request = new TestRequestTypeThree("value"); + await Assert.ThrowsAnyAsync(async () => await server.ExecuteRequestAsync(TestDocumentHandler.MethodName, request, CancellationToken.None)); + await server.AssertServerShuttingDownAsync(); } internal record TestRequestTypeOne([property: JsonPropertyName("textDocument"), JsonRequired] TextDocumentIdentifier TextDocumentIdentifier); @@ -151,6 +163,28 @@ public Task HandleRequestAsync(TestRequestTypeOne request, RequestContex } } + [ExportCSharpVisualBasicStatelessLspService(typeof(TestNonMutatingDocumentHandler)), PartNotDiscoverable, Shared] + [LanguageServerEndpoint(MethodName, LanguageServerConstants.DefaultLanguageName)] + [method: ImportingConstructor] + [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + internal sealed class TestNonMutatingDocumentHandler() : ILspServiceDocumentRequestHandler + { + public const string MethodName = nameof(TestNonMutatingDocumentHandler); + + public bool MutatesSolutionState => false; + public bool RequiresLSPSolution => true; + + public TextDocumentIdentifier GetTextDocumentIdentifier(TestRequestTypeOne request) + { + return request.TextDocumentIdentifier; + } + + public Task HandleRequestAsync(TestRequestTypeOne request, RequestContext context, CancellationToken cancellationToken) + { + return Task.FromResult(this.GetType().Name); + } + } + [ExportCSharpVisualBasicStatelessLspService(typeof(TestRequestHandlerWithNoParams)), PartNotDiscoverable, Shared] [LanguageServerEndpoint(MethodName, LanguageServerConstants.DefaultLanguageName)] [method: ImportingConstructor] diff --git a/src/LanguageServer/ProtocolUnitTests/Miscellaneous/LspMiscellaneousFilesWorkspaceTests.cs b/src/LanguageServer/ProtocolUnitTests/Miscellaneous/LspMiscellaneousFilesWorkspaceTests.cs index 0e953e623948d..8374320d9f140 100644 --- a/src/LanguageServer/ProtocolUnitTests/Miscellaneous/LspMiscellaneousFilesWorkspaceTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/Miscellaneous/LspMiscellaneousFilesWorkspaceTests.cs @@ -214,12 +214,14 @@ void M() public async Task TestLooseFile_OpenedWithLanguageId(bool mutatingLspWorkspace) { var source = -@"class A -{ - void M() - { - } -}"; + """ + class A + { + void M() + { + } + } + """; // Create a server that supports LSP misc files and verify no misc files present. await using var testLspServer = await CreateTestLspServerAsync(string.Empty, mutatingLspWorkspace, new InitializationOptions { ServerKind = WellKnownLspServerKinds.CSharpVisualBasicLspServer }); @@ -240,6 +242,56 @@ void M() Assert.Equal(LanguageNames.CSharp, miscDoc.Project.Language); } + [Theory, CombinatorialData] + public async Task TestLooseFile_OpenedWithLanguageIdWithSubsequentRequest(bool mutatingLspWorkspace) + { + var source = + """ + class A + { + void M() + { + A a = new A(); + } + } + """; + + // Create a server that supports LSP misc files and verify no misc files present. + await using var testLspServer = await CreateTestLspServerAsync(string.Empty, mutatingLspWorkspace, new InitializationOptions { ServerKind = WellKnownLspServerKinds.CSharpVisualBasicLspServer }); + Assert.Null(GetMiscellaneousDocument(testLspServer)); + + // Open an empty loose file that hasn't been saved with a name. + +#pragma warning disable RS0030 // Do not use banned APIs + var looseFileUri = new Uri("untitled:untitledFile"); +#pragma warning restore + + await testLspServer.OpenDocumentAsync(looseFileUri, source, languageId: "csharp").ConfigureAwait(false); + // Make an immediate followup request as soon as we queue the didOpen. + // This should succeed and use the language from the didOpen. + var result = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentDefinitionName, + CreateTextDocumentPositionParams(new LSP.Location + { + Uri = looseFileUri, + Range = new LSP.Range + { + Start = new(4, 8) + } + }), CancellationToken.None); + + // Verify file was added to the misc file workspace. + await AssertFileInMiscWorkspaceAsync(testLspServer, looseFileUri).ConfigureAwait(false); + var miscDoc = GetMiscellaneousDocument(testLspServer); + AssertEx.NotNull(miscDoc); + Assert.Equal(LanguageNames.CSharp, miscDoc.Project.Language); + + // Verify GTD request succeeded. + Assert.Equal(0, result.Single().Range.Start.Line); + Assert.Equal(6, result.Single().Range.Start.Character); + Assert.Equal(0, result.Single().Range.End.Line); + Assert.Equal(7, result.Single().Range.End.Character); + } + private static async Task AssertFileInMiscWorkspaceAsync(TestLspServer testLspServer, Uri fileUri) { var (lspWorkspace, _, _) = await testLspServer.GetManager().GetLspDocumentInfoAsync(new LSP.TextDocumentIdentifier { Uri = fileUri }, CancellationToken.None); diff --git a/src/VisualStudio/Xaml/Impl/Implementation/LanguageServer/XamlRequestExecutionQueue.cs b/src/VisualStudio/Xaml/Impl/Implementation/LanguageServer/XamlRequestExecutionQueue.cs index a1f82aee85ac9..d973ca8e34384 100644 --- a/src/VisualStudio/Xaml/Impl/Implementation/LanguageServer/XamlRequestExecutionQueue.cs +++ b/src/VisualStudio/Xaml/Impl/Implementation/LanguageServer/XamlRequestExecutionQueue.cs @@ -23,7 +23,6 @@ public XamlRequestExecutionQueue( _projectService = projectService; } - [Obsolete] protected internal override void BeforeRequest(TRequest request) { if (request is ITextDocumentParams textDocumentParams && From b2cd0f5a4ebbf486116e2468f9328fd0a8c01b4b Mon Sep 17 00:00:00 2001 From: Orachor Date: Tue, 9 Jul 2024 21:04:28 +0200 Subject: [PATCH 51/59] Fix UseNullPropagationCodeFixProvider for parenthesized property access --- .../UseNullPropagationTests.cs | 40 +++++++++++++++++++ ...stractUseNullPropagationCodeFixProvider.cs | 7 ++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs b/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs index aa9353c212a0b..fd23f28af5bf6 100644 --- a/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs +++ b/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs @@ -1949,6 +1949,46 @@ void M(object o) """); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74273")] + public async Task TestParenthesizedPropertyAccess() + { + await TestInRegularAndScript1Async(""" + using System; + + class C + { + int? Length(Array array) => [|array == null ? null : (array.Length)|]; + } + """, """ + using System; + + class C + { + int? Length(Array array) => (array?.Length); + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74273")] + public async Task TestReversedParenthesizedPropertyAccess() + { + await TestInRegularAndScript1Async(""" + using System; + + class C + { + int? Length(Array array) => [|array != null ? (array.Length) : null|]; + } + """, """ + using System; + + class C + { + int? Length(Array array) => (array?.Length); + } + """); + } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] public async Task TestParenthesizedNull() { diff --git a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs index d4c1209b43121..492219688d700 100644 --- a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs @@ -102,9 +102,8 @@ private void FixConditionalExpression( var conditionalPart = root.FindNode(diagnostic.AdditionalLocations[1].SourceSpan, getInnermostNodeForTie: true); var whenPart = root.FindNode(diagnostic.AdditionalLocations[2].SourceSpan, getInnermostNodeForTie: true); syntaxFacts.GetPartsOfConditionalExpression( - conditionalExpression, out var condition, out var whenTrue, out var whenFalse); + conditionalExpression, out _, out var whenTrue, out _); whenTrue = syntaxFacts.WalkDownParentheses(whenTrue); - whenFalse = syntaxFacts.WalkDownParentheses(whenFalse); var whenPartIsNullable = diagnostic.Properties.ContainsKey(UseNullPropagationConstants.WhenPartIsNullable); editor.ReplaceNode( @@ -116,12 +115,14 @@ private void FixConditionalExpression( var currentWhenPartToCheck = whenPart == whenTrue ? currentWhenTrue : currentWhenFalse; + var unwrappedCurrentWhenPartToCheck = syntaxFacts.WalkDownParentheses(currentWhenPartToCheck); + var match = AbstractUseNullPropagationDiagnosticAnalyzer< TSyntaxKind, TExpressionSyntax, TStatementSyntax, TConditionalExpressionSyntax, TBinaryExpressionSyntax, TInvocationExpressionSyntax, TConditionalAccessExpressionSyntax, TElementAccessExpressionSyntax, TMemberAccessExpressionSyntax, TIfStatementSyntax, TExpressionStatementSyntax>.GetWhenPartMatch( - syntaxFacts, semanticModel, (TExpressionSyntax)conditionalPart, (TExpressionSyntax)currentWhenPartToCheck, cancellationToken); + syntaxFacts, semanticModel, (TExpressionSyntax)conditionalPart, (TExpressionSyntax)unwrappedCurrentWhenPartToCheck, cancellationToken); if (match == null) { return conditionalExpression; From 6ceee073027b99f6c84d5e73672bcdb3918d9b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Tue, 9 Jul 2024 13:35:05 -0700 Subject: [PATCH 52/59] Remove fallbacks (#74041) --- .../CSharpAnalyzerOptionsProvider.cs | 4 +- .../CSharpAddBracesCodeFixProvider.cs | 2 +- .../AddInheritdocCodeFixProvider.cs | 4 +- ...tractAssignOutParametersCodeFixProvider.cs | 2 +- .../ConvertNamespaceCodeFixProvider.cs | 4 +- ...tchStatementToExpressionCodeFixProvider.cs | 2 +- .../CSharpConvertToRecordCodeFixProvider.cs | 2 +- .../ConvertToRecord/ConvertToRecordEngine.cs | 6 +- ...DisambiguateSameVariableCodeFixProvider.cs | 2 +- ...rpFixIncorrectConstraintCodeFixProvider.cs | 2 +- .../CSharpFixReturnTypeCodeFixProvider.cs | 2 +- ...BaseCodeFixProvider.AddNewKeywordAction.cs | 5 +- .../HideBase/HideBaseCodeFixProvider.cs | 2 +- .../CSharpInlineDeclarationCodeFixProvider.cs | 4 +- ...ateWithConditionalAccessCodeFixProvider.cs | 2 +- ...eAnonymousFunctionStaticCodeFixProvider.cs | 2 +- .../MakeLocalFunctionStaticCodeFixHelper.cs | 6 +- .../MakeLocalFunctionStaticCodeFixProvider.cs | 2 +- ...uredVariablesAsArgumentsCodeFixProvider.cs | 6 +- ...CSharpMakeMemberRequiredCodeFixProvider.cs | 2 +- ...akeStatementAsynchronousCodeFixProvider.cs | 2 +- ...MakeStructFieldsWritableCodeFixProvider.cs | 2 +- ...MakeStructMemberReadOnlyCodeFixProvider.cs | 1 - ...CSharpMakeStructReadOnlyCodeFixProvider.cs | 1 - ...MisplacedUsingDirectivesCodeFixProvider.cs | 2 +- ...beddedStatementPlacementCodeFixProvider.cs | 8 +- .../CSharpDeclareAsNullableCodeFixProvider.cs | 1 - ...arpRemoveUnnecessaryCastCodeFixProvider.cs | 2 +- ...essaryDiscardDesignationCodeFixProvider.cs | 2 +- ...ecessaryLambdaExpressionCodeFixProvider.cs | 2 +- ...cessaryNullableDirectiveCodeFixProvider.cs | 1 - ...arpRemoveUnreachableCodeCodeFixProvider.cs | 2 +- ...emoveUnusedLocalFunctionCodeFixProvider.cs | 2 +- ...pSimplifyPropertyPatternCodeFixProvider.cs | 2 +- ...rpTransposeRecordKeywordCodeFixProvider.cs | 2 +- .../CSharpCollectionExpressionRewriter.cs | 1 - ...ectionExpressionForArrayCodeFixProvider.cs | 2 - ...tionExpressionForBuilderCodeFixProvider.cs | 2 - ...ctionExpressionForCreateCodeFixProvider.cs | 2 - ...ectionExpressionForEmptyCodeFixProvider.cs | 1 - ...ctionExpressionForFluentCodeFixProvider.cs | 5 +- ...nExpressionForStackAllocCodeFixProvider.cs | 2 - ...UseCollectionInitializerCodeFixProvider.cs | 6 +- ...zerCodeFixProvider_CollectionExpression.cs | 2 - ...mpoundCoalesceAssignmentCodeFixProvider.cs | 2 +- .../CSharpUseDeconstructionCodeFixProvider.cs | 2 +- .../CSharpUseDefaultLiteralCodeFixProvider.cs | 2 +- .../UseExpressionBodyCodeFixProvider.cs | 2 +- ...eExpressionBodyForLambdaCodeFixProvider.cs | 8 +- ...seImplicitObjectCreationCodeFixProvider.cs | 2 +- .../UseExplicitTypeCodeFixProvider.cs | 2 +- .../UseImplicitTypeCodeFixProvider.cs | 2 +- .../CSharpUseIndexOperatorCodeFixProvider.cs | 2 +- .../CSharpUseRangeOperatorCodeFixProvider.cs | 2 +- ...terpolatedVerbatimStringCodeFixProvider.cs | 2 +- ...rCastAndEqualityOperatorCodeFixProvider.cs | 2 +- ...seNullCheckOverTypeCheckCodeFixProvider.cs | 2 +- .../CSharpUseLocalFunctionCodeFixProvider.cs | 4 +- ...harpUseNameofInAttributeCodeFixProvider.cs | 1 - ...arpUsePatternCombinatorsCodeFixProvider.cs | 2 +- .../CSharpAsAndMemberAccessCodeFixProvider.cs | 2 +- .../CSharpAsAndNullCheckCodeFixProvider.cs | 2 +- .../CSharpIsAndCastCheckCodeFixProvider.cs | 2 +- .../CSharpUseNotPatternCodeFixProvider.cs | 2 +- .../UseSimpleUsingStatementCodeFixProvider.cs | 2 +- .../UseThrowExpressionCodeFixProvider.cs | 2 +- .../CSharpUseTupleSwapCodeFixProvider.cs | 2 +- .../UseUtf8StringLiteralCodeFixProvider.cs | 2 +- ...ddAccessibilityModifiersCodeFixProvider.cs | 2 +- ...dAnonymousTypeMemberNameCodeFixProvider.cs | 2 +- .../AbstractAddExplicitCastCodeFixProvider.cs | 1 - ...ractAddObsoleteAttributeCodeFixProvider.cs | 2 +- .../AddRequiredParenthesesCodeFixProvider.cs | 2 +- ...stractAliasAmbiguousTypeCodeFixProvider.cs | 2 +- ...actConvertTypeOfToNameOfCodeFixProvider.cs | 2 +- .../AbstractFileHeaderCodeFixProvider.cs | 12 +-- .../AbstractForEachCastCodeFixProvider.cs | 2 +- .../Formatting/FormattingCodeFixProvider.cs | 6 +- ...bstractMakeFieldReadonlyCodeFixProvider.cs | 2 +- ...AbstractMakeMemberStaticCodeFixProvider.cs | 2 +- ...AbstractMakeTypeAbstractCodeFixProvider.cs | 2 +- .../AbstractMakeTypePartialCodeFixProvider.cs | 2 +- ...derCodeFixProvider.CustomFixAllProvider.cs | 8 +- ...geNamespaceToMatchFolderCodeFixProvider.cs | 6 +- ...cutiveStatementPlacementCodeFixProvider.cs | 12 +-- .../AbstractOrderModifiersCodeFixProvider.cs | 2 +- .../AbstractPopulateSwitchCodeFixProvider.cs | 2 +- ...tractQualifyMemberAccessCodeFixProvider.cs | 2 +- ...tractRemoveAsyncModifierCodeFixProvider.cs | 2 +- .../RemoveRedundantEqualityCodeFixProvider.cs | 1 - ...RemoveUnnecessaryImportsCodeFixProvider.cs | 5 +- ...veUnnecessaryParenthesesCodeFixProvider.cs | 2 +- ...aryAttributeSuppressionsCodeFixProvider.cs | 2 +- ...essaryPragmaSuppressionsCodeFixProvider.cs | 2 +- ...tractRemoveUnusedMembersCodeFixProvider.cs | 2 +- ...stractRemoveUnusedValuesCodeFixProvider.cs | 4 +- .../SimplifyConditionalCodeFixProvider.cs | 1 - ...actSimplifyInterpolationCodeFixProvider.cs | 2 +- ...SimplifyLinqExpressionCodeFixProvider`3.cs | 2 +- ...UpdateLegacySuppressionsCodeFixProvider.cs | 2 +- ...nForIfNullStatementCheckCodeFixProvider.cs | 2 +- ...eTernaryConditionalCheckCodeFixProvider.cs | 2 +- ...rTernaryConditionalCheckCodeFixProvider.cs | 2 +- ...UseCollectionInitializerCodeFixProvider.cs | 5 +- ...actUseCompoundAssignmentCodeFixProvider.cs | 2 +- ...UseConditionalExpressionCodeFixProvider.cs | 4 +- .../UseExplicitTupleNameCodeFixProvider.cs | 2 +- ...actUseInferredMemberNameCodeFixProvider.cs | 2 +- ...IsNullForReferenceEqualsCodeFixProvider.cs | 2 +- ...stractUseNullPropagationCodeFixProvider.cs | 2 +- ...ractUseObjectInitializerCodeFixProvider.cs | 1 - .../UseSystemHashCodeCodeFixProvider.cs | 2 +- .../VisualBasicAnalyzerOptionsProvider.vb | 2 +- ...icRemoveUnnecessaryByValCodeFixProvider.vb | 2 +- ...sicRemoveUnnecessaryCastCodeFixProvider.vb | 1 - ...icSimplifyObjectCreationCodeFixProvider.vb | 2 +- ...UseCollectionInitializerCodeFixProvider.vb | 1 - ...lBasicUseIsNotExpressionCodeFixProvider.vb | 1 - .../CSharpChangeSignatureCommandHandler.cs | 2 +- .../EncapsulateFieldCommandHandler.cs | 4 +- ...EventHookupCommandHandler_TabKeyCommand.cs | 8 +- .../EventHookup/EventHookupSessionManager.cs | 6 +- ...HookupSessionManager_EventHookupSession.cs | 4 - .../CSharpEditorInlineRenameService.cs | 6 +- .../DeclarationNameCompletionProviderTests.cs | 54 +++++----- .../PartialMethodCompletionProviderTests.cs | 21 ++-- .../EncapsulateFieldTestState.cs | 8 +- .../CSharpTest/Intents/IntentTestsBase.cs | 5 +- .../AbstractAddImportsPasteCommandHandler.cs | 2 +- .../AbstractChangeSignatureCommandHandler.cs | 5 +- .../AbstractEncapsulateFieldCommandHandler.cs | 4 +- ...AddMissingImportsFeatureServiceAccessor.cs | 2 +- ...neRenameService.InlineRenameLocationSet.cs | 7 +- ...torInlineRenameService.SymbolRenameInfo.cs | 5 +- .../AbstractEditorInlineRenameService.cs | 7 +- .../Intents/DeleteParameterIntentProvider.cs | 6 +- .../EditorHoverCreationService.cs | 2 +- .../Core/Options/TextBufferOptionProviders.cs | 4 +- .../ChangeSignatureTestState.cs | 4 +- .../CodeGeneration/CodeGenerationTests.cs | 50 ++++------ .../Formatting/InferredIndentationTests.cs | 6 +- .../Test2/Rename/RenameEngineResult.vb | 4 +- .../AbstractCompletionProviderTests.cs | 8 +- ...stractNewDocumentFormattingServiceTests.cs | 2 +- ...isualBasicChangeSignatureCommandHandler.vb | 4 +- .../EncapsulateFieldCommandHandler.vb | 3 +- .../VisualBasicEditorInlineRenameService.vb | 4 +- ...NavigationBarItemService_CodeGeneration.vb | 14 +-- ...tAbstractClassOrInterfaceCommandHandler.vb | 2 +- .../ChangeSignature/RemoveParametersTests.vb | 3 +- .../EncapsulateFieldCommandHandlerTests.vb | 1 - .../EncapsulateFieldTestState.vb | 1 - .../CSharpChangeSignatureService.cs | 7 +- .../GenerateEnumMemberCodeFixProvider.cs | 4 +- .../GenerateConversionCodeFixProvider.cs | 4 +- ...enerateDeconstructMethodCodeFixProvider.cs | 2 +- .../GenerateMethodCodeFixProvider.cs | 4 +- .../GenerateTypeCodeFixProvider.cs | 4 +- ...FunctionToMethodCodeRefactoringProvider.cs | 5 +- ...eCodeRefactoringProvider.FixAllProvider.cs | 3 +- .../EnableNullableCodeRefactoringProvider.cs | 19 ++-- .../DeclarationNameRecommender.cs | 2 +- ...tyToFullPropertyCodeRefactoringProvider.cs | 3 +- ...ConvertNamespaceCodeRefactoringProvider.cs | 4 +- ...gularConstructorCodeRefactoringProvider.cs | 3 +- ...vertProgramTransform_TopLevelStatements.cs | 4 +- .../ConvertToProgramMainCodeFixProvider.cs | 6 +- ...ertToProgramMainCodeRefactoringProvider.cs | 2 +- ...vertToTopLevelStatementsCodeFixProvider.cs | 6 +- ...pLevelStatementsCodeRefactoringProvider.cs | 4 +- ...SharpConvertToRecordRefactoringProvider.cs | 2 +- .../CSharpEncapsulateFieldService.cs | 5 +- .../GenerateConstructorCodeFixProvider.cs | 4 +- ...uctorFromMembersCodeRefactoringProvider.cs | 2 +- .../GenerateType/CSharpGenerateTypeService.cs | 4 +- .../CSharpGenerateVariableCodeFixProvider.cs | 4 +- ...tructorParameterCodeRefactoringProvider.cs | 2 +- ...ParameterCodeRefactoringProvider_Update.cs | 2 +- ...alFunctionStaticCodeRefactoringProvider.cs | 2 +- ...CSharpReplacePropertyWithMethodsService.cs | 3 +- ...seExpressionBodyCodeRefactoringProvider.cs | 4 +- ...sAndCastCheckWithoutNameCodeFixProvider.cs | 2 +- .../Wrapping/CSharpSyntaxWrappingOptions.cs | 14 +-- .../CSharpWrappingCodeRefactoringProvider.cs | 4 +- ...romMembersCodeRefactoringProvider.State.cs | 6 +- ...etersFromMembersCodeRefactoringProvider.cs | 10 +- ...actAddFileBannerCodeRefactoringProvider.cs | 2 +- .../AbstractAddImportCodeFixProvider.cs | 2 +- ...tChangeSignatureCodeRefactoringProvider.cs | 2 +- .../AbstractChangeSignatureService.cs | 12 +-- .../ChangeSignatureAnalyzedContext.cs | 3 +- .../AbstractGenerateMemberCodeFixProvider.cs | 4 +- ...ppressionCodeFixProvider.FixAllProvider.cs | 8 +- ...r.GlobalSuppressMessageFixAllCodeAction.cs | 21 ++-- ...actAddMissingImportsRefactoringProvider.cs | 2 +- .../AbstractMoveTypeService.MoveTypeEditor.cs | 4 +- .../AbstractChangeNamespaceService.cs | 39 +++----- ...actSyncNamespaceCodeRefactoringProvider.cs | 2 +- .../Portable/Completion/CompletionOptions.cs | 2 - ...stractMemberInsertingCompletionProvider.cs | 15 +-- .../AbstractImportCompletionProvider.cs | 6 +- ...ymousTypeToClassCodeRefactoringProvider.cs | 8 +- ...tyToFullPropertyCodeRefactoringProvider.cs | 9 +- ...ertTupleToStructCodeRefactoringProvider.cs | 34 +++---- ...ertTupleToStructCodeRefactoringProvider.cs | 2 +- ...vertTupleToStructCodeRefactoringService.cs | 23 ----- .../AbstractJsonDetectionCodeFixProvider.cs | 2 +- .../AbstractEncapsulateFieldService.cs | 58 +++++------ .../EncapsulateFieldRefactoringProvider.cs | 2 +- .../IRemoteEncapsulateFieldService.cs | 23 ----- ...AbstractExtractClassRefactoringProvider.cs | 4 +- .../ExtractClassWithDialogCodeAction.cs | 6 +- .../AbstractExtractInterfaceService.cs | 8 +- ...parisonOperatorsCodeRefactoringProvider.cs | 8 +- ...rovider.ConstructorDelegatingCodeAction.cs | 9 +- ...oringProvider.FieldDelegatingCodeAction.cs | 9 +- ...GenerateConstructorWithDialogCodeAction.cs | 12 +-- ...romMembersCodeRefactoringProvider.State.cs | 6 +- ...uctorFromMembersCodeRefactoringProvider.cs | 24 ++--- ...nerateDefaultConstructorCodeFixProvider.cs | 2 +- ...tConstructorsService.AbstractCodeAction.cs | 8 +- ...teDefaultConstructorsService.CodeAction.cs | 4 +- ...efaultConstructorsService.CodeActionAll.cs | 3 +- ...tractGenerateDefaultConstructorsService.cs | 5 +- ...aultConstructorsCodeRefactoringProvider.cs | 2 +- .../IGenerateDefaultConstructorsService.cs | 2 +- .../GenerateEqualsAndGetHashCodeAction.cs | 6 +- ...hCodeFromMembersCodeRefactoringProvider.cs | 35 +++---- ...nerateEqualsAndHashWithDialogCodeAction.cs | 4 +- ...bstractGenerateConstructorService.State.cs | 19 ++-- .../AbstractGenerateConstructorService.cs | 4 +- .../IGenerateConstructorService.cs | 2 +- ...actGenerateEnumMemberService.CodeAction.cs | 9 +- .../AbstractGenerateEnumMemberService.cs | 4 +- .../IGenerateEnumMemberService.cs | 3 +- .../AbstractGenerateConversionService.cs | 3 +- ...bstractGenerateDeconstructMethodService.cs | 3 +- .../AbstractGenerateMethodService.cs | 3 +- ...teParameterizedMemberService.CodeAction.cs | 9 +- ...tractGenerateParameterizedMemberService.cs | 10 +- .../IGenerateConversionService.cs | 3 +- .../IGenerateDeconstructMemberService.cs | 2 +- .../IGenerateParameterizedMemberService.cs | 2 +- ...tractGenerateVariableService.CodeAction.cs | 8 +- ...VariableService.GenerateLocalCodeAction.cs | 5 +- .../AbstractGenerateVariableService.cs | 53 +++++----- .../IGenerateVariableService.cs | 3 +- ...enerateOverridesCodeRefactoringProvider.cs | 2 +- .../GenerateOverridesWithDialogCodeAction.cs | 7 +- .../AbstractGenerateTypeService.CodeAction.cs | 11 +-- .../AbstractGenerateTypeService.Editor.cs | 24 ++--- .../AbstractGenerateTypeService.cs | 14 ++- .../GenerateType/IGenerateTypeService.cs | 2 +- .../ImplementAbstractClassData.cs | 2 +- ...actImplementInterfaceService.CodeAction.cs | 3 +- ...terfaceService.DisposePatternCodeAction.cs | 4 +- ...erCodeRefactoringProviderMemberCreation.cs | 35 +++---- ...troduceParameterCodeRefactoringProvider.cs | 10 +- .../IntroduceParameterDocumentRewriter.cs | 4 +- ...ntroduceVariableCodeRefactoringProvider.cs | 2 +- .../AbstractMetadataAsSourceService.cs | 3 +- ...actMoveStaticMembersRefactoringProvider.cs | 2 +- .../MoveStaticMembersWithDialogCodeAction.cs | 9 +- .../AbstractMoveToNamespaceService.cs | 5 +- .../PreferFrameworkTypeCodeFixProvider.cs | 2 +- ...AbstractPullMemberUpRefactoringProvider.cs | 4 +- .../PullMemberUpWithDialogCodeAction.cs | 6 +- .../Portable/PullMemberUp/MembersPuller.cs | 16 ++- ...ractRemoveUnusedVariableCodeFixProvider.cs | 2 +- ...thodWithPropertyCodeRefactoringProvider.cs | 13 +-- ...stractReplacePropertyWithMethodsService.cs | 2 +- .../IReplacePropertyWithMethodsService.cs | 1 - ...pertyWithMethodsCodeRefactoringProvider.cs | 10 +- .../Shared/Extensions/DocumentExtensions.cs | 16 +-- .../Shared/Utilities/ExtractTypeHelpers.cs | 10 +- ...AbstractSimplifyThisOrMeCodeFixProvider.cs | 2 +- ...bstractSimplifyTypeNamesCodeFixProvider.cs | 2 +- .../AbstractSnippetProvider.cs | 2 +- .../AbstractUseAutoPropertyCodeFixProvider.cs | 2 +- ...AbstractWrappingCodeRefactoringProvider.cs | 4 +- .../AspNetCoreAddPackageCodeAction.cs | 4 +- .../OmniSharp/Rename/OmniSharpRenamer.cs | 2 +- .../VisualBasicChangeSignatureService.vb | 6 +- .../GenerateEnumMemberCodeFixProvider.vb | 4 +- ...GenerateEventCodeFixProvider.CodeAction.vb | 8 +- .../GenerateEventCodeFixProvider.vb | 8 +- .../GenerateConversionCodeFixProvider.vb | 4 +- ...erateParameterizedMemberCodeFixProvider.vb | 4 +- .../GenerateTypeCodeFixProvider.vb | 4 +- ...lBasicConvertAutoPropertyToFullProperty.vb | 2 +- .../VisualBasicEncapsulateFieldService.vb | 1 - .../GenerateConstructorCodeFixProvider.vb | 4 +- ...uctorFromMembersCodeRefactoringProvider.vb | 2 +- .../VisualBasicGenerateTypeService.vb | 3 +- ...ualBasicGenerateVariableCodeFixProvider.vb | 4 +- ...eSharedFromModuleMembersCodeFixProvider.vb | 2 +- .../VisualBasicReplacePropertyWithMethods.vb | 1 - .../VisualBasicSyntaxWrappingOptions.vb | 11 +-- ...ualBasicWrappingCodeRefactoringProvider.vb | 4 +- .../Razor/FormatNewFileHandler.cs | 2 +- .../AddImportPlacementOptionsStorage.cs | 19 ---- .../Options/CodeCleanupOptionsStorage.cs | 19 ---- .../Options/CodeGenerationOptionsStorage.cs | 28 ------ .../Options/CompletionOptionsStorage.cs | 1 - .../DocumentFormattingOptionsStorage.cs | 19 ---- .../GlobalCodeActionOptionsProvider.cs | 2 +- .../Options/LineFormattingOptionsStorage.cs | 19 ---- .../Protocol/Handler/Rename/RenameHandler.cs | 20 ++-- .../Options/LspOptionsTests.cs | 4 +- .../Razor/Cohost/Handlers/Rename.cs | 7 +- .../Implementation/AbstractEditorFactory.cs | 3 +- ...anguage.IVsContainedLanguageCodeSupport.cs | 5 +- .../Def/Venus/ContainedLanguageCodeSupport.cs | 13 +-- .../Core/Impl/CodeModel/FileCodeModel.cs | 5 +- .../InternalElements/AbstractCodeElement.cs | 5 +- .../Impl/CodeModel/ProjectCodeModelFactory.cs | 4 - .../CSharpContainedLanguageSupportTests.vb | 8 -- ...isualBasicContainedLanguageSupportTests.vb | 9 -- .../Venus/VisualBasicContainedLanguage.vb | 1 - .../CSharpSimplificationService.cs | 2 +- .../IChangeNamespaceService.cs | 4 +- .../Core/Portable/CodeActions/CodeAction.cs | 10 +- .../CodeActions/CodeAction_Cleanup.cs | 3 +- .../DocumentBasedFixAllProviderHelpers.cs | 1 - .../Core/Portable/Editing/ImportAdder.cs | 2 +- .../ExtractMethod/ExtractMethodOptions.cs | 4 +- .../Core/Portable/Formatting/Formatter.cs | 2 +- .../VisualBasicSyntaxFormattingOptions.cs | 4 +- ...anCodeGenerationOptionsWorkspaceService.cs | 18 ---- ...GlobalCodeActionOptionsWorkspaceService.cs | 64 ------------ .../ConflictResolver.Session.cs | 5 +- .../Rename/ConflictEngine/ConflictResolver.cs | 12 +-- .../ConflictEngine/RenamedSpansTracker.cs | 4 +- .../Portable/Rename/IRemoteRenamerService.cs | 19 ---- .../Rename/LightweightRenameLocations.cs | 4 +- .../Renamer.SyncNamespaceDocumentAction.cs | 10 +- .../Core/Portable/Rename/Renamer.cs | 28 ++---- .../Workspaces/TestWorkspace`1.cs | 3 + .../Remote/Core/ServiceDescriptors.cs | 6 +- ...vertTupleToStructCodeRefactoringService.cs | 23 ++--- .../RemoteEncapsulateFieldService.cs | 12 +-- .../Services/Renamer/RemoteRenamerService.cs | 19 ++-- .../CSharpCodeGenerationOptions.cs | 24 ++--- .../Formatting/CSharpSyntaxFormatting.cs | 2 +- .../CSharpSyntaxFormattingOptions.cs | 84 ++++++++-------- .../Simplification/CSharpSimplification.cs | 2 +- .../Simplification/CSharpSimplifierOptions.cs | 18 ++-- .../AddImport/AddImportPlacementOptions.cs | 11 +-- .../Core/CodeCleanup/CodeCleanupOptions.cs | 22 +---- .../CleanCodeGenerationOptions.cs | 18 +--- .../CodeGeneration/CodeGenerationOptions.cs | 31 +++--- .../Formatting/DocumentFormattingOptions.cs | 22 ++--- .../Core/Formatting/LineFormattingOptions.cs | 23 ++--- .../Formatting/SyntaxFormattingOptions.cs | 17 ++-- .../Core/NamingStyles/NamingStyleOptions.cs | 15 +-- .../Options/EditorConfigValueSerializer`1.cs | 5 +- .../Compiler/Core/Options/IOptionReader.cs | 6 ++ .../Core/Simplification/SimplifierOptions.cs | 14 +-- .../VisualBasicSimplifierOptions.cs | 4 +- .../VisualBasicSimplification.vb | 2 +- .../CSharpCodeFixOptionsProvider.cs | 99 ++++--------------- .../CSharpCodeGenerationService.cs | 4 +- .../CSharpAddImportsService.cs | 4 +- .../AddImportPlacementOptionsProviders.cs | 6 +- .../CodeActions/CodeFixOptionsProvider.cs | 63 ++---------- ...ForkingSyntaxEditorBasedCodeFixProvider.cs | 3 - .../SyntaxEditorBasedCodeFixProvider.cs | 13 ++- .../AbstractCodeGenerationService.cs | 6 +- .../CodeGeneration/CodeGenerationContext.cs | 6 +- .../CodeGeneration/ICodeGenerationService.cs | 2 +- .../VisualBasicCodeGenerationOptions.cs | 4 +- .../AddImports/AbstractAddImportsService.cs | 14 +-- .../AddImports/IAddImportsService.cs | 2 +- .../Core/Utilities/ParsedDocument.cs | 1 + .../VisualBasicAddImportsService.vb | 4 +- .../VisualBasicCodeGenerationService.vb | 4 +- .../Formatting/VisualBasicSyntaxFormatting.vb | 2 +- .../VisualBasicSimplificationService.vb | 2 +- 378 files changed, 929 insertions(+), 1714 deletions(-) delete mode 100644 src/LanguageServer/Protocol/Features/Options/AddImportPlacementOptionsStorage.cs delete mode 100644 src/LanguageServer/Protocol/Features/Options/CodeCleanupOptionsStorage.cs delete mode 100644 src/LanguageServer/Protocol/Features/Options/CodeGenerationOptionsStorage.cs delete mode 100644 src/LanguageServer/Protocol/Features/Options/DocumentFormattingOptionsStorage.cs delete mode 100644 src/LanguageServer/Protocol/Features/Options/LineFormattingOptionsStorage.cs delete mode 100644 src/Workspaces/Core/Portable/Options/ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService.cs delete mode 100644 src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs diff --git a/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs b/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs index 4413bf53ca539..0bd7b8598310b 100644 --- a/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs +++ b/src/Analyzers/CSharp/Analyzers/CodeStyle/CSharpAnalyzerOptionsProvider.cs @@ -29,7 +29,7 @@ internal readonly struct CSharpAnalyzerOptionsProvider(IOptionsReader options) public CodeStyleOption2 PreferBraces => GetOption(CSharpCodeStyleOptions.PreferBraces); internal CSharpSimplifierOptions GetSimplifierOptions() - => new(options, fallbackOptions: null); + => new(options); // SyntaxFormattingOptions @@ -73,7 +73,7 @@ internal CSharpSimplifierOptions GetSimplifierOptions() // CodeGenerationOptions internal CSharpCodeGenerationOptions GetCodeGenerationOptions() - => new(options, fallbackOptions: null); + => new(options); public CodeStyleOption2 PreferExpressionBodiedLambdas => GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas); public CodeStyleOption2 PreferReadOnlyStruct => GetOption(CSharpCodeStyleOptions.PreferReadOnlyStruct); diff --git a/src/Analyzers/CSharp/CodeFixes/AddBraces/CSharpAddBracesCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/AddBraces/CSharpAddBracesCodeFixProvider.cs index 0d7122a551717..ce87505e16a52 100644 --- a/src/Analyzers/CSharp/CodeFixes/AddBraces/CSharpAddBracesCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/AddBraces/CSharpAddBracesCodeFixProvider.cs @@ -35,7 +35,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var root = editor.OriginalRoot; foreach (var diagnostic in diagnostics) diff --git a/src/Analyzers/CSharp/CodeFixes/AddInheritdoc/AddInheritdocCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/AddInheritdoc/AddInheritdocCodeFixProvider.cs index 97a19eb02677d..b8bc2a6442d2a 100644 --- a/src/Analyzers/CSharp/CodeFixes/AddInheritdoc/AddInheritdocCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/AddInheritdoc/AddInheritdocCodeFixProvider.cs @@ -79,7 +79,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { string? newLine = null; SourceText? sourceText = null; @@ -93,7 +93,7 @@ protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var unassignedParameters = await GetUnassignedParametersAsync( document, diagnostics, cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/CSharp/CodeFixes/ConvertNamespace/ConvertNamespaceCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/ConvertNamespace/ConvertNamespaceCodeFixProvider.cs index a6ac61e24b48f..2007769def97e 100644 --- a/src/Analyzers/CSharp/CodeFixes/ConvertNamespace/ConvertNamespaceCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/ConvertNamespace/ConvertNamespaceCodeFixProvider.cs @@ -52,13 +52,13 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var diagnostic = diagnostics.First(); var namespaceDecl = (BaseNamespaceDeclarationSyntax)diagnostic.AdditionalLocations[0].FindNode(cancellationToken); - var options = await document.GetCSharpCodeFixOptionsProviderAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var converted = await ConvertNamespaceTransform.ConvertAsync(document, namespaceDecl, options.GetFormattingOptions(), cancellationToken).ConfigureAwait(false); editor.ReplaceNode( diff --git a/src/Analyzers/CSharp/CodeFixes/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs index 4c00de4eef8b5..97263cf4f55c8 100644 --- a/src/Analyzers/CSharp/CodeFixes/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionCodeFixProvider.cs @@ -54,7 +54,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(diagnostics.Length, out var spans); foreach (var diagnostic in diagnostics) diff --git a/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/CSharpConvertToRecordCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/CSharpConvertToRecordCodeFixProvider.cs index c6ba051fba87a..0db46321a101d 100644 --- a/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/CSharpConvertToRecordCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/CSharpConvertToRecordCodeFixProvider.cs @@ -46,7 +46,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) return; var action = await ConvertToRecordEngine.GetCodeActionAsync( - document, typeDeclaration, context.GetOptionsProvider(), cancellationToken).ConfigureAwait(false); + document, typeDeclaration, cancellationToken).ConfigureAwait(false); if (action != null) context.RegisterCodeFix(action, context.Diagnostics); diff --git a/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/ConvertToRecordEngine.cs b/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/ConvertToRecordEngine.cs index b785edb46c8f1..6efd82df26bf0 100644 --- a/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/ConvertToRecordEngine.cs +++ b/src/Analyzers/CSharp/CodeFixes/ConvertToRecord/ConvertToRecordEngine.cs @@ -31,7 +31,7 @@ internal static class ConvertToRecordEngine SyntaxRemoveOptions.AddElasticMarker; public static async Task GetCodeActionAsync( - Document document, TypeDeclarationSyntax typeDeclaration, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, TypeDeclarationSyntax typeDeclaration, CancellationToken cancellationToken) { // any type declared partial requires complex movement, don't offer refactoring if (typeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword)) @@ -70,7 +70,6 @@ internal static class ConvertToRecordEngine type, positionalParameterInfos, typeDeclaration, - fallbackOptions, cancellationToken), nameof(CSharpCodeFixesResources.Convert_to_positional_record)); // note: when adding nested actions, use string.Format(CSharpFeaturesResources.Convert_0_to_record, type.Name) as title string @@ -82,7 +81,6 @@ private static async Task ConvertToPositionalRecordAsync( INamedTypeSymbol type, ImmutableArray positionalParameterInfos, TypeDeclarationSyntax typeDeclaration, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -241,7 +239,7 @@ await RefactorInitializersAsync(type, solutionEditor, propertiesToAssign, cancel } } - var optionsProvider = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var optionsProvider = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var lineFormattingOptions = optionsProvider.GetLineFormattingOptions(); var modifiedClassTrivia = GetModifiedClassTrivia( diff --git a/src/Analyzers/CSharp/CodeFixes/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs index 1b6f217aa2ba8..2abf253e24c64 100644 --- a/src/Analyzers/CSharp/CodeFixes/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs @@ -137,7 +137,7 @@ where m.IsAccessibleWithin(enclosingType) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxFacts = CSharpSyntaxFacts.Instance; var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/CSharp/CodeFixes/FixIncorrectConstraint/CSharpFixIncorrectConstraintCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/FixIncorrectConstraint/CSharpFixIncorrectConstraintCodeFixProvider.cs index e613465d2b23a..e6666760eb187 100644 --- a/src/Analyzers/CSharp/CodeFixes/FixIncorrectConstraint/CSharpFixIncorrectConstraintCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/FixIncorrectConstraint/CSharpFixIncorrectConstraintCodeFixProvider.cs @@ -81,7 +81,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/CSharp/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs index 5d1de16881a7b..f0daf69247ea2 100644 --- a/src/Analyzers/CSharp/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/FixReturnType/CSharpFixReturnTypeCodeFixProvider.cs @@ -129,7 +129,7 @@ static bool IsVoid(TypeSyntax typeSyntax) return (declarationTypeToFix, fixedDeclaration); } - protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var (declarationTypeToFix, fixedDeclaration) = await TryGetOldAndNewReturnTypeAsync(document, diagnostics, cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.AddNewKeywordAction.cs b/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.AddNewKeywordAction.cs index 0c332830bd858..c6c2aa4a1bcfe 100644 --- a/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.AddNewKeywordAction.cs +++ b/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.AddNewKeywordAction.cs @@ -18,18 +18,17 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase; internal partial class HideBaseCodeFixProvider { - private class AddNewKeywordAction(Document document, SyntaxNode node, CodeActionOptionsProvider fallbackOptions) : CodeAction + private class AddNewKeywordAction(Document document, SyntaxNode node) : CodeAction { private readonly Document _document = document; private readonly SyntaxNode _node = node; - private readonly CodeActionOptionsProvider _fallbackOptions = fallbackOptions; public override string Title => CSharpCodeFixesResources.Hide_base_member; protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) { var root = await _document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var options = await _document.GetCSharpCodeFixOptionsProviderAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await _document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var newNode = GetNewNode(_node, options.PreferredModifierOrder.Value); var newRoot = root.ReplaceNode(_node, newNode); diff --git a/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.cs index 23104d5089746..a1a9c282c4214 100644 --- a/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/HideBase/HideBaseCodeFixProvider.cs @@ -46,6 +46,6 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) if (originalNode == null) return; - context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode, context.GetOptionsProvider()), context.Diagnostics); + context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics); } } diff --git a/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs index 34ac23b0be67a..49732b79122a2 100644 --- a/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs @@ -47,9 +47,9 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { - var options = await document.GetCSharpCodeFixOptionsProviderAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); // Gather all statements to be removed // We need this to find the statements we can safely attach trivia to diff --git a/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs index 137af59d50036..fe53a9bf2da42 100644 --- a/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs @@ -48,7 +48,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/MakeAnonymousFunctionStatic/CSharpMakeAnonymousFunctionStaticCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeAnonymousFunctionStatic/CSharpMakeAnonymousFunctionStaticCodeFixProvider.cs index 4691f825733e9..122513c0fc3b8 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeAnonymousFunctionStatic/CSharpMakeAnonymousFunctionStaticCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeAnonymousFunctionStatic/CSharpMakeAnonymousFunctionStaticCodeFixProvider.cs @@ -35,7 +35,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var generator = editor.Generator; diff --git a/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixHelper.cs b/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixHelper.cs index d2240442f6abf..adfd18228e12b 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixHelper.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixHelper.cs @@ -29,12 +29,11 @@ public static async Task MakeLocalFunctionStaticAsync( Document document, LocalFunctionStatementSyntax localFunction, ImmutableArray captures, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var syntaxEditor = new SyntaxEditor(root, document.Project.Solution.Services); - await MakeLocalFunctionStaticAsync(document, localFunction, captures, syntaxEditor, fallbackOptions, cancellationToken).ConfigureAwait(false); + await MakeLocalFunctionStaticAsync(document, localFunction, captures, syntaxEditor, cancellationToken).ConfigureAwait(false); return document.WithSyntaxRoot(syntaxEditor.GetChangedRoot()); } @@ -43,7 +42,6 @@ public static async Task MakeLocalFunctionStaticAsync( LocalFunctionStatementSyntax localFunction, ImmutableArray captures, SyntaxEditor syntaxEditor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -171,7 +169,7 @@ public static async Task MakeLocalFunctionStaticAsync( var info = new CSharpCodeGenerationContextInfo( CodeGenerationContext.Default, CSharpCodeGenerationOptions.Default, new CSharpCodeGenerationService(document.Project.GetExtendedLanguageServices().LanguageServices), root.SyntaxTree.Options.LanguageVersion()); #else - var info = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); #endif // Updates the local function declaration with variables passed in as parameters diff --git a/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs index 59747d0d61848..949282ecddc0f 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeFixProvider.cs @@ -35,7 +35,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) } protected override Task FixAllAsync( - Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var localFunctions = diagnostics.SelectAsArray(d => d.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken)); foreach (var localFunction in localFunctions) diff --git a/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs index ac4f5e1e8cbe0..7ba958a71a6da 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs @@ -44,7 +44,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( CSharpCodeFixesResources.Pass_in_captured_variables_as_arguments, - cancellationToken => MakeLocalFunctionStaticCodeFixHelper.MakeLocalFunctionStaticAsync(document, localFunction, captures, context.GetOptionsProvider(), cancellationToken), + cancellationToken => MakeLocalFunctionStaticCodeFixHelper.MakeLocalFunctionStaticAsync(document, localFunction, captures, cancellationToken), nameof(CSharpCodeFixesResources.Pass_in_captured_variables_as_arguments)), diagnostic); @@ -53,12 +53,12 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) context.CancellationToken); } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) => WrapFixAsync( document, diagnostics, (document, localFunction, captures) => MakeLocalFunctionStaticCodeFixHelper.MakeLocalFunctionStaticAsync( - document, localFunction, captures, editor, fallbackOptions, cancellationToken), + document, localFunction, captures, editor, cancellationToken), cancellationToken); // The purpose of this wrapper is to share some common logic between FixOne and FixAll. The main reason we chose diff --git a/src/Analyzers/CSharp/CodeFixes/MakeMemberRequired/CSharpMakeMemberRequiredCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeMemberRequired/CSharpMakeMemberRequiredCodeFixProvider.cs index 835ec2a1a3653..9497c77015b2e 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeMemberRequired/CSharpMakeMemberRequiredCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeMemberRequired/CSharpMakeMemberRequiredCodeFixProvider.cs @@ -110,7 +110,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) }; } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var root = editor.OriginalRoot; var generator = editor.Generator; diff --git a/src/Analyzers/CSharp/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs index c490d8e1d7355..848b7bc5a181e 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs @@ -52,7 +52,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs index 8a328a197cb16..db0495d70e4d6 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeStructFieldsWritable/CSharpMakeStructFieldsWritableCodeFixProvider.cs @@ -40,7 +40,7 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/MakeStructMemberReadOnly/CSharpMakeStructMemberReadOnlyCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeStructMemberReadOnly/CSharpMakeStructMemberReadOnlyCodeFixProvider.cs index 6cb4963dafa6d..e18ea95725837 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeStructMemberReadOnly/CSharpMakeStructMemberReadOnlyCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeStructMemberReadOnly/CSharpMakeStructMemberReadOnlyCodeFixProvider.cs @@ -37,7 +37,6 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var generator = editor.Generator; diff --git a/src/Analyzers/CSharp/CodeFixes/MakeStructReadOnly/CSharpMakeStructReadOnlyCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeStructReadOnly/CSharpMakeStructReadOnlyCodeFixProvider.cs index fa6647c757172..3f21860c25103 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeStructReadOnly/CSharpMakeStructReadOnlyCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeStructReadOnly/CSharpMakeStructReadOnlyCodeFixProvider.cs @@ -39,7 +39,6 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var typeDeclarations = diagnostics.Select(d => d.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken)); diff --git a/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs index f52e61fc4371b..c0463c723161f 100644 --- a/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs @@ -62,7 +62,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var compilationUnit = (CompilationUnitSyntax)syntaxRoot; - var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.GetOptionsProvider(), cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var simplifierOptions = options.GetSimplifierOptions(); // Read the preferred placement option and verify if it can be applied to this code file. There are cases diff --git a/src/Analyzers/CSharp/CodeFixes/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementCodeFixProvider.cs index 6b05c0c12e76f..45709ce592734 100644 --- a/src/Analyzers/CSharp/CodeFixes/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementCodeFixProvider.cs @@ -40,18 +40,18 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( CSharpCodeFixesResources.Place_statement_on_following_line, - c => FixAllAsync(document, [diagnostic], context.GetOptionsProvider(), c), + c => FixAllAsync(document, [diagnostic], c), nameof(CSharpCodeFixesResources.Place_statement_on_following_line)), context.Diagnostics); return Task.CompletedTask; } - public static async Task FixAllAsync(Document document, ImmutableArray diagnostics, CodeActionOptionsProvider codeActionOptionsProvider, CancellationToken cancellationToken) + public static async Task FixAllAsync(Document document, ImmutableArray diagnostics, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var editor = new SyntaxEditor(root, document.Project.Solution.Services); - var options = await document.GetCSharpCodeFixOptionsProviderAsync(codeActionOptionsProvider, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var endOfLineTrivia = ElasticEndOfLine(options.NewLine); @@ -136,5 +136,5 @@ private static SyntaxToken AddLeadingTrivia(SyntaxToken token, SyntaxTrivia triv public override FixAllProvider GetFixAllProvider() => FixAllProvider.Create( - async (context, document, diagnostics) => await FixAllAsync(document, diagnostics, context.GetOptionsProvider(), context.CancellationToken).ConfigureAwait(false)); + async (context, document, diagnostics) => await FixAllAsync(document, diagnostics, context.CancellationToken).ConfigureAwait(false)); } diff --git a/src/Analyzers/CSharp/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs index 3b49e503aec70..db2870ee9e8f6 100644 --- a/src/Analyzers/CSharp/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs @@ -75,7 +75,6 @@ protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // a method can have multiple `return null;` statements, but we should only fix its return type once diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryCast/CSharpRemoveUnnecessaryCastCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryCast/CSharpRemoveUnnecessaryCastCodeFixProvider.cs index 6be9261f0e31b..2b2a2f999063c 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryCast/CSharpRemoveUnnecessaryCastCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryCast/CSharpRemoveUnnecessaryCastCodeFixProvider.cs @@ -44,7 +44,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var castNodes = diagnostics.SelectAsArray( d => (ExpressionSyntax)d.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken)); diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryDiscardDesignation/CSharpRemoveUnnecessaryDiscardDesignationCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryDiscardDesignation/CSharpRemoveUnnecessaryDiscardDesignationCodeFixProvider.cs index 334cfead66dc8..14ae92e57b383 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryDiscardDesignation/CSharpRemoveUnnecessaryDiscardDesignationCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryDiscardDesignation/CSharpRemoveUnnecessaryDiscardDesignationCodeFixProvider.cs @@ -41,7 +41,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = editor.Generator; diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryLambdaExpression/CSharpRemoveUnnecessaryLambdaExpressionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryLambdaExpression/CSharpRemoveUnnecessaryLambdaExpressionCodeFixProvider.cs index fc63163451ef6..3eadd802378e5 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryLambdaExpression/CSharpRemoveUnnecessaryLambdaExpressionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryLambdaExpression/CSharpRemoveUnnecessaryLambdaExpressionCodeFixProvider.cs @@ -42,7 +42,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider.cs index 7b21ee94e9510..616707576572e 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider.cs @@ -50,7 +50,6 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // We first group the nullable directives by the token they are attached This allows to replace each token diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs index 87a5ec0c765e2..fc80ca447fac3 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs @@ -51,7 +51,7 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs index 134f003d50746..1cf3df3dd320a 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnusedLocalFunction/CSharpRemoveUnusedLocalFunctionCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var root = editor.OriginalRoot; diff --git a/src/Analyzers/CSharp/CodeFixes/SimplifyPropertyPattern/CSharpSimplifyPropertyPatternCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/SimplifyPropertyPattern/CSharpSimplifyPropertyPatternCodeFixProvider.cs index 49e1cd6eb64fc..894b5a51e583a 100644 --- a/src/Analyzers/CSharp/CodeFixes/SimplifyPropertyPattern/CSharpSimplifyPropertyPatternCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/SimplifyPropertyPattern/CSharpSimplifyPropertyPatternCodeFixProvider.cs @@ -42,7 +42,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { // Process subpatterns in reverse order so we rewrite from inside-to-outside with nested // patterns. diff --git a/src/Analyzers/CSharp/CodeFixes/TransposeRecordKeyword/CSharpTransposeRecordKeywordCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/TransposeRecordKeyword/CSharpTransposeRecordKeywordCodeFixProvider.cs index 37d5bea62bf4d..2bd72a73938e3 100644 --- a/src/Analyzers/CSharp/CodeFixes/TransposeRecordKeyword/CSharpTransposeRecordKeywordCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/TransposeRecordKeyword/CSharpTransposeRecordKeywordCodeFixProvider.cs @@ -100,7 +100,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs index 4fbb6222312c9..3912db017c814 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpCollectionExpressionRewriter.cs @@ -32,7 +32,6 @@ internal static class CSharpCollectionExpressionRewriter /// public static async Task CreateCollectionExpressionAsync( Document workspaceDocument, - CodeActionOptionsProvider fallbackOptions, TParentExpression expressionToReplace, ImmutableArray> matches, Func getInitializer, diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForArrayCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForArrayCodeFixProvider.cs index 92645fb39b683..6131ccff3191a 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForArrayCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForArrayCodeFixProvider.cs @@ -36,7 +36,6 @@ internal partial class CSharpUseCollectionExpressionForArrayCodeFixProvider() protected sealed override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, ExpressionSyntax arrayCreationExpression, ImmutableDictionary properties, CancellationToken cancellationToken) @@ -72,7 +71,6 @@ and not ImplicitArrayCreationExpressionSyntax var collectionExpression = await CSharpCollectionExpressionRewriter.CreateCollectionExpressionAsync( document, - fallbackOptions, arrayCreationExpression, matches, static e => e switch diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderCodeFixProvider.cs index 9f30628e78fad..7079f10191638 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderCodeFixProvider.cs @@ -38,7 +38,6 @@ internal partial class CSharpUseCollectionExpressionForBuilderCodeFixProvider() protected override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, InvocationExpressionSyntax invocationExpression, ImmutableDictionary properties, CancellationToken cancellationToken) @@ -66,7 +65,6 @@ protected override async Task FixAsync( // Get the new collection expression. var collectionExpression = await CreateCollectionExpressionAsync( newDocument, - fallbackOptions, dummyObjectCreation, analysisResult.Matches.SelectAsArray(m => new CollectionExpressionMatch(m.Statement, m.UseSpread)), static o => o.Initializer, diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForCreateCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForCreateCodeFixProvider.cs index 95ecf90d68186..0466efe136cb1 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForCreateCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForCreateCodeFixProvider.cs @@ -35,7 +35,6 @@ internal partial class CSharpUseCollectionExpressionForCreateCodeFixProvider() protected override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, InvocationExpressionSyntax invocationExpression, ImmutableDictionary properties, CancellationToken cancellationToken) @@ -67,7 +66,6 @@ protected override async Task FixAsync( var collectionExpression = await CreateCollectionExpressionAsync( newSemanticDocument.Document, - fallbackOptions, dummyObjectCreation, matches, static o => o.Initializer, diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs index cc0c528767f72..8dd7fc80b9d32 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs @@ -34,7 +34,6 @@ internal sealed partial class CSharpUseCollectionExpressionForEmptyCodeFixProvid protected override Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, SyntaxNode diagnosticNode, ImmutableDictionary properties, CancellationToken cancellationToken) diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs index d81166a7aea57..e6d5670884c6b 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForFluentCodeFixProvider.cs @@ -43,7 +43,6 @@ internal partial class CSharpUseCollectionExpressionForFluentCodeFixProvider() protected override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, InvocationExpressionSyntax invocationExpression, ImmutableDictionary properties, CancellationToken cancellationToken) @@ -69,7 +68,7 @@ protected override async Task FixAsync( var semanticDocument = await SemanticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); // Get the expressions that we're going to fill the new collection expression with. - var arguments = await GetArgumentsAsync(document, fallbackOptions, analysisResult.Matches, cancellationToken).ConfigureAwait(false); + var arguments = await GetArgumentsAsync(document, analysisResult.Matches, cancellationToken).ConfigureAwait(false); var argumentListTrailingTrivia = analysisResult.ExistingInitializer is null ? default @@ -90,7 +89,6 @@ protected override async Task FixAsync( var collectionExpression = await CreateCollectionExpressionAsync( newSemanticDocument.Document, - fallbackOptions, dummyObjectCreation, matches, static o => o.Initializer, @@ -139,7 +137,6 @@ static ImmutableArray> CreateMatches static async Task> GetArgumentsAsync( Document document, - CodeActionOptionsProvider fallbackOptions, ImmutableArray> matches, CancellationToken cancellationToken) { diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocCodeFixProvider.cs index 2299e93e4e016..7774bb8c9acd4 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocCodeFixProvider.cs @@ -32,7 +32,6 @@ internal partial class CSharpUseCollectionExpressionForStackAllocCodeFixProvider protected sealed override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, ExpressionSyntax stackAllocExpression, ImmutableDictionary properties, CancellationToken cancellationToken) @@ -48,7 +47,6 @@ protected sealed override async Task FixAsync( var collectionExpression = await CSharpCollectionExpressionRewriter.CreateCollectionExpressionAsync( document, - fallbackOptions, stackAllocExpression, matches, static e => e switch diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs index 497e67f369c67..3203bff642c22 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider.cs @@ -35,27 +35,25 @@ protected override CSharpUseCollectionInitializerAnalyzer GetAnalyzer() protected override async Task<(SyntaxNode, SyntaxNode)> GetReplacementNodesAsync( Document document, - CodeActionOptionsProvider fallbackOptions, BaseObjectCreationExpressionSyntax objectCreation, bool useCollectionExpression, ImmutableArray> matches, CancellationToken cancellationToken) { var newObjectCreation = await GetNewObjectCreationAsync( - document, fallbackOptions, objectCreation, useCollectionExpression, matches, cancellationToken).ConfigureAwait(false); + document, objectCreation, useCollectionExpression, matches, cancellationToken).ConfigureAwait(false); return (objectCreation, newObjectCreation); } private static async Task GetNewObjectCreationAsync( Document document, - CodeActionOptionsProvider fallbackOptions, BaseObjectCreationExpressionSyntax objectCreation, bool useCollectionExpression, ImmutableArray> matches, CancellationToken cancellationToken) { return useCollectionExpression - ? await CreateCollectionExpressionAsync(document, fallbackOptions, objectCreation, matches, cancellationToken).ConfigureAwait(false) + ? await CreateCollectionExpressionAsync(document, objectCreation, matches, cancellationToken).ConfigureAwait(false) : CreateObjectInitializerExpression(objectCreation, matches); } } diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider_CollectionExpression.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider_CollectionExpression.cs index 7104850f27cd6..f84f195875f0a 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider_CollectionExpression.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionInitializer/CSharpUseCollectionInitializerCodeFixProvider_CollectionExpression.cs @@ -20,14 +20,12 @@ internal partial class CSharpUseCollectionInitializerCodeFixProvider /// private static Task CreateCollectionExpressionAsync( Document document, - CodeActionOptionsProvider fallbackOptions, BaseObjectCreationExpressionSyntax objectCreation, ImmutableArray> matches, CancellationToken cancellationToken) { return CSharpCollectionExpressionRewriter.CreateCollectionExpressionAsync( document, - fallbackOptions, objectCreation, matches.SelectAsArray(m => new CollectionExpressionMatch(m.Statement, m.UseSpread)), static objectCreation => objectCreation.Initializer, diff --git a/src/Analyzers/CSharp/CodeFixes/UseCompoundAssignment/CSharpUseCompoundCoalesceAssignmentCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCompoundAssignment/CSharpUseCompoundCoalesceAssignmentCodeFixProvider.cs index c7a2a8eb775a9..de964491ae666 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCompoundAssignment/CSharpUseCompoundCoalesceAssignmentCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCompoundAssignment/CSharpUseCompoundCoalesceAssignmentCodeFixProvider.cs @@ -44,7 +44,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/CSharp/CodeFixes/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs index 7a6408f8eefbe..202e5e056442c 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseDeconstruction/CSharpUseDeconstructionCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var nodesToProcess = diagnostics.SelectAsArray(d => d.Location.FindToken(cancellationToken).Parent); diff --git a/src/Analyzers/CSharp/CodeFixes/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs index dc3da197868e1..f181a58a5be65 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseDefaultLiteral/CSharpUseDefaultLiteralCodeFixProvider.cs @@ -38,7 +38,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { // Fix-All for this feature is somewhat complicated. Each time we fix one case, it // may make the next case unfixable. For example: diff --git a/src/Analyzers/CSharp/CodeFixes/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs index e26f88caadee0..75c711fece736 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseExpressionBody/UseExpressionBodyCodeFixProvider.cs @@ -54,7 +54,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/CSharp/CodeFixes/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs index acd9a5861d81a..3b51259a77378 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeFixProvider.cs @@ -47,10 +47,10 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) - => FixAllAsync(document, diagnostics, editor, cancellationToken); + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) + => FixAllImplAsync(document, diagnostics, editor, cancellationToken); - private static async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) + private static async Task FixAllImplAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); foreach (var diagnostic in diagnostics) @@ -62,7 +62,7 @@ private static async Task FixAllAsync(Document document, ImmutableArray FixWithSyntaxEditorAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) => FixAllWithEditorAsync( - document, editor => FixAllAsync(document, [diagnostic], editor, cancellationToken), cancellationToken); + document, editor => FixAllImplAsync(document, [diagnostic], editor, cancellationToken), cancellationToken); private static void AddEdits( SyntaxEditor editor, SemanticModel semanticModel, diff --git a/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs index f2dbf68ad4aa4..453c9ed5f7092 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseImplicitObjectCreation/CSharpUseImplicitObjectCreationCodeFixProvider.cs @@ -48,7 +48,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { // process from inside->out so that outer rewrites see the effects of inner changes. var nodes = diagnostics diff --git a/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseExplicitTypeCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseExplicitTypeCodeFixProvider.cs index 564251e4178d1..7ae79431b5afb 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseExplicitTypeCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseExplicitTypeCodeFixProvider.cs @@ -45,7 +45,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var root = editor.OriginalRoot; diff --git a/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseImplicitTypeCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseImplicitTypeCodeFixProvider.cs index 95a7ff2e517f9..7d443979d010c 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseImplicitTypeCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseImplicitOrExplicitType/UseImplicitTypeCodeFixProvider.cs @@ -41,7 +41,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var root = editor.OriginalRoot; diff --git a/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs index 5206ffe65c3fc..16429204d2f7f 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseIndexOperatorCodeFixProvider.cs @@ -42,7 +42,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { // Process diagnostics from innermost to outermost in case any are nested. foreach (var diagnostic in diagnostics.OrderByDescending(d => d.Location.SourceSpan.Start)) diff --git a/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs index 77bd5c04a6d73..ae163dd59f6f9 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseIndexOrRangeOperator/CSharpUseRangeOperatorCodeFixProvider.cs @@ -49,7 +49,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var invocationNodes = diagnostics.Select(d => GetInvocationExpression(d, cancellationToken)) .OrderByDescending(i => i.SpanStart) diff --git a/src/Analyzers/CSharp/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs index fca0f8a0142e0..e6f9c13a3b0ee 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseInterpolatedVerbatimString/CSharpUseInterpolatedVerbatimStringCodeFixProvider.cs @@ -45,7 +45,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs index 22a8b3688ef38..8b0f7f4352440 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider.cs @@ -57,7 +57,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseNullCheckOverTypeCheckCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseNullCheckOverTypeCheckCodeFixProvider.cs index eb784c182f703..9e8d38a5f5f36 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseNullCheckOverTypeCheckCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseIsNullCheck/CSharpUseNullCheckOverTypeCheckCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs index 90ffa1fef5fb2..233060a239f19 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseLocalFunction/CSharpUseLocalFunctionCodeFixProvider.cs @@ -55,7 +55,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -97,7 +97,7 @@ protected override async Task FixAllAsync( var info = new CSharpCodeGenerationContextInfo( CodeGenerationContext.Default, CSharpCodeGenerationOptions.Default, new CSharpCodeGenerationService(document.Project.GetExtendedLanguageServices().LanguageServices), root.SyntaxTree.Options.LanguageVersion()); #else - var info = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); #endif var options = (CSharpCodeGenerationOptions)info.Options; diff --git a/src/Analyzers/CSharp/CodeFixes/UseNameofInAttribute/CSharpUseNameofInAttributeCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseNameofInAttribute/CSharpUseNameofInAttributeCodeFixProvider.cs index e28a8b4ec7927..4f4ecf47dbc53 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseNameofInAttribute/CSharpUseNameofInAttributeCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseNameofInAttribute/CSharpUseNameofInAttributeCodeFixProvider.cs @@ -42,7 +42,6 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) diff --git a/src/Analyzers/CSharp/CodeFixes/UsePatternCombinators/CSharpUsePatternCombinatorsCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UsePatternCombinators/CSharpUsePatternCombinatorsCodeFixProvider.cs index 3a4b38255dff4..c5f2bdfd401d3 100644 --- a/src/Analyzers/CSharp/CodeFixes/UsePatternCombinators/CSharpUsePatternCombinatorsCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UsePatternCombinators/CSharpUsePatternCombinatorsCodeFixProvider.cs @@ -77,7 +77,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); foreach (var diagnostic in diagnostics) diff --git a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndMemberAccessCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndMemberAccessCodeFixProvider.cs index 6e3d3eed462ae..0b98dabe808a6 100644 --- a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndMemberAccessCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndMemberAccessCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics.OrderByDescending(d => d.Location.SourceSpan.Start)) FixOne(editor, diagnostic, cancellationToken); diff --git a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs index c58d7853b87b2..6844779691092 100644 --- a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpAsAndNullCheckCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { using var _1 = PooledHashSet.GetInstance(out var declaratorLocations); using var _2 = PooledHashSet.GetInstance(out var statementParentScopes); diff --git a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs index cf0d065725f49..bbf9084d3e89d 100644 --- a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpUseNotPatternCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpUseNotPatternCodeFixProvider.cs index 81b7a2ffe7553..4f10d8cdcad1d 100644 --- a/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpUseNotPatternCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpUseNotPatternCodeFixProvider.cs @@ -38,7 +38,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); foreach (var diagnostic in diagnostics) diff --git a/src/Analyzers/CSharp/CodeFixes/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs index 282bb5ea8acab..74953322bd152 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseSimpleUsingStatement/UseSimpleUsingStatementCodeFixProvider.cs @@ -50,7 +50,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var topmostUsingStatements = diagnostics.Select(d => (UsingStatementSyntax)d.AdditionalLocations[0].FindNode(cancellationToken)).ToSet(); var blocks = topmostUsingStatements.Select(u => (BlockSyntax)u.Parent); diff --git a/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs index 713cbd464ba07..ce4845dc99f36 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs @@ -44,7 +44,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = editor.Generator; var root = editor.OriginalRoot; diff --git a/src/Analyzers/CSharp/CodeFixes/UseTupleSwap/CSharpUseTupleSwapCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseTupleSwap/CSharpUseTupleSwapCodeFixProvider.cs index 1a82de7b16c0a..1435cb8ad5c8a 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseTupleSwap/CSharpUseTupleSwapCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseTupleSwap/CSharpUseTupleSwapCodeFixProvider.cs @@ -43,7 +43,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) FixOne(editor, diagnostic, cancellationToken); diff --git a/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs index 2d77751619c70..3a241ce78237a 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs @@ -46,7 +46,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider options, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs index 513b171f8c9d8..275be2ee50cb0 100644 --- a/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs @@ -42,7 +42,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) protected sealed override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/AddAnonymousTypeMemberName/AbstractAddAnonymousTypeMemberNameCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddAnonymousTypeMemberName/AbstractAddAnonymousTypeMemberNameCodeFixProvider.cs index a957390cda11e..29762c5ad3f12 100644 --- a/src/Analyzers/Core/CodeFixes/AddAnonymousTypeMemberName/AbstractAddAnonymousTypeMemberNameCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddAnonymousTypeMemberName/AbstractAddAnonymousTypeMemberNameCodeFixProvider.cs @@ -82,7 +82,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { // If we're only introducing one name, then add the rename annotation to // it so the user can pick a better name if they want. diff --git a/src/Analyzers/Core/CodeFixes/AddExplicitCast/AbstractAddExplicitCastCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddExplicitCast/AbstractAddExplicitCastCodeFixProvider.cs index 4bd41fdbffdf4..9b5dc56baf43d 100644 --- a/src/Analyzers/Core/CodeFixes/AddExplicitCast/AbstractAddExplicitCastCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddExplicitCast/AbstractAddExplicitCastCodeFixProvider.cs @@ -213,7 +213,6 @@ protected sealed override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/AddObsoleteAttribute/AbstractAddObsoleteAttributeCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddObsoleteAttribute/AbstractAddObsoleteAttributeCodeFixProvider.cs index d1246e968e40e..4c59eb92ce7ed 100644 --- a/src/Analyzers/Core/CodeFixes/AddObsoleteAttribute/AbstractAddObsoleteAttributeCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddObsoleteAttribute/AbstractAddObsoleteAttributeCodeFixProvider.cs @@ -70,7 +70,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var obsoleteAttribute = await GetObsoleteAttributeAsync(document, cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs index 69d8b97018d2c..0e0eb0e65c4bf 100644 --- a/src/Analyzers/Core/CodeFixes/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddRequiredParentheses/AddRequiredParenthesesCodeFixProvider.cs @@ -41,7 +41,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = document.GetRequiredLanguageService(); diff --git a/src/Analyzers/Core/CodeFixes/AliasAmbiguousType/AbstractAliasAmbiguousTypeCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AliasAmbiguousType/AbstractAliasAmbiguousTypeCodeFixProvider.cs index ff015dabf6f0f..9a471eb13795c 100644 --- a/src/Analyzers/Core/CodeFixes/AliasAmbiguousType/AbstractAliasAmbiguousTypeCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AliasAmbiguousType/AbstractAliasAmbiguousTypeCodeFixProvider.cs @@ -48,7 +48,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) var syntaxGenerator = document.GetRequiredLanguageService(); var compilation = semanticModel.Compilation; - var placementOption = await document.GetAddImportPlacementOptionsAsync(addImportService, context.GetOptionsProvider(), cancellationToken).ConfigureAwait(false); + var placementOption = await document.GetAddImportPlacementOptionsAsync(addImportService, cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder.GetInstance(out var actions); foreach (var symbol in Sort(symbolInfo.CandidateSymbols.Cast(), placementOption.PlaceSystemNamespaceFirst)) diff --git a/src/Analyzers/Core/CodeFixes/ConvertTypeOfToNameOf/AbstractConvertTypeOfToNameOfCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/ConvertTypeOfToNameOf/AbstractConvertTypeOfToNameOfCodeFixProvider.cs index 66d14ce2db6a4..5aa864ea89dfe 100644 --- a/src/Analyzers/Core/CodeFixes/ConvertTypeOfToNameOf/AbstractConvertTypeOfToNameOfCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/ConvertTypeOfToNameOf/AbstractConvertTypeOfToNameOfCodeFixProvider.cs @@ -33,7 +33,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); foreach (var diagnostic in diagnostics) diff --git a/src/Analyzers/Core/CodeFixes/FileHeaders/AbstractFileHeaderCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/FileHeaders/AbstractFileHeaderCodeFixProvider.cs index 55068c1eba0c3..f2996a7356445 100644 --- a/src/Analyzers/Core/CodeFixes/FileHeaders/AbstractFileHeaderCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/FileHeaders/AbstractFileHeaderCodeFixProvider.cs @@ -35,7 +35,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( CodeFixesResources.Add_file_header, - cancellationToken => GetTransformedDocumentAsync(context.Document, context.GetOptionsProvider(), cancellationToken), + cancellationToken => GetTransformedDocumentAsync(context.Document, cancellationToken), nameof(AbstractFileHeaderCodeFixProvider)), diagnostic); } @@ -43,12 +43,12 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - private async Task GetTransformedDocumentAsync(Document document, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) - => document.WithSyntaxRoot(await GetTransformedSyntaxRootAsync(document, fallbackOptions, cancellationToken).ConfigureAwait(false)); + private async Task GetTransformedDocumentAsync(Document document, CancellationToken cancellationToken) + => document.WithSyntaxRoot(await GetTransformedSyntaxRootAsync(document, cancellationToken).ConfigureAwait(false)); - private async Task GetTransformedSyntaxRootAsync(Document document, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private async Task GetTransformedSyntaxRootAsync(Document document, CancellationToken cancellationToken) { - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var generator = document.GetRequiredLanguageService(); var newLineTrivia = generator.EndOfLine(options.NewLine); @@ -232,6 +232,6 @@ public override FixAllProvider GetFixAllProvider() if (diagnostics.IsEmpty) return null; - return await this.GetTransformedDocumentAsync(document, context.GetOptionsProvider(), context.CancellationToken).ConfigureAwait(false); + return await this.GetTransformedDocumentAsync(document, context.CancellationToken).ConfigureAwait(false); }); } diff --git a/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs index 5fc4bd8e9c582..21055abecac29 100644 --- a/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs @@ -42,7 +42,7 @@ protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxFacts = document.GetRequiredLanguageService(); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/Formatting/FormattingCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/Formatting/FormattingCodeFixProvider.cs index 2669f4355011c..15d5ceb71cbd3 100644 --- a/src/Analyzers/Core/CodeFixes/Formatting/FormattingCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/Formatting/FormattingCodeFixProvider.cs @@ -62,16 +62,16 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) private async Task FixOneAsync(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken) { - var options = await context.Document.GetCodeFixOptionsAsync(context.GetOptionsProvider(), cancellationToken).ConfigureAwait(false); + var options = await context.Document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingOptions = options.GetFormattingOptions(SyntaxFormatting); var tree = await context.Document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var updatedTree = await FormattingCodeFixHelper.FixOneAsync(tree, SyntaxFormatting, formattingOptions, diagnostic, cancellationToken).ConfigureAwait(false); return context.Document.WithText(await updatedTree.GetTextAsync(cancellationToken).ConfigureAwait(false)); } - protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingOptions = options.GetFormattingOptions(SyntaxFormatting); var updatedRoot = Formatter.Format(editor.OriginalRoot, SyntaxFormatting, formattingOptions, cancellationToken); editor.ReplaceNode(editor.OriginalRoot, updatedRoot); diff --git a/src/Analyzers/Core/CodeFixes/MakeFieldReadonly/AbstractMakeFieldReadonlyCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/MakeFieldReadonly/AbstractMakeFieldReadonlyCodeFixProvider.cs index 8ddf3bbe3d123..5db2af601d9f0 100644 --- a/src/Analyzers/Core/CodeFixes/MakeFieldReadonly/AbstractMakeFieldReadonlyCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MakeFieldReadonly/AbstractMakeFieldReadonlyCodeFixProvider.cs @@ -39,7 +39,7 @@ protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var declarators = new List(); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/MakeMemberStatic/AbstractMakeMemberStaticCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/MakeMemberStatic/AbstractMakeMemberStaticCodeFixProvider.cs index def47e999fad0..1ee2dd22b664e 100644 --- a/src/Analyzers/Core/CodeFixes/MakeMemberStatic/AbstractMakeMemberStaticCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MakeMemberStatic/AbstractMakeMemberStaticCodeFixProvider.cs @@ -30,7 +30,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) } protected sealed override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { for (var i = 0; i < diagnostics.Length; i++) { diff --git a/src/Analyzers/Core/CodeFixes/MakeTypeAbstract/AbstractMakeTypeAbstractCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/MakeTypeAbstract/AbstractMakeTypeAbstractCodeFixProvider.cs index 4d9aaad35bcb2..82d39e92f2fcd 100644 --- a/src/Analyzers/Core/CodeFixes/MakeTypeAbstract/AbstractMakeTypeAbstractCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MakeTypeAbstract/AbstractMakeTypeAbstractCodeFixProvider.cs @@ -30,7 +30,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) } protected sealed override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { for (var i = 0; i < diagnostics.Length; i++) { diff --git a/src/Analyzers/Core/CodeFixes/MakeTypePartial/AbstractMakeTypePartialCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/MakeTypePartial/AbstractMakeTypePartialCodeFixProvider.cs index d72b9da4503cb..37f501bdb90d5 100644 --- a/src/Analyzers/Core/CodeFixes/MakeTypePartial/AbstractMakeTypePartialCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MakeTypePartial/AbstractMakeTypePartialCodeFixProvider.cs @@ -26,7 +26,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxRoot = editor.OriginalRoot; var generator = editor.Generator; diff --git a/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.CustomFixAllProvider.cs b/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.CustomFixAllProvider.cs index 3a25c37639087..d19dfd6f28cb8 100644 --- a/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.CustomFixAllProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.CustomFixAllProvider.cs @@ -45,11 +45,6 @@ private class CustomFixAllProvider : FixAllProvider fixAllContext.Project.Solution, diagnostics, fixAllContext.Progress, -#if CODE_STYLE - CodeActionOptions.DefaultProvider, -#else - fixAllContext.State.CodeActionOptionsProvider, -#endif cancellationToken), title); @@ -71,7 +66,6 @@ private static async Task FixAllByDocumentAsync( Solution solution, ImmutableArray diagnostics, IProgress progressTracker, - CodeActionOptionsProvider options, CancellationToken cancellationToken) { // Use documentId instead of tree here because the @@ -94,7 +88,7 @@ private static async Task FixAllByDocumentAsync( var document = newSolution.GetRequiredDocument(documentId); using var _ = progressTracker.ItemCompletedScope(document.Name); - newSolution = await FixAllInDocumentAsync(document, diagnosticsInTree, options, cancellationToken).ConfigureAwait(false); + newSolution = await FixAllInDocumentAsync(document, diagnosticsInTree, cancellationToken).ConfigureAwait(false); } return newSolution; diff --git a/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.cs index 35e77aeaa8391..25f7c018648d6 100644 --- a/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MatchFolderAndNamespace/AbstractChangeNamespaceToMatchFolderCodeFixProvider.cs @@ -31,7 +31,6 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) CodeAction.Create( AnalyzersResources.Change_namespace_to_match_folder_structure, cancellationToken => FixAllInDocumentAsync(context.Document, context.Diagnostics, - context.GetOptionsProvider(), cancellationToken), nameof(AnalyzersResources.Change_namespace_to_match_folder_structure)), context.Diagnostics); @@ -40,7 +39,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - private static async Task FixAllInDocumentAsync(Document document, ImmutableArray diagnostics, CodeActionOptionsProvider options, CancellationToken cancellationToken) + private static async Task FixAllInDocumentAsync(Document document, ImmutableArray diagnostics, CancellationToken cancellationToken) { // All the target namespaces should be the same for a given document Debug.Assert(diagnostics.Select(diagnostic => diagnostic.Properties[MatchFolderAndNamespaceConstants.TargetNamespace]).Distinct().Count() == 1); @@ -57,9 +56,6 @@ private static async Task FixAllInDocumentAsync(Document document, Imm var renameActionSet = await Renamer.RenameDocumentAsync( documentWithInvalidFolders, new DocumentRenameOptions(), -#if !CODE_STYLE - options, -#endif documentWithInvalidFolders.Name, newDocumentFolders: targetFolders, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementCodeFixProvider.cs index 101ac36b1a488..b2f596fd3bafb 100644 --- a/src/Analyzers/Core/CodeFixes/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementCodeFixProvider.cs @@ -31,19 +31,19 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) var diagnostic = context.Diagnostics.First(); context.RegisterCodeFix(CodeAction.Create( CodeFixesResources.Add_blank_line_after_block, - c => UpdateDocumentAsync(document, diagnostic, context.GetOptionsProvider(), c), + c => UpdateDocumentAsync(document, diagnostic, c), nameof(CodeFixesResources.Add_blank_line_after_block)), context.Diagnostics); return Task.CompletedTask; } - private static Task UpdateDocumentAsync(Document document, Diagnostic diagnostic, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) - => FixAllAsync(document, [diagnostic], fallbackOptions, cancellationToken); + private static Task UpdateDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) + => FixAllAsync(document, [diagnostic], cancellationToken); - public static async Task FixAllAsync(Document document, ImmutableArray diagnostics, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public static async Task FixAllAsync(Document document, ImmutableArray diagnostics, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var generator = document.GetRequiredLanguageService(); var endOfLineTrivia = generator.EndOfLine(options.NewLine); @@ -57,5 +57,5 @@ public static async Task FixAllAsync(Document document, ImmutableArray } public override FixAllProvider GetFixAllProvider() - => FixAllProvider.Create(async (context, document, diagnostics) => await FixAllAsync(document, diagnostics, context.GetOptionsProvider(), context.CancellationToken).ConfigureAwait(false)); + => FixAllProvider.Create(async (context, document, diagnostics) => await FixAllAsync(document, diagnostics, context.CancellationToken).ConfigureAwait(false)); } diff --git a/src/Analyzers/Core/CodeFixes/OrderModifiers/AbstractOrderModifiersCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/OrderModifiers/AbstractOrderModifiersCodeFixProvider.cs index b264cdb40a6c5..5715e8a08182c 100644 --- a/src/Analyzers/Core/CodeFixes/OrderModifiers/AbstractOrderModifiersCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/OrderModifiers/AbstractOrderModifiersCodeFixProvider.cs @@ -50,7 +50,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } protected override async Task FixAllAsync( - Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var options = await document.GetAnalyzerOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var option = GetCodeStyleOption(options); diff --git a/src/Analyzers/Core/CodeFixes/PopulateSwitch/AbstractPopulateSwitchCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/PopulateSwitch/AbstractPopulateSwitchCodeFixProvider.cs index f11e3341e79c6..145908f6c307d 100644 --- a/src/Analyzers/Core/CodeFixes/PopulateSwitch/AbstractPopulateSwitchCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/PopulateSwitch/AbstractPopulateSwitchCodeFixProvider.cs @@ -220,7 +220,7 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { // If the user is performing a fix-all, then fix up all the issues we see. i.e. // add missing cases and missing 'default' cases for any switches we reported an diff --git a/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs index d57f8d9b8b3ce..4b0cb0f386fa3 100644 --- a/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs @@ -34,7 +34,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = document.GetRequiredLanguageService(); diff --git a/src/Analyzers/Core/CodeFixes/RemoveAsyncModifier/AbstractRemoveAsyncModifierCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveAsyncModifier/AbstractRemoveAsyncModifierCodeFixProvider.cs index 250c040db27fe..e62c68493be53 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveAsyncModifier/AbstractRemoveAsyncModifierCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveAsyncModifier/AbstractRemoveAsyncModifierCodeFixProvider.cs @@ -62,7 +62,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) protected sealed override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var solutionServices = document.Project.Solution.Services; var generator = editor.Generator; diff --git a/src/Analyzers/Core/CodeFixes/RemoveRedundantEquality/RemoveRedundantEqualityCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveRedundantEquality/RemoveRedundantEqualityCodeFixProvider.cs index de18bbeca7810..56ec6abe94604 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveRedundantEquality/RemoveRedundantEqualityCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveRedundantEquality/RemoveRedundantEqualityCodeFixProvider.cs @@ -31,7 +31,6 @@ protected override (string title, string equivalenceKey) GetTitleAndEquivalenceK protected override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, SyntaxNode node, ImmutableDictionary properties, CancellationToken cancellationToken) diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsCodeFixProvider.cs index 31fe78427eca9..e922d0b210d18 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryImports/AbstractRemoveUnnecessaryImportsCodeFixProvider.cs @@ -30,7 +30,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( title, - c => RemoveUnnecessaryImportsAsync(context.Document, context.GetOptionsProvider(), c), + c => RemoveUnnecessaryImportsAsync(context.Document, c), title), context.Diagnostics); return Task.CompletedTask; @@ -40,12 +40,11 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) private async Task RemoveUnnecessaryImportsAsync( Document document, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var service = document.GetRequiredLanguageService(); - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingOptions = options.GetFormattingOptions(GetSyntaxFormatting()); return await service.RemoveUnnecessaryImportsAsync(document, formattingOptions, cancellationToken).ConfigureAwait(false); } diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesCodeFixProvider.cs index 0e78d6cb60a46..c21ae53bb9a8c 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnnecessaryParentheses/AbstractRemoveUnnecessaryParenthesesCodeFixProvider.cs @@ -33,7 +33,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxFacts = document.GetRequiredLanguageService(); var originalNodes = diagnostics.SelectAsArray( diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsCodeFixProvider.cs index 757a5e987076b..b5e2c50e00f1b 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsCodeFixProvider.cs @@ -37,7 +37,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryPragmaSuppressionsCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryPragmaSuppressionsCodeFixProvider.cs index ccca2c2108063..8d6418a13237f 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryPragmaSuppressionsCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnnecessarySuppressions/RemoveUnnecessaryPragmaSuppressionsCodeFixProvider.cs @@ -44,7 +44,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { // We need to track unique set of processed nodes when removing the nodes. // This is because we generate an unnecessary pragma suppression diagnostic at both the pragma disable and matching pragma restore location diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnusedMembers/AbstractRemoveUnusedMembersCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnusedMembers/AbstractRemoveUnusedMembersCodeFixProvider.cs index 69c2f4a991ade..9a4b01563fc17 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnusedMembers/AbstractRemoveUnusedMembersCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnusedMembers/AbstractRemoveUnusedMembersCodeFixProvider.cs @@ -43,7 +43,7 @@ protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var declarators = new HashSet(); var fieldDeclarators = new HashSet(); diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs index b70f54298a2fd..fe31e1baf04c7 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs @@ -282,9 +282,9 @@ private static async Task PreprocessDocumentAsync(Document document, I return document.WithSyntaxRoot(root); } - protected sealed override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected sealed override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingOptions = options.GetFormattingOptions(GetSyntaxFormatting()); var preprocessedDocument = await PreprocessDocumentAsync(document, diagnostics, cancellationToken).ConfigureAwait(false); var newRoot = await GetNewRootAsync(preprocessedDocument, formattingOptions, diagnostics, cancellationToken).ConfigureAwait(false); diff --git a/src/Analyzers/Core/CodeFixes/SimplifyBooleanExpression/SimplifyConditionalCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/SimplifyBooleanExpression/SimplifyConditionalCodeFixProvider.cs index 03c3b4a1e7c64..5603a59570c29 100644 --- a/src/Analyzers/Core/CodeFixes/SimplifyBooleanExpression/SimplifyConditionalCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/SimplifyBooleanExpression/SimplifyConditionalCodeFixProvider.cs @@ -38,7 +38,6 @@ protected sealed override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); diff --git a/src/Analyzers/Core/CodeFixes/SimplifyInterpolation/AbstractSimplifyInterpolationCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/SimplifyInterpolation/AbstractSimplifyInterpolationCodeFixProvider.cs index 9543b0e29eea6..dacdf7160341c 100644 --- a/src/Analyzers/Core/CodeFixes/SimplifyInterpolation/AbstractSimplifyInterpolationCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/SimplifyInterpolation/AbstractSimplifyInterpolationCodeFixProvider.cs @@ -48,7 +48,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var generator = editor.Generator; diff --git a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs index cbe3bc882fa57..fd404a25cbadf 100644 --- a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs +++ b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs @@ -34,7 +34,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var root = editor.OriginalRoot; var expressionsToReWrite = diagnostics.Select(d => GetInvocation(root, d)).OrderByDescending(i => i.SpanStart); diff --git a/src/Analyzers/Core/CodeFixes/UpdateLegacySuppressions/UpdateLegacySuppressionsCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UpdateLegacySuppressions/UpdateLegacySuppressionsCodeFixProvider.cs index 197962bb0b77f..6733f37c256e8 100644 --- a/src/Analyzers/Core/CodeFixes/UpdateLegacySuppressions/UpdateLegacySuppressionsCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UpdateLegacySuppressions/UpdateLegacySuppressionsCodeFixProvider.cs @@ -38,7 +38,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { diff --git a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckCodeFixProvider.cs index 3e742ba80a9e3..4587299b879b3 100644 --- a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckCodeFixProvider.cs @@ -35,7 +35,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxFacts = document.GetRequiredLanguageService(); var generator = editor.Generator; diff --git a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs index db4260c963717..be0c9156f20df 100644 --- a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs @@ -36,7 +36,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var expressionTypeOpt = semanticModel.Compilation.ExpressionOfTType(); diff --git a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs index 87487264798eb..048139c0e6652 100644 --- a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs @@ -37,7 +37,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var expressionTypeOpt = semanticModel.Compilation.ExpressionOfTType(); diff --git a/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs index f6c40118d1f93..3bd8365d3a7b3 100644 --- a/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs @@ -54,12 +54,11 @@ public sealed override ImmutableArray FixableDiagnosticIds protected abstract TAnalyzer GetAnalyzer(); protected abstract Task<(SyntaxNode oldNode, SyntaxNode newNode)> GetReplacementNodesAsync( - Document document, CodeActionOptionsProvider fallbackOptions, TObjectCreationExpressionSyntax objectCreation, bool useCollectionExpression, ImmutableArray> matches, CancellationToken cancellationToken); + Document document, TObjectCreationExpressionSyntax objectCreation, bool useCollectionExpression, ImmutableArray> matches, CancellationToken cancellationToken); protected sealed override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, TObjectCreationExpressionSyntax objectCreation, ImmutableDictionary properties, CancellationToken cancellationToken) @@ -83,7 +82,7 @@ protected sealed override async Task FixAsync( return; var (oldNode, newNode) = await GetReplacementNodesAsync( - document, fallbackOptions, objectCreation, useCollectionExpression, matches, cancellationToken).ConfigureAwait(false); + document, objectCreation, useCollectionExpression, matches, cancellationToken).ConfigureAwait(false); editor.ReplaceNode(oldNode, newNode); foreach (var match in matches) diff --git a/src/Analyzers/Core/CodeFixes/UseCompoundAssignment/AbstractUseCompoundAssignmentCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCompoundAssignment/AbstractUseCompoundAssignmentCodeFixProvider.cs index f4ed3a1fc1ba8..20ec1d9dfe293 100644 --- a/src/Analyzers/Core/CodeFixes/UseCompoundAssignment/AbstractUseCompoundAssignmentCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCompoundAssignment/AbstractUseCompoundAssignmentCodeFixProvider.cs @@ -51,7 +51,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxFacts = document.GetRequiredLanguageService(); var syntaxKinds = syntaxFacts.SyntaxKinds; diff --git a/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs index 3f13dbb450124..580548d1cd46d 100644 --- a/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs @@ -51,7 +51,7 @@ protected abstract Task FixOneAsync( protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -60,7 +60,7 @@ protected override async Task FixAllAsync( #else var provider = document.Project.Solution.Services; #endif - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingOptions = options.GetFormattingOptions(GetSyntaxFormatting()); // Defer to our callback to actually make the edits for each diagnostic. In turn, it diff --git a/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs index ca3b5da7ebbce..50b9ce94f5389 100644 --- a/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs @@ -33,7 +33,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = editor.Generator; diff --git a/src/Analyzers/Core/CodeFixes/UseInferredMemberName/AbstractUseInferredMemberNameCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseInferredMemberName/AbstractUseInferredMemberNameCodeFixProvider.cs index c97cc9c07be29..c6cd72ba08ebd 100644 --- a/src/Analyzers/Core/CodeFixes/UseInferredMemberName/AbstractUseInferredMemberNameCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseInferredMemberName/AbstractUseInferredMemberNameCodeFixProvider.cs @@ -30,7 +30,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var root = editor.OriginalRoot; diff --git a/src/Analyzers/Core/CodeFixes/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs index c2e2c9dfc0cd1..1c2bf9963d409 100644 --- a/src/Analyzers/Core/CodeFixes/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseIsNullCheck/AbstractUseIsNullForReferenceEqualsCodeFixProvider.cs @@ -49,7 +49,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var syntaxFacts = document.GetRequiredLanguageService(); diff --git a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs index 492219688d700..f305c1adaa66f 100644 --- a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs @@ -67,7 +67,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var root = editor.OriginalRoot; diff --git a/src/Analyzers/Core/CodeFixes/UseObjectInitializer/AbstractUseObjectInitializerCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseObjectInitializer/AbstractUseObjectInitializerCodeFixProvider.cs index daf96d208e1dc..e24f92920c2fb 100644 --- a/src/Analyzers/Core/CodeFixes/UseObjectInitializer/AbstractUseObjectInitializerCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseObjectInitializer/AbstractUseObjectInitializerCodeFixProvider.cs @@ -60,7 +60,6 @@ public override ImmutableArray FixableDiagnosticIds protected override async Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, TObjectCreationExpressionSyntax objectCreation, ImmutableDictionary properties, CancellationToken cancellationToken) diff --git a/src/Analyzers/Core/CodeFixes/UseSystemHashCode/UseSystemHashCodeCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseSystemHashCode/UseSystemHashCodeCodeFixProvider.cs index 12b56496dcd6b..5197aa83293c2 100644 --- a/src/Analyzers/Core/CodeFixes/UseSystemHashCode/UseSystemHashCodeCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseSystemHashCode/UseSystemHashCodeCodeFixProvider.cs @@ -34,7 +34,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var generatorInternal = document.GetRequiredLanguageService(); diff --git a/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb b/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb index 324ccd7641048..677b9a337fa1e 100644 --- a/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb +++ b/src/Analyzers/VisualBasic/Analyzers/CodeStyle/VisualBasicAnalyzerOptionsProvider.vb @@ -23,7 +23,7 @@ Namespace Microsoft.CodeAnalysis.Diagnostics End Sub Public Function GetSimplifierOptions() As VisualBasicSimplifierOptions - Return New VisualBasicSimplifierOptions(_options, fallbackOptions:=Nothing) + Return New VisualBasicSimplifierOptions(_options) End Function Public ReadOnly Property PreferredModifierOrder As CodeStyleOption2(Of String) diff --git a/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryByVal/VisualBasicRemoveUnnecessaryByValCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryByVal/VisualBasicRemoveUnnecessaryByValCodeFixProvider.vb index 60b50b68f7392..11cd4e7dfc9c5 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryByVal/VisualBasicRemoveUnnecessaryByValCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryByVal/VisualBasicRemoveUnnecessaryByValCodeFixProvider.vb @@ -34,7 +34,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryByVal Return Task.CompletedTask End Function - Protected Overrides Async Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, fallbackOptions As CodeActionOptionsProvider, cancellationToken As CancellationToken) As Task + Protected Overrides Async Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, cancellationToken As CancellationToken) As Task Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) For Each diagnostic In diagnostics Dim node = DirectCast(root.FindNode(diagnostic.AdditionalLocations(0).SourceSpan), ParameterSyntax) diff --git a/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryCast/VisualBasicRemoveUnnecessaryCastCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryCast/VisualBasicRemoveUnnecessaryCastCodeFixProvider.vb index df86bd8d3fa21..5da4201250f97 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryCast/VisualBasicRemoveUnnecessaryCastCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/RemoveUnnecessaryCast/VisualBasicRemoveUnnecessaryCastCodeFixProvider.vb @@ -53,7 +53,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveUnnecessaryCast document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, - fallbackOptions As CodeActionOptionsProvider, cancellationToken As CancellationToken) As Task ' VB parsing is extremely hairy. Unlike C#, it can be very dangerous to go and remove a diff --git a/src/Analyzers/VisualBasic/CodeFixes/SimplifyObjectCreation/VisualBasicSimplifyObjectCreationCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/SimplifyObjectCreation/VisualBasicSimplifyObjectCreationCodeFixProvider.vb index df87268ef8788..e39dfdb1b486d 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/SimplifyObjectCreation/VisualBasicSimplifyObjectCreationCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/SimplifyObjectCreation/VisualBasicSimplifyObjectCreationCodeFixProvider.vb @@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyObjectCreation Return Task.CompletedTask End Function - Protected Overrides Async Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, fallbackOptions As CodeActionOptionsProvider, cancellationToken As CancellationToken) As Task + Protected Overrides Async Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, cancellationToken As CancellationToken) As Task Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) For Each diagnostic In diagnostics Dim node = DirectCast(root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie:=True), VariableDeclaratorSyntax) diff --git a/src/Analyzers/VisualBasic/CodeFixes/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb index 82e0c1837616e..4d0b85942cbfe 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/UseCollectionInitializer/VisualBasicUseCollectionInitializerCodeFixProvider.vb @@ -40,7 +40,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseCollectionInitializer Protected Overrides Function GetReplacementNodesAsync( document As Document, - options As CodeActionOptionsProvider, objectCreation As ObjectCreationExpressionSyntax, useCollectionExpression As Boolean, matches As ImmutableArray(Of Match(Of StatementSyntax)), diff --git a/src/Analyzers/VisualBasic/CodeFixes/UseIsNotExpression/VisualBasicUseIsNotExpressionCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/UseIsNotExpression/VisualBasicUseIsNotExpressionCodeFixProvider.vb index 8f86dbb0c0ae3..7df3b32d7cf4d 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/UseIsNotExpression/VisualBasicUseIsNotExpressionCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/UseIsNotExpression/VisualBasicUseIsNotExpressionCodeFixProvider.vb @@ -34,7 +34,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseIsNotExpression document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, - fallbackOptions As CodeActionOptionsProvider, cancellationToken As CancellationToken) As Task For Each diagnostic In diagnostics diff --git a/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs b/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs index 2acb0a635722c..0d05a0d03f487 100644 --- a/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs @@ -18,6 +18,6 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.ChangeSignature; [Name(PredefinedCommandHandlerNames.ChangeSignature)] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpChangeSignatureCommandHandler(IThreadingContext threadingContext, IGlobalOptionService globalOptions) : AbstractChangeSignatureCommandHandler(threadingContext, globalOptions) +internal sealed class CSharpChangeSignatureCommandHandler(IThreadingContext threadingContext) : AbstractChangeSignatureCommandHandler(threadingContext) { } diff --git a/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs b/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs index 48aa771a49a1e..87f09c9e47207 100644 --- a/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs +++ b/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs @@ -7,7 +7,6 @@ using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.EncapsulateField; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text.Operations; @@ -24,7 +23,6 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.EncapsulateField; internal class EncapsulateFieldCommandHandler( IThreadingContext threadingContext, ITextBufferUndoManagerProvider undoManager, - IGlobalOptionService globalOptions, - IAsynchronousOperationListenerProvider listenerProvider) : AbstractEncapsulateFieldCommandHandler(threadingContext, undoManager, globalOptions, listenerProvider) + IAsynchronousOperationListenerProvider listenerProvider) : AbstractEncapsulateFieldCommandHandler(threadingContext, undoManager, listenerProvider) { } diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs index b0a57873eaf63..a065c13adb9dd 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupCommandHandler_TabKeyCommand.cs @@ -209,7 +209,7 @@ async Task TryExecuteCommandAsync() } } - private async Task<(Solution solution, TextSpan renameSpan)?> TryGetNewSolutionWithAddedMethodAsync( + private static async Task<(Solution solution, TextSpan renameSpan)?> TryGetNewSolutionWithAddedMethodAsync( Document document, Task eventNameTask, int position, CancellationToken cancellationToken) { var eventHandlerMethodName = await eventNameTask.WithCancellation(cancellationToken).ConfigureAwait(false); @@ -224,16 +224,14 @@ async Task TryExecuteCommandAsync() var semanticDocument = await SemanticDocument.CreateAsync( documentWithNameAndAnnotationsAdded, cancellationToken).ConfigureAwait(false); - var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync( - _globalOptions, cancellationToken).ConfigureAwait(false); + var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var updatedRoot = AddGeneratedHandlerMethodToSolution( semanticDocument, options, eventHandlerMethodName, cancellationToken); if (updatedRoot == null) return null; - var cleanupOptions = await documentWithNameAndAnnotationsAdded.GetCodeCleanupOptionsAsync( - _globalOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await documentWithNameAndAnnotationsAdded.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var simplifiedDocument = await Simplifier.ReduceAsync( documentWithNameAndAnnotationsAdded.WithSyntaxRoot(updatedRoot), Simplifier.Annotation, cleanupOptions.SimplifierOptions, cancellationToken).ConfigureAwait(false); var formattedDocument = await Formatter.FormatAsync( diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs index 5726d27d96435..4159ee9de1ff6 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs @@ -25,12 +25,10 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.EventHookup; [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal sealed partial class EventHookupSessionManager( IThreadingContext threadingContext, - IToolTipService toolTipService, - IGlobalOptionService globalOptions) + IToolTipService toolTipService) { public readonly IThreadingContext ThreadingContext = threadingContext; private readonly IToolTipService _toolTipService = toolTipService; - private readonly IGlobalOptionService _globalOptions = globalOptions; private IToolTipPresenter _toolTipPresenter; @@ -113,7 +111,7 @@ internal void BeginSession( Mutex testSessionHookupMutex) { CurrentSession = new EventHookupSession( - this, eventHookupCommandHandler, textView, subjectBuffer, position, document, asyncListener, _globalOptions, testSessionHookupMutex); + this, eventHookupCommandHandler, textView, subjectBuffer, position, document, asyncListener, testSessionHookupMutex); } public void DismissExistingSessions() diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs index d777fcd367c42..795850ed1cf19 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs @@ -39,7 +39,6 @@ internal class EventHookupSession private readonly ITrackingSpan _trackingSpan; private readonly ITextView _textView; private readonly ITextBuffer _subjectBuffer; - private readonly IGlobalOptionService _globalOptions; public event Action Dismissed = () => { }; @@ -90,7 +89,6 @@ public EventHookupSession( int position, Document document, IAsynchronousOperationListener asyncListener, - IGlobalOptionService globalOptions, Mutex testSessionHookupMutex) { _threadingContext = eventHookupSessionManager.ThreadingContext; @@ -100,7 +98,6 @@ public EventHookupSession( var cancellationToken = _cancellationTokenSource.Token; _textView = textView; _subjectBuffer = subjectBuffer; - _globalOptions = globalOptions; this.TESTSessionHookupMutex = testSessionHookupMutex; // If the caret is at the end of the document we just create an empty span @@ -179,7 +176,6 @@ public EventHookupSession( new SymbolKindOrTypeKind(MethodKind.Ordinary), new DeclarationModifiers(isStatic: plusEqualsToken.Value.GetRequiredParent().IsInStaticContext()), Accessibility.Private, - _globalOptions.CreateProvider(), cancellationToken).ConfigureAwait(false); return GetEventHandlerName( diff --git a/src/EditorFeatures/CSharp/InlineRename/CSharpEditorInlineRenameService.cs b/src/EditorFeatures/CSharp/InlineRename/CSharpEditorInlineRenameService.cs index bbb8adf16055d..2182856f1451e 100644 --- a/src/EditorFeatures/CSharp/InlineRename/CSharpEditorInlineRenameService.cs +++ b/src/EditorFeatures/CSharp/InlineRename/CSharpEditorInlineRenameService.cs @@ -7,15 +7,13 @@ using System.Composition; using Microsoft.CodeAnalysis.Editor.Implementation.InlineRename; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; namespace Microsoft.CodeAnalysis.Editor.CSharp.InlineRename; [ExportLanguageService(typeof(IEditorInlineRenameService), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpEditorInlineRenameService( - [ImportMany] IEnumerable refactorNotifyServices, - IGlobalOptionService globalOptions) : AbstractEditorInlineRenameService(refactorNotifyServices, globalOptions) +internal sealed class CSharpEditorInlineRenameService([ImportMany] IEnumerable refactorNotifyServices) + : AbstractEditorInlineRenameService(refactorNotifyServices) { } diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs index a7c3c5c0a6f93..6a59b3af516b2 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs @@ -6,11 +6,12 @@ using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Completion; +using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Completion.Providers; using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.NamingStyles; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; @@ -704,11 +705,10 @@ public async Task Parameter13() using var workspaceFixture = GetOrCreateWorkspaceFixture(); var workspace = workspaceFixture.Target.GetWorkspace(GetComposition()); - - var options = new CompletionOptions() + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) { - NamingStyleFallbackOptions = ParameterCamelCaseWithPascalCaseFallback() - }; + { NamingStyleOptions.NamingPreferences, ParameterCamelCaseWithPascalCaseFallback() } + }); var markup = """ using System.Threading; @@ -717,8 +717,8 @@ public class C void Goo(CancellationToken $$ } """; - await VerifyItemExistsAsync(markup, "cancellationToken", glyph: (int)Glyph.Parameter, options: options); - await VerifyItemIsAbsentAsync(markup, "CancellationToken", options: options); + await VerifyItemExistsAsync(markup, "cancellationToken", glyph: (int)Glyph.Parameter); + await VerifyItemIsAbsentAsync(markup, "CancellationToken"); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52534")] @@ -2355,10 +2355,10 @@ public async Task CustomNamingStyleInsideClass() var workspace = workspaceFixture.Target.GetWorkspace(GetComposition()); - var options = new CompletionOptions() + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) { - NamingStyleFallbackOptions = NamesEndWithSuffixPreferences() - }; + { NamingStyleOptions.NamingPreferences, NamesEndWithSuffixPreferences() } + }); var markup = """ class Configuration @@ -2367,13 +2367,13 @@ class Configuration } """; await VerifyItemExistsAsync(markup, "ConfigurationField", glyph: (int)Glyph.FieldPublic, - expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name, options: options); + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); await VerifyItemExistsAsync(markup, "ConfigurationProperty", glyph: (int)Glyph.PropertyPublic, - expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name, options: options); + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); await VerifyItemExistsAsync(markup, "ConfigurationMethod", glyph: (int)Glyph.MethodPublic, - expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name, options: options); - await VerifyItemIsAbsentAsync(markup, "ConfigurationLocal", options: options); - await VerifyItemIsAbsentAsync(markup, "ConfigurationLocalFunction", options: options); + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); + await VerifyItemIsAbsentAsync(markup, "ConfigurationLocal"); + await VerifyItemIsAbsentAsync(markup, "ConfigurationLocalFunction"); } [Fact] @@ -2383,10 +2383,10 @@ public async Task CustomNamingStyleInsideMethod() var workspace = workspaceFixture.Target.GetWorkspace(GetComposition()); - var options = new CompletionOptions() + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) { - NamingStyleFallbackOptions = NamesEndWithSuffixPreferences() - }; + { NamingStyleOptions.NamingPreferences, NamesEndWithSuffixPreferences() } + }); var markup = """ class Configuration @@ -2398,12 +2398,12 @@ void M() } """; await VerifyItemExistsAsync(markup, "ConfigurationLocal", glyph: (int)Glyph.Local, - expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name, options: options); + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); await VerifyItemExistsAsync(markup, "ConfigurationLocalFunction", glyph: (int)Glyph.MethodPublic, - expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name, options: options); - await VerifyItemIsAbsentAsync(markup, "ConfigurationField", options: options); - await VerifyItemIsAbsentAsync(markup, "ConfigurationMethod", options: options); - await VerifyItemIsAbsentAsync(markup, "ConfigurationProperty", options: options); + expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name); + await VerifyItemIsAbsentAsync(markup, "ConfigurationField"); + await VerifyItemIsAbsentAsync(markup, "ConfigurationMethod"); + await VerifyItemIsAbsentAsync(markup, "ConfigurationProperty"); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31304")] @@ -2799,10 +2799,10 @@ public async Task ConflictingLocalVariable() var workspace = workspaceFixture.Target.GetWorkspace(GetComposition()); - var options = new CompletionOptions() + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) { - NamingStyleFallbackOptions = MultipleCamelCaseLocalRules() - }; + { NamingStyleOptions.NamingPreferences, MultipleCamelCaseLocalRules() } + }); var markup = """ public class MyClass @@ -2814,7 +2814,7 @@ void M() } } """; - await VerifyItemExistsAsync(markup, "myClass1", glyph: (int)Glyph.Local, options: options); + await VerifyItemExistsAsync(markup, "myClass1", glyph: (int)Glyph.Local); } [Fact] diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/PartialMethodCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/PartialMethodCompletionProviderTests.cs index 426f931ce747b..ad53c33da24ba 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/PartialMethodCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/PartialMethodCompletionProviderTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.Completion.Providers; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; @@ -883,9 +884,10 @@ public async Task ExpressionBodyMethod() using var workspaceFixture = GetOrCreateWorkspaceFixture(); var workspace = workspaceFixture.Target.GetWorkspace(GetComposition()); - workspace.GlobalOptions.SetGlobalOption( - CSharpCodeStyleOptions.PreferExpressionBodiedMethods, - new CodeStyleOption2(ExpressionBodyPreference.WhenPossible, NotificationOption2.Silent)); + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) + { + { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, new CodeStyleOption2(ExpressionBodyPreference.WhenPossible, NotificationOption2.Silent) } + }); var text = """ using System; @@ -894,8 +896,7 @@ partial class Bar partial void Foo(); partial $$ } - """ -; + """; var expected = """ using System; @@ -904,8 +905,7 @@ partial class Bar partial void Foo(); partial void Foo() => throw new NotImplementedException();$$ } - """ -; + """; await VerifyCustomCommitProviderAsync(text, "Foo()", expected); } @@ -916,9 +916,10 @@ public async Task ExpressionBodyMethodExtended() using var workspaceFixture = GetOrCreateWorkspaceFixture(); var workspace = workspaceFixture.Target.GetWorkspace(GetComposition()); - workspace.GlobalOptions.SetGlobalOption( - CSharpCodeStyleOptions.PreferExpressionBodiedMethods, - new CodeStyleOption2(ExpressionBodyPreference.WhenPossible, NotificationOption2.Silent)); + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) + { + { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, new CodeStyleOption2(ExpressionBodyPreference.WhenPossible, NotificationOption2.Silent) } + }); var text = """ using System; diff --git a/src/EditorFeatures/CSharpTest/EncapsulateField/EncapsulateFieldTestState.cs b/src/EditorFeatures/CSharpTest/EncapsulateField/EncapsulateFieldTestState.cs index 3621cfbca0454..d1168bd300556 100644 --- a/src/EditorFeatures/CSharpTest/EncapsulateField/EncapsulateFieldTestState.cs +++ b/src/EditorFeatures/CSharpTest/EncapsulateField/EncapsulateFieldTestState.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.Editor.CSharp.EncapsulateField; using Microsoft.CodeAnalysis.Editor.UnitTests; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; using Microsoft.CodeAnalysis.Notification; @@ -42,8 +43,11 @@ public static EncapsulateFieldTestState Create(string markup) { var workspace = EditorTestWorkspace.CreateCSharp(markup, composition: EditorTestCompositions.EditorFeatures); - workspace.GlobalOptions.SetGlobalOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.NeverWithSilentEnforcement); - workspace.GlobalOptions.SetGlobalOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithSilentEnforcement); + workspace.SetAnalyzerFallbackOptions(new OptionsCollection(LanguageNames.CSharp) + { + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.NeverWithSilentEnforcement }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithSilentEnforcement } + }); return new EncapsulateFieldTestState(workspace); } diff --git a/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs b/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs index bb034974a541b..45efedfb6e970 100644 --- a/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs +++ b/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs @@ -97,10 +97,7 @@ internal static async Task> GetIntentsAsync( OptionsCollection? options = null, string? intentData = null) { - if (options != null) - { - workspace.SetAnalyzerFallbackOptions(options); - } + workspace.SetAnalyzerFallbackOptions(options); var intentSource = workspace.ExportProvider.GetExportedValue(); diff --git a/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs b/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs index 9a6b5f99f6e92..9d9b78f9f1b8d 100644 --- a/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs +++ b/src/EditorFeatures/Core/AddImports/AbstractAddImportsPasteCommandHandler.cs @@ -153,7 +153,7 @@ private async Task ExecuteAsync(Document document, SnapshotSpan snapshotSpan, IT var addMissingImportsService = document.GetRequiredLanguageService(); - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var options = new AddMissingImportsOptions( CleanupOptions: cleanupOptions, diff --git a/src/EditorFeatures/Core/ChangeSignature/AbstractChangeSignatureCommandHandler.cs b/src/EditorFeatures/Core/ChangeSignature/AbstractChangeSignatureCommandHandler.cs index b507304529471..3123472b90d4a 100644 --- a/src/EditorFeatures/Core/ChangeSignature/AbstractChangeSignatureCommandHandler.cs +++ b/src/EditorFeatures/Core/ChangeSignature/AbstractChangeSignatureCommandHandler.cs @@ -23,12 +23,10 @@ internal abstract class AbstractChangeSignatureCommandHandler : ICommandHandler< ICommandHandler { private readonly IThreadingContext _threadingContext; - private readonly IGlobalOptionService _globalOptions; - protected AbstractChangeSignatureCommandHandler(IThreadingContext threadingContext, IGlobalOptionService globalOptions) + protected AbstractChangeSignatureCommandHandler(IThreadingContext threadingContext) { _threadingContext = threadingContext; - _globalOptions = globalOptions; } public string DisplayName => EditorFeaturesResources.Change_Signature; @@ -87,7 +85,6 @@ private bool ExecuteCommand(ITextView textView, ITextBuffer subjectBuffer, Comma document, caretPoint.Value.Position, restrictToDeclarations: false, - _globalOptions.CreateProvider(), cancellationToken).WaitAndGetResult(context.OperationContext.UserCancellationToken); // UI thread bound operation to show the change signature dialog. diff --git a/src/EditorFeatures/Core/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs b/src/EditorFeatures/Core/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs index ba26636d3a759..eef94a67609e2 100644 --- a/src/EditorFeatures/Core/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs +++ b/src/EditorFeatures/Core/EncapsulateField/AbstractEncapsulateFieldCommandHandler.cs @@ -25,12 +25,10 @@ namespace Microsoft.CodeAnalysis.EncapsulateField; internal abstract class AbstractEncapsulateFieldCommandHandler( IThreadingContext threadingContext, ITextBufferUndoManagerProvider undoManager, - IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider) : ICommandHandler { private readonly IThreadingContext _threadingContext = threadingContext; private readonly ITextBufferUndoManagerProvider _undoManager = undoManager; - private readonly IGlobalOptionService _globalOptions = globalOptions; private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.EncapsulateField); public string DisplayName => EditorFeaturesResources.Encapsulate_Field; @@ -80,7 +78,7 @@ private async Task ExecuteAsync( var service = document.GetRequiredLanguageService(); var result = await service.EncapsulateFieldsInSpanAsync( - document, span.Span.ToTextSpan(), _globalOptions.CreateProvider(), useDefaultBehavior: true, cancellationToken).ConfigureAwait(false); + document, span.Span.ToTextSpan(), useDefaultBehavior: true, cancellationToken).ConfigureAwait(false); if (result == null) { diff --git a/src/EditorFeatures/Core/ExternalAccess/UnitTestGenerator/Api/UnitTestGeneratorAddMissingImportsFeatureServiceAccessor.cs b/src/EditorFeatures/Core/ExternalAccess/UnitTestGenerator/Api/UnitTestGeneratorAddMissingImportsFeatureServiceAccessor.cs index b7e63cf54a632..2f835872dc4d6 100644 --- a/src/EditorFeatures/Core/ExternalAccess/UnitTestGenerator/Api/UnitTestGeneratorAddMissingImportsFeatureServiceAccessor.cs +++ b/src/EditorFeatures/Core/ExternalAccess/UnitTestGenerator/Api/UnitTestGeneratorAddMissingImportsFeatureServiceAccessor.cs @@ -53,7 +53,7 @@ internal async Task AddMissingImportsAsync(Document document, WrappedM private async Task GetOptionsAsync(Document document, CancellationToken cancellationToken) { - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var options = new AddMissingImportsOptions( CleanupOptions: cleanupOptions, diff --git a/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.InlineRenameLocationSet.cs b/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.InlineRenameLocationSet.cs index e5bde7f99fc98..edf97e98f5c60 100644 --- a/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.InlineRenameLocationSet.cs +++ b/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.InlineRenameLocationSet.cs @@ -17,19 +17,16 @@ internal abstract partial class AbstractEditorInlineRenameService private class InlineRenameLocationSet : IInlineRenameLocationSet { private readonly LightweightRenameLocations _renameLocationSet; - private readonly CodeCleanupOptionsProvider _fallbackOptions; private readonly SymbolInlineRenameInfo _renameInfo; public IList Locations { get; } public InlineRenameLocationSet( SymbolInlineRenameInfo renameInfo, - LightweightRenameLocations renameLocationSet, - CodeCleanupOptionsProvider fallbackOptions) + LightweightRenameLocations renameLocationSet) { _renameInfo = renameInfo; _renameLocationSet = renameLocationSet; - _fallbackOptions = fallbackOptions; this.Locations = renameLocationSet.Locations.Where(RenameLocation.ShouldRename) .Select(ConvertLocation) .ToImmutableArray(); @@ -47,7 +44,7 @@ public async Task GetReplacementsAsync( CancellationToken cancellationToken) { var conflicts = await _renameLocationSet.ResolveConflictsAsync( - _renameInfo.RenameSymbol, _renameInfo.GetFinalSymbolName(replacementText), nonConflictSymbolKeys: default, _fallbackOptions, cancellationToken).ConfigureAwait(false); + _renameInfo.RenameSymbol, _renameInfo.GetFinalSymbolName(replacementText), nonConflictSymbolKeys: default, cancellationToken).ConfigureAwait(false); return new InlineRenameReplacementInfo(conflicts); } diff --git a/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs b/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs index 22c70dce44a93..84ce9c84ad181 100644 --- a/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs +++ b/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs @@ -31,7 +31,6 @@ private partial class SymbolInlineRenameInfo : IInlineRenameInfo private readonly SymbolicRenameInfo _info; private Document Document => _info.Document!; - private readonly CodeCleanupOptionsProvider _fallbackOptions; private readonly IEnumerable _refactorNotifyServices; /// @@ -56,7 +55,6 @@ private partial class SymbolInlineRenameInfo : IInlineRenameInfo public SymbolInlineRenameInfo( IEnumerable refactorNotifyServices, SymbolicRenameInfo info, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { Contract.ThrowIfTrue(info.IsError); @@ -64,7 +62,6 @@ public SymbolInlineRenameInfo( _info = info; _refactorNotifyServices = refactorNotifyServices; - _fallbackOptions = fallbackOptions; this.HasOverloads = RenameUtilities.GetOverloadedSymbols(this.RenameSymbol).Any(); @@ -139,7 +136,7 @@ public async Task FindRenameLocationsAsync(SymbolRenam var locations = await Renamer.FindRenameLocationsAsync( solution, this.RenameSymbol, options, cancellationToken).ConfigureAwait(false); - return new InlineRenameLocationSet(this, locations, _fallbackOptions); + return new InlineRenameLocationSet(this, locations); } public bool TryOnBeforeGlobalSymbolRenamed(Workspace workspace, IEnumerable changedDocumentIDs, string replacementText) diff --git a/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.cs b/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.cs index 5534d677149a0..da79cfcc93338 100644 --- a/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.cs +++ b/src/EditorFeatures/Core/InlineRename/AbstractEditorInlineRenameService.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Rename; namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename; @@ -13,12 +12,10 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename; internal abstract partial class AbstractEditorInlineRenameService : IEditorInlineRenameService { private readonly IEnumerable _refactorNotifyServices; - private readonly IGlobalOptionService _globalOptions; - protected AbstractEditorInlineRenameService(IEnumerable refactorNotifyServices, IGlobalOptionService globalOptions) + protected AbstractEditorInlineRenameService(IEnumerable refactorNotifyServices) { _refactorNotifyServices = refactorNotifyServices; - _globalOptions = globalOptions; } public async Task GetRenameInfoAsync(Document document, int position, CancellationToken cancellationToken) @@ -28,6 +25,6 @@ public async Task GetRenameInfoAsync(Document document, int p return new FailureInlineRenameInfo(symbolicInfo.LocalizedErrorMessage); return new SymbolInlineRenameInfo( - _refactorNotifyServices, symbolicInfo, _globalOptions.CreateProvider(), cancellationToken); + _refactorNotifyServices, symbolicInfo, cancellationToken); } } diff --git a/src/EditorFeatures/Core/Intents/DeleteParameterIntentProvider.cs b/src/EditorFeatures/Core/Intents/DeleteParameterIntentProvider.cs index 39bcf08b2e211..403c3981ef0d8 100644 --- a/src/EditorFeatures/Core/Intents/DeleteParameterIntentProvider.cs +++ b/src/EditorFeatures/Core/Intents/DeleteParameterIntentProvider.cs @@ -20,10 +20,8 @@ namespace Microsoft.CodeAnalysis.EditorFeatures.Intents; [IntentProvider(WellKnownIntents.DeleteParameter, LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class DeleteParameterIntentProvider(IGlobalOptionService globalOptionService) : IIntentProvider +internal sealed class DeleteParameterIntentProvider() : IIntentProvider { - private readonly IGlobalOptionService _globalOptionService = globalOptionService; - public async Task> ComputeIntentAsync( Document priorDocument, TextSpan priorSelection, @@ -33,7 +31,7 @@ public async Task> ComputeIntentAsync( { var changeSignatureService = priorDocument.GetRequiredLanguageService(); var contextResult = await changeSignatureService.GetChangeSignatureContextAsync( - priorDocument, priorSelection.Start, restrictToDeclarations: false, _globalOptionService.CreateProvider(), cancellationToken).ConfigureAwait(false); + priorDocument, priorSelection.Start, restrictToDeclarations: false, cancellationToken).ConfigureAwait(false); if (contextResult is not ChangeSignatureAnalysisSucceededContext context) { diff --git a/src/EditorFeatures/Core/LanguageServer/EditorHoverCreationService.cs b/src/EditorFeatures/Core/LanguageServer/EditorHoverCreationService.cs index 6cd6b3c9f2149..ee23ab84b775d 100644 --- a/src/EditorFeatures/Core/LanguageServer/EditorHoverCreationService.cs +++ b/src/EditorFeatures/Core/LanguageServer/EditorHoverCreationService.cs @@ -45,7 +45,7 @@ public async Task CreateHoverAsync( : new IntellisenseQuickInfoBuilderContext( document, classificationOptions, - await document.GetLineFormattingOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false), + await document.GetLineFormattingOptionsAsync(cancellationToken).ConfigureAwait(false), threadingContext: null, operationExecutor: null, asynchronousOperationListener: null, diff --git a/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs b/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs index 50ab0fb90a025..fc5a3c94fa71c 100644 --- a/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs +++ b/src/EditorFeatures/Core/Options/TextBufferOptionProviders.cs @@ -69,7 +69,7 @@ public static AddImportPlacementOptions GetAddImportPlacementOptions(this ITextB { var editorOptions = optionsProvider.Factory.GetOptions(textBuffer); var configOptions = editorOptions.ToAnalyzerConfigOptions(fallbackOptions); - return configOptions.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions, fallbackOptions: null); + return configOptions.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions); } public static CodeCleanupOptions GetCodeCleanupOptions(this ITextBuffer textBuffer, EditorOptionsService optionsProvider, StructuredAnalyzerConfigOptions fallbackOptions, LanguageServices languageServices, bool explicitFormat, bool allowImportsInHiddenRegions) @@ -77,7 +77,7 @@ public static CodeCleanupOptions GetCodeCleanupOptions(this ITextBuffer textBuff var editorOptions = optionsProvider.Factory.GetOptions(textBuffer); var configOptions = editorOptions.ToAnalyzerConfigOptions(fallbackOptions); - var options = configOptions.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions: null); + var options = configOptions.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions); var lineFormattingOptions = GetLineFormattingOptionsImpl(textBuffer, editorOptions, optionsProvider.IndentationManager, explicitFormat); return options with { FormattingOptions = options.FormattingOptions with { LineFormatting = lineFormattingOptions } }; diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs b/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs index 9c7a3734976ca..827de1a7e388e 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/ChangeSignature/ChangeSignatureTestState.cs @@ -72,14 +72,14 @@ public TestChangeSignatureOptionsService TestChangeSignatureOptionsService public async Task ChangeSignatureAsync() { - var context = await ChangeSignatureService.GetChangeSignatureContextAsync(InvocationDocument, _testDocument.CursorPosition.Value, restrictToDeclarations: false, Workspace.GlobalOptions.CreateProvider(), CancellationToken.None).ConfigureAwait(false); + var context = await ChangeSignatureService.GetChangeSignatureContextAsync(InvocationDocument, _testDocument.CursorPosition.Value, restrictToDeclarations: false, CancellationToken.None).ConfigureAwait(false); var options = AbstractChangeSignatureService.GetChangeSignatureOptions(context); return await ChangeSignatureService.ChangeSignatureWithContextAsync(context, options, CancellationToken.None); } public async Task GetParameterConfigurationAsync() { - var context = await ChangeSignatureService.GetChangeSignatureContextAsync(InvocationDocument, _testDocument.CursorPosition.Value, restrictToDeclarations: false, Workspace.GlobalOptions.CreateProvider(), CancellationToken.None); + var context = await ChangeSignatureService.GetChangeSignatureContextAsync(InvocationDocument, _testDocument.CursorPosition.Value, restrictToDeclarations: false, CancellationToken.None); if (context is ChangeSignatureAnalysisSucceededContext changeSignatureAnalyzedSucceedContext) { return changeSignatureAnalyzedSucceedContext.ParameterConfiguration; diff --git a/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs b/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs index 2129744c6d369..3a9abd1f05eec 100644 --- a/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs +++ b/src/EditorFeatures/Test/CodeGeneration/CodeGenerationTests.cs @@ -47,8 +47,7 @@ internal static async Task TestAddNamespaceAsync( testContext.Result = await testContext.Service.AddNamespaceAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamespaceSymbol)testContext.GetDestination(), @namespace, CancellationToken.None); @@ -82,8 +81,7 @@ internal static async Task TestAddFieldAsync( testContext.Result = await testContext.Service.AddFieldAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), field, CancellationToken.None); @@ -91,7 +89,7 @@ internal static async Task TestAddFieldAsync( else { var root = await testContext.Document.GetSyntaxRootAsync(); - var options = await testContext.Document.GetCodeGenerationOptionsAsync(testContext.Workspace.GlobalOptions, CancellationToken.None); + var options = await testContext.Document.GetCodeGenerationOptionsAsync(CancellationToken.None); var info = testContext.Service.GetInfo(context ?? CodeGenerationContext.Default, options, root.SyntaxTree.Options); var newRoot = testContext.Service.AddField(root, field, info, CancellationToken.None); testContext.Result = testContext.Document.WithSyntaxRoot(newRoot); @@ -125,8 +123,7 @@ internal static async Task TestAddConstructorAsync( testContext.Result = await testContext.Service.AddMethodAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), ctor, CancellationToken.None); @@ -171,8 +168,7 @@ internal static async Task TestAddMethodAsync( testContext.Result = await testContext.Service.AddMethodAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), method, CancellationToken.None); @@ -213,8 +209,7 @@ internal static async Task TestAddOperatorsAsync( testContext.Result = await testContext.Service.AddMembersAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), methods.ToArray(), CancellationToken.None); @@ -249,8 +244,7 @@ internal static async Task TestAddUnsupportedOperatorAsync( await testContext.Service.AddMethodAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), method, CancellationToken.None); @@ -296,8 +290,7 @@ internal static async Task TestAddConversionAsync( testContext.Result = await testContext.Service.AddMethodAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), method, CancellationToken.None); @@ -317,7 +310,7 @@ internal static async Task TestAddStatementsAsync( using var testContext = await TestContext.CreateAsync(initial, expected); var parsedStatements = testContext.ParseStatements(statements); var oldSyntax = testContext.GetSelectedSyntax(true); - var options = await testContext.Document.GetCodeGenerationOptionsAsync(testContext.Workspace.GlobalOptions, CancellationToken.None); + var options = await testContext.Document.GetCodeGenerationOptionsAsync(CancellationToken.None); var info = testContext.Service.GetInfo(context ?? CodeGenerationContext.Default, options, oldSyntax.SyntaxTree.Options); var newSyntax = testContext.Service.AddStatements(oldSyntax, parsedStatements, info, CancellationToken.None); testContext.Result = testContext.Document.WithSyntaxRoot((await testContext.Document.GetSyntaxRootAsync()).ReplaceNode(oldSyntax, newSyntax)); @@ -332,7 +325,7 @@ internal static async Task TestAddParametersAsync( using var testContext = await TestContext.CreateAsync(initial, expected); var parameterSymbols = GetParameterSymbols(parameters, testContext); var oldMemberSyntax = testContext.GetSelectedSyntax(true); - var options = await testContext.Document.GetCodeGenerationOptionsAsync(testContext.Workspace.GlobalOptions, CancellationToken.None); + var options = await testContext.Document.GetCodeGenerationOptionsAsync(CancellationToken.None); var info = testContext.Service.GetInfo(context ?? CodeGenerationContext.Default, options, oldMemberSyntax.SyntaxTree.Options); var newMemberSyntax = testContext.Service.AddParameters(oldMemberSyntax, parameterSymbols, info, CancellationToken.None); @@ -365,8 +358,7 @@ internal static async Task TestAddDelegateTypeAsync( testContext.Result = await testContext.Service.AddNamedTypeAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), type, CancellationToken.None); @@ -406,8 +398,7 @@ internal static async Task TestAddEventAsync( testContext.Result = await testContext.Service.AddEventAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), @event, CancellationToken.None); @@ -442,7 +433,7 @@ internal static async Task TestAddPropertyAsync( using var testContext = await TestContext.CreateAsync(initial, expected); var workspace = testContext.Workspace; - options?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackOptions(options); var typeSymbol = GetTypeSymbol(type)(testContext.SemanticModel); var getParameterSymbols = GetParameterSymbols(parameters, testContext); @@ -500,8 +491,7 @@ internal static async Task TestAddPropertyAsync( testContext.Result = await testContext.Service.AddPropertyAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamedTypeSymbol)testContext.GetDestination(), property, CancellationToken.None); @@ -530,8 +520,7 @@ internal static async Task TestAddNamedTypeAsync( testContext.Result = await testContext.Service.AddNamedTypeAsync( new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()), + context ?? CodeGenerationContext.Default), (INamespaceSymbol)testContext.GetDestination(), type, CancellationToken.None); @@ -547,7 +536,7 @@ internal static async Task TestAddAttributeAsync( var attr = CodeGenerationSymbolFactory.CreateAttributeData(GetTypeSymbol(attributeClass)(testContext.SemanticModel)); var oldNode = testContext.GetDestinationNode(); var codeGenerator = testContext.Document.GetRequiredLanguageService(); - var options = await testContext.Document.GetCodeGenerationOptionsAsync(testContext.Workspace.GlobalOptions, CancellationToken.None); + var options = await testContext.Document.GetCodeGenerationOptionsAsync(CancellationToken.None); var info = codeGenerator.GetInfo(CodeGenerationContext.Default, options, oldNode.SyntaxTree.Options); var newNode = codeGenerator.AddAttributes(oldNode, new[] { attr }, target, info, CancellationToken.None) .WithAdditionalAnnotations(Formatter.Annotation); @@ -566,7 +555,7 @@ internal static async Task TestRemoveAttributeAsync( var attribute = attributeTarget.GetAttributes().Single(attr => Equals(attr.AttributeClass, attributeType)); var declarationNode = taggedNode.FirstAncestorOrSelf(); var codeGenerator = testContext.Document.GetRequiredLanguageService(); - var options = await testContext.Document.GetCodeGenerationOptionsAsync(testContext.Workspace.GlobalOptions, CancellationToken.None); + var options = await testContext.Document.GetCodeGenerationOptionsAsync(CancellationToken.None); var info = codeGenerator.GetInfo(CodeGenerationContext.Default, options, testContext.SemanticModel.SyntaxTree.Options); var newNode = codeGenerator.RemoveAttribute(declarationNode, attribute, info, CancellationToken.None) .WithAdditionalAnnotations(Formatter.Annotation); @@ -588,7 +577,7 @@ internal static async Task TestUpdateDeclarationAsync( var updatedDeclarationNode = declarationNode; var codeGenerator = testContext.Document.GetRequiredLanguageService(); - var options = await testContext.Document.GetCodeGenerationOptionsAsync(testContext.Workspace.GlobalOptions, CancellationToken.None); + var options = await testContext.Document.GetCodeGenerationOptionsAsync(CancellationToken.None); var info = codeGenerator.GetInfo(new CodeGenerationContext(reuseSyntax: true), options, declarationNode.SyntaxTree.Options); if (accessibility.HasValue) { @@ -648,8 +637,7 @@ internal static async Task TestGenerateFromSourceSymbolAsync( var solutionContext = new CodeGenerationSolutionContext( testContext.Solution, - context ?? CodeGenerationContext.Default, - testContext.Workspace.GlobalOptions.CreateProvider()); + context ?? CodeGenerationContext.Default); var symbol = TestContext.GetSelectedSymbol(destSpan, semanticModel); var destination = testContext.GetDestination(); diff --git a/src/EditorFeatures/Test/Formatting/InferredIndentationTests.cs b/src/EditorFeatures/Test/Formatting/InferredIndentationTests.cs index 9cd143b45590e..3f56cc8e89ee0 100644 --- a/src/EditorFeatures/Test/Formatting/InferredIndentationTests.cs +++ b/src/EditorFeatures/Test/Formatting/InferredIndentationTests.cs @@ -23,7 +23,7 @@ public async Task BlankFileMatchesWorkspaceSettings() { using var testWorkspace = CreateWithLines( ""); - var options = await testWorkspace.CurrentSolution.Projects.Single().Documents.Single().GetLineFormattingOptionsAsync(testWorkspace.GlobalOptions, CancellationToken.None); + var options = await testWorkspace.CurrentSolution.Projects.Single().Documents.Single().GetLineFormattingOptionsAsync(CancellationToken.None); Assert.Equal(FormattingOptions.UseTabs.DefaultValue, options.UseTabs); } @@ -36,7 +36,7 @@ public async Task SingleLineWithTab() "{", "\tvoid M() { }", "}"); - var options = await testWorkspace.CurrentSolution.Projects.Single().Documents.Single().GetLineFormattingOptionsAsync(testWorkspace.GlobalOptions, CancellationToken.None); + var options = await testWorkspace.CurrentSolution.Projects.Single().Documents.Single().GetLineFormattingOptionsAsync(CancellationToken.None); // the indentation is only inferred by a command handler: Assert.False(options.UseTabs); @@ -50,7 +50,7 @@ public async Task SingleLineWithFourSpaces() "{", " void M() { }", "}"); - var options = await testWorkspace.CurrentSolution.Projects.Single().Documents.Single().GetLineFormattingOptionsAsync(testWorkspace.GlobalOptions, CancellationToken.None); + var options = await testWorkspace.CurrentSolution.Projects.Single().Documents.Single().GetLineFormattingOptionsAsync(CancellationToken.None); Assert.False(options.UseTabs); Assert.Equal(4, options.IndentationSize); diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb index f0aa89b965adf..9ae5870c7b80f 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb @@ -137,13 +137,13 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Dim locations = Renamer.FindRenameLocationsAsync( solution, symbol, renameOptions, CancellationToken.None).GetAwaiter().GetResult() - Return locations.ResolveConflictsAsync(symbol, renameTo, nonConflictSymbolKeys:=Nothing, CodeActionOptions.DefaultProvider, CancellationToken.None).GetAwaiter().GetResult() + Return locations.ResolveConflictsAsync(symbol, renameTo, nonConflictSymbolKeys:=Nothing, CancellationToken.None).GetAwaiter().GetResult() Else ' This tests that rename properly works when the entire call is remoted to OOP and the final result is ' marshaled back. Return Renamer.RenameSymbolAsync( - solution, symbol, renameTo, renameOptions, CodeActionOptions.DefaultProvider, + solution, symbol, renameTo, renameOptions, nonConflictSymbolKeys:=Nothing, CancellationToken.None).GetAwaiter().GetResult() End If End Function diff --git a/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs b/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs index 391038d500ee7..f7cb89eafdcb4 100644 --- a/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs +++ b/src/EditorFeatures/TestUtilities/Completion/AbstractCompletionProviderTests.cs @@ -246,7 +246,7 @@ private async Task VerifyAsync( var position = workspaceFixture.Target.Position; // Set options that are not CompletionOptions - NonCompletionOptions?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(NonCompletionOptions); await VerifyWorkerAsync( code, position, expectedItemOrNull, expectedDescriptionOrNull, @@ -263,7 +263,7 @@ protected async Task GetCompletionListAsync(string markup, strin var workspace = workspaceFixture.Target.GetWorkspace(markup, GetComposition(), workspaceKind: workspaceKind); // Set options that are not CompletionOptions - NonCompletionOptions?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(NonCompletionOptions); var currentDocument = workspace.CurrentSolution.GetDocument(workspaceFixture.Target.CurrentDocument.Id); var position = workspaceFixture.Target.Position; @@ -441,7 +441,7 @@ protected virtual async Task VerifyCustomCommitProviderWorkerAsync(string codeBe var workspace = workspaceFixture.Target.GetWorkspace(); // Set options that are not CompletionOptions - NonCompletionOptions?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(NonCompletionOptions); var document1 = workspaceFixture.Target.UpdateDocument(codeBeforeCommit, sourceCodeKind); await VerifyCustomCommitProviderCheckResultsAsync(document1, codeBeforeCommit, position, itemToCommit, expectedCodeAfterCommit, commitChar); @@ -564,7 +564,7 @@ private async Task VerifyProviderCommitWorkerAsync(string codeBeforeCommit, int var workspace = workspaceFixture.Target.GetWorkspace(); // Set options that are not CompletionOptions - NonCompletionOptions?.SetGlobalOptions(workspace.GlobalOptions); + workspace.SetAnalyzerFallbackAndGlobalOptions(NonCompletionOptions); var document1 = workspaceFixture.Target.UpdateDocument(codeBeforeCommit, sourceCodeKind); await VerifyProviderCommitCheckResultsAsync(document1, position, itemToCommit, expectedCodeAfterCommit, commitChar); diff --git a/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs b/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs index 4a669f198a215..441ac828ce5b6 100644 --- a/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs +++ b/src/EditorFeatures/TestUtilities/Formatting/AbstractNewDocumentFormattingServiceTests.cs @@ -31,7 +31,7 @@ internal async Task TestAsync(string testCode, string expected, OptionsCollectio var languageServices = document.Project.Services; var cleanupOptions = - options?.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions: false, fallbackOptions: null) ?? + options?.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions: false) ?? CodeCleanupOptions.GetDefault(languageServices); var formattingService = document.GetRequiredLanguageService(); diff --git a/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb b/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb index c14df486a5d79..4d3eb23909fbd 100644 --- a/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/ChangeSignature/VisualBasicChangeSignatureCommandHandler.vb @@ -19,8 +19,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.ChangeSignature - Public Sub New(threadingContext As IThreadingContext, globalOptions As IGlobalOptionService) - MyBase.New(threadingContext, globalOptions) + Public Sub New(threadingContext As IThreadingContext) + MyBase.New(threadingContext) End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasic/EncapsulateField/EncapsulateFieldCommandHandler.vb b/src/EditorFeatures/VisualBasic/EncapsulateField/EncapsulateFieldCommandHandler.vb index 692cfdb2df231..d4b69f411287a 100644 --- a/src/EditorFeatures/VisualBasic/EncapsulateField/EncapsulateFieldCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/EncapsulateField/EncapsulateFieldCommandHandler.vb @@ -25,9 +25,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EncapsulateField Public Sub New(threadingContext As IThreadingContext, undoManager As ITextBufferUndoManagerProvider, - globalOptions As IGlobalOptionService, listenerProvider As IAsynchronousOperationListenerProvider) - MyBase.New(threadingContext, undoManager, globalOptions, listenerProvider) + MyBase.New(threadingContext, undoManager, listenerProvider) End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasic/InlineRename/VisualBasicEditorInlineRenameService.vb b/src/EditorFeatures/VisualBasic/InlineRename/VisualBasicEditorInlineRenameService.vb index 81d7f2af0c0ac..1cf77bbc7ccfd 100644 --- a/src/EditorFeatures/VisualBasic/InlineRename/VisualBasicEditorInlineRenameService.vb +++ b/src/EditorFeatures/VisualBasic/InlineRename/VisualBasicEditorInlineRenameService.vb @@ -15,8 +15,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.InlineRename Public Sub New( - refactorNotifyServices As IEnumerable(Of IRefactorNotifyService), globalOptions As IGlobalOptionService) - MyBase.New(refactorNotifyServices, globalOptions) + refactorNotifyServices As IEnumerable(Of IRefactorNotifyService)) + MyBase.New(refactorNotifyServices) End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb b/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb index b98364b8ffbf6..3ee84e235c595 100644 --- a/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb +++ b/src/EditorFeatures/VisualBasic/NavigationBar/VisualBasicEditorNavigationBarItemService_CodeGeneration.vb @@ -29,7 +29,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar Dim generatedTree = Await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) Dim generatedNode = generatedTree.GetAnnotatedNodes(GeneratedSymbolAnnotation).Single().FirstAncestorOrSelf(Of MethodBlockBaseSyntax) - Dim formattingOptions = Await document.GetLineFormattingOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(False) + Dim formattingOptions = Await document.GetLineFormattingOptionsAsync(cancellationToken).ConfigureAwait(False) Dim indentSize = formattingOptions.IndentationSize Dim navigationPoint = NavigationPointHelpers.GetNavigationPoint(generatedTree.GetText(text.Encoding), indentSize, generatedNode) @@ -146,8 +146,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar Return Await CodeGenerator.AddMethodDeclarationAsync( New CodeGenerationSolutionContext( document.Project.Solution, - codeGenerationContext, - fallbackOptions), + codeGenerationContext), destinationType, methodSymbol, cancellationToken).ConfigureAwait(False) @@ -203,8 +202,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar Return Await CodeGenerator.AddMethodDeclarationAsync( New CodeGenerationSolutionContext( document.Project.Solution, - codeGenerationContext, - fallbackOptions), + codeGenerationContext), destinationType, methodSymbol, cancellationToken).ConfigureAwait(False) @@ -249,8 +247,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar Return Await CodeGenerator.AddMethodDeclarationAsync( New CodeGenerationSolutionContext( document.Project.Solution, - codeGenerationContext, - fallbackOptions), + codeGenerationContext), destinationType, finalizerMethodSymbol, cancellationToken).ConfigureAwait(False) @@ -278,8 +275,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.NavigationBar Return Await CodeGenerator.AddMethodDeclarationAsync( New CodeGenerationSolutionContext( document.Project.Solution, - codeGenerationContext, - fallbackOptions), + codeGenerationContext), destinationType, codeGenerationSymbol, cancellationToken).ConfigureAwait(False) diff --git a/src/EditorFeatures/VisualBasic/Utilities/CommandHandlers/AbstractImplementAbstractClassOrInterfaceCommandHandler.vb b/src/EditorFeatures/VisualBasic/Utilities/CommandHandlers/AbstractImplementAbstractClassOrInterfaceCommandHandler.vb index a6e99c41e1b21..689a32dea0b0e 100644 --- a/src/EditorFeatures/VisualBasic/Utilities/CommandHandlers/AbstractImplementAbstractClassOrInterfaceCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/Utilities/CommandHandlers/AbstractImplementAbstractClassOrInterfaceCommandHandler.vb @@ -171,7 +171,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Utilities.CommandHandlers Return False End If - Dim cleanupOptions = newDocument.GetCodeCleanupOptionsAsync(_globalOptions, cancellationToken).AsTask().WaitAndGetResult(cancellationToken) + Dim cleanupOptions = newDocument.GetCodeCleanupOptionsAsync(cancellationToken).AsTask().WaitAndGetResult(cancellationToken) newDocument = Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, cleanupOptions.SimplifierOptions, cancellationToken).WaitAndGetResult(cancellationToken) newDocument = Formatter.FormatAsync(newDocument, Formatter.Annotation, cleanupOptions.FormattingOptions, cancellationToken).WaitAndGetResult(cancellationToken) diff --git a/src/EditorFeatures/VisualBasicTest/ChangeSignature/RemoveParametersTests.vb b/src/EditorFeatures/VisualBasicTest/ChangeSignature/RemoveParametersTests.vb index f39edbc377563..32fd1ee558113 100644 --- a/src/EditorFeatures/VisualBasicTest/ChangeSignature/RemoveParametersTests.vb +++ b/src/EditorFeatures/VisualBasicTest/ChangeSignature/RemoveParametersTests.vb @@ -115,8 +115,7 @@ End Module Dim textView = workspace.Documents.Single().GetTextView() Dim handler = New VisualBasicChangeSignatureCommandHandler( - workspace.GetService(Of IThreadingContext), - workspace.GlobalOptions) + workspace.GetService(Of IThreadingContext)) Dim state = handler.GetCommandState(New ReorderParametersCommandArgs(textView, textView.TextBuffer)) Assert.True(state.IsUnspecified) diff --git a/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldCommandHandlerTests.vb b/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldCommandHandlerTests.vb index 32189a5d737eb..54d0e6f4edc8f 100644 --- a/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldCommandHandlerTests.vb +++ b/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldCommandHandlerTests.vb @@ -155,7 +155,6 @@ End Class Dim handler = New EncapsulateFieldCommandHandler( workspace.GetService(Of IThreadingContext), workspace.GetService(Of ITextBufferUndoManagerProvider), - workspace.GlobalOptions, workspace.GetService(Of IAsynchronousOperationListenerProvider)()) Dim state = handler.GetCommandState(New EncapsulateFieldCommandArgs(textView, textView.TextBuffer)) diff --git a/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldTestState.vb b/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldTestState.vb index 74958b71dda2a..efdacb32827ab 100644 --- a/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldTestState.vb +++ b/src/EditorFeatures/VisualBasicTest/EncapsulateField/EncapsulateFieldTestState.vb @@ -35,7 +35,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EncapsulateField Dim commandHandler = New EncapsulateFieldCommandHandler( Workspace.ExportProvider.GetExportedValue(Of IThreadingContext)(), Workspace.GetService(Of ITextBufferUndoManagerProvider)(), - Workspace.GlobalOptions, Workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)) Dim provider = Workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)() Dim waiter = DirectCast(provider.GetListener(FeatureAttribute.EncapsulateField), IAsynchronousOperationWaiter) diff --git a/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs b/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs index d22b7ece85de4..198bb9af69ab6 100644 --- a/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs +++ b/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs @@ -292,7 +292,6 @@ public override async Task ChangeSignatureAsync( SyntaxNode potentiallyUpdatedNode, SyntaxNode originalNode, SignatureChange signaturePermutation, - LineFormattingOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var updatedNode = potentiallyUpdatedNode as CSharpSyntaxNode; @@ -308,7 +307,7 @@ or SyntaxKind.RecordDeclaration or SyntaxKind.StructDeclaration or SyntaxKind.ClassDeclaration) { - var updatedLeadingTrivia = await UpdateParamTagsInLeadingTriviaAsync(document, updatedNode, declarationSymbol, signaturePermutation, fallbackOptions, cancellationToken).ConfigureAwait(false); + var updatedLeadingTrivia = await UpdateParamTagsInLeadingTriviaAsync(document, updatedNode, declarationSymbol, signaturePermutation, cancellationToken).ConfigureAwait(false); if (updatedLeadingTrivia != default && !updatedLeadingTrivia.IsEmpty) { updatedNode = updatedNode.WithLeadingTrivia(updatedLeadingTrivia); @@ -767,7 +766,7 @@ private ImmutableArray TransferLeadingWhitespaceTrivia(IEnumerable n } private async ValueTask> UpdateParamTagsInLeadingTriviaAsync( - Document document, CSharpSyntaxNode node, ISymbol declarationSymbol, SignatureChange updatedSignature, LineFormattingOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, CSharpSyntaxNode node, ISymbol declarationSymbol, SignatureChange updatedSignature, CancellationToken cancellationToken) { if (!node.HasLeadingTrivia) { @@ -785,7 +784,7 @@ private async ValueTask> UpdateParamTagsInLeadingTr return []; } - var options = await document.GetLineFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetLineFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); return GetPermutedDocCommentTrivia(node, permutedParamNodes, document.Project.Services, options); } diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs index 00ede73eb5763..9c8da121dba61 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.cs @@ -33,10 +33,10 @@ public GenerateEnumMemberCodeFixProvider() public override ImmutableArray FixableDiagnosticIds { get; } = [CS0117, CS1061]; - protected override Task> GetCodeActionsAsync(Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override Task> GetCodeActionsAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) { var service = document.GetRequiredLanguageService(); - return service.GenerateEnumMemberAsync(document, node, fallbackOptions, cancellationToken); + return service.GenerateEnumMemberAsync(document, node, cancellationToken); } protected override bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnostic diagnostic) diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs index fe99b42575431..4bfacf947f333 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateConversionCodeFixProvider.cs @@ -60,9 +60,9 @@ node is SimpleNameSyntax || } protected override Task> GetCodeActionsAsync( - Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, SyntaxNode node, CancellationToken cancellationToken) { var service = document.GetRequiredLanguageService(); - return service.GenerateConversionAsync(document, node, fallbackOptions, cancellationToken); + return service.GenerateConversionAsync(document, node, cancellationToken); } } diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs index 9cd82d9dd31cf..a84226960196d 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateDeconstructMethodCodeFixProvider.cs @@ -106,7 +106,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) } var service = document.GetLanguageService(); - var codeActions = await service.GenerateDeconstructMethodAsync(document, target, (INamedTypeSymbol)type, context.Options, cancellationToken).ConfigureAwait(false); + var codeActions = await service.GenerateDeconstructMethodAsync(document, target, (INamedTypeSymbol)type, cancellationToken).ConfigureAwait(false); Debug.Assert(!codeActions.IsDefault); context.RegisterFixes(codeActions, context.Diagnostics); diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs index 7b01c1784564c..5c30027be904c 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateMethod/GenerateMethodCodeFixProvider.cs @@ -83,9 +83,9 @@ node is SimpleNameSyntax || } protected override Task> GetCodeActionsAsync( - Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, SyntaxNode node, CancellationToken cancellationToken) { var service = document.GetRequiredLanguageService(); - return service.GenerateMethodAsync(document, node, fallbackOptions, cancellationToken); + return service.GenerateMethodAsync(document, node, cancellationToken); } } diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs index 5f4a347ab3c4d..1e08fed0e35b8 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs @@ -60,9 +60,9 @@ protected override bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnost => ((ExpressionSyntax)node).GetRightmostName(); protected override Task> GetCodeActionsAsync( - Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, SyntaxNode node, CancellationToken cancellationToken) { var service = document.GetRequiredLanguageService(); - return service.GenerateTypeAsync(document, node, fallbackOptions, cancellationToken); + return service.GenerateTypeAsync(document, node, cancellationToken); } } diff --git a/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs index e9d1997514994..da17567e32e99 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/ConvertLocalFunctionToMethod/CSharpConvertLocalFunctionToMethodCodeRefactoringProvider.cs @@ -58,7 +58,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( CSharpFeaturesResources.Convert_to_method, - c => UpdateDocumentAsync(document, parentBlock, localFunction, container, context.Options, c), + c => UpdateDocumentAsync(document, parentBlock, localFunction, container, c), nameof(CSharpFeaturesResources.Convert_to_method)), localFunction.Span); } @@ -68,7 +68,6 @@ private static async Task UpdateDocumentAsync( BlockSyntax parentBlock, LocalFunctionStatementSyntax localFunction, MemberDeclarationSyntax container, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -127,7 +126,7 @@ private static async Task UpdateDocumentAsync( typeParameters: [.. typeParameters], parameters: parameters.AddRange(capturesAsParameters)); - var info = (CSharpCodeGenerationContextInfo)await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = (CSharpCodeGenerationContextInfo)await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); var method = MethodGenerator.GenerateMethodDeclaration(methodSymbol, CodeGenerationDestination.Unspecified, info, cancellationToken); if (localFunction.AttributeLists.Count > 0) diff --git a/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.FixAllProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.FixAllProvider.cs index 7dd06526a4517..232fe809dbc93 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.FixAllProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.FixAllProvider.cs @@ -46,8 +46,7 @@ async Task EnableNullableReferenceTypesInSolutionAsync( if (!ShouldOfferRefactoring(project)) continue; - solution = await EnableNullableReferenceTypesAsync(project, purpose, - fixAllContext.GetOptionsProvider(), progress, fixAllContext.CancellationToken).ConfigureAwait(false); + solution = await EnableNullableReferenceTypesAsync(project, purpose, fixAllContext.CancellationToken).ConfigureAwait(false); } return solution; diff --git a/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.cs index 03b08066988bc..9178dc16f1f98 100644 --- a/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/CodeRefactorings/EnableNullable/EnableNullableCodeRefactoringProvider.cs @@ -54,7 +54,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte } context.RegisterRefactoring(new CustomCodeAction( - (purpose, progress, cancellationToken) => EnableNullableReferenceTypesAsync(document.Project, purpose, context.Options, progress, cancellationToken))); + (purpose, _, cancellationToken) => EnableNullableReferenceTypesAsync(document.Project, purpose, cancellationToken))); } private static bool ShouldOfferRefactoring(Project project) @@ -65,21 +65,20 @@ private static bool ShouldOfferRefactoring(Project project) }; private static async Task EnableNullableReferenceTypesAsync( - Project project, CodeActionPurpose purpose, CodeActionOptionsProvider fallbackOptions, IProgress _, CancellationToken cancellationToken) + Project project, CodeActionPurpose purpose, CancellationToken cancellationToken) { var solution = project.Solution; var updatedDocumentRoots = await ProducerConsumer<(DocumentId documentId, SyntaxNode newRoot)>.RunParallelAsync( source: project.Documents, - produceItems: static async (document, callback, fallbackOptions, cancellationToken) => + produceItems: static async (document, callback, _, cancellationToken) => { if (await document.IsGeneratedCodeAsync(cancellationToken).ConfigureAwait(false)) return; - var updatedDocumentRoot = await EnableNullableReferenceTypesAsync( - document, fallbackOptions, cancellationToken).ConfigureAwait(false); + var updatedDocumentRoot = await EnableNullableReferenceTypesAsync(document, cancellationToken).ConfigureAwait(false); callback((document.Id, updatedDocumentRoot)); }, - args: fallbackOptions, + args: 0, cancellationToken).ConfigureAwait(false); solution = solution.WithDocumentSyntaxRoots(updatedDocumentRoots); @@ -93,7 +92,7 @@ private static async Task EnableNullableReferenceTypesAsync( return solution; } - private static async Task EnableNullableReferenceTypesAsync(Document document, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private static async Task EnableNullableReferenceTypesAsync(Document document, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var firstToken = GetFirstTokenOfInterest(root); @@ -111,7 +110,7 @@ private static async Task EnableNullableReferenceTypesAsync(Document // * Add '#nullable disable' if the document didn't specify other semantics // * Remove leading '#nullable restore' (was '#nullable enable' prior to rewrite in the previous step) // * Otherwise, leave existing '#nullable' directive since it will control the initial semantics for the document - return await DisableNullableReferenceTypesInExistingDocumentIfNecessaryAsync(document, root, firstToken, fallbackOptions, cancellationToken).ConfigureAwait(false); + return await DisableNullableReferenceTypesInExistingDocumentIfNecessaryAsync(document, root, firstToken, cancellationToken).ConfigureAwait(false); } private static (SyntaxNode root, SyntaxToken firstToken) RewriteExistingDirectives(SyntaxNode root, SyntaxToken firstToken) @@ -158,9 +157,9 @@ private static (SyntaxNode root, SyntaxToken firstToken) RewriteExistingDirectiv return (updatedRoot, GetFirstTokenOfInterest(updatedRoot)); } - private static async Task DisableNullableReferenceTypesInExistingDocumentIfNecessaryAsync(Document document, SyntaxNode root, SyntaxToken firstToken, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private static async Task DisableNullableReferenceTypesInExistingDocumentIfNecessaryAsync(Document document, SyntaxNode root, SyntaxToken firstToken, CancellationToken cancellationToken) { - var options = await document.GetCSharpCodeFixOptionsProviderAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var newLine = SyntaxFactory.EndOfLine(options.NewLine); // Add a new '#nullable disable' to the top of each file diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationName/DeclarationNameRecommender.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationName/DeclarationNameRecommender.cs index 9051e654375c1..1adedeb351dc4 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationName/DeclarationNameRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationName/DeclarationNameRecommender.cs @@ -56,7 +56,7 @@ public DeclarationNameRecommender() if (!names.IsDefaultOrEmpty) { - var namingStyleOptions = await document.GetNamingStylePreferencesAsync(completionContext.CompletionOptions.NamingStyleFallbackOptions, cancellationToken).ConfigureAwait(false); + var namingStyleOptions = await document.GetNamingStylePreferencesAsync(cancellationToken).ConfigureAwait(false); GetRecommendedNames(names, nameInfo, context, result, namingStyleOptions, cancellationToken); } diff --git a/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs index aa099ad520612..d6a267dceda5d 100644 --- a/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs @@ -34,13 +34,12 @@ public CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider() { } - protected override async Task GetFieldNameAsync(Document document, IPropertySymbol property, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task GetFieldNameAsync(Document document, IPropertySymbol property, CancellationToken cancellationToken) { var rule = await document.GetApplicableNamingRuleAsync( new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Field), property.IsStatic ? DeclarationModifiers.Static : DeclarationModifiers.None, Accessibility.Private, - fallbackOptions, cancellationToken).ConfigureAwait(false); var fieldName = rule.NamingStyle.MakeCompliant(property.Name).First(); diff --git a/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs index 839cd36843729..5449604678af5 100644 --- a/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs @@ -47,7 +47,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (!IsValidPosition(namespaceDecl, position)) return; - var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.Options, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); if (!CanOfferRefactoring(namespaceDecl, root, options, out var info)) return; @@ -92,7 +92,7 @@ protected override async Task FixAllAsync( CancellationToken cancellationToken) { var root = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var options = await document.GetCSharpCodeFixOptionsProviderAsync(optionsProvider, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var namespaceDecl = root.DescendantNodes().OfType().FirstOrDefault(); if (!CanOfferRefactoring(namespaceDecl, root, options, out var info) || info.Value.equivalenceKey != equivalenceKey) diff --git a/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs index 617ca5843708c..f602fc0a057ac 100644 --- a/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs @@ -74,14 +74,13 @@ private static async Task ConvertAsync( var semanticModel = await GetSemanticModelAsync(document).ConfigureAwait(false); - var contextInfo = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, optionsProvider, cancellationToken).ConfigureAwait(false); + var contextInfo = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); // The naming rule we need to follow if we synthesize new private fields. var fieldNameRule = await document.GetApplicableNamingRuleAsync( new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Field), DeclarationModifiers.None, Accessibility.Private, - optionsProvider, cancellationToken).ConfigureAwait(false); // Get the named type and all its parameters for use during the rewrite. diff --git a/src/Features/CSharp/Portable/ConvertProgram/ConvertProgramTransform_TopLevelStatements.cs b/src/Features/CSharp/Portable/ConvertProgram/ConvertProgramTransform_TopLevelStatements.cs index 7cbadc2a91c8a..d56c030d2ee27 100644 --- a/src/Features/CSharp/Portable/ConvertProgram/ConvertProgramTransform_TopLevelStatements.cs +++ b/src/Features/CSharp/Portable/ConvertProgram/ConvertProgramTransform_TopLevelStatements.cs @@ -27,7 +27,7 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertProgram; internal static partial class ConvertProgramTransform { public static async Task ConvertToTopLevelStatementsAsync( - Document document, MethodDeclarationSyntax methodDeclaration, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) { var typeDeclaration = (TypeDeclarationSyntax?)methodDeclaration.Parent; Contract.ThrowIfNull(typeDeclaration); // checked by analyzer @@ -45,7 +45,7 @@ public static async Task ConvertToTopLevelStatementsAsync( // We were parented by a namespace. Add using statements to bring in all the symbols that were // previously visible within the namespace. Then remove any that we don't need once we've done that. - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); document = await AddUsingDirectivesAsync( document, rootWithGlobalStatements, namespaceDeclaration, cleanupOptions, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeFixProvider.cs b/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeFixProvider.cs index 347150ad940a2..3da827966e8c0 100644 --- a/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeFixProvider.cs @@ -35,7 +35,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var document = context.Document; var cancellationToken = context.CancellationToken; - var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.Options, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var priority = options.PreferTopLevelStatements.Notification.Severity == ReportDiagnostic.Hidden ? CodeActionPriority.Low : CodeActionPriority.Default; @@ -44,9 +44,9 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } protected override async Task FixAllAsync( - Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { - var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeFixOptionsAsync(cancellationToken).ConfigureAwait(false); var fixedDocument = await ConvertToProgramMainAsync(document, options.AccessibilityModifiersRequired, cancellationToken).ConfigureAwait(false); var fixedRoot = await fixedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeRefactoringProvider.cs index de889c76f2974..ffaa168778071 100644 --- a/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertProgram/ConvertToProgramMainCodeRefactoringProvider.cs @@ -46,7 +46,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (!acceptableLocation.SourceSpan.IntersectsWith(position)) return; - var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.Options, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); if (!CanOfferUseProgramMain(options.PreferTopLevelStatements, root, compilation, forAnalyzer: false)) diff --git a/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeFixProvider.cs b/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeFixProvider.cs index 15409774cd2e7..a39e3138992d6 100644 --- a/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeFixProvider.cs @@ -36,7 +36,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var document = context.Document; var cancellationToken = context.CancellationToken; - var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.Options, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); var priority = options.PreferTopLevelStatements.Notification.Severity == ReportDiagnostic.Hidden ? CodeActionPriority.Low : CodeActionPriority.Default; @@ -45,11 +45,11 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } protected override async Task FixAllAsync( - Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { var methodDeclaration = (MethodDeclarationSyntax)diagnostics[0].AdditionalLocations[0].FindNode(cancellationToken); - var newDocument = await ConvertToTopLevelStatementsAsync(document, methodDeclaration, fallbackOptions, cancellationToken).ConfigureAwait(false); + var newDocument = await ConvertToTopLevelStatementsAsync(document, methodDeclaration, cancellationToken).ConfigureAwait(false); var newRoot = await newDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); editor.ReplaceNode(editor.OriginalRoot, newRoot); diff --git a/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeRefactoringProvider.cs index 372d31499f45b..997ca9cfad008 100644 --- a/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertProgram/ConvertToTopLevelStatementsCodeRefactoringProvider.cs @@ -42,7 +42,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (methodDeclaration is null) return; - var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.Options, cancellationToken).ConfigureAwait(false); + var options = await document.GetCSharpCodeFixOptionsProviderAsync(cancellationToken).ConfigureAwait(false); if (!CanOfferUseTopLevelStatements(options.PreferTopLevelStatements, forAnalyzer: false)) return; @@ -57,7 +57,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring(CodeAction.Create( CSharpAnalyzersResources.Convert_to_top_level_statements, - c => ConvertToTopLevelStatementsAsync(document, methodDeclaration, context.Options, c), + c => ConvertToTopLevelStatementsAsync(document, methodDeclaration, c), nameof(CSharpAnalyzersResources.Convert_to_top_level_statements), CodeActionPriority.Low)); } diff --git a/src/Features/CSharp/Portable/ConvertToRecord/CSharpConvertToRecordRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertToRecord/CSharpConvertToRecordRefactoringProvider.cs index f7bd675792d8e..f6654766ae5bf 100644 --- a/src/Features/CSharp/Portable/ConvertToRecord/CSharpConvertToRecordRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertToRecord/CSharpConvertToRecordRefactoringProvider.cs @@ -25,7 +25,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; var action = await ConvertToRecordEngine.GetCodeActionAsync( - document, typeDeclaration, context.Options, cancellationToken).ConfigureAwait(false); + document, typeDeclaration, cancellationToken).ConfigureAwait(false); if (action != null) context.RegisterRefactoring(action); } diff --git a/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs b/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs index d52d8ba83cd72..242aac9f9c563 100644 --- a/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs +++ b/src/Features/CSharp/Portable/EncapsulateField/CSharpEncapsulateFieldService.cs @@ -37,7 +37,7 @@ public CSharpEncapsulateFieldService() { } - protected override async Task RewriteFieldNameAndAccessibilityAsync(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task RewriteFieldNameAndAccessibilityAsync(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -109,8 +109,7 @@ protected override async Task RewriteFieldNameAndAccessibilityAsync( var withField = await codeGenService.AddFieldAsync( new CodeGenerationSolutionContext( document.Project.Solution, - CodeGenerationContext.Default, - fallbackOptions), + CodeGenerationContext.Default), field.ContainingType, fieldToAdd, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs b/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs index 641b0976e9424..ec7933d35312d 100644 --- a/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.cs @@ -45,10 +45,10 @@ public GenerateConstructorCodeFixProvider() public override ImmutableArray FixableDiagnosticIds => GenerateConstructorDiagnosticIds.AllDiagnosticIds; protected override Task> GetCodeActionsAsync( - Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, SyntaxNode node, CancellationToken cancellationToken) { var service = document.GetLanguageService(); - return service.GenerateConstructorAsync(document, node, fallbackOptions, cancellationToken); + return service.GenerateConstructorAsync(document, node, cancellationToken); } protected override bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnostic diagnostic) diff --git a/src/Features/CSharp/Portable/GenerateConstructorFromMembers/CSharpGenerateConstructorFromMembersCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/GenerateConstructorFromMembers/CSharpGenerateConstructorFromMembersCodeRefactoringProvider.cs index d301224badb3d..f52511a9949f2 100644 --- a/src/Features/CSharp/Portable/GenerateConstructorFromMembers/CSharpGenerateConstructorFromMembersCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/GenerateConstructorFromMembers/CSharpGenerateConstructorFromMembersCodeRefactoringProvider.cs @@ -47,7 +47,7 @@ protected override bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol c protected override string ToDisplayString(IParameterSymbol parameter, SymbolDisplayFormat format) => SymbolDisplay.ToDisplayString(parameter, format); - protected override async ValueTask PrefersThrowExpressionAsync(Document document, SimplifierOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async ValueTask PrefersThrowExpressionAsync(Document document, CancellationToken cancellationToken) { var options = (CSharpSimplifierOptions)await document.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(false); return options.PreferThrowExpression.Value; diff --git a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs index 2f4a2f2ada6e8..129b0945c52bf 100644 --- a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs +++ b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs @@ -743,7 +743,7 @@ internal override bool IsSimpleName(ExpressionSyntax expression) => expression is SimpleNameSyntax; internal override async Task TryAddUsingsOrImportToDocumentAsync( - Solution updatedSolution, SyntaxNode modifiedRoot, Document document, SimpleNameSyntax simpleName, string includeUsingsOrImports, AddImportPlacementOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Solution updatedSolution, SyntaxNode modifiedRoot, Document document, SimpleNameSyntax simpleName, string includeUsingsOrImports, CancellationToken cancellationToken) { // Nothing to include if (string.IsNullOrWhiteSpace(includeUsingsOrImports)) @@ -779,7 +779,7 @@ internal override async Task TryAddUsingsOrImportToDocumentAsync( return updatedSolution; } - var addImportOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var addImportOptions = await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); var addedCompilationRoot = compilationRoot.AddUsingDirectives([usingDirective], addImportOptions.PlaceSystemNamespaceFirst, Formatter.Annotation); updatedSolution = updatedSolution.WithDocumentSyntaxRoot(document.Id, addedCompilationRoot, PreservationMode.PreserveIdentity); } diff --git a/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs b/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs index 58d06f9ae15b1..5c496ede5cd18 100644 --- a/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/GenerateVariable/CSharpGenerateVariableCodeFixProvider.cs @@ -59,9 +59,9 @@ protected override SyntaxNode GetTargetNode(SyntaxNode node) } protected override Task> GetCodeActionsAsync( - Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, SyntaxNode node, CancellationToken cancellationToken) { var service = document.GetLanguageService(); - return service.GenerateVariableAsync(document, node, fallbackOptions, cancellationToken); + return service.GenerateVariableAsync(document, node, cancellationToken); } } diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs index bb0d0296fc386..07158eeb295dc 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs @@ -69,7 +69,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // Haven't initialized any fields/properties with this parameter. Offer to assign to an existing matching // field/prop if we can find one, or add a new field/prop if we can't. var fallbackOptions = context.Options; - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); var parameterNameParts = IdentifierNameParts.CreateIdentifierNameParts(parameter, rules); if (parameterNameParts.BaseName == "") return; diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs index 1218900b9e64c..9cd99f371eedd 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs @@ -92,7 +92,7 @@ static async Task AddSingleMemberAsync( var parseOptions = document.DocumentState.ParseOptions!; var solutionEditor = new SolutionEditor(solution); - var options = await document.GetCodeGenerationOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var codeGenerator = document.GetRequiredLanguageService(); // We're assigning the parameter to a new field/prop . Convert all existing references to this primary diff --git a/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeRefactoringProvider.cs index 152fd933329a5..26245b4d4b3ae 100644 --- a/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticCodeRefactoringProvider.cs @@ -43,7 +43,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte { context.RegisterRefactoring(CodeAction.Create( CSharpAnalyzersResources.Make_local_function_static, - cancellationToken => MakeLocalFunctionStaticCodeFixHelper.MakeLocalFunctionStaticAsync(document, localFunction, captures, context.Options, cancellationToken), + cancellationToken => MakeLocalFunctionStaticCodeFixHelper.MakeLocalFunctionStaticAsync(document, localFunction, captures, cancellationToken), nameof(CSharpAnalyzersResources.Make_local_function_static))); } } diff --git a/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs b/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs index e74409937af67..5c5cc1a570072 100644 --- a/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs +++ b/src/Features/CSharp/Portable/ReplacePropertyWithMethods/CSharpReplacePropertyWithMethodsService.cs @@ -43,13 +43,12 @@ public override async Task> GetReplacementMembersAsyn IFieldSymbol propertyBackingField, string desiredGetMethodName, string desiredSetMethodName, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { if (propertyDeclarationNode is not PropertyDeclarationSyntax propertyDeclaration) return []; - var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var languageVersion = syntaxTree.Options.LanguageVersion(); diff --git a/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs index 6c9bb8f0e59e6..f69678a6b1b9c 100644 --- a/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/UseExpressionBody/UseExpressionBodyCodeRefactoringProvider.cs @@ -80,7 +80,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte } var text = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false); - var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(context.Options, cancellationToken).ConfigureAwait(false); + var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); foreach (var helper in _helpers) { @@ -200,7 +200,7 @@ protected override async Task FixAllAsync( var (helper, useExpressionBody) = s_equivalenceKeyMap[equivalenceKey]; var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(optionsProvider, cancellationToken).ConfigureAwait(false); + var options = (CSharpCodeGenerationOptions)await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var declarationsToFix = GetDeclarationsToFix(fixAllSpans, root, helper, useExpressionBody, options, cancellationToken); await FixDeclarationsAsync(document, editor, root, declarationsToFix.ToImmutableArray(), helper, useExpressionBody, cancellationToken).ConfigureAwait(false); return; diff --git a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs index d57be78cab580..f68e980cf8bc8 100644 --- a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckWithoutNameCodeFixProvider.cs @@ -46,7 +46,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { Debug.Assert(diagnostics.Length == 1); var location = diagnostics[0].Location; diff --git a/src/Features/CSharp/Portable/Wrapping/CSharpSyntaxWrappingOptions.cs b/src/Features/CSharp/Portable/Wrapping/CSharpSyntaxWrappingOptions.cs index 660cc0073a9b3..ad87123375a11 100644 --- a/src/Features/CSharp/Portable/Wrapping/CSharpSyntaxWrappingOptions.cs +++ b/src/Features/CSharp/Portable/Wrapping/CSharpSyntaxWrappingOptions.cs @@ -20,13 +20,9 @@ internal sealed class CSharpSyntaxWrappingOptions( internal static class CSharpSyntaxWrappingOptionsProviders { - public static CSharpSyntaxWrappingOptions GetCSharpSyntaxWrappingOptions(this IOptionsReader options, CodeActionOptions fallbackOptions) - { - var newLineBeforeOpenBraceDefault = ((CSharpSyntaxFormattingOptions)fallbackOptions.CleanupOptions.FormattingOptions).NewLines.ToNewLineBeforeOpenBracePlacement(); - - return new( - new CSharpSyntaxFormattingOptions(options, (CSharpSyntaxFormattingOptions)fallbackOptions.CleanupOptions.FormattingOptions), - operatorPlacement: options.GetOption(CodeStyleOptions2.OperatorPlacementWhenWrapping, fallbackOptions.CodeStyleOptions.OperatorPlacementWhenWrapping), - newLinesForBracesInObjectCollectionArrayInitializers: options.GetOption(CSharpFormattingOptions2.NewLineBeforeOpenBrace, newLineBeforeOpenBraceDefault).HasFlag(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers)); - } + public static CSharpSyntaxWrappingOptions GetCSharpSyntaxWrappingOptions(this IOptionsReader options) + => new( + new CSharpSyntaxFormattingOptions(options), + operatorPlacement: options.GetOption(CodeStyleOptions2.OperatorPlacementWhenWrapping), + newLinesForBracesInObjectCollectionArrayInitializers: options.GetOption(CSharpFormattingOptions2.NewLineBeforeOpenBrace).HasFlag(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers)); } diff --git a/src/Features/CSharp/Portable/Wrapping/CSharpWrappingCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/Wrapping/CSharpWrappingCodeRefactoringProvider.cs index ce0355f1eb39b..feaabfa4ff44d 100644 --- a/src/Features/CSharp/Portable/Wrapping/CSharpWrappingCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/Wrapping/CSharpWrappingCodeRefactoringProvider.cs @@ -30,6 +30,6 @@ internal class CSharpWrappingCodeRefactoringProvider() : AbstractWrappingCodeRef new CSharpCollectionExpressionWrapper(), ]; - protected override SyntaxWrappingOptions GetWrappingOptions(IOptionsReader options, CodeActionOptions ideOptions) - => options.GetCSharpSyntaxWrappingOptions(ideOptions); + protected override SyntaxWrappingOptions GetWrappingOptions(IOptionsReader options) + => options.GetCSharpSyntaxWrappingOptions(); } diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs index 043bbc57b1488..9eb44f2e1aae8 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.State.cs @@ -27,12 +27,11 @@ private class State public static async Task GenerateAsync( ImmutableArray selectedMembers, Document document, - NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) { var state = new State(); if (!await state.TryInitializeAsync( - selectedMembers, document, fallbackOptions, cancellationToken).ConfigureAwait(false)) + selectedMembers, document, cancellationToken).ConfigureAwait(false)) { return null; } @@ -43,12 +42,11 @@ private class State private async Task TryInitializeAsync( ImmutableArray selectedMembers, Document document, - NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) { ContainingType = selectedMembers[0].ContainingType; - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); var parametersForSelectedMembers = DetermineParameters(selectedMembers, rules); if (!selectedMembers.All(IsWritableInstanceFieldOrProperty) || diff --git a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs index b098aff0e85d3..4de2c54743918 100644 --- a/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.cs @@ -42,7 +42,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; } - var result = await AddConstructorParametersFromMembersAsync(document, textSpan, context.Options, cancellationToken).ConfigureAwait(false); + var result = await AddConstructorParametersFromMembersAsync(document, textSpan, cancellationToken).ConfigureAwait(false); if (result == null) { return; @@ -53,7 +53,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte } private static async Task AddConstructorParametersFromMembersAsync( - Document document, TextSpan textSpan, CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, TextSpan textSpan, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateFromMembers_AddConstructorParametersFromMembers, cancellationToken)) { @@ -65,10 +65,10 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (info != null) { - var state = await State.GenerateAsync(info.SelectedMembers, document, fallbackOptions, cancellationToken).ConfigureAwait(false); + var state = await State.GenerateAsync(info.SelectedMembers, document, cancellationToken).ConfigureAwait(false); if (state?.ConstructorCandidates != null && !state.ConstructorCandidates.IsEmpty) { - var contextInfo = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, fallbackOptions, cancellationToken).ConfigureAwait(false); + var contextInfo = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); return CreateCodeActions(document, contextInfo, state); } } @@ -167,7 +167,7 @@ public async Task> ComputeIntentAsync( IntentDataProvider intentDataProvider, CancellationToken cancellationToken) { - var addConstructorParametersResult = await AddConstructorParametersFromMembersAsync(priorDocument, priorSelection, intentDataProvider.FallbackOptions, cancellationToken).ConfigureAwait(false); + var addConstructorParametersResult = await AddConstructorParametersFromMembersAsync(priorDocument, priorSelection, cancellationToken).ConfigureAwait(false); if (addConstructorParametersResult == null) { return []; diff --git a/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerCodeRefactoringProvider.cs b/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerCodeRefactoringProvider.cs index 10e3af7d8af4c..8d47511a3bf60 100644 --- a/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/AddFileBanner/AbstractAddFileBannerCodeRefactoringProvider.cs @@ -40,7 +40,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; } - var formattingOptions = await document.GetDocumentFormattingOptionsAsync(context.Options, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetDocumentFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(formattingOptions.FileHeaderTemplate)) { // If we have a defined file header template, allow the analyzer and code fix to handle it diff --git a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs index e28103db8442b..5c4a5f50a52ab 100644 --- a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs @@ -75,7 +75,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) searchOptions = searchOptions with { SearchNuGetPackages = false }; } - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(context.Options, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var addImportOptions = new AddImportOptions( searchOptions, diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs index 8e5c17f2df83e..33df06ae11ee0 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureCodeRefactoringProvider.cs @@ -28,7 +28,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex if (span.IsEmpty) { var service = document.GetLanguageService(); - var actions = await service.GetChangeSignatureCodeActionAsync(document, span, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await service.GetChangeSignatureCodeActionAsync(document, span, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index 440ae7946921c..dede202ce5e56 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -55,7 +55,6 @@ public abstract Task ChangeSignatureAsync( SyntaxNode potentiallyUpdatedNode, SyntaxNode originalNode, SignatureChange signaturePermutation, - LineFormattingOptionsProvider fallbackOptions, CancellationToken cancellationToken); protected abstract ImmutableArray GetFormattingRules(Document document); @@ -91,9 +90,9 @@ protected abstract TArgumentSyntax AddNameToArgument(TArgumentS protected abstract SyntaxGenerator Generator { get; } protected abstract ISyntaxFacts SyntaxFacts { get; } - public async Task> GetChangeSignatureCodeActionAsync(Document document, TextSpan span, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public async Task> GetChangeSignatureCodeActionAsync(Document document, TextSpan span, CancellationToken cancellationToken) { - var context = await GetChangeSignatureContextAsync(document, span.Start, restrictToDeclarations: true, fallbackOptions, cancellationToken).ConfigureAwait(false); + var context = await GetChangeSignatureContextAsync(document, span.Start, restrictToDeclarations: true, cancellationToken).ConfigureAwait(false); return context is ChangeSignatureAnalysisSucceededContext changeSignatureAnalyzedSucceedContext ? [new ChangeSignatureCodeAction(this, changeSignatureAnalyzedSucceedContext)] @@ -101,7 +100,7 @@ public async Task> GetChangeSignatureC } internal async Task GetChangeSignatureContextAsync( - Document document, int position, bool restrictToDeclarations, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, int position, bool restrictToDeclarations, CancellationToken cancellationToken) { var (symbol, selectedIndex) = await GetInvocationSymbolAsync( document, position, restrictToDeclarations, cancellationToken).ConfigureAwait(false); @@ -186,7 +185,7 @@ internal async Task GetChangeSignatureContextAsy symbol.IsExtensionMethod(), selectedIndex); return new ChangeSignatureAnalysisSucceededContext( - declarationDocument, positionForTypeBinding, symbol, parameterConfiguration, fallbackOptions); + declarationDocument, positionForTypeBinding, symbol, parameterConfiguration); } internal async Task ChangeSignatureWithContextAsync(ChangeSignatureAnalyzedContext context, ChangeSignatureOptionsResult? options, CancellationToken cancellationToken) @@ -396,7 +395,6 @@ private static async Task> FindChangeSignatureR potentiallyUpdatedNode, originalNode, UpdateSignatureChangeToIncludeExtraParametersFromTheDeclarationSymbol(definitionToUse[originalNode], options.UpdatedSignature), - context.FallbackOptions, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); }); @@ -421,7 +419,7 @@ private static async Task> FindChangeSignatureR { var (currentSolution, updatedRoots, context) = args; var updatedDoc = currentSolution.GetRequiredDocument(docId).WithSyntaxRoot(updatedRoots[docId]); - var cleanupOptions = await updatedDoc.GetCodeCleanupOptionsAsync(context.FallbackOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await updatedDoc.GetCodeCleanupOptionsAsync(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); diff --git a/src/Features/Core/Portable/ChangeSignature/ChangeSignatureAnalyzedContext.cs b/src/Features/Core/Portable/ChangeSignature/ChangeSignatureAnalyzedContext.cs index bfdc33e7cc6b8..ec8a94219f7a1 100644 --- a/src/Features/Core/Portable/ChangeSignature/ChangeSignatureAnalyzedContext.cs +++ b/src/Features/Core/Portable/ChangeSignature/ChangeSignatureAnalyzedContext.cs @@ -11,13 +11,12 @@ internal abstract class ChangeSignatureAnalyzedContext } internal sealed class ChangeSignatureAnalysisSucceededContext( - Document document, int positionForTypeBinding, ISymbol symbol, ParameterConfiguration parameterConfiguration, CodeCleanupOptionsProvider fallbackOptions) : ChangeSignatureAnalyzedContext + Document document, int positionForTypeBinding, ISymbol symbol, ParameterConfiguration parameterConfiguration) : ChangeSignatureAnalyzedContext { public readonly Document Document = document; public readonly ISymbol Symbol = symbol; public readonly ParameterConfiguration ParameterConfiguration = parameterConfiguration; public readonly int PositionForTypeBinding = positionForTypeBinding; - public readonly CodeCleanupOptionsProvider FallbackOptions = fallbackOptions; public Solution Solution => Document.Project.Solution; } diff --git a/src/Features/Core/Portable/CodeFixes/GenerateMember/AbstractGenerateMemberCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/GenerateMember/AbstractGenerateMemberCodeFixProvider.cs index baac9918047b7..81e779dad1590 100644 --- a/src/Features/Core/Portable/CodeFixes/GenerateMember/AbstractGenerateMemberCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/GenerateMember/AbstractGenerateMemberCodeFixProvider.cs @@ -24,7 +24,7 @@ internal abstract class AbstractGenerateMemberCodeFixProvider : CodeFixProvider return null; } - protected abstract Task> GetCodeActionsAsync(Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + protected abstract Task> GetCodeActionsAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); protected abstract bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnostic diagnostic); public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) @@ -44,7 +44,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) var names = GetTargetNodes(syntaxFacts, root, context.Span, diagnostic); foreach (var name in names) { - var codeActions = await GetCodeActionsAsync(context.Document, name, context.Options, context.CancellationToken).ConfigureAwait(false); + var codeActions = await GetCodeActionsAsync(context.Document, name, context.CancellationToken).ConfigureAwait(false); if (codeActions.IsDefaultOrEmpty) { continue; diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs index 7ffb555181f4d..1ab45dbb6c11b 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs @@ -38,19 +38,15 @@ public override async Task GetFixAsync(FixAllContext fixAllContext) if (NestedSuppressionCodeAction.IsEquivalenceKeyForGlobalSuppression(fixAllContext.CodeActionEquivalenceKey)) { - var fallbackOptions = fixAllContext.GetOptionsProvider(); - // For global suppressions, we defer to the global suppression system to handle directly. var title = fixAllContext.CodeActionEquivalenceKey; return fixAllContext.Document != null ? GlobalSuppressMessageFixAllCodeAction.Create( title, suppressionFixer, fixAllContext.Document, - await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false), - fallbackOptions) + await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false)) : GlobalSuppressMessageFixAllCodeAction.Create( title, suppressionFixer, fixAllContext.Project, - await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false), - fallbackOptions); + await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false)); } if (NestedSuppressionCodeAction.IsEquivalenceKeyForPragmaWarning(fixAllContext.CodeActionEquivalenceKey)) diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs index 0db9273f39dbf..18811bd6f4d5a 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs @@ -26,32 +26,29 @@ internal sealed class GlobalSuppressMessageFixAllCodeAction : AbstractGlobalSupp { private readonly INamedTypeSymbol _suppressMessageAttribute; private readonly IEnumerable>> _diagnosticsBySymbol; - private readonly CodeActionOptionsProvider _fallbackOptions; private GlobalSuppressMessageFixAllCodeAction( AbstractSuppressionCodeFixProvider fixer, INamedTypeSymbol suppressMessageAttribute, IEnumerable>> diagnosticsBySymbol, - Project project, - CodeActionOptionsProvider fallbackOptions) + Project project) : base(fixer, project) { _suppressMessageAttribute = suppressMessageAttribute; _diagnosticsBySymbol = diagnosticsBySymbol; - _fallbackOptions = fallbackOptions; } - internal static CodeAction Create(string title, AbstractSuppressionCodeFixProvider fixer, Document triggerDocument, ImmutableDictionary> diagnosticsByDocument, CodeActionOptionsProvider fallbackOptions) + internal static CodeAction Create(string title, AbstractSuppressionCodeFixProvider fixer, Document triggerDocument, ImmutableDictionary> diagnosticsByDocument) { return new GlobalSuppressionSolutionChangeAction(title, - (_, ct) => CreateChangedSolutionAsync(fixer, triggerDocument, diagnosticsByDocument, fallbackOptions, ct), + (_, ct) => CreateChangedSolutionAsync(fixer, triggerDocument, diagnosticsByDocument, ct), equivalenceKey: title); } - internal static CodeAction Create(string title, AbstractSuppressionCodeFixProvider fixer, Project triggerProject, ImmutableDictionary> diagnosticsByProject, CodeActionOptionsProvider fallbackOptions) + internal static CodeAction Create(string title, AbstractSuppressionCodeFixProvider fixer, Project triggerProject, ImmutableDictionary> diagnosticsByProject) { return new GlobalSuppressionSolutionChangeAction(title, - (_, ct) => CreateChangedSolutionAsync(fixer, triggerProject, diagnosticsByProject, fallbackOptions, ct), + (_, ct) => CreateChangedSolutionAsync(fixer, triggerProject, diagnosticsByProject, ct), equivalenceKey: title); } @@ -71,7 +68,6 @@ private static async Task CreateChangedSolutionAsync( AbstractSuppressionCodeFixProvider fixer, Document triggerDocument, ImmutableDictionary> diagnosticsByDocument, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var currentSolution = triggerDocument.Project.Solution; @@ -87,7 +83,7 @@ private static async Task CreateChangedSolutionAsync( var diagnosticsBySymbol = await CreateDiagnosticsBySymbolAsync(fixer, grouping, cancellationToken).ConfigureAwait(false); if (diagnosticsBySymbol.Any()) { - var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction(fixer, supressMessageAttribute, diagnosticsBySymbol, currentProject, fallbackOptions); + var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction(fixer, supressMessageAttribute, diagnosticsBySymbol, currentProject); var newDocument = await projectCodeAction.GetChangedSuppressionDocumentAsync(cancellationToken).ConfigureAwait(false); currentSolution = newDocument.Project.Solution; } @@ -101,7 +97,6 @@ private static async Task CreateChangedSolutionAsync( AbstractSuppressionCodeFixProvider fixer, Project triggerProject, ImmutableDictionary> diagnosticsByProject, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var currentSolution = triggerProject.Solution; @@ -117,7 +112,7 @@ private static async Task CreateChangedSolutionAsync( if (diagnosticsBySymbol.Any()) { var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction( - fixer, suppressMessageAttribute, diagnosticsBySymbol, currentProject, fallbackOptions); + fixer, suppressMessageAttribute, diagnosticsBySymbol, currentProject); var newDocument = await projectCodeAction.GetChangedSuppressionDocumentAsync(cancellationToken).ConfigureAwait(false); currentSolution = newDocument.Project.Solution; } @@ -136,7 +131,7 @@ protected override async Task GetChangedSuppressionDocumentAsync(Cance var services = suppressionsDoc.Project.Solution.Services; var suppressionsRoot = await suppressionsDoc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var addImportsService = suppressionsDoc.GetRequiredLanguageService(); - var cleanupOptions = await suppressionsDoc.GetCodeCleanupOptionsAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await suppressionsDoc.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); foreach (var (targetSymbol, diagnostics) in _diagnosticsBySymbol) { diff --git a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs index 9a9344144e2ad..1c6ae905ebebc 100644 --- a/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/AddMissingImports/AbstractAddMissingImportsRefactoringProvider.cs @@ -42,7 +42,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // Check pasted text span for missing imports var addMissingImportsService = document.GetRequiredLanguageService(); - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(context.Options, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var options = new AddMissingImportsOptions( cleanupOptions, context.Options.GetOptions(document.Project.Services).HideAdvancedMembers); diff --git a/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs b/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs index 7f687654b0529..ed50eee129f6c 100644 --- a/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs +++ b/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs @@ -158,7 +158,7 @@ private async Task AddNewDocumentWithSingleTypeDeclarationAsync(Docume /// private async Task AddFinalNewLineIfDesiredAsync(Document document, SyntaxNode modifiedRoot) { - var documentFormattingOptions = await document.GetDocumentFormattingOptionsAsync(State.FallbackOptions, CancellationToken).ConfigureAwait(false); + var documentFormattingOptions = await document.GetDocumentFormattingOptionsAsync(CancellationToken).ConfigureAwait(false); var insertFinalNewLine = documentFormattingOptions.InsertFinalNewLine; if (insertFinalNewLine) { @@ -169,7 +169,7 @@ private async Task AddFinalNewLineIfDesiredAsync(Document document, if (endOfFileToken.LeadingTrivia.IsEmpty() && !previousToken.TrailingTrivia.Any(syntaxFacts.IsEndOfLineTrivia)) { - var lineFormattingOptions = await document.GetLineFormattingOptionsAsync(State.FallbackOptions, CancellationToken).ConfigureAwait(false); + var lineFormattingOptions = await document.GetLineFormattingOptionsAsync(CancellationToken).ConfigureAwait(false); var generator = document.GetRequiredLanguageService(); var endOfLine = generator.EndOfLine(lineFormattingOptions.NewLine); return modifiedRoot.ReplaceToken( diff --git a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs index f41600e751013..cdc645c34fe07 100644 --- a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs @@ -38,9 +38,9 @@ internal abstract class AbstractChangeNamespaceService : IChangeNamespaceService { public abstract Task CanChangeNamespaceAsync(Document document, SyntaxNode container, CancellationToken cancellationToken); - public abstract Task ChangeNamespaceAsync(Document document, SyntaxNode container, string targetNamespace, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + public abstract Task ChangeNamespaceAsync(Document document, SyntaxNode container, string targetNamespace, CancellationToken cancellationToken); - public abstract Task TryChangeTopLevelNamespacesAsync(Document document, string targetNamespace, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + public abstract Task TryChangeTopLevelNamespacesAsync(Document document, string targetNamespace, CancellationToken cancellationToken); /// /// Try to get a new node to replace given node, which is a reference to a top-level type declared inside the @@ -114,7 +114,6 @@ public override async Task CanChangeNamespaceAsync(Document document, Synt public override async Task TryChangeTopLevelNamespacesAsync( Document document, string targetNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var syntaxFacts = document.GetRequiredLanguageService(); @@ -156,7 +155,7 @@ public override async Task CanChangeNamespaceAsync(Document document, Synt Debug.Assert(namespaces.Length == originalNamespaceDeclarations.Length); var namespaceToRename = namespaces[i]; - solution = await ChangeNamespaceAsync(document, namespaceToRename, targetNamespace, fallbackOptions, cancellationToken).ConfigureAwait(false); + solution = await ChangeNamespaceAsync(document, namespaceToRename, targetNamespace, cancellationToken).ConfigureAwait(false); document = solution.GetRequiredDocument(document.Id); } @@ -177,7 +176,6 @@ public override async Task ChangeNamespaceAsync( Document document, SyntaxNode container, string targetNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // Make sure given namespace name is valid, "" means global namespace. @@ -226,7 +224,7 @@ public override async Task ChangeNamespaceAsync( foreach (var documentId in documentIds) { var (newSolution, refDocumentIds) = - await ChangeNamespaceInSingleDocumentAsync(solutionAfterNamespaceChange, documentId, declaredNamespace, targetNamespace, fallbackOptions, cancellationToken) + await ChangeNamespaceInSingleDocumentAsync(solutionAfterNamespaceChange, documentId, declaredNamespace, targetNamespace, cancellationToken) .ConfigureAwait(false); solutionAfterNamespaceChange = newSolution; referenceDocuments.AddRange(refDocumentIds); @@ -255,14 +253,12 @@ await ChangeNamespaceInSingleDocumentAsync(solutionAfterNamespaceChange, documen solutionAfterFirstMerge, documentIds, GetAllNamespaceImportsForDeclaringDocument(declaredNamespace, targetNamespace), - fallbackOptions, cancellationToken).ConfigureAwait(false); solutionAfterImportsRemoved = await RemoveUnnecessaryImportsAsync( solutionAfterImportsRemoved, [.. referenceDocuments], [declaredNamespace, targetNamespace], - fallbackOptions, cancellationToken).ConfigureAwait(false); return await MergeDiffAsync(solutionAfterFirstMerge, solutionAfterImportsRemoved, cancellationToken).ConfigureAwait(false); @@ -432,7 +428,6 @@ private static SyntaxNode CreateImport(SyntaxGenerator syntaxGenerator, string n DocumentId id, string oldNamespace, string newNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var document = solution.GetRequiredDocument(id); @@ -469,7 +464,7 @@ private static SyntaxNode CreateImport(SyntaxGenerator syntaxGenerator, string n } } - var documentWithNewNamespace = await FixDeclarationDocumentAsync(document, refLocationsInCurrentDocument, oldNamespace, newNamespace, fallbackOptions, cancellationToken) + var documentWithNewNamespace = await FixDeclarationDocumentAsync(document, refLocationsInCurrentDocument, oldNamespace, newNamespace, cancellationToken) .ConfigureAwait(false); var solutionWithChangedNamespace = documentWithNewNamespace.Project.Solution; @@ -492,16 +487,15 @@ private static SyntaxNode CreateImport(SyntaxGenerator syntaxGenerator, string n source: refLocationGroups, produceItems: static async (refInOneDocument, callback, args, cancellationToken) => { - var (solutionWithChangedNamespace, newNamespace, fallbackOptions) = args; + var (solutionWithChangedNamespace, newNamespace) = args; var result = await FixReferencingDocumentAsync( solutionWithChangedNamespace.GetRequiredDocument(refInOneDocument.Key), refInOneDocument, newNamespace, - fallbackOptions, cancellationToken).ConfigureAwait(false); callback((result.Id, await result.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false))); }, - args: (solutionWithChangedNamespace, newNamespace, fallbackOptions), + args: (solutionWithChangedNamespace, newNamespace), cancellationToken).ConfigureAwait(false); var solutionWithFixedReferences = solutionWithChangedNamespace.WithDocumentSyntaxRoots(fixedDocuments); @@ -567,7 +561,6 @@ private async Task FixDeclarationDocumentAsync( IReadOnlyList refLocations, string oldNamespace, string newNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { Debug.Assert(newNamespace != null); @@ -598,7 +591,7 @@ private async Task FixDeclarationDocumentAsync( if (refLocations.Count > 0) { - (document, containersToAddImports) = await FixReferencesAsync(document, this, addImportService, refLocations, newNamespaceParts, fallbackOptions, cancellationToken) + (document, containersToAddImports) = await FixReferencesAsync(document, this, addImportService, refLocations, newNamespaceParts, cancellationToken) .ConfigureAwait(false); } else @@ -616,7 +609,7 @@ private async Task FixDeclarationDocumentAsync( // references to the type inside it's new namespace var namesToImport = GetAllNamespaceImportsForDeclaringDocument(oldNamespace, newNamespace); - var documentOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var documentOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var documentWithAddedImports = await AddImportsInContainersAsync( document, @@ -644,7 +637,6 @@ private static async Task FixReferencingDocumentAsync( Document document, IEnumerable refLocations, string newNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // 1. Fully qualify all simple references (i.e. not via an alias) with new namespace. @@ -657,10 +649,10 @@ private static async Task FixReferencingDocumentAsync( var newNamespaceParts = GetNamespaceParts(newNamespace); var (documentWithRefFixed, containers) = - await FixReferencesAsync(document, changeNamespaceService, addImportService, refLocations, newNamespaceParts, fallbackOptions, cancellationToken) + await FixReferencesAsync(document, changeNamespaceService, addImportService, refLocations, newNamespaceParts, cancellationToken) .ConfigureAwait(false); - var documentOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var documentOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var documentWithAdditionalImports = await AddImportsInContainersAsync( documentWithRefFixed, @@ -691,7 +683,6 @@ await FixReferencesAsync(document, changeNamespaceService, addImportService, ref IAddImportsService addImportService, IEnumerable refLocations, ImmutableArray newNamespaceParts, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); @@ -741,7 +732,7 @@ await FixReferencesAsync(document, changeNamespaceService, addImportService, ref } } - var addImportsOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var addImportsOptions = await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); // Use a dummy import node to figure out which container the new import will be added to. var container = addImportService.GetImportContainer(root, refNode, dummyImport, addImportsOptions); @@ -765,7 +756,6 @@ private static async Task RemoveUnnecessaryImportsAsync( Solution solution, ImmutableArray ids, ImmutableArray names, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using var _1 = PooledHashSet.GetInstance(out var linkedDocumentsToSkip); @@ -783,16 +773,15 @@ private static async Task RemoveUnnecessaryImportsAsync( var changedDocuments = await ProducerConsumer<(DocumentId documentId, SyntaxNode newRoot)>.RunParallelAsync( source: documentsToProcess, - produceItems: static async (doc, callback, args, cancellationToken) => + produceItems: static async (doc, callback, names, cancellationToken) => { - var (names, fallbackOptions) = args; var result = await RemoveUnnecessaryImportsWorkerAsync( doc, CreateImports(doc, names, withFormatterAnnotation: false), cancellationToken).ConfigureAwait(false); callback((result.Id, await result.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false))); }, - args: (names, fallbackOptions), + args: names, cancellationToken).ConfigureAwait(false); return solution.WithDocumentSyntaxRoots(changedDocuments); diff --git a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractSyncNamespaceCodeRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractSyncNamespaceCodeRefactoringProvider.cs index 72a327c8bdb0d..02e2bb37a7f5a 100644 --- a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractSyncNamespaceCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractSyncNamespaceCodeRefactoringProvider.cs @@ -73,7 +73,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte : string.Format(FeaturesResources.Change_namespace_to_0, state.TargetNamespace); var solutionChangeAction = CodeAction.Create( title, - token => service.ChangeNamespaceAsync(document, state.Container, state.TargetNamespace, context.Options, token), + token => service.ChangeNamespaceAsync(document, state.Container, state.TargetNamespace, token), title); context.RegisterRefactoring(solutionChangeAction, textSpan); diff --git a/src/Features/Core/Portable/Completion/CompletionOptions.cs b/src/Features/Core/Portable/Completion/CompletionOptions.cs index 1ee9389f0e01a..4c74807eca9dd 100644 --- a/src/Features/Core/Portable/Completion/CompletionOptions.cs +++ b/src/Features/Core/Portable/Completion/CompletionOptions.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Recommendations; using Microsoft.CodeAnalysis.Shared; @@ -51,7 +50,6 @@ internal sealed record class CompletionOptions public bool? ShowNewSnippetExperienceUserOption { get; init; } = null; public bool ShowNewSnippetExperienceFeatureFlag { get; init; } = true; public ExpandedCompletionMode ExpandedCompletionBehavior { get; init; } = ExpandedCompletionMode.AllItems; - public NamingStylePreferences? NamingStyleFallbackOptions { get; init; } = null; public static readonly CompletionOptions Default = new(); diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs index 0120aed951328..25e3bb8a6e34d 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractMemberInsertingCompletionProvider.cs @@ -36,11 +36,7 @@ public AbstractMemberInsertingCompletionProvider() public override async Task GetChangeAsync(Document document, CompletionItem item, char? commitKey = null, CancellationToken cancellationToken = default) { - // TODO: pass fallback options: https://github.com/dotnet/roslyn/issues/60786 - var globalOptions = document.Project.Solution.Services.GetService(); - var fallbackOptions = globalOptions?.Provider ?? CodeActionOptions.DefaultProvider; - - var newDocument = await DetermineNewDocumentAsync(document, item, fallbackOptions, cancellationToken).ConfigureAwait(false); + var newDocument = await DetermineNewDocumentAsync(document, item, cancellationToken).ConfigureAwait(false); var newText = await newDocument.GetValueTextAsync(cancellationToken).ConfigureAwait(false); var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -73,7 +69,6 @@ public override async Task GetChangeAsync(Document document, C private async Task DetermineNewDocumentAsync( Document document, CompletionItem completionItem, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var text = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false); @@ -89,7 +84,7 @@ private async Task DetermineNewDocumentAsync( // avoid trigger source generator, which is expensive and not needed for calculating the change. document = document.WithSyntaxRoot(annotatedRoot).WithFrozenPartialSemantics(cancellationToken); - var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, fallbackOptions, cancellationToken).ConfigureAwait(false); + var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false); if (memberContainingDocument == null) { // Generating the new document failed because we somehow couldn't resolve @@ -98,7 +93,7 @@ private async Task DetermineNewDocumentAsync( return document; } - var memberContainingDocumentCleanupOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var memberContainingDocumentCleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var insertionRoot = await GetTreeWithAddedSyntaxNodeRemovedAsync(memberContainingDocument, memberContainingDocumentCleanupOptions, cancellationToken).ConfigureAwait(false); var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, memberContainingDocumentCleanupOptions, cancellationToken).ConfigureAwait(false); @@ -120,7 +115,6 @@ private async Task DetermineNewDocumentAsync( Document document, CompletionItem completionItem, TextLine line, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var codeGenService = document.GetRequiredLanguageService(); @@ -144,8 +138,7 @@ private async Task DetermineNewDocumentAsync( var context = new CodeGenerationSolutionContext( document.Project.Solution, new CodeGenerationContext( - contextLocation: semanticModel.SyntaxTree.GetLocation(TextSpan.FromBounds(line.Start, line.Start))), - fallbackOptions); + contextLocation: semanticModel.SyntaxTree.GetLocation(TextSpan.FromBounds(line.Start, line.Start)))); var generatedMember = await GenerateMemberAsync(overriddenMember, containingType, document, completionItem, cancellationToken).ConfigureAwait(false); generatedMember = _annotation.AddAnnotationToSymbol(generatedMember); diff --git a/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs index 81edfcc979f8a..a2a827b6cbd5f 100644 --- a/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs @@ -149,11 +149,7 @@ public override async Task GetChangeAsync( var addImportService = document.GetRequiredLanguageService(); var generator = document.GetRequiredLanguageService(); - // TODO: fallback options https://github.com/dotnet/roslyn/issues/60786 - var globalOptions = document.Project.Solution.Services.GetService(); - var fallbackOptions = globalOptions?.Provider ?? CodeActionOptions.DefaultProvider; - - var addImportsOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var addImportsOptions = await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var importNode = CreateImport(document, containingNamespace); diff --git a/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs index 64b091094e07e..6500eba0a36e8 100644 --- a/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertAnonymousType/AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs @@ -63,7 +63,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( FeaturesResources.Convert_to_record, - c => ConvertAsync(document, textSpan, context.Options, isRecord: true, c), + c => ConvertAsync(document, textSpan, isRecord: true, c), nameof(FeaturesResources.Convert_to_record)), anonymousObject.Span); } @@ -71,12 +71,12 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( FeaturesResources.Convert_to_class, - c => ConvertAsync(document, textSpan, context.Options, isRecord: false, c), + c => ConvertAsync(document, textSpan, isRecord: false, c), nameof(FeaturesResources.Convert_to_class)), anonymousObject.Span); } - private async Task ConvertAsync(Document document, TextSpan span, CodeActionOptionsProvider fallbackOptions, bool isRecord, CancellationToken cancellationToken) + private async Task ConvertAsync(Document document, TextSpan span, bool isRecord, CancellationToken cancellationToken) { var (anonymousObject, anonymousType) = await TryGetAnonymousObjectAsync(document, span, cancellationToken).ConfigureAwait(false); @@ -129,7 +129,7 @@ await ReplaceMatchingAnonymousTypesAsync( sortMembers: false, autoInsertionLocation: false); - var info = await document.GetCodeGenerationInfoAsync(context, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await document.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); // Then, actually insert the new class in the appropriate container. diff --git a/src/Features/Core/Portable/ConvertAutoPropertyToFullProperty/AbstractConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertAutoPropertyToFullProperty/AbstractConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs index 751f1711f1482..52200d6f72152 100644 --- a/src/Features/Core/Portable/ConvertAutoPropertyToFullProperty/AbstractConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertAutoPropertyToFullProperty/AbstractConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs @@ -22,7 +22,7 @@ internal abstract class AbstractConvertAutoPropertyToFullPropertyCodeRefactoring where TTypeDeclarationNode : SyntaxNode where TCodeGenerationContextInfo : CodeGenerationContextInfo { - protected abstract Task GetFieldNameAsync(Document document, IPropertySymbol propertySymbol, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken); + protected abstract Task GetFieldNameAsync(Document document, IPropertySymbol propertySymbol, CancellationToken cancellationToken); protected abstract (SyntaxNode newGetAccessor, SyntaxNode newSetAccessor) GetNewAccessors( TCodeGenerationContextInfo info, SyntaxNode property, string fieldName, SyntaxGenerator generator, CancellationToken cancellationToken); protected abstract SyntaxNode GetPropertyWithoutInitializer(SyntaxNode property); @@ -49,7 +49,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( FeaturesResources.Convert_to_full_property, - c => ExpandToFullPropertyAsync(document, property, propertySymbol, root, context.Options, c), + c => ExpandToFullPropertyAsync(document, property, propertySymbol, root, c), nameof(FeaturesResources.Convert_to_full_property)), property.Span); } @@ -75,18 +75,17 @@ private async Task ExpandToFullPropertyAsync( SyntaxNode property, IPropertySymbol propertySymbol, SyntaxNode root, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { Contract.ThrowIfNull(document.DocumentState.ParseOptions); var editor = new SyntaxEditor(root, document.Project.Solution.Services); var generator = editor.Generator; - var info = (TCodeGenerationContextInfo)await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = (TCodeGenerationContextInfo)await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); // Create full property. If the auto property had an initial value // we need to remove it and later add it to the backing field - var fieldName = await GetFieldNameAsync(document, propertySymbol, fallbackOptions, cancellationToken).ConfigureAwait(false); + var fieldName = await GetFieldNameAsync(document, propertySymbol, cancellationToken).ConfigureAwait(false); var (newGetAccessor, newSetAccessor) = GetNewAccessors(info, property, fieldName, generator, cancellationToken); var fullProperty = generator .WithAccessorDeclarations( diff --git a/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs index 5a5864579ecad..651f39a9f512c 100644 --- a/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs @@ -90,7 +90,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var syntaxFacts = document.GetRequiredLanguageService(); if (syntaxFacts.SupportsRecordStruct(syntaxTree.Options)) { - var recordChildActions = CreateChildActions(document, textSpan, tupleExprOrTypeNode, fields, capturedTypeParameters, context.Options, isRecord: true); + var recordChildActions = CreateChildActions(document, textSpan, tupleExprOrTypeNode, fields, capturedTypeParameters, isRecord: true); if (recordChildActions.Length > 0) { context.RegisterRefactoring( @@ -102,7 +102,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte } } - var childActions = CreateChildActions(document, textSpan, tupleExprOrTypeNode, fields, capturedTypeParameters, context.Options, isRecord: false); + var childActions = CreateChildActions(document, textSpan, tupleExprOrTypeNode, fields, capturedTypeParameters, isRecord: false); if (childActions.Length > 0) { context.RegisterRefactoring( @@ -121,14 +121,13 @@ ImmutableArray CreateChildActions( SyntaxNode tupleExprOrTypeNode, ImmutableArray fields, ImmutableArray capturedTypeParameters, - CleanCodeGenerationOptionsProvider fallbackOptions, bool isRecord) { using var scopes = TemporaryArray.Empty; var containingMember = GetContainingMember(context.Document, tupleExprOrTypeNode); if (containingMember != null) - scopes.Add(CreateAction(document, span, Scope.ContainingMember, fallbackOptions, isRecord)); + scopes.Add(CreateAction(document, span, Scope.ContainingMember, isRecord)); // If we captured any Method type-parameters, we can only replace the tuple types we // find in the containing method. No other tuple types in other members would be able @@ -137,7 +136,7 @@ ImmutableArray CreateChildActions( { var containingType = tupleExprOrTypeNode.GetAncestor(); if (containingType != null) - scopes.Add(CreateAction(document, span, Scope.ContainingType, fallbackOptions, isRecord)); + scopes.Add(CreateAction(document, span, Scope.ContainingType, isRecord)); // If we captured any Type type-parameters, we can only replace the tuple // types we find in the containing type. No other tuple types in other @@ -152,8 +151,8 @@ ImmutableArray CreateChildActions( // latter has members called Item1 and Item2, but those names don't show up in source. if (fields.All(f => f.CorrespondingTupleField != f)) { - scopes.Add(CreateAction(document, span, Scope.ContainingProject, fallbackOptions, isRecord)); - scopes.Add(CreateAction(document, span, Scope.DependentProjects, fallbackOptions, isRecord)); + scopes.Add(CreateAction(document, span, Scope.ContainingProject, isRecord)); + scopes.Add(CreateAction(document, span, Scope.DependentProjects, isRecord)); } } } @@ -168,8 +167,8 @@ ImmutableArray CreateChildActions( return tupleExprOrTypeNode.FirstAncestorOrSelf((node, syntaxFacts) => syntaxFacts.IsMethodLevelMember(node), syntaxFacts); } - private CodeAction CreateAction(Document document, TextSpan span, Scope scope, CleanCodeGenerationOptionsProvider fallbackOptions, bool isRecord) - => CodeAction.Create(GetTitle(scope), c => ConvertToStructAsync(document, span, scope, fallbackOptions, isRecord, c), scope.ToString()); + private CodeAction CreateAction(Document document, TextSpan span, Scope scope, bool isRecord) + => CodeAction.Create(GetTitle(scope), c => ConvertToStructAsync(document, span, scope, isRecord, c), scope.ToString()); private static string GetTitle(Scope scope) => scope switch @@ -215,7 +214,7 @@ private static string GetTitle(Scope scope) } public async Task ConvertToStructAsync( - Document document, TextSpan span, Scope scope, CleanCodeGenerationOptionsProvider fallbackOptions, bool isRecord, CancellationToken cancellationToken) + Document document, TextSpan span, Scope scope, bool isRecord, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -227,8 +226,7 @@ public async Task ConvertToStructAsync( { var result = await client.TryInvokeAsync( solution, - (service, solutionInfo, callbackId, cancellationToken) => service.ConvertToStructAsync(solutionInfo, callbackId, document.Id, span, scope, isRecord, cancellationToken), - callbackTarget: new RemoteOptionsProvider(solution.Services, fallbackOptions), + (service, solutionInfo, cancellationToken) => service.ConvertToStructAsync(solutionInfo, document.Id, span, scope, isRecord, cancellationToken), cancellationToken).ConfigureAwait(false); if (!result.HasValue) @@ -245,7 +243,7 @@ public async Task ConvertToStructAsync( } return await ConvertToStructInCurrentProcessAsync( - document, span, scope, fallbackOptions, isRecord, cancellationToken).ConfigureAwait(false); + document, span, scope, isRecord, cancellationToken).ConfigureAwait(false); } private static async Task AddRenameTokenAsync( @@ -262,7 +260,7 @@ private static async Task AddRenameTokenAsync( } private async Task ConvertToStructInCurrentProcessAsync( - Document document, TextSpan span, Scope scope, CleanCodeGenerationOptionsProvider fallbackOptions, bool isRecord, CancellationToken cancellationToken) + Document document, TextSpan span, Scope scope, bool isRecord, CancellationToken cancellationToken) { var (tupleExprOrTypeNode, tupleType) = await TryGetTupleInfoAsync( document, span, cancellationToken).ConfigureAwait(false); @@ -294,7 +292,7 @@ private async Task ConvertToStructInCurrentProcessAsync( // (and importantly not any of the documents where we change the call sites, below) // For records we don't use this however, but rather leave the parameters exactly as the tuple elements // were defined, since they function as both the parameters and the property names. - var parameterNamingRule = await document.GetApplicableNamingRuleAsync(SymbolKind.Parameter, Accessibility.NotApplicable, fallbackOptions, cancellationToken).ConfigureAwait(false); + var parameterNamingRule = await document.GetApplicableNamingRuleAsync(SymbolKind.Parameter, Accessibility.NotApplicable, cancellationToken).ConfigureAwait(false); // Next, generate the full struct that will be used to replace all instances of this // tuple type. @@ -315,7 +313,7 @@ await ReplaceExpressionAndTypesInScopeAsync( await GenerateStructIntoContainingNamespaceAsync( document, tupleExprOrTypeNode, namedTypeSymbol, - documentToEditorMap, fallbackOptions, cancellationToken).ConfigureAwait(false); + documentToEditorMap, cancellationToken).ConfigureAwait(false); var updatedSolution = await ApplyChangesAsync( document, documentToEditorMap, cancellationToken).ConfigureAwait(false); @@ -554,7 +552,7 @@ private static ImmutableArray GetDocumentsToUpdateForContainin private static async Task GenerateStructIntoContainingNamespaceAsync( Document document, SyntaxNode tupleExprOrTypeNode, INamedTypeSymbol namedTypeSymbol, Dictionary documentToEditorMap, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -575,7 +573,7 @@ private static async Task GenerateStructIntoContainingNamespaceAsync( sortMembers: false, autoInsertionLocation: false); - var info = await document.GetCodeGenerationInfoAsync(context, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await document.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); // Then, actually insert the new class in the appropriate container. editor.ReplaceNode(container, (currentContainer, _) => diff --git a/src/Features/Core/Portable/ConvertTupleToStruct/IConvertTupleToStructCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertTupleToStruct/IConvertTupleToStructCodeRefactoringProvider.cs index 3ba67a53a0209..1220eaed05d3d 100644 --- a/src/Features/Core/Portable/ConvertTupleToStruct/IConvertTupleToStructCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertTupleToStruct/IConvertTupleToStructCodeRefactoringProvider.cs @@ -13,5 +13,5 @@ namespace Microsoft.CodeAnalysis.ConvertTupleToStruct; internal interface IConvertTupleToStructCodeRefactoringProvider : ILanguageService { Task ConvertToStructAsync( - Document document, TextSpan span, Scope scope, CleanCodeGenerationOptionsProvider fallbackOptions, bool isRecord, CancellationToken cancellationToken); + Document document, TextSpan span, Scope scope, bool isRecord, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/ConvertTupleToStruct/IRemoteConvertTupleToStructCodeRefactoringService.cs b/src/Features/Core/Portable/ConvertTupleToStruct/IRemoteConvertTupleToStructCodeRefactoringService.cs index a33fb6252463d..86a7e352721a6 100644 --- a/src/Features/Core/Portable/ConvertTupleToStruct/IRemoteConvertTupleToStructCodeRefactoringService.cs +++ b/src/Features/Core/Portable/ConvertTupleToStruct/IRemoteConvertTupleToStructCodeRefactoringService.cs @@ -2,28 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; -using System.Composition; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CodeGeneration; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.ConvertTupleToStruct; internal interface IRemoteConvertTupleToStructCodeRefactoringService { - internal interface ICallback : IRemoteOptionsCallback - { - } - ValueTask ConvertToStructAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, DocumentId documentId, TextSpan span, Scope scope, @@ -31,19 +21,6 @@ ValueTask ConvertToStructAsync( CancellationToken cancellationToken); } -[ExportRemoteServiceCallbackDispatcher(typeof(IRemoteConvertTupleToStructCodeRefactoringService)), Shared] -internal sealed class RemoteConvertTupleToStructCodeRefactoringServiceCallbackDispatcher : RemoteServiceCallbackDispatcher, IRemoteConvertTupleToStructCodeRefactoringService.ICallback -{ - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RemoteConvertTupleToStructCodeRefactoringServiceCallbackDispatcher() - { - } - - public ValueTask GetOptionsAsync(RemoteServiceCallbackId callbackId, string language, CancellationToken cancellationToken) - => ((RemoteOptionsProvider)GetCallback(callbackId)).GetOptionsAsync(language, cancellationToken); -} - [DataContract] internal readonly struct SerializableConvertTupleToStructResult( ImmutableArray<(DocumentId, ImmutableArray)> documentTextChanges, diff --git a/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonDetectionCodeFixProvider.cs b/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonDetectionCodeFixProvider.cs index 59fa1e1c4662f..f8d00d39affd4 100644 --- a/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonDetectionCodeFixProvider.cs +++ b/src/Features/Core/Portable/EmbeddedLanguages/Json/LanguageServices/AbstractJsonDetectionCodeFixProvider.cs @@ -57,7 +57,7 @@ public void Fix(SyntaxEditor editor, Diagnostic diagnostic, CancellationToken ca protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) Fix(editor, diagnostic, cancellationToken); diff --git a/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs b/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs index 9649e4abbdde2..b683bd5d55a9a 100644 --- a/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs +++ b/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs @@ -37,11 +37,11 @@ internal abstract partial class AbstractEncapsulateFieldService : ILanguageServi RenameInComments: false, RenameFile: false); - protected abstract Task RewriteFieldNameAndAccessibilityAsync(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + protected abstract Task RewriteFieldNameAndAccessibilityAsync(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken); protected abstract Task> GetFieldsAsync(Document document, TextSpan span, CancellationToken cancellationToken); protected abstract IEnumerable GetConstructorNodes(INamedTypeSymbol containingType); - public async Task EncapsulateFieldsInSpanAsync(Document document, TextSpan span, CleanCodeGenerationOptionsProvider fallbackOptions, bool useDefaultBehavior, CancellationToken cancellationToken) + public async Task EncapsulateFieldsInSpanAsync(Document document, TextSpan span, bool useDefaultBehavior, CancellationToken cancellationToken) { var fields = await GetFieldsAsync(document, span, cancellationToken).ConfigureAwait(false); if (fields.IsDefaultOrEmpty) @@ -51,10 +51,10 @@ public async Task EncapsulateFieldsInSpanAsync(Document return new EncapsulateFieldResult( firstField.ToDisplayString(), firstField.GetGlyph(), - cancellationToken => EncapsulateFieldsAsync(document, fields, fallbackOptions, useDefaultBehavior, cancellationToken)); + cancellationToken => EncapsulateFieldsAsync(document, fields, useDefaultBehavior, cancellationToken)); } - public async Task> GetEncapsulateFieldCodeActionsAsync(Document document, TextSpan span, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public async Task> GetEncapsulateFieldCodeActionsAsync(Document document, TextSpan span, CancellationToken cancellationToken) { var fields = await GetFieldsAsync(document, span, cancellationToken).ConfigureAwait(false); if (fields.IsDefaultOrEmpty) @@ -63,7 +63,7 @@ public async Task> GetEncapsulateFieldCodeActionsAsyn if (fields.Length == 1) { // there is only one field - return EncapsulateOneField(document, fields[0], fallbackOptions); + return EncapsulateOneField(document, fields[0]); } // there are multiple fields. @@ -73,44 +73,43 @@ public async Task> GetEncapsulateFieldCodeActionsAsyn { // if there is no selection, get action for each field + all of them. foreach (var field in fields) - builder.AddRange(EncapsulateOneField(document, field, fallbackOptions)); + builder.AddRange(EncapsulateOneField(document, field)); } - builder.AddRange(EncapsulateAllFields(document, fields, fallbackOptions)); + builder.AddRange(EncapsulateAllFields(document, fields)); return builder.ToImmutableAndClear(); } - private ImmutableArray EncapsulateAllFields(Document document, ImmutableArray fields, CleanCodeGenerationOptionsProvider fallbackOptions) + private ImmutableArray EncapsulateAllFields(Document document, ImmutableArray fields) => [ CodeAction.Create( FeaturesResources.Encapsulate_fields_and_use_property, - cancellationToken => EncapsulateFieldsAsync(document, fields, fallbackOptions, updateReferences: true, cancellationToken), + cancellationToken => EncapsulateFieldsAsync(document, fields, updateReferences: true, cancellationToken), nameof(FeaturesResources.Encapsulate_fields_and_use_property)), CodeAction.Create( FeaturesResources.Encapsulate_fields_but_still_use_field, - cancellationToken => EncapsulateFieldsAsync(document, fields, fallbackOptions, updateReferences: false, cancellationToken), + cancellationToken => EncapsulateFieldsAsync(document, fields, updateReferences: false, cancellationToken), nameof(FeaturesResources.Encapsulate_fields_but_still_use_field)), ]; - private ImmutableArray EncapsulateOneField(Document document, IFieldSymbol field, CleanCodeGenerationOptionsProvider fallbackOptions) + private ImmutableArray EncapsulateOneField(Document document, IFieldSymbol field) { var fields = ImmutableArray.Create(field); return [ CodeAction.Create( string.Format(FeaturesResources.Encapsulate_field_colon_0_and_use_property, field.Name), - cancellationToken => EncapsulateFieldsAsync(document, fields, fallbackOptions, updateReferences: true, cancellationToken), + cancellationToken => EncapsulateFieldsAsync(document, fields, updateReferences: true, cancellationToken), nameof(FeaturesResources.Encapsulate_field_colon_0_and_use_property) + "_" + field.Name), CodeAction.Create( string.Format(FeaturesResources.Encapsulate_field_colon_0_but_still_use_field, field.Name), - cancellationToken => EncapsulateFieldsAsync(document, fields, fallbackOptions, updateReferences: false, cancellationToken), + cancellationToken => EncapsulateFieldsAsync(document, fields, updateReferences: false, cancellationToken), nameof(FeaturesResources.Encapsulate_field_colon_0_but_still_use_field) + "_" + field.Name), ]; } public async Task EncapsulateFieldsAsync( Document document, ImmutableArray fields, - CleanCodeGenerationOptionsProvider fallbackOptions, bool updateReferences, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -125,8 +124,7 @@ public async Task EncapsulateFieldsAsync( var result = await client.TryInvokeAsync)>>( solution, - (service, solutionInfo, callbackId, cancellationToken) => service.EncapsulateFieldsAsync(solutionInfo, callbackId, document.Id, fieldSymbolKeys, updateReferences, cancellationToken), - callbackTarget: new RemoteOptionsProvider(solution.Services, fallbackOptions), + (service, solutionInfo, cancellationToken) => service.EncapsulateFieldsAsync(solutionInfo, document.Id, fieldSymbolKeys, updateReferences, cancellationToken), cancellationToken).ConfigureAwait(false); if (!result.HasValue) @@ -138,10 +136,10 @@ public async Task EncapsulateFieldsAsync( } return await EncapsulateFieldsInCurrentProcessAsync( - document, fields, fallbackOptions, updateReferences, cancellationToken).ConfigureAwait(false); + document, fields, updateReferences, cancellationToken).ConfigureAwait(false); } - private async Task EncapsulateFieldsInCurrentProcessAsync(Document document, ImmutableArray fields, CleanCodeGenerationOptionsProvider fallbackOptions, bool updateReferences, CancellationToken cancellationToken) + private async Task EncapsulateFieldsInCurrentProcessAsync(Document document, ImmutableArray fields, bool updateReferences, CancellationToken cancellationToken) { Contract.ThrowIfTrue(fields.Length == 0); @@ -157,7 +155,7 @@ private async Task EncapsulateFieldsInCurrentProcessAsync(Document doc if (field.GetSymbolKey(cancellationToken).Resolve(compilation, cancellationToken: cancellationToken).Symbol is not IFieldSymbol currentField) continue; - var nextSolution = await EncapsulateFieldAsync(document, currentField, updateReferences, fallbackOptions, cancellationToken).ConfigureAwait(false); + var nextSolution = await EncapsulateFieldAsync(document, currentField, updateReferences, cancellationToken).ConfigureAwait(false); if (nextSolution == null) continue; @@ -171,7 +169,6 @@ private async Task EncapsulateFieldAsync( Document document, IFieldSymbol field, bool updateReferences, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var originalField = field; @@ -195,11 +192,11 @@ private async Task EncapsulateFieldAsync( return null; var solutionNeedingProperty = await UpdateReferencesAsync( - updateReferences, solution, document, field, finalFieldName, generatedPropertyName, fallbackOptions, cancellationToken).ConfigureAwait(false); + updateReferences, solution, document, field, finalFieldName, generatedPropertyName, cancellationToken).ConfigureAwait(false); document = solutionNeedingProperty.GetDocument(document.Id); var markFieldPrivate = field.DeclaredAccessibility != Accessibility.Private; - var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibilityAsync(finalFieldName, markFieldPrivate, document, declarationAnnotation, fallbackOptions, cancellationToken).ConfigureAwait(false); + var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibilityAsync(finalFieldName, markFieldPrivate, document, declarationAnnotation, cancellationToken).ConfigureAwait(false); var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); @@ -223,7 +220,7 @@ private async Task EncapsulateFieldAsync( var simplifierOptions = await document.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(false); var documentWithProperty = await AddPropertyAsync( - document, document.Project.Solution, field, generatedProperty, fallbackOptions, cancellationToken).ConfigureAwait(false); + document, document.Project.Solution, field, generatedProperty, cancellationToken).ConfigureAwait(false); documentWithProperty = await Formatter.FormatAsync(documentWithProperty, Formatter.Annotation, formattingOptions, cancellationToken).ConfigureAwait(false); documentWithProperty = await Simplifier.ReduceAsync(documentWithProperty, simplifierOptions, cancellationToken).ConfigureAwait(false); @@ -232,7 +229,7 @@ private async Task EncapsulateFieldAsync( } private async Task UpdateReferencesAsync( - bool updateReferences, Solution solution, Document document, IFieldSymbol field, string finalFieldName, string generatedPropertyName, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + bool updateReferences, Solution solution, Document document, IFieldSymbol field, string finalFieldName, string generatedPropertyName, CancellationToken cancellationToken) { if (!updateReferences) return solution; @@ -249,7 +246,7 @@ private async Task UpdateReferencesAsync( if (finalFieldName != field.Name && constructorLocations.Count > 0) { solution = await RenameAsync( - solution, field, finalFieldName, fallbackOptions, linkedProjectIds, + solution, field, finalFieldName, linkedProjectIds, filter: (docId, span) => IntersectsWithAny(docId, span, constructorLocations), cancellationToken).ConfigureAwait(false); @@ -262,7 +259,7 @@ private async Task UpdateReferencesAsync( // Outside the constructor we want to rename references to the field to final property name. return await RenameAsync( - solution, field, generatedPropertyName, fallbackOptions, linkedProjectIds, + solution, field, generatedPropertyName, linkedProjectIds, filter: (documentId, span) => !IntersectsWithAny(documentId, span, constructorLocations), cancellationToken).ConfigureAwait(false); } @@ -270,7 +267,7 @@ private async Task UpdateReferencesAsync( { // Just rename everything. return await RenameAsync( - solution, field, generatedPropertyName, fallbackOptions, linkedProjectIds, + solution, field, generatedPropertyName, linkedProjectIds, filter: static (documentId, span) => true, cancellationToken).ConfigureAwait(false); } @@ -280,7 +277,6 @@ private static async Task RenameAsync( Solution solution, IFieldSymbol field, string finalName, - CodeCleanupOptionsProvider fallbackOptions, HashSet linkedProjectIds, Func filter, CancellationToken cancellationToken) @@ -292,7 +288,7 @@ private static async Task RenameAsync( // edit the files in the current project var resolution = await initialLocations .Filter((documentId, span) => !linkedProjectIds.Contains(documentId.ProjectId) && filter(documentId, span)) - .ResolveConflictsAsync(field, finalName, nonConflictSymbolKeys: default, fallbackOptions, cancellationToken).ConfigureAwait(false); + .ResolveConflictsAsync(field, finalName, nonConflictSymbolKeys: default, cancellationToken).ConfigureAwait(false); Contract.ThrowIfFalse(resolution.IsSuccessful); @@ -321,7 +317,6 @@ protected static async Task AddPropertyAsync( Solution destinationSolution, IFieldSymbol field, IPropertySymbol property, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var codeGenerationService = document.GetLanguageService(); @@ -331,8 +326,7 @@ protected static async Task AddPropertyAsync( var context = new CodeGenerationSolutionContext( destinationSolution, new CodeGenerationContext( - contextLocation: fieldDeclaration.SyntaxTree.GetLocation(fieldDeclaration.Span)), - fallbackOptions); + contextLocation: fieldDeclaration.SyntaxTree.GetLocation(fieldDeclaration.Span))); var destination = field.ContainingType; return await codeGenerationService.AddPropertyAsync( diff --git a/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs b/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs index 9ad942eb65c93..9705677551493 100644 --- a/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs +++ b/src/Features/Core/Portable/EncapsulateField/EncapsulateFieldRefactoringProvider.cs @@ -25,7 +25,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex var (document, textSpan, cancellationToken) = context; var service = document.GetRequiredLanguageService(); - var actions = await service.GetEncapsulateFieldCodeActionsAsync(document, textSpan, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await service.GetEncapsulateFieldCodeActionsAsync(document, textSpan, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/Core/Portable/EncapsulateField/IRemoteEncapsulateFieldService.cs b/src/Features/Core/Portable/EncapsulateField/IRemoteEncapsulateFieldService.cs index d974ebec3fc51..74bec39df7c2f 100644 --- a/src/Features/Core/Portable/EncapsulateField/IRemoteEncapsulateFieldService.cs +++ b/src/Features/Core/Portable/EncapsulateField/IRemoteEncapsulateFieldService.cs @@ -4,42 +4,19 @@ #nullable disable -using System; using System.Collections.Immutable; -using System.Composition; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.CodeGeneration; -using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.EncapsulateField; internal interface IRemoteEncapsulateFieldService { - internal interface ICallback : IRemoteOptionsCallback - { - } - ValueTask)>> EncapsulateFieldsAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, DocumentId documentId, ImmutableArray fieldSymbolKeys, bool updateReferences, CancellationToken cancellationToken); } - -[ExportRemoteServiceCallbackDispatcher(typeof(IRemoteEncapsulateFieldService)), Shared] -internal sealed class RemoteConvertTupleToStructCodeRefactoringServiceCallbackDispatcher : RemoteServiceCallbackDispatcher, IRemoteEncapsulateFieldService.ICallback -{ - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RemoteConvertTupleToStructCodeRefactoringServiceCallbackDispatcher() - { - } - - public ValueTask GetOptionsAsync(RemoteServiceCallbackId callbackId, string language, CancellationToken cancellationToken) - => ((RemoteOptionsProvider)GetCallback(callbackId)).GetOptionsAsync(language, cancellationToken); -} diff --git a/src/Features/Core/Portable/ExtractClass/AbstractExtractClassRefactoringProvider.cs b/src/Features/Core/Portable/ExtractClass/AbstractExtractClassRefactoringProvider.cs index e5e4c11f67e8d..99451f99e067f 100644 --- a/src/Features/Core/Portable/ExtractClass/AbstractExtractClassRefactoringProvider.cs +++ b/src/Features/Core/Portable/ExtractClass/AbstractExtractClassRefactoringProvider.cs @@ -107,7 +107,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte } var action = new ExtractClassWithDialogCodeAction( - document, memberSpan, optionsService, containingType, containingTypeDeclarationNode, context.Options, selectedMembers); + document, memberSpan, optionsService, containingType, containingTypeDeclarationNode, selectedMembers); return (action, false); } @@ -134,7 +134,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte } return new ExtractClassWithDialogCodeAction( - document, span, optionsService, selectedType, selectedClassNode, context.Options, selectedMembers: []); + document, span, optionsService, selectedType, selectedClassNode, selectedMembers: []); } private static bool HasBaseType(INamedTypeSymbol containingType) => containingType.BaseType?.SpecialType != SpecialType.System_Object; diff --git a/src/Features/Core/Portable/ExtractClass/ExtractClassWithDialogCodeAction.cs b/src/Features/Core/Portable/ExtractClass/ExtractClassWithDialogCodeAction.cs index 4fa3b561c7aa5..7ee3ab7a48de2 100644 --- a/src/Features/Core/Portable/ExtractClass/ExtractClassWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/ExtractClass/ExtractClassWithDialogCodeAction.cs @@ -28,14 +28,12 @@ internal class ExtractClassWithDialogCodeAction( IExtractClassOptionsService service, INamedTypeSymbol selectedType, SyntaxNode selectedTypeDeclarationNode, - CleanCodeGenerationOptionsProvider fallbackOptions, ImmutableArray selectedMembers) : CodeActionWithOptions { private readonly Document _document = document; private readonly ImmutableArray _selectedMembers = selectedMembers; private readonly INamedTypeSymbol _selectedType = selectedType; private readonly SyntaxNode _selectedTypeDeclarationNode = selectedTypeDeclarationNode; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; private readonly IExtractClassOptionsService _service = service; // If the user brought up the lightbulb on a class itself, it's more likely that they want to extract a base @@ -98,7 +96,6 @@ protected override async Task> ComputeOperation symbolMapping.AnnotatedSolution.GetRequiredDocument(_document.Id), newType, symbolMapping, - _fallbackOptions, cancellationToken).ConfigureAwait(false) : await ExtractTypeHelpers.AddTypeToNewFileAsync( symbolMapping.AnnotatedSolution, @@ -108,7 +105,6 @@ protected override async Task> ComputeOperation _document.Folders, newType, _document, - _fallbackOptions, cancellationToken).ConfigureAwait(false); // Update the original type to have the new base @@ -207,7 +203,7 @@ private async Task PullMembersUpAsync( var pullMemberUpOptions = PullMembersUpOptionsBuilder.BuildPullMembersUpOptions(newType, pullMembersBuilder.ToImmutable()); var updatedOriginalDocument = solution.GetRequiredDocument(_document.Id); - return await MembersPuller.PullMembersUpAsync(updatedOriginalDocument, pullMemberUpOptions, _fallbackOptions, cancellationToken).ConfigureAwait(false); + return await MembersPuller.PullMembersUpAsync(updatedOriginalDocument, pullMemberUpOptions, cancellationToken).ConfigureAwait(false); } private static async Task GetNewTypeSymbolAsync(Document document, SyntaxAnnotation typeAnnotation, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index 7db9025faab74..757f30f9b1531 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -194,7 +194,6 @@ private async Task ExtractInterfaceToNewFileAsync( refactoringResult.DocumentToExtractFrom.Folders, extractedInterfaceSymbol, refactoringResult.DocumentToExtractFrom, - extractInterfaceOptions.FallbackOptions, cancellationToken).ConfigureAwait(false); var completedUnformattedSolution = await GetSolutionWithOriginalTypeUpdatedAsync( @@ -210,7 +209,6 @@ private async Task ExtractInterfaceToNewFileAsync( var completedSolution = await GetFormattedSolutionAsync( completedUnformattedSolution, symbolMapping.DocumentIdsToSymbolMap.Keys.Concat(unformattedInterfaceDocument.Id), - extractInterfaceOptions.FallbackOptions, cancellationToken).ConfigureAwait(false); return new ExtractInterfaceResult( @@ -236,7 +234,6 @@ private async Task ExtractInterfaceToSameFileAsync( document, extractedInterfaceSymbol, symbolMapping, - extractInterfaceOptions.FallbackOptions, cancellationToken).ConfigureAwait(false); var unformattedSolution = documentWithInterface.Project.Solution; @@ -251,7 +248,6 @@ private async Task ExtractInterfaceToSameFileAsync( var completedSolution = await GetFormattedSolutionAsync( unformattedSolutionWithUpdatedType, symbolMapping.DocumentIdsToSymbolMap.Keys.Concat(refactoringResult.DocumentToExtractFrom.Id), - extractInterfaceOptions.FallbackOptions, cancellationToken).ConfigureAwait(false); return new ExtractInterfaceResult( @@ -290,7 +286,7 @@ internal static async Task GetExtractInterfaceOpt cancellationToken).ConfigureAwait(false); } - private static async Task GetFormattedSolutionAsync(Solution unformattedSolution, IEnumerable documentIds, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private static async Task GetFormattedSolutionAsync(Solution unformattedSolution, IEnumerable documentIds, CancellationToken cancellationToken) { // Since code action performs formatting and simplification on a single document, // this ensures that anything marked with formatter or simplifier annotations gets @@ -300,7 +296,7 @@ private static async Task GetFormattedSolutionAsync(Solution unformatt { var document = formattedSolution.GetDocument(documentId); - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var formattedDocument = await Formatter.FormatAsync( document, diff --git a/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs index 2f38f00782e23..c6e64993f5256 100644 --- a/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs @@ -96,7 +96,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var missingType = missingComparableTypes[0]; context.RegisterRefactoring(CodeAction.Create( FeaturesResources.Generate_comparison_operators, - c => GenerateComparisonOperatorsAsync(document, typeDeclaration, missingType, context.Options, c), + c => GenerateComparisonOperatorsAsync(document, typeDeclaration, missingType, c), nameof(FeaturesResources.Generate_comparison_operators))); return; } @@ -109,7 +109,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var displayString = typeArg.ToMinimalDisplayString(semanticModel, textSpan.Start); nestedActions.Add(CodeAction.Create( string.Format(FeaturesResources.Generate_for_0, displayString), - c => GenerateComparisonOperatorsAsync(document, typeDeclaration, missingType, context.Options, c), + c => GenerateComparisonOperatorsAsync(document, typeDeclaration, missingType, c), nameof(FeaturesResources.Generate_for_0) + "_" + displayString)); } @@ -134,7 +134,6 @@ private static async Task GenerateComparisonOperatorsAsync( Document document, SyntaxNode typeDeclaration, INamedTypeSymbol comparableType, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -151,8 +150,7 @@ private static async Task GenerateComparisonOperatorsAsync( var solutionContext = new CodeGenerationSolutionContext( document.Project.Solution, - new CodeGenerationContext(contextLocation: typeDeclaration.GetLocation()), - fallbackOptions); + new CodeGenerationContext(contextLocation: typeDeclaration.GetLocation())); return await codeGenService.AddMembersAsync(solutionContext, containingType, operators, cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.ConstructorDelegatingCodeAction.cs b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.ConstructorDelegatingCodeAction.cs index f32ca8a5e0deb..98d9879c14c61 100644 --- a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.ConstructorDelegatingCodeAction.cs +++ b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.ConstructorDelegatingCodeAction.cs @@ -21,14 +21,12 @@ private sealed class ConstructorDelegatingCodeAction( AbstractGenerateConstructorFromMembersCodeRefactoringProvider service, Document document, State state, - bool addNullChecks, - CleanCodeGenerationOptionsProvider fallbackOptions) : CodeAction + bool addNullChecks) : CodeAction { private readonly AbstractGenerateConstructorFromMembersCodeRefactoringProvider _service = service; private readonly Document _document = document; private readonly State _state = state; private readonly bool _addNullChecks = addNullChecks; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) { @@ -52,7 +50,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke using var _1 = ArrayBuilder.GetInstance(out var nullCheckStatements); using var _2 = ArrayBuilder.GetInstance(out var assignStatements); - var useThrowExpressions = await _service.PrefersThrowExpressionAsync(_document, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var useThrowExpressions = await _service.PrefersThrowExpressionAsync(_document, cancellationToken).ConfigureAwait(false); for (var i = _state.DelegatedConstructor.Parameters.Length; i < _state.Parameters.Length; i++) { @@ -85,8 +83,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke _document.Project.Solution, new CodeGenerationContext( contextLocation: syntaxTree.GetLocation(_state.TextSpan), - afterThisLocation: afterThisLocation), - _fallbackOptions), + afterThisLocation: afterThisLocation)), _state.ContainingType, CodeGenerationSymbolFactory.CreateConstructorSymbol( attributes: default, diff --git a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.FieldDelegatingCodeAction.cs b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.FieldDelegatingCodeAction.cs index 4d1978eb28173..c2ac3f8841bf4 100644 --- a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.FieldDelegatingCodeAction.cs +++ b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.FieldDelegatingCodeAction.cs @@ -19,14 +19,12 @@ private sealed class FieldDelegatingCodeAction( AbstractGenerateConstructorFromMembersCodeRefactoringProvider service, Document document, State state, - bool addNullChecks, - CleanCodeGenerationOptionsProvider fallbackOptions) : CodeAction + bool addNullChecks) : CodeAction { private readonly AbstractGenerateConstructorFromMembersCodeRefactoringProvider _service = service; private readonly Document _document = document; private readonly State _state = state; private readonly bool _addNullChecks = addNullChecks; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) { @@ -44,7 +42,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke var semanticModel = await _document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var syntaxTree = semanticModel.SyntaxTree; - var preferThrowExpression = await _service.PrefersThrowExpressionAsync(_document, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var preferThrowExpression = await _service.PrefersThrowExpressionAsync(_document, cancellationToken).ConfigureAwait(false); var members = factory.CreateMemberDelegatingConstructor( semanticModel, @@ -72,8 +70,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke _document.Project.Solution, new CodeGenerationContext( contextLocation: syntaxTree.GetLocation(_state.TextSpan), - afterThisLocation: afterThisLocation), - _fallbackOptions), + afterThisLocation: afterThisLocation)), _state.ContainingType, members, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.GenerateConstructorWithDialogCodeAction.cs b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.GenerateConstructorWithDialogCodeAction.cs index 1b89718070601..3e0dc1d8070c5 100644 --- a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.GenerateConstructorWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.GenerateConstructorWithDialogCodeAction.cs @@ -28,15 +28,13 @@ private class GenerateConstructorWithDialogCodeAction( INamedTypeSymbol containingType, Accessibility? desiredAccessibility, ImmutableArray viableMembers, - ImmutableArray pickMembersOptions, - CleanCodeGenerationOptionsProvider fallbackOptions) : CodeActionWithOptions + ImmutableArray pickMembersOptions) : CodeActionWithOptions { private readonly Document _document = document; private readonly INamedTypeSymbol _containingType = containingType; private readonly Accessibility? _desiredAccessibility = desiredAccessibility; private readonly AbstractGenerateConstructorFromMembersCodeRefactoringProvider _service = service; private readonly TextSpan _textSpan = textSpan; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; internal ImmutableArray ViableMembers { get; } = viableMembers; internal ImmutableArray PickMembersOptions { get; } = pickMembersOptions; @@ -74,7 +72,7 @@ protected override async Task> ComputeOperation var addNullChecks = (addNullChecksOption?.Value ?? false); var state = await State.TryGenerateAsync( _service, _document, _textSpan, _containingType, _desiredAccessibility, - result.Members, _fallbackOptions, cancellationToken).ConfigureAwait(false); + result.Members, cancellationToken).ConfigureAwait(false); if (state == null) return []; @@ -87,7 +85,7 @@ protected override async Task> ComputeOperation { if (state.MatchingConstructor.IsImplicitlyDeclared) { - var codeAction = new FieldDelegatingCodeAction(_service, _document, state, addNullChecks, _fallbackOptions); + var codeAction = new FieldDelegatingCodeAction(_service, _document, state, addNullChecks); return await codeAction.GetOperationsAsync(solution, progressTracker, cancellationToken).ConfigureAwait(false); } @@ -101,8 +99,8 @@ protected override async Task> ComputeOperation else { var codeAction = state.DelegatedConstructor != null - ? new ConstructorDelegatingCodeAction(_service, _document, state, addNullChecks, _fallbackOptions) - : (CodeAction)new FieldDelegatingCodeAction(_service, _document, state, addNullChecks, _fallbackOptions); + ? new ConstructorDelegatingCodeAction(_service, _document, state, addNullChecks) + : (CodeAction)new FieldDelegatingCodeAction(_service, _document, state, addNullChecks); return await codeAction.GetOperationsAsync(solution, progressTracker, cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.State.cs b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.State.cs index 6a6bf0e26b805..f43137c327287 100644 --- a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.State.cs +++ b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.State.cs @@ -38,11 +38,10 @@ private class State INamedTypeSymbol containingType, Accessibility? desiredAccessibility, ImmutableArray selectedMembers, - NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) { var state = new State(); - if (!await state.TryInitializeAsync(service, document, textSpan, containingType, desiredAccessibility, selectedMembers, fallbackOptions, cancellationToken).ConfigureAwait(false)) + if (!await state.TryInitializeAsync(service, document, textSpan, containingType, desiredAccessibility, selectedMembers, cancellationToken).ConfigureAwait(false)) return null; return state; @@ -55,7 +54,6 @@ private async Task TryInitializeAsync( INamedTypeSymbol containingType, Accessibility? desiredAccessibility, ImmutableArray selectedMembers, - NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) { var mappedMembers = selectedMembers.Select(m => TryMapToWritableInstanceFieldOrProperty(service, m, cancellationToken)).Distinct().ToImmutableArray(); @@ -72,7 +70,7 @@ private async Task TryInitializeAsync( IsContainedInUnsafeType = service.ContainingTypesOrSelfHasUnsafeKeyword(containingType); - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); Parameters = DetermineParameters(SelectedMembers, rules); MatchingConstructor = GetMatchingConstructorBasedOnParameterTypes(ContainingType, Parameters); // We are going to create a new contructor and pass part of the parameters into DelegatedConstructor, so diff --git a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.cs index 998e586662463..4b30ec9d3c782 100644 --- a/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateConstructorFromMembers/AbstractGenerateConstructorFromMembersCodeRefactoringProvider.cs @@ -57,7 +57,7 @@ protected AbstractGenerateConstructorFromMembersCodeRefactoringProvider(IPickMem protected abstract bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol containingType); protected abstract string ToDisplayString(IParameterSymbol parameter, SymbolDisplayFormat format); - protected abstract ValueTask PrefersThrowExpressionAsync(Document document, SimplifierOptionsProvider fallbackOptions, CancellationToken cancellationToken); + protected abstract ValueTask PrefersThrowExpressionAsync(Document document, CancellationToken cancellationToken); protected abstract IFieldSymbol? TryMapToWritableInstanceField(IPropertySymbol property, CancellationToken cancellationToken); public override Task ComputeRefactoringsAsync(CodeRefactoringContext context) @@ -68,7 +68,6 @@ public override Task ComputeRefactoringsAsync(CodeRefactoringContext context) context.RegisterRefactoring, actions => context.RegisterRefactorings(actions), desiredAccessibility: null, - context.Options, context.CancellationToken); } @@ -84,7 +83,6 @@ await ComputeRefactoringsAsync( (singleAction, applicableToSpan) => actions.Add(singleAction), actions.AddRange, desiredAccessibility: accessibility, - intentDataProvider.FallbackOptions, cancellationToken).ConfigureAwait(false); if (actions.IsEmpty) @@ -153,7 +151,6 @@ private async Task ComputeRefactoringsAsync( Action registerSingleAction, Action> registerMultipleActions, Accessibility? desiredAccessibility, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { if (document.Project.Solution.WorkspaceKind == WorkspaceKind.MiscellaneousFiles) @@ -162,7 +159,7 @@ private async Task ComputeRefactoringsAsync( } var actions = await GenerateConstructorFromMembersAsync( - document, textSpan, addNullChecks: false, desiredAccessibility, fallbackOptions, cancellationToken).ConfigureAwait(false); + document, textSpan, addNullChecks: false, desiredAccessibility, cancellationToken).ConfigureAwait(false); if (!actions.IsDefault) { registerMultipleActions(actions); @@ -170,7 +167,7 @@ private async Task ComputeRefactoringsAsync( if (actions.IsDefaultOrEmpty && textSpan.IsEmpty) { - var nonSelectionAction = await HandleNonSelectionAsync(document, textSpan, desiredAccessibility, fallbackOptions, cancellationToken).ConfigureAwait(false); + var nonSelectionAction = await HandleNonSelectionAsync(document, textSpan, desiredAccessibility, cancellationToken).ConfigureAwait(false); if (nonSelectionAction != null) { registerSingleAction(nonSelectionAction.Value.CodeAction, nonSelectionAction.Value.ApplicableToSpan); @@ -182,7 +179,6 @@ private async Task ComputeRefactoringsAsync( Document document, TextSpan textSpan, Accessibility? desiredAccessibility, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var helpers = document.GetRequiredLanguageService(); @@ -251,33 +247,33 @@ private async Task ComputeRefactoringsAsync( return (new GenerateConstructorWithDialogCodeAction( this, document, textSpan, containingType, desiredAccessibility, viableMembers, - pickMemberOptions.ToImmutable(), fallbackOptions), typeDeclaration.Span); + pickMemberOptions.ToImmutable()), typeDeclaration.Span); } public async Task> GenerateConstructorFromMembersAsync( - Document document, TextSpan textSpan, bool addNullChecks, Accessibility? desiredAccessibility, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, TextSpan textSpan, bool addNullChecks, Accessibility? desiredAccessibility, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateFromMembers_GenerateConstructorFromMembers, cancellationToken)) { var info = await GetSelectedMemberInfoAsync(document, textSpan, allowPartialSelection: true, cancellationToken).ConfigureAwait(false); if (info != null) { - var state = await State.TryGenerateAsync(this, document, textSpan, info.ContainingType, desiredAccessibility, info.SelectedMembers, fallbackOptions, cancellationToken).ConfigureAwait(false); + var state = await State.TryGenerateAsync(this, document, textSpan, info.ContainingType, desiredAccessibility, info.SelectedMembers, cancellationToken).ConfigureAwait(false); if (state != null && state.MatchingConstructor == null) - return GetCodeActions(document, state, addNullChecks, fallbackOptions); + return GetCodeActions(document, state, addNullChecks); } return default; } } - private ImmutableArray GetCodeActions(Document document, State state, bool addNullChecks, CleanCodeGenerationOptionsProvider fallbackOptions) + private ImmutableArray GetCodeActions(Document document, State state, bool addNullChecks) { using var result = TemporaryArray.Empty; - result.Add(new FieldDelegatingCodeAction(this, document, state, addNullChecks, fallbackOptions)); + result.Add(new FieldDelegatingCodeAction(this, document, state, addNullChecks)); if (state.DelegatedConstructor != null) - result.Add(new ConstructorDelegatingCodeAction(this, document, state, addNullChecks, fallbackOptions)); + result.Add(new ConstructorDelegatingCodeAction(this, document, state, addNullChecks)); return result.ToImmutableAndClear(); } diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorCodeFixProvider.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorCodeFixProvider.cs index 1618b512172cf..7a6bc47b6c552 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorCodeFixProvider.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorCodeFixProvider.cs @@ -36,7 +36,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var service = document.GetRequiredLanguageService(); var actions = await service.GenerateDefaultConstructorsAsync( - document, new TextSpan(typeName.Value.Span.Start, 0), context.Options, forRefactoring: false, cancellationToken).ConfigureAwait(false); + document, new TextSpan(typeName.Value.Span.Start, 0), forRefactoring: false, cancellationToken).ConfigureAwait(false); context.RegisterFixes(actions, diagnostic); } } diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.AbstractCodeAction.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.AbstractCodeAction.cs index 5ba428e91a415..a130506638d6d 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.AbstractCodeAction.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.AbstractCodeAction.cs @@ -22,20 +22,17 @@ private abstract class AbstractCodeAction : CodeAction private readonly Document _document; private readonly State _state; private readonly string _title; - private readonly CodeAndImportGenerationOptionsProvider _fallbackOptions; protected AbstractCodeAction( Document document, State state, IList constructors, - string title, - CodeAndImportGenerationOptionsProvider fallbackOptions) + string title) { _document = document; _state = state; _constructors = constructors; _title = title; - _fallbackOptions = fallbackOptions; } public override string Title => _title; @@ -46,8 +43,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke var result = await CodeGenerator.AddMemberDeclarationsAsync( new CodeGenerationSolutionContext( _document.Project.Solution, - CodeGenerationContext.Default, - _fallbackOptions), + CodeGenerationContext.Default), _state.ClassType, _constructors.Select(CreateConstructorDefinition), cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.CodeAction.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.CodeAction.cs index 609672f763982..f62af687ffcff 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.CodeAction.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.CodeAction.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Linq; -using Microsoft.CodeAnalysis.CodeGeneration; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.GenerateDefaultConstructors; @@ -13,8 +12,7 @@ internal abstract partial class AbstractGenerateDefaultConstructorsService constructors, - CodeAndImportGenerationOptionsProvider fallbackOptions) : AbstractCodeAction(document, state, constructors, FeaturesResources.Generate_all, fallbackOptions) + IList constructors) : AbstractCodeAction(document, state, constructors, FeaturesResources.Generate_all) { } } diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.cs index 40bbda4c13000..0476ef6ab81b9 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/AbstractGenerateDefaultConstructorsService.cs @@ -28,7 +28,6 @@ protected abstract bool TryInitializeState( public async Task> GenerateDefaultConstructorsAsync( Document document, TextSpan textSpan, - CodeAndImportGenerationOptionsProvider fallbackOptions, bool forRefactoring, CancellationToken cancellationToken) { @@ -43,10 +42,10 @@ public async Task> GenerateDefaultConstructorsAsync( if (state != null) { foreach (var constructor in state.UnimplementedConstructors) - result.Add(new GenerateDefaultConstructorCodeAction(document, state, constructor, fallbackOptions)); + result.Add(new GenerateDefaultConstructorCodeAction(document, state, constructor)); if (state.UnimplementedConstructors.Length > 1) - result.Add(new CodeActionAll(document, state, state.UnimplementedConstructors, fallbackOptions)); + result.Add(new CodeActionAll(document, state, state.UnimplementedConstructors)); } } diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs index c2434b95ce1a1..663cef174b2a3 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/GenerateDefaultConstructorsCodeRefactoringProvider.cs @@ -46,7 +46,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var service = document.GetRequiredLanguageService(); var actions = await service.GenerateDefaultConstructorsAsync( - document, textSpan, context.Options, forRefactoring: true, cancellationToken).ConfigureAwait(false); + document, textSpan, forRefactoring: true, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/Core/Portable/GenerateDefaultConstructors/IGenerateDefaultConstructorsService.cs b/src/Features/Core/Portable/GenerateDefaultConstructors/IGenerateDefaultConstructorsService.cs index e0fde8bb1ccbe..b36bdfd4a7817 100644 --- a/src/Features/Core/Portable/GenerateDefaultConstructors/IGenerateDefaultConstructorsService.cs +++ b/src/Features/Core/Portable/GenerateDefaultConstructors/IGenerateDefaultConstructorsService.cs @@ -15,5 +15,5 @@ namespace Microsoft.CodeAnalysis.GenerateDefaultConstructors; internal interface IGenerateDefaultConstructorsService : ILanguageService { Task> GenerateDefaultConstructorsAsync( - Document document, TextSpan textSpan, CodeAndImportGenerationOptionsProvider fallbackOptions, bool forRefactoring, CancellationToken cancellationToken); + Document document, TextSpan textSpan, bool forRefactoring, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs index 89696ad7a4c93..e21b01c830d2b 100644 --- a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs +++ b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs @@ -23,7 +23,6 @@ private partial class GenerateEqualsAndGetHashCodeAction( SyntaxNode typeDeclaration, INamedTypeSymbol containingType, ImmutableArray selectedMembers, - CleanCodeGenerationOptionsProvider fallbackOptions, bool generateEquals, bool generateGetHashCode, bool implementIEquatable, @@ -42,7 +41,6 @@ private partial class GenerateEqualsAndGetHashCodeAction( private readonly SyntaxNode _typeDeclaration = typeDeclaration; private readonly INamedTypeSymbol _containingType = containingType; private readonly ImmutableArray _selectedMembers = selectedMembers; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; public override string EquivalenceKey => Title; @@ -72,7 +70,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke await AddOperatorsAsync(methods, cancellationToken).ConfigureAwait(false); } - var info = await _document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await _document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); var formattingOptions = await _document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var newTypeDeclaration = info.Service.AddMembers(_typeDeclaration, methods, info, cancellationToken); @@ -118,7 +116,7 @@ private async Task UpdateDocumentAndAddImportsAsync(SyntaxNode oldType { var oldRoot = await _document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newDocument = _document.WithSyntaxRoot(oldRoot.ReplaceNode(oldType, newType)); - var addImportOptions = await _document.GetAddImportPlacementOptionsAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false); + var addImportOptions = await _document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); newDocument = await ImportAdder.AddImportsFromSymbolAnnotationAsync(newDocument, addImportOptions, cancellationToken).ConfigureAwait(false); return newDocument; diff --git a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs index 026aebe1f1a3b..de20348c4545f 100644 --- a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs @@ -56,18 +56,16 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; } - var actions = await GenerateEqualsAndGetHashCodeFromMembersAsync(document, textSpan, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await GenerateEqualsAndGetHashCodeFromMembersAsync(document, textSpan, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); if (actions.IsDefaultOrEmpty && textSpan.IsEmpty) { - await HandleNonSelectionAsync(context, context.Options).ConfigureAwait(false); + await HandleNonSelectionAsync(context).ConfigureAwait(false); } } - private async Task HandleNonSelectionAsync( - CodeRefactoringContext context, - CleanCodeGenerationOptionsProvider fallbackOptions) + private async Task HandleNonSelectionAsync(CodeRefactoringContext context) { var (document, textSpan, cancellationToken) = context; @@ -114,7 +112,7 @@ private async Task HandleNonSelectionAsync( return; var actions = await CreateActionsAsync( - document, typeDeclaration, containingType, viableMembers, fallbackOptions, + document, typeDeclaration, containingType, viableMembers, hasEquals, hasGetHashCode, withDialog: true, globalOptions, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions, textSpan); @@ -169,7 +167,6 @@ private static void GetExistingMemberInfo(INamedTypeSymbol containingType, out b public async Task> GenerateEqualsAndGetHashCodeFromMembersAsync( Document document, TextSpan textSpan, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateFromMembers_GenerateEqualsAndGetHashCode, cancellationToken)) @@ -189,7 +186,7 @@ public async Task> GenerateEqualsAndGetHashCodeFromMe RoslynDebug.AssertNotNull(typeDeclaration); return await CreateActionsAsync( - document, typeDeclaration, info.ContainingType, info.SelectedMembers, fallbackOptions, + document, typeDeclaration, info.ContainingType, info.SelectedMembers, hasEquals, hasGetHashCode, withDialog: false, globalOptions: null, cancellationToken).ConfigureAwait(false); } } @@ -200,7 +197,6 @@ public async Task> GenerateEqualsAndGetHashCodeFromMe private async Task> CreateActionsAsync( Document document, SyntaxNode typeDeclaration, INamedTypeSymbol containingType, ImmutableArray selectedMembers, - CleanCodeGenerationOptionsProvider fallbackOptions, bool hasEquals, bool hasGetHashCode, bool withDialog, ILegacyGlobalOptionsWorkspaceService? globalOptions, CancellationToken cancellationToken) { using var _ = ArrayBuilder>.GetInstance(out var tasks); @@ -215,22 +211,22 @@ private async Task> CreateActionsAsync( // the user would need to bother just generating that member without also // generating 'Equals' as well. tasks.Add(CreateCodeActionAsync( - document, typeDeclaration, containingType, selectedMembers, fallbackOptions, globalOptions, + document, typeDeclaration, containingType, selectedMembers, globalOptions, generateEquals: true, generateGetHashCode: false, withDialog, cancellationToken)); tasks.Add(CreateCodeActionAsync( - document, typeDeclaration, containingType, selectedMembers, fallbackOptions, globalOptions, + document, typeDeclaration, containingType, selectedMembers, globalOptions, generateEquals: true, generateGetHashCode: true, withDialog, cancellationToken)); } else if (!hasEquals) { tasks.Add(CreateCodeActionAsync( - document, typeDeclaration, containingType, selectedMembers, fallbackOptions, globalOptions, + document, typeDeclaration, containingType, selectedMembers, globalOptions, generateEquals: true, generateGetHashCode: false, withDialog, cancellationToken)); } else if (!hasGetHashCode) { tasks.Add(CreateCodeActionAsync( - document, typeDeclaration, containingType, selectedMembers, fallbackOptions, globalOptions, + document, typeDeclaration, containingType, selectedMembers, globalOptions, generateEquals: false, generateGetHashCode: true, withDialog, cancellationToken)); } @@ -241,24 +237,24 @@ private async Task> CreateActionsAsync( private Task CreateCodeActionAsync( Document document, SyntaxNode typeDeclaration, INamedTypeSymbol containingType, ImmutableArray members, - CleanCodeGenerationOptionsProvider fallbackOptions, ILegacyGlobalOptionsWorkspaceService? globalOptions, + ILegacyGlobalOptionsWorkspaceService? globalOptions, bool generateEquals, bool generateGetHashCode, bool withDialog, CancellationToken cancellationToken) { if (withDialog) { // We can't create dialog code action if globalOptions is null Contract.ThrowIfNull(globalOptions); - return CreateCodeActionWithDialogAsync(document, typeDeclaration, containingType, members, fallbackOptions, globalOptions, generateEquals, generateGetHashCode, cancellationToken); + return CreateCodeActionWithDialogAsync(document, typeDeclaration, containingType, members, globalOptions, generateEquals, generateGetHashCode, cancellationToken); } else { - return CreateCodeActionWithoutDialogAsync(document, typeDeclaration, containingType, members, fallbackOptions, generateEquals, generateGetHashCode, cancellationToken); + return CreateCodeActionWithoutDialogAsync(document, typeDeclaration, containingType, members, generateEquals, generateGetHashCode, cancellationToken); } } private async Task CreateCodeActionWithDialogAsync( Document document, SyntaxNode typeDeclaration, INamedTypeSymbol containingType, ImmutableArray members, - CleanCodeGenerationOptionsProvider fallbackOptions, ILegacyGlobalOptionsWorkspaceService globalOptions, + ILegacyGlobalOptionsWorkspaceService globalOptions, bool generateEquals, bool generateGetHashCode, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -290,12 +286,11 @@ private async Task CreateCodeActionWithDialogAsync( } return new GenerateEqualsAndGetHashCodeWithDialogCodeAction( - this, document, typeDeclaration, containingType, members, pickMembersOptions.ToImmutable(), fallbackOptions, globalOptions, generateEquals, generateGetHashCode); + this, document, typeDeclaration, containingType, members, pickMembersOptions.ToImmutable(), globalOptions, generateEquals, generateGetHashCode); } private static async Task CreateCodeActionWithoutDialogAsync( Document document, SyntaxNode typeDeclaration, INamedTypeSymbol containingType, ImmutableArray members, - CleanCodeGenerationOptionsProvider fallbackOptions, bool generateEquals, bool generateGetHashCode, CancellationToken cancellationToken) { var implementIEquatable = false; @@ -311,7 +306,7 @@ private static async Task CreateCodeActionWithoutDialogAsync( } return new GenerateEqualsAndGetHashCodeAction( - document, typeDeclaration, containingType, members, fallbackOptions, + document, typeDeclaration, containingType, members, generateEquals, generateGetHashCode, implementIEquatable, generateOperators); } } diff --git a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndHashWithDialogCodeAction.cs b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndHashWithDialogCodeAction.cs index d051b48a45e80..a096ad822ea42 100644 --- a/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndHashWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndHashWithDialogCodeAction.cs @@ -25,7 +25,6 @@ private sealed class GenerateEqualsAndGetHashCodeWithDialogCodeAction( INamedTypeSymbol containingType, ImmutableArray viableMembers, ImmutableArray pickMembersOptions, - CleanCodeGenerationOptionsProvider fallbackOptions, ILegacyGlobalOptionsWorkspaceService globalOptions, bool generateEquals = false, bool generateGetHashCode = false) : CodeActionWithOptions @@ -38,7 +37,6 @@ private sealed class GenerateEqualsAndGetHashCodeWithDialogCodeAction( private readonly INamedTypeSymbol _containingType = containingType; private readonly ImmutableArray _viableMembers = viableMembers; private readonly ImmutableArray _pickMembersOptions = pickMembersOptions; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; private readonly ILegacyGlobalOptionsWorkspaceService _globalOptions = globalOptions; public override string EquivalenceKey => Title; @@ -81,7 +79,7 @@ protected override async Task> ComputeOperation var generatorOperators = generateOperatorsOption?.Value ?? false; var action = new GenerateEqualsAndGetHashCodeAction( - _document, _typeDeclaration, _containingType, result.Members, _fallbackOptions, + _document, _typeDeclaration, _containingType, result.Members, _generateEquals, _generateGetHashCode, implementIEquatable, generatorOperators); return await action.GetOperationsAsync(solution, progressTracker, cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.State.cs index bb35aac9afd84..0f8c62b9c2bba 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.State.cs @@ -28,7 +28,6 @@ protected internal class State { private readonly TService _service; private readonly SemanticDocument _document; - private readonly CodeAndImportGenerationOptionsProvider _fallbackOptions; private readonly NamingRule _fieldNamingRule; private readonly NamingRule _propertyNamingRule; @@ -54,7 +53,7 @@ protected internal class State public ImmutableDictionary ParameterToNewPropertyMap { get; private set; } public bool IsContainedInUnsafeType { get; private set; } - private State(TService service, SemanticDocument document, NamingRule fieldNamingRule, NamingRule propertyNamingRule, NamingRule parameterNamingRule, CodeAndImportGenerationOptionsProvider fallbackOptions) + private State(TService service, SemanticDocument document, NamingRule fieldNamingRule, NamingRule propertyNamingRule, NamingRule parameterNamingRule) { _service = service; _document = document; @@ -64,21 +63,19 @@ private State(TService service, SemanticDocument document, NamingRule fieldNamin ParameterToNewFieldMap = ImmutableDictionary.Empty; ParameterToNewPropertyMap = ImmutableDictionary.Empty; - _fallbackOptions = fallbackOptions; } public static async Task GenerateAsync( TService service, SemanticDocument document, SyntaxNode node, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { - var fieldNamingRule = await document.Document.GetApplicableNamingRuleAsync(SymbolKind.Field, Accessibility.Private, fallbackOptions, cancellationToken).ConfigureAwait(false); - var propertyNamingRule = await document.Document.GetApplicableNamingRuleAsync(SymbolKind.Property, Accessibility.Public, fallbackOptions, cancellationToken).ConfigureAwait(false); - var parameterNamingRule = await document.Document.GetApplicableNamingRuleAsync(SymbolKind.Parameter, Accessibility.NotApplicable, fallbackOptions, cancellationToken).ConfigureAwait(false); + var fieldNamingRule = await document.Document.GetApplicableNamingRuleAsync(SymbolKind.Field, Accessibility.Private, cancellationToken).ConfigureAwait(false); + var propertyNamingRule = await document.Document.GetApplicableNamingRuleAsync(SymbolKind.Property, Accessibility.Public, cancellationToken).ConfigureAwait(false); + var parameterNamingRule = await document.Document.GetApplicableNamingRuleAsync(SymbolKind.Parameter, Accessibility.NotApplicable, cancellationToken).ConfigureAwait(false); - var state = new State(service, document, fieldNamingRule, propertyNamingRule, parameterNamingRule, fallbackOptions); + var state = new State(service, document, fieldNamingRule, propertyNamingRule, parameterNamingRule); if (!await state.TryInitializeAsync(node, cancellationToken).ConfigureAwait(false)) { return null; @@ -597,8 +594,7 @@ public async Task GetChangedDocumentAsync( var context = new CodeGenerationSolutionContext( document.Project.Solution, - new CodeGenerationContext(Token.GetLocation()), - _fallbackOptions); + new CodeGenerationContext(Token.GetLocation())); return await provider.GetRequiredService().AddMembersAsync( context, @@ -646,8 +642,7 @@ private async Task GenerateMemberDelegatingConstructorAsync( return await provider.GetRequiredService().AddMembersAsync( new CodeGenerationSolutionContext( document.Project.Solution, - new CodeGenerationContext(Token.GetLocation()), - _fallbackOptions), + new CodeGenerationContext(Token.GetLocation())), TypeToGenerateIn, provider.GetRequiredService().CreateMemberDelegatingConstructor( semanticModel, diff --git a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.cs b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.cs index ceb40cd622e76..c5d6f26dec73d 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.cs @@ -75,13 +75,13 @@ protected bool WillCauseConstructorCycle(State state, SemanticDocument document, return true; } - public async Task> GenerateConstructorAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public async Task> GenerateConstructorAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateMember_GenerateConstructor, cancellationToken)) { var semanticDocument = await SemanticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); - var state = await State.GenerateAsync((TService)this, semanticDocument, node, fallbackOptions, cancellationToken).ConfigureAwait(false); + var state = await State.GenerateAsync((TService)this, semanticDocument, node, cancellationToken).ConfigureAwait(false); if (state != null) { Contract.ThrowIfNull(state.TypeToGenerateIn); diff --git a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/IGenerateConstructorService.cs b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/IGenerateConstructorService.cs index aaaae7bd33cdd..e44d9b87d1ed2 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/IGenerateConstructorService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/IGenerateConstructorService.cs @@ -13,5 +13,5 @@ namespace Microsoft.CodeAnalysis.GenerateMember.GenerateConstructor; internal interface IGenerateConstructorService : ILanguageService { - Task> GenerateConstructorAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GenerateConstructorAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.CodeAction.cs b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.CodeAction.cs index 93ced25ab8079..48cf055fa3c7f 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.CodeAction.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.CodeAction.cs @@ -15,14 +15,10 @@ namespace Microsoft.CodeAnalysis.GenerateMember.GenerateEnumMember; internal abstract partial class AbstractGenerateEnumMemberService { - private partial class GenerateEnumMemberCodeAction( - Document document, - State state, - CodeAndImportGenerationOptionsProvider fallbackOptions) : CodeAction + private partial class GenerateEnumMemberCodeAction(Document document, State state) : CodeAction { private readonly Document _document = document; private readonly State _state = state; - private readonly CodeAndImportGenerationOptionsProvider _fallbackOptions = fallbackOptions; protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) { @@ -38,8 +34,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke new CodeGenerationSolutionContext( _document.Project.Solution, new CodeGenerationContext( - contextLocation: _state.IdentifierToken.GetLocation()), - _fallbackOptions), + contextLocation: _state.IdentifierToken.GetLocation())), _state.TypeToGenerateIn, CodeGenerationSymbolFactory.CreateFieldSymbol( attributes: default, diff --git a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.cs b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.cs index dfa4ee8c51261..d3d79ea8ae948 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.cs @@ -26,7 +26,7 @@ protected AbstractGenerateEnumMemberService() protected abstract bool IsIdentifierNameGeneration(SyntaxNode node); protected abstract bool TryInitializeIdentifierNameState(SemanticDocument document, TSimpleNameSyntax identifierName, CancellationToken cancellationToken, out SyntaxToken identifierToken, out TExpressionSyntax simpleNameOrMemberAccessExpression); - public async Task> GenerateEnumMemberAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public async Task> GenerateEnumMemberAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateMember_GenerateEnumMember, cancellationToken)) { @@ -37,7 +37,7 @@ public async Task> GenerateEnumMemberAsync(Document d return []; } - return [new GenerateEnumMemberCodeAction(document, state, fallbackOptions)]; + return [new GenerateEnumMemberCodeAction(document, state)]; } } } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/IGenerateEnumMemberService.cs b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/IGenerateEnumMemberService.cs index 521a875bbc49b..dd40206ea2ccc 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/IGenerateEnumMemberService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/IGenerateEnumMemberService.cs @@ -6,12 +6,11 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.GenerateMember.GenerateEnumMember; internal interface IGenerateEnumMemberService : ILanguageService { - Task> GenerateEnumMemberAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GenerateEnumMemberAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateConversionService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateConversionService.cs index 5a97f237bef06..596ae892b8e81 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateConversionService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateConversionService.cs @@ -29,7 +29,6 @@ internal abstract partial class AbstractGenerateConversionService> GenerateConversionAsync( Document document, SyntaxNode node, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateMember_GenerateMethod, cancellationToken)) @@ -41,7 +40,7 @@ public async Task> GenerateConversionAsync( return []; } - return await GetActionsAsync(document, state, fallbackOptions, cancellationToken).ConfigureAwait(false); + return await GetActionsAsync(document, state, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateDeconstructMethodService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateDeconstructMethodService.cs index bdc689a94bc3b..e5733af1c5217 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateDeconstructMethodService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateDeconstructMethodService.cs @@ -25,7 +25,6 @@ public async Task> GenerateDeconstructMethodAsync( Document document, SyntaxNode leftSide, INamedTypeSymbol typeToGenerateIn, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateMember_GenerateMethod, cancellationToken)) @@ -35,7 +34,7 @@ public async Task> GenerateDeconstructMethodAsync( var state = await State.GenerateDeconstructMethodStateAsync( (TService)this, semanticDocument, leftSide, typeToGenerateIn, cancellationToken).ConfigureAwait(false); - return state != null ? await GetActionsAsync(document, state, fallbackOptions, cancellationToken).ConfigureAwait(false) : []; + return state != null ? await GetActionsAsync(document, state, cancellationToken).ConfigureAwait(false) : []; } } } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs index bc8f34092c985..466eff0317b09 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateMethodService.cs @@ -30,7 +30,6 @@ internal abstract partial class AbstractGenerateMethodService> GenerateMethodAsync( Document document, SyntaxNode node, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateMember_GenerateMethod, cancellationToken)) @@ -42,7 +41,7 @@ public async Task> GenerateMethodAsync( return []; } - return await GetActionsAsync(document, state, fallbackOptions, cancellationToken).ConfigureAwait(false); + return await GetActionsAsync(document, state, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.CodeAction.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.CodeAction.cs index 2e9b1bef5bca6..24dc35aa27167 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.CodeAction.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.CodeAction.cs @@ -23,20 +23,17 @@ private partial class GenerateParameterizedMemberCodeAction : CodeAction private readonly bool _isAbstract; private readonly bool _generateProperty; private readonly string _equivalenceKey; - private readonly CodeAndImportGenerationOptionsProvider _fallbackOptions; public GenerateParameterizedMemberCodeAction( TService service, Document document, State state, - CodeAndImportGenerationOptionsProvider fallbackOptions, bool isAbstract, bool generateProperty) { _service = service; _document = document; _state = state; - _fallbackOptions = fallbackOptions; _isAbstract = isAbstract; _generateProperty = generateProperty; _equivalenceKey = Title; @@ -78,8 +75,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke _document.Project.Solution, new CodeGenerationContext( afterThisLocation: _state.IdentifierToken.GetLocation(), - generateMethodBodies: _state.TypeToGenerateIn.TypeKind != TypeKind.Interface), - _fallbackOptions), + generateMethodBodies: _state.TypeToGenerateIn.TypeKind != TypeKind.Interface)), _state.TypeToGenerateIn, property, cancellationToken).ConfigureAwait(false); @@ -95,8 +91,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke _document.Project.Solution, new CodeGenerationContext( afterThisLocation: _state.Location, - generateMethodBodies: _state.TypeToGenerateIn.TypeKind != TypeKind.Interface), - _fallbackOptions), + generateMethodBodies: _state.TypeToGenerateIn.TypeKind != TypeKind.Interface)), _state.TypeToGenerateIn, method, cancellationToken) diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.cs index b5b1561c3b3a5..fef378293e666 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.cs @@ -39,10 +39,10 @@ protected virtual string GetImplicitConversionDisplayText(State state) protected virtual string GetExplicitConversionDisplayText(State state) => string.Empty; - protected async ValueTask> GetActionsAsync(Document document, State state, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected async ValueTask> GetActionsAsync(Document document, State state, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); - result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, fallbackOptions, isAbstract: false, generateProperty: false)); + result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, isAbstract: false, generateProperty: false)); // If we're trying to generate an instance method into an abstract class (but not a // static class or an interface), then offer to generate it abstractly. @@ -52,7 +52,7 @@ protected async ValueTask> GetActionsAsync(Document d !state.IsStatic; if (canGenerateAbstractly) - result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, fallbackOptions, isAbstract: true, generateProperty: false)); + result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, isAbstract: true, generateProperty: false)); var semanticFacts = document.Project.Solution.Services.GetLanguageServices(state.TypeToGenerateIn.Language).GetService(); @@ -64,10 +64,10 @@ protected async ValueTask> GetActionsAsync(Document d if (typeParameters.Length == 0 && returnType.SpecialType != SpecialType.System_Void) { - result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, fallbackOptions, isAbstract: false, generateProperty: true)); + result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, isAbstract: false, generateProperty: true)); if (canGenerateAbstractly) - result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, fallbackOptions, isAbstract: true, generateProperty: true)); + result.Add(new GenerateParameterizedMemberCodeAction((TService)this, document, state, isAbstract: true, generateProperty: true)); } } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateConversionService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateConversionService.cs index b78f1dbb57ecd..d1d35952c9d95 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateConversionService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateConversionService.cs @@ -6,12 +6,11 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.GenerateMember.GenerateParameterizedMember; internal interface IGenerateConversionService : ILanguageService { - Task> GenerateConversionAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GenerateConversionAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateDeconstructMemberService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateDeconstructMemberService.cs index 9038ac16f8750..7d4bb7a675e5f 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateDeconstructMemberService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateDeconstructMemberService.cs @@ -14,5 +14,5 @@ namespace Microsoft.CodeAnalysis.GenerateMember.GenerateParameterizedMember; internal interface IGenerateDeconstructMemberService : ILanguageService { Task> GenerateDeconstructMethodAsync( - Document document, SyntaxNode targetVariables, INamedTypeSymbol typeToGenerateIn, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Document document, SyntaxNode targetVariables, INamedTypeSymbol typeToGenerateIn, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateParameterizedMemberService.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateParameterizedMemberService.cs index 9c3d34014b908..82dac9dd59a98 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateParameterizedMemberService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/IGenerateParameterizedMemberService.cs @@ -13,5 +13,5 @@ namespace Microsoft.CodeAnalysis.GenerateMember.GenerateParameterizedMember; internal interface IGenerateParameterizedMemberService : ILanguageService { - Task> GenerateMethodAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GenerateMethodAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.CodeAction.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.CodeAction.cs index 0d3310d2404d0..4c5a8e168bf49 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.CodeAction.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.CodeAction.cs @@ -28,7 +28,6 @@ private partial class GenerateVariableCodeAction : CodeAction private readonly RefKind _refKind; private readonly SemanticDocument _semanticDocument; private readonly string _equivalenceKey; - private readonly CodeAndImportGenerationOptionsProvider _fallbackOptions; public GenerateVariableCodeAction( SemanticDocument document, @@ -36,8 +35,7 @@ public GenerateVariableCodeAction( bool generateProperty, bool isReadonly, bool isConstant, - RefKind refKind, - CodeAndImportGenerationOptionsProvider fallbackOptions) + RefKind refKind) { _semanticDocument = document; _state = state; @@ -46,7 +44,6 @@ public GenerateVariableCodeAction( _isConstant = isConstant; _refKind = refKind; _equivalenceKey = Title; - _fallbackOptions = fallbackOptions; } protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) @@ -59,8 +56,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke new CodeGenerationContext( afterThisLocation: _state.AfterThisLocation, beforeThisLocation: _state.BeforeThisLocation, - contextLocation: _state.IdentifierToken.GetLocation()), - _fallbackOptions); + contextLocation: _state.IdentifierToken.GetLocation())); if (_generateProperty) { diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateLocalCodeAction.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateLocalCodeAction.cs index 89c3b25fa84a7..27009e75e9acf 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateLocalCodeAction.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.GenerateLocalCodeAction.cs @@ -18,12 +18,11 @@ namespace Microsoft.CodeAnalysis.GenerateMember.GenerateVariable; internal partial class AbstractGenerateVariableService { - private sealed class GenerateLocalCodeAction(TService service, Document document, State state, CodeGenerationOptionsProvider fallbackOptions) : CodeAction + private sealed class GenerateLocalCodeAction(TService service, Document document, State state) : CodeAction { private readonly TService _service = service; private readonly Document _document = document; private readonly State _state = state; - private readonly CodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; public override string Title { @@ -65,7 +64,7 @@ private async Task GetNewRootAsync(CancellationToken cancellationTok var root = _state.IdentifierToken.GetAncestors().Last(); var context = new CodeGenerationContext(beforeThisLocation: _state.IdentifierToken.GetLocation()); - var info = await _document.GetCodeGenerationInfoAsync(context, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await _document.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); return info.Service.AddStatements(root, [localStatement], info, cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs index bf396bb120d95..3aa8496a69924 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.cs @@ -39,7 +39,6 @@ protected AbstractGenerateVariableService() public async Task> GenerateVariableAsync( Document document, SyntaxNode node, - CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateMember_GenerateVariable, cancellationToken)) @@ -63,18 +62,18 @@ public async Task> GenerateVariableAsync( var name = state.IdentifierToken.ValueText; if (char.IsUpper(name.ToCharArray().FirstOrDefault())) { - await AddPropertyCodeActionsAsync(actions, semanticDocument, state, fallbackOptions, cancellationToken).ConfigureAwait(false); - AddFieldCodeActions(actions, semanticDocument, state, fallbackOptions); + await AddPropertyCodeActionsAsync(actions, semanticDocument, state, cancellationToken).ConfigureAwait(false); + AddFieldCodeActions(actions, semanticDocument, state); } else { - AddFieldCodeActions(actions, semanticDocument, state, fallbackOptions); - await AddPropertyCodeActionsAsync(actions, semanticDocument, state, fallbackOptions, cancellationToken).ConfigureAwait(false); + AddFieldCodeActions(actions, semanticDocument, state); + await AddPropertyCodeActionsAsync(actions, semanticDocument, state, cancellationToken).ConfigureAwait(false); } } - await AddLocalCodeActionsAsync(actions, document, state, fallbackOptions, cancellationToken).ConfigureAwait(false); - await AddParameterCodeActionsAsync(actions, document, state, fallbackOptions, cancellationToken).ConfigureAwait(false); + await AddLocalCodeActionsAsync(actions, document, state, cancellationToken).ConfigureAwait(false); + await AddParameterCodeActionsAsync(actions, document, state, cancellationToken).ConfigureAwait(false); if (actions.Count > 1) { @@ -94,7 +93,7 @@ protected virtual bool ContainingTypesOrSelfHasUnsafeKeyword(INamedTypeSymbol co => false; private static async Task AddPropertyCodeActionsAsync( - ArrayBuilder result, SemanticDocument document, State state, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + ArrayBuilder result, SemanticDocument document, State state, CancellationToken cancellationToken) { if (state.IsInOutContext) return; @@ -107,7 +106,7 @@ private static async Task AddPropertyCodeActionsAsync( // Don't generate properties with a `_` prefix unless that's what the user really wants as their naming style. if (await NameIsHighlyUnlikelyToWarrantSymbolAsync( - document.Document, state, SymbolKind.Property, state.DetermineMaximalAccessibility(), fallbackOptions, cancellationToken).ConfigureAwait(false)) + document.Document, state, SymbolKind.Property, state.DetermineMaximalAccessibility(), cancellationToken).ConfigureAwait(false)) { return; } @@ -116,20 +115,20 @@ private static async Task AddPropertyCodeActionsAsync( if (isOnlyReadAndIsInInterface || state.IsInConstructor) { result.Add(new GenerateVariableCodeAction( - document, state, generateProperty: true, isReadonly: true, isConstant: false, refKind: GetRefKindFromContext(state), fallbackOptions)); + document, state, generateProperty: true, isReadonly: true, isConstant: false, refKind: GetRefKindFromContext(state))); } - GenerateWritableProperty(result, document, state, fallbackOptions); + GenerateWritableProperty(result, document, state); } private static async Task NameIsHighlyUnlikelyToWarrantSymbolAsync( - Document document, State state, SymbolKind kind, Accessibility accessibility, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) + Document document, State state, SymbolKind kind, Accessibility accessibility, CancellationToken cancellationToken) { // Check If the user explicitly used _ as the start of the name they're generating. Don't offer to generate // a non-field symbol unless that's genuinely the naming style they have setup. if (state.IdentifierToken.ValueText.StartsWith("_")) { - var namingStyle = await document.GetApplicableNamingRuleAsync(kind, accessibility, fallbackOptions, cancellationToken).ConfigureAwait(false); + var namingStyle = await document.GetApplicableNamingRuleAsync(kind, accessibility, cancellationToken).ConfigureAwait(false); if (namingStyle.NamingStyle.Prefix != "_") return true; } @@ -137,27 +136,27 @@ private static async Task NameIsHighlyUnlikelyToWarrantSymbolAsync( return false; } - private static void GenerateWritableProperty(ArrayBuilder result, SemanticDocument document, State state, CodeAndImportGenerationOptionsProvider fallbackOptions) + private static void GenerateWritableProperty(ArrayBuilder result, SemanticDocument document, State state) { result.Add(new GenerateVariableCodeAction( document, state, generateProperty: true, isReadonly: false, isConstant: false, - refKind: GetRefKindFromContext(state), fallbackOptions)); + refKind: GetRefKindFromContext(state))); } - private static void AddFieldCodeActions(ArrayBuilder result, SemanticDocument document, State state, CodeAndImportGenerationOptionsProvider fallbackOptions) + private static void AddFieldCodeActions(ArrayBuilder result, SemanticDocument document, State state) { if (state.TypeToGenerateIn.TypeKind != TypeKind.Interface) { if (state.IsConstant) { result.Add(new GenerateVariableCodeAction( - document, state, generateProperty: false, isReadonly: false, isConstant: true, refKind: RefKind.None, fallbackOptions)); + document, state, generateProperty: false, isReadonly: false, isConstant: true, refKind: RefKind.None)); } else { if (!state.OfferReadOnlyFieldFirst) { - GenerateWriteableField(result, document, state, fallbackOptions); + GenerateWriteableField(result, document, state); } // If we haven't written to the field, or we're in the constructor for the type @@ -165,47 +164,47 @@ private static void AddFieldCodeActions(ArrayBuilder result, Semanti if (!state.IsWrittenTo || state.IsInConstructor) { result.Add(new GenerateVariableCodeAction( - document, state, generateProperty: false, isReadonly: true, isConstant: false, refKind: RefKind.None, fallbackOptions)); + document, state, generateProperty: false, isReadonly: true, isConstant: false, refKind: RefKind.None)); } if (state.OfferReadOnlyFieldFirst) { - GenerateWriteableField(result, document, state, fallbackOptions); + GenerateWriteableField(result, document, state); } } } } - private static void GenerateWriteableField(ArrayBuilder result, SemanticDocument document, State state, CodeAndImportGenerationOptionsProvider fallbackOptions) + private static void GenerateWriteableField(ArrayBuilder result, SemanticDocument document, State state) { result.Add(new GenerateVariableCodeAction( - document, state, generateProperty: false, isReadonly: false, isConstant: false, refKind: RefKind.None, fallbackOptions)); + document, state, generateProperty: false, isReadonly: false, isConstant: false, refKind: RefKind.None)); } private async Task AddLocalCodeActionsAsync( - ArrayBuilder result, Document document, State state, CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + ArrayBuilder result, Document document, State state, CancellationToken cancellationToken) { if (state.CanGenerateLocal()) { // Don't generate locals with a `_` prefix unless that's what the user really wants as their naming style. if (await NameIsHighlyUnlikelyToWarrantSymbolAsync( - document, state, SymbolKind.Local, Accessibility.NotApplicable, fallbackOptions, cancellationToken).ConfigureAwait(false)) + document, state, SymbolKind.Local, Accessibility.NotApplicable, cancellationToken).ConfigureAwait(false)) { return; } - result.Add(new GenerateLocalCodeAction((TService)this, document, state, fallbackOptions)); + result.Add(new GenerateLocalCodeAction((TService)this, document, state)); } } private static async Task AddParameterCodeActionsAsync( - ArrayBuilder result, Document document, State state, CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + ArrayBuilder result, Document document, State state, CancellationToken cancellationToken) { if (state.CanGenerateParameter()) { // Don't generate parameters with a `_` prefix unless that's what the user really wants as their naming style. if (await NameIsHighlyUnlikelyToWarrantSymbolAsync( - document, state, SymbolKind.Parameter, Accessibility.NotApplicable, fallbackOptions, cancellationToken).ConfigureAwait(false)) + document, state, SymbolKind.Parameter, Accessibility.NotApplicable, cancellationToken).ConfigureAwait(false)) { return; } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/IGenerateVariableService.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/IGenerateVariableService.cs index 1720a70b74b80..742f3d0d3e369 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/IGenerateVariableService.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/IGenerateVariableService.cs @@ -8,12 +8,11 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.GenerateMember.GenerateVariable; internal interface IGenerateVariableService : ILanguageService { - Task> GenerateVariableAsync(Document document, SyntaxNode node, CodeAndImportGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GenerateVariableAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs index b87e4da9a9937..dcf02f3bae548 100644 --- a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesCodeRefactoringProvider.cs @@ -54,7 +54,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( new GenerateOverridesWithDialogCodeAction( - this, document, textSpan, containingType, overridableMembers, context.Options), + this, document, textSpan, containingType, overridableMembers), typeDeclaration.Span); } } diff --git a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs index dafdd480c971e..ab69fc2aa0117 100644 --- a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs @@ -25,15 +25,13 @@ private sealed class GenerateOverridesWithDialogCodeAction( Document document, TextSpan textSpan, INamedTypeSymbol containingType, - ImmutableArray viableMembers, - CodeAndImportGenerationOptionsProvider fallbackOptions) : CodeActionWithOptions + ImmutableArray viableMembers) : CodeActionWithOptions { private readonly GenerateOverridesCodeRefactoringProvider _service = service; private readonly Document _document = document; private readonly INamedTypeSymbol _containingType = containingType; private readonly ImmutableArray _viableMembers = viableMembers; private readonly TextSpan _textSpan = textSpan; - private readonly CodeAndImportGenerationOptionsProvider _fallbackOptions = fallbackOptions; public override string Title => FeaturesResources.Generate_overrides; @@ -76,8 +74,7 @@ protected override async Task> ComputeOperation _document.Project.Solution, new CodeGenerationContext( afterThisLocation: afterThisLocation, - contextLocation: syntaxTree.GetLocation(_textSpan)), - _fallbackOptions), + contextLocation: syntaxTree.GetLocation(_textSpan))), _containingType, members, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.CodeAction.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.CodeAction.cs index 65beaeaa71a6a..6c3ca86fd1c93 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.CodeAction.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.CodeAction.cs @@ -27,20 +27,17 @@ private sealed class GenerateTypeCodeAction : CodeAction private readonly Document _document; private readonly State _state; private readonly string _equivalenceKey; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions; public GenerateTypeCodeAction( TService service, Document document, State state, - CleanCodeGenerationOptionsProvider fallbackOptions, bool intoNamespace, bool inNewFile) { _service = service; _document = document; _state = state; - _fallbackOptions = fallbackOptions; _intoNamespace = intoNamespace; _inNewFile = inNewFile; _equivalenceKey = Title; @@ -70,7 +67,7 @@ protected override async Task> ComputeOperat { var semanticDocument = await SemanticDocument.CreateAsync(_document, cancellationToken).ConfigureAwait(false); - var editor = new Editor(_service, semanticDocument, _state, _fallbackOptions, _intoNamespace, _inNewFile, cancellationToken); + var editor = new Editor(_service, semanticDocument, _state, _intoNamespace, _inNewFile, cancellationToken); return await editor.GetOperationsAsync().ConfigureAwait(false); } @@ -88,14 +85,12 @@ private sealed class GenerateTypeCodeActionWithOption : CodeActionWithOptions private readonly TService _service; private readonly Document _document; private readonly State _state; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions; - internal GenerateTypeCodeActionWithOption(TService service, Document document, State state, CleanCodeGenerationOptionsProvider fallbackOptions) + internal GenerateTypeCodeActionWithOption(TService service, Document document, State state) { _service = service; _document = document; _state = state; - _fallbackOptions = fallbackOptions; } public override string Title => FeaturesResources.Generate_new_type; @@ -183,7 +178,7 @@ protected override async Task> ComputeOperation if (options is GenerateTypeOptionsResult generateTypeOptions && !generateTypeOptions.IsCancelled) { var semanticDocument = await SemanticDocument.CreateAsync(_document, cancellationToken).ConfigureAwait(false); - var editor = new Editor(_service, semanticDocument, _state, _fallbackOptions, fromDialog: true, generateTypeOptions, cancellationToken); + var editor = new Editor(_service, semanticDocument, _state, fromDialog: true, generateTypeOptions, cancellationToken); operations = await editor.GetOperationsAsync().ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs index 4967c41cf956b..e1cee305dece0 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs @@ -41,13 +41,11 @@ private partial class Editor private readonly bool _fromDialog; private readonly GenerateTypeOptionsResult _generateTypeOptionsResult; private readonly CancellationToken _cancellationToken; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions; public Editor( TService service, SemanticDocument document, State state, - CleanCodeGenerationOptionsProvider fallbackOptions, bool intoNamespace, bool inNewFile, CancellationToken cancellationToken) @@ -55,7 +53,6 @@ public Editor( _service = service; _semanticDocument = document; _state = state; - _fallbackOptions = fallbackOptions; _intoNamespace = intoNamespace; _inNewFile = inNewFile; _cancellationToken = cancellationToken; @@ -65,7 +62,6 @@ public Editor( TService service, SemanticDocument document, State state, - CleanCodeGenerationOptionsProvider fallbackOptions, bool fromDialog, GenerateTypeOptionsResult generateTypeOptionsResult, CancellationToken cancellationToken) @@ -76,7 +72,6 @@ public Editor( _service = service; _semanticDocument = document; _state = state; - _fallbackOptions = fallbackOptions; _fromDialog = fromDialog; _generateTypeOptionsResult = generateTypeOptionsResult; _cancellationToken = cancellationToken; @@ -299,8 +294,7 @@ private async Task> GetGenerateInNewFileOper var codeGenResult = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync( new CodeGenerationSolutionContext( newSolution, - new CodeGenerationContext(newSemanticModel.SyntaxTree.GetLocation(new TextSpan())), - _fallbackOptions), + new CodeGenerationContext(newSemanticModel.SyntaxTree.GetLocation(new TextSpan()))), enclosingNamespace, rootNamespaceOrType, _cancellationToken).ConfigureAwait(false); @@ -320,7 +314,7 @@ private async Task> GetGenerateInNewFileOper var formattingService = newDocument.GetLanguageService(); if (formattingService is not null) { - var cleanupOptions = await codeGenResult.GetCodeCleanupOptionsAsync(_fallbackOptions, _cancellationToken).ConfigureAwait(false); + var cleanupOptions = await codeGenResult.GetCodeCleanupOptionsAsync(_cancellationToken).ConfigureAwait(false); codeGenResult = await formattingService.FormatNewDocumentAsync(codeGenResult, _semanticDocument.Document, cleanupOptions, _cancellationToken).ConfigureAwait(false); } } @@ -367,7 +361,7 @@ private async Task> CreateAddDocumentAndUpda { updatedSolution = await _service.TryAddUsingsOrImportToDocumentAsync( updatedSolution, modifiedRoot: null, _semanticDocument.Document, _state.SimpleName, - includeUsingsOrImports, _fallbackOptions, cancellationToken).ConfigureAwait(false); + includeUsingsOrImports, cancellationToken).ConfigureAwait(false); } // Add reference of the updated project to the triggering Project if they are 2 different projects @@ -398,8 +392,7 @@ private async Task> GetGenerateIntoContainin var codeGenResult = await CodeGenerator.AddNamedTypeDeclarationAsync( new CodeGenerationSolutionContext( solution, - new CodeGenerationContext(afterThisLocation: _semanticDocument.SyntaxTree.GetLocation(_state.SimpleName.Span)), - _fallbackOptions), + new CodeGenerationContext(afterThisLocation: _semanticDocument.SyntaxTree.GetLocation(_state.SimpleName.Span))), enclosingNamespace, namedType, _cancellationToken).ConfigureAwait(false); @@ -445,8 +438,7 @@ private async Task> GetGenerateIntoExistingD var codeGenResult = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync( new CodeGenerationSolutionContext( solution, - new CodeGenerationContext(afterThisLocation: enclosingNamespaceGeneratedTypeToAddAndLocation.Item3), - _fallbackOptions), + new CodeGenerationContext(afterThisLocation: enclosingNamespaceGeneratedTypeToAddAndLocation.Item3)), enclosingNamespaceGeneratedTypeToAddAndLocation.Item1, enclosingNamespaceGeneratedTypeToAddAndLocation.Item2, _cancellationToken).ConfigureAwait(false); @@ -462,7 +454,6 @@ private async Task> GetGenerateIntoExistingD _semanticDocument.Document, _state.SimpleName, includeUsingsOrImports, - _fallbackOptions, _cancellationToken).ConfigureAwait(false); } @@ -560,8 +551,7 @@ private async Task> GetGenerateIntoTypeOpera var codeGenResult = await CodeGenerator.AddNamedTypeDeclarationAsync( new CodeGenerationSolutionContext( solution, - new CodeGenerationContext(contextLocation: _state.SimpleName.GetLocation()), - _fallbackOptions), + new CodeGenerationContext(contextLocation: _state.SimpleName.GetLocation())), _state.TypeToGenerateInOpt, namedType, _cancellationToken) @@ -616,7 +606,7 @@ where IsViableFieldOrProperty(parameterType, m) } } - var fieldNamingRule = await _semanticDocument.Document.GetApplicableNamingRuleAsync(SymbolKind.Field, Accessibility.Private, _fallbackOptions, _cancellationToken).ConfigureAwait(false); + var fieldNamingRule = await _semanticDocument.Document.GetApplicableNamingRuleAsync(SymbolKind.Field, Accessibility.Private, _cancellationToken).ConfigureAwait(false); var nameToUse = fieldNamingRule.NamingStyle.MakeCompliant(parameterName.NameBasedOnArgument).First(); parameterToNewFieldMap[parameterName.BestNameForParameter] = nameToUse; return false; diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs index b9054236ad970..3653f01c7db78 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs @@ -60,7 +60,7 @@ protected AbstractGenerateTypeService() internal abstract bool IsSimpleName(TExpressionSyntax expression); internal abstract Task TryAddUsingsOrImportToDocumentAsync( - Solution updatedSolution, SyntaxNode modifiedRoot, Document document, TSimpleNameSyntax simpleName, string includeUsingsOrImports, AddImportPlacementOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Solution updatedSolution, SyntaxNode modifiedRoot, Document document, TSimpleNameSyntax simpleName, string includeUsingsOrImports, CancellationToken cancellationToken); protected abstract bool TryGetNameParts(TExpressionSyntax expression, out IList nameParts); @@ -71,7 +71,6 @@ internal abstract Task TryAddUsingsOrImportToDocumentAsync( public async Task> GenerateTypeAsync( Document document, SyntaxNode node, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.Refactoring_GenerateType, cancellationToken)) @@ -81,7 +80,7 @@ public async Task> GenerateTypeAsync( var state = await State.GenerateAsync((TService)this, semanticDocument, node, cancellationToken).ConfigureAwait(false); if (state != null) { - var actions = GetActions(semanticDocument, node, state, fallbackOptions, cancellationToken); + var actions = GetActions(semanticDocument, node, state, cancellationToken); if (actions.Length > 1) { // Wrap the generate type actions into a single top level suggestion @@ -105,7 +104,6 @@ private ImmutableArray GetActions( SemanticDocument document, SyntaxNode node, State state, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); @@ -116,7 +114,7 @@ private ImmutableArray GetActions( if (document.Project.Solution.CanApplyChange(ApplyChangesKind.AddDocument)) { generateNewTypeInDialog = true; - result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, fallbackOptions, intoNamespace: true, inNewFile: true)); + result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, intoNamespace: true, inNewFile: true)); } // If they just are generating "Goo" then we want to offer to generate it into the @@ -129,15 +127,15 @@ private ImmutableArray GetActions( if ((isSimpleName || generateIntoContaining) && CanGenerateIntoContainingNamespace(document, node, cancellationToken)) { - result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, fallbackOptions, intoNamespace: true, inNewFile: false)); + result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, intoNamespace: true, inNewFile: false)); } } if (state.TypeToGenerateInOpt != null) - result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, fallbackOptions, intoNamespace: false, inNewFile: false)); + result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, intoNamespace: false, inNewFile: false)); if (generateNewTypeInDialog) - result.Add(new GenerateTypeCodeActionWithOption((TService)this, document.Document, state, fallbackOptions)); + result.Add(new GenerateTypeCodeActionWithOption((TService)this, document.Document, state)); return result.ToImmutableAndClear(); } diff --git a/src/Features/Core/Portable/GenerateType/IGenerateTypeService.cs b/src/Features/Core/Portable/GenerateType/IGenerateTypeService.cs index 1529d3f39d636..5ee998341958c 100644 --- a/src/Features/Core/Portable/GenerateType/IGenerateTypeService.cs +++ b/src/Features/Core/Portable/GenerateType/IGenerateTypeService.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.GenerateType; internal interface IGenerateTypeService : ILanguageService { - Task> GenerateTypeAsync(Document document, SyntaxNode node, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GenerateTypeAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); Task<(INamespaceSymbol, INamespaceOrTypeSymbol, Location)> GetOrGenerateEnclosingNamespaceSymbolAsync(INamedTypeSymbol namedTypeSymbol, string[] containers, Document selectedDocument, SyntaxNode selectedDocumentRoot, CancellationToken cancellationToken); string GetRootNamespace(CompilationOptions options); } diff --git a/src/Features/Core/Portable/ImplementAbstractClass/ImplementAbstractClassData.cs b/src/Features/Core/Portable/ImplementAbstractClass/ImplementAbstractClassData.cs index f304e08c863d0..9cd87ac4d2858 100644 --- a/src/Features/Core/Portable/ImplementAbstractClass/ImplementAbstractClassData.cs +++ b/src/Features/Core/Portable/ImplementAbstractClass/ImplementAbstractClassData.cs @@ -101,7 +101,7 @@ public async Task ImplementAbstractClassAsync( autoInsertionLocation: groupMembers, sortMembers: groupMembers); - var info = await _document.GetCodeGenerationInfoAsync(context, _options.FallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await _document.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); var updatedClassNode = info.Service.AddMembers( classNodeToAddMembersTo, diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs index 0a02004557f60..2b8daa5c52513 100644 --- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs +++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs @@ -211,8 +211,7 @@ protected async Task GetUpdatedDocumentAsync( new CodeGenerationContext( contextLocation: classOrStructDecl.GetLocation(), autoInsertionLocation: groupMembers, - sortMembers: groupMembers), - Options.FallbackOptions), + sortMembers: groupMembers)), classOrStructType, memberDefinitions.Concat(extraMembers), cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs index 266f6ab4f48c5..2a4a3598d0c5e 100644 --- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs +++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs @@ -153,7 +153,7 @@ public override async Task GetUpdatedDocumentAsync( sortMembers: false, autoInsertionLocation: false); - var info = await document.GetCodeGenerationInfoAsync(context, Options.FallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await document.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); var typeDeclarationWithAllMembers = info.Service.AddMembers( typeDeclarationWithCoreMembers, @@ -344,7 +344,7 @@ private async Task CreateDisposedValueFieldAsync( CancellationToken cancellationToken) { var rule = await document.GetApplicableNamingRuleAsync( - SymbolKind.Field, Accessibility.Private, Options.FallbackOptions, cancellationToken).ConfigureAwait(false); + SymbolKind.Field, Accessibility.Private, cancellationToken).ConfigureAwait(false); var requireAccessiblity = await GetAccessibilityModifiersRequiredAsync(document, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs index 6b9515fe627aa..4007137e18a60 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs @@ -85,7 +85,7 @@ protected sealed override async Task> GetRefactorings // to an existing matching field/prop if we can find one, or add a new field/prop // if we can't. - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); var parameterNameParts = IdentifierNameParts.CreateIdentifierNameParts(parameter, rules); if (parameterNameParts.BaseName == "") return []; @@ -96,12 +96,12 @@ protected sealed override async Task> GetRefactorings if (fieldOrProperty != null) { return HandleExistingFieldOrProperty( - document, parameter, constructorDeclaration, blockStatement, fieldOrProperty, isThrowNotImplementedProperty, fallbackOptions); + document, parameter, constructorDeclaration, blockStatement, fieldOrProperty, isThrowNotImplementedProperty); } return await HandleNoExistingFieldOrPropertyAsync( document, parameter, constructorDeclaration, - method, blockStatement, rules, fallbackOptions, cancellationToken).ConfigureAwait(false); + method, blockStatement, rules, cancellationToken).ConfigureAwait(false); } private async Task> HandleNoExistingFieldOrPropertyAsync( @@ -111,7 +111,6 @@ private async Task> HandleNoExistingFieldOrPropertyAs IMethodSymbol method, IBlockOperation? blockStatement, ImmutableArray rules, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // Didn't find a field/prop that this parameter could be assigned to. @@ -121,7 +120,7 @@ private async Task> HandleNoExistingFieldOrPropertyAs var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var (fieldAction, propertyAction) = AddSpecificParameterInitializationActions( - document, parameter, constructorDeclaration, blockStatement, rules, formattingOptions.AccessibilityModifiersRequired, fallbackOptions); + document, parameter, constructorDeclaration, blockStatement, rules, formattingOptions.AccessibilityModifiersRequired); // Check if the surrounding parameters are assigned to another field in this class. If so, offer to // make this parameter into a field as well. Otherwise, default to generating a property @@ -138,7 +137,7 @@ private async Task> HandleNoExistingFieldOrPropertyAs } var (allFieldsAction, allPropertiesAction) = AddAllParameterInitializationActions( - document, constructorDeclaration, method, blockStatement, rules, formattingOptions.AccessibilityModifiersRequired, fallbackOptions); + document, constructorDeclaration, method, blockStatement, rules, formattingOptions.AccessibilityModifiersRequired); if (allFieldsAction != null && allPropertiesAction != null) { @@ -163,8 +162,7 @@ private async Task> HandleNoExistingFieldOrPropertyAs IMethodSymbol method, IBlockOperation? blockStatement, ImmutableArray rules, - AccessibilityModifiersRequired accessibilityModifiersRequired, - CodeGenerationOptionsProvider fallbackOptions) + AccessibilityModifiersRequired accessibilityModifiersRequired) { if (blockStatement == null) return default; @@ -180,12 +178,12 @@ private async Task> HandleNoExistingFieldOrPropertyAs var allFieldsAction = CodeAction.Create( FeaturesResources.Create_and_assign_remaining_as_fields, c => AddAllSymbolInitializationsAsync( - document, constructorDeclaration, blockStatement, parameters, fields, fallbackOptions, c), + document, constructorDeclaration, blockStatement, parameters, fields, c), nameof(FeaturesResources.Create_and_assign_remaining_as_fields)); var allPropertiesAction = CodeAction.Create( FeaturesResources.Create_and_assign_remaining_as_properties, c => AddAllSymbolInitializationsAsync( - document, constructorDeclaration, blockStatement, parameters, properties, fallbackOptions, c), + document, constructorDeclaration, blockStatement, parameters, properties, c), nameof(FeaturesResources.Create_and_assign_remaining_as_properties)); return (allFieldsAction, allPropertiesAction); @@ -197,8 +195,7 @@ private async Task> HandleNoExistingFieldOrPropertyAs SyntaxNode constructorDeclaration, IBlockOperation? blockStatement, ImmutableArray rules, - AccessibilityModifiersRequired accessibilityModifiersRequired, - CodeGenerationOptionsProvider fallbackOptions) + AccessibilityModifiersRequired accessibilityModifiersRequired) { var field = CreateField(parameter, accessibilityModifiersRequired, rules); var property = CreateProperty(parameter, accessibilityModifiersRequired, rules); @@ -208,11 +205,11 @@ private async Task> HandleNoExistingFieldOrPropertyAs var fieldAction = CodeAction.Create( string.Format(FeaturesResources.Create_and_assign_field_0, field.Name), - c => AddSingleSymbolInitializationAsync(document, constructorDeclaration, blockStatement, parameter, field, isThrowNotImplementedProperty, fallbackOptions, c), + c => AddSingleSymbolInitializationAsync(document, constructorDeclaration, blockStatement, parameter, field, isThrowNotImplementedProperty, c), nameof(FeaturesResources.Create_and_assign_field_0) + "_" + field.Name); var propertyAction = CodeAction.Create( string.Format(FeaturesResources.Create_and_assign_property_0, property.Name), - c => AddSingleSymbolInitializationAsync(document, constructorDeclaration, blockStatement, parameter, property, isThrowNotImplementedProperty, fallbackOptions, c), + c => AddSingleSymbolInitializationAsync(document, constructorDeclaration, blockStatement, parameter, property, isThrowNotImplementedProperty, c), nameof(FeaturesResources.Create_and_assign_property_0) + "_" + property.Name); return (fieldAction, propertyAction); @@ -247,8 +244,7 @@ private ImmutableArray HandleExistingFieldOrProperty( SyntaxNode functionDeclaration, IBlockOperation? blockStatement, ISymbol fieldOrProperty, - bool isThrowNotImplementedProperty, - CodeGenerationOptionsProvider fallbackOptions) + bool isThrowNotImplementedProperty) { // Found a field/property that this parameter should be assigned to. // Just offer the simple assignment to it. @@ -262,7 +258,7 @@ private ImmutableArray HandleExistingFieldOrProperty( return [CodeAction.Create( title, c => AddSingleSymbolInitializationAsync( - document, functionDeclaration, blockStatement, parameter, fieldOrProperty, isThrowNotImplementedProperty, fallbackOptions, c), + document, functionDeclaration, blockStatement, parameter, fieldOrProperty, isThrowNotImplementedProperty, c), title)]; } @@ -368,7 +364,6 @@ private async Task AddAllSymbolInitializationsAsync( IBlockOperation? blockStatement, ImmutableArray parameters, ImmutableArray fieldsOrProperties, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { Debug.Assert(parameters.Length >= 2); @@ -421,7 +416,6 @@ private async Task AddAllSymbolInitializationsAsync( currentParameter, fieldOrProperty, isThrowNotImplementedProperty: false, - fallbackOptions, cancellationToken).ConfigureAwait(false); } @@ -435,14 +429,13 @@ private async Task AddSingleSymbolInitializationAsync( IParameterSymbol parameter, ISymbol fieldOrProperty, bool isThrowNotImplementedProperty, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var services = document.Project.Solution.Services; var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var editor = new SyntaxEditor(root, services); var generator = editor.Generator; - var options = await document.GetCodeGenerationOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var codeGenerator = document.GetRequiredLanguageService(); if (fieldOrProperty.ContainingType == null) diff --git a/src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs b/src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs index 03f44f9dc54bd..d2c0584ca6e04 100644 --- a/src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs @@ -88,7 +88,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex if (IsDestructor(methodSymbol)) return; - var actions = await GetActionsAsync(document, expression, methodSymbol, containingMethod, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await GetActionsAsync(document, expression, methodSymbol, containingMethod, cancellationToken).ConfigureAwait(false); if (actions is null) return; @@ -138,7 +138,7 @@ private static bool IsValidExpression(SyntaxNode expression, ISyntaxFactsService /// is a constructor. /// private async Task<(ImmutableArray actions, ImmutableArray actionsAllOccurrences)?> GetActionsAsync(Document document, - TExpressionSyntax expression, IMethodSymbol methodSymbol, SyntaxNode containingMethod, CodeGenerationOptionsProvider fallbackOptions, + TExpressionSyntax expression, IMethodSymbol methodSymbol, SyntaxNode containingMethod, CancellationToken cancellationToken) { var (shouldDisplay, containsClassExpression) = await ShouldExpressionDisplayCodeActionAsync( @@ -184,7 +184,7 @@ CodeAction CreateNewCodeAction(string actionName, bool allOccurrences, Introduce { return CodeAction.Create( actionName, - cancellationToken => IntroduceParameterAsync(document, expression, methodSymbol, containingMethod, methodCallSites, allOccurrences, selectedCodeAction, fallbackOptions, cancellationToken), + cancellationToken => IntroduceParameterAsync(document, expression, methodSymbol, containingMethod, methodCallSites, allOccurrences, selectedCodeAction, cancellationToken), actionName); } } @@ -236,11 +236,11 @@ CodeAction CreateNewCodeAction(string actionName, bool allOccurrences, Introduce /// private async Task IntroduceParameterAsync(Document originalDocument, TExpressionSyntax expression, IMethodSymbol methodSymbol, SyntaxNode containingMethod, Dictionary> methodCallSites, bool allOccurrences, IntroduceParameterCodeActionKind selectedCodeAction, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var modifiedSolution = originalDocument.Project.Solution; var rewriter = new IntroduceParameterDocumentRewriter(this, originalDocument, - expression, methodSymbol, containingMethod, selectedCodeAction, fallbackOptions, allOccurrences); + expression, methodSymbol, containingMethod, selectedCodeAction, allOccurrences); var changedRoots = await ProducerConsumer<(DocumentId documentId, SyntaxNode newRoot)>.RunParallelAsync( source: methodCallSites.GroupBy(kvp => kvp.Key.Project), diff --git a/src/Features/Core/Portable/IntroduceParameter/IntroduceParameterDocumentRewriter.cs b/src/Features/Core/Portable/IntroduceParameter/IntroduceParameterDocumentRewriter.cs index 5ac5ef14103ec..5caa7d6a6efa4 100644 --- a/src/Features/Core/Portable/IntroduceParameter/IntroduceParameterDocumentRewriter.cs +++ b/src/Features/Core/Portable/IntroduceParameter/IntroduceParameterDocumentRewriter.cs @@ -27,7 +27,6 @@ private class IntroduceParameterDocumentRewriter( IMethodSymbol methodSymbol, SyntaxNode containingMethod, IntroduceParameterCodeActionKind selectedCodeAction, - CodeGenerationOptionsProvider fallbackOptions, bool allOccurrences) { private readonly AbstractIntroduceParameterCodeRefactoringProvider _service = service; @@ -39,7 +38,6 @@ private class IntroduceParameterDocumentRewriter( private readonly IMethodSymbol _methodSymbol = methodSymbol; private readonly SyntaxNode _containerMethod = containingMethod; private readonly IntroduceParameterCodeActionKind _actionKind = selectedCodeAction; - private readonly CodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; private readonly bool _allOccurrences = allOccurrences; public async Task RewriteDocumentAsync(Compilation compilation, Document document, List invocations, CancellationToken cancellationToken) @@ -443,7 +441,7 @@ private async Task GenerateNewMethodOverloadAsync(int insertionIndex private async Task CreateMethodDeclarationAsync(SyntaxNode newStatement, ImmutableArray? validParameters, string? newMethodIdentifier, ITypeSymbol? typeSymbol, bool isTrampoline, CancellationToken cancellationToken) { - var info = await _originalDocument.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await _originalDocument.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); var newMethod = isTrampoline ? CodeGenerationSymbolFactory.CreateMethodSymbol(_methodSymbol, name: newMethodIdentifier, parameters: validParameters, statements: [newStatement], returnType: typeSymbol) diff --git a/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs b/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs index b6755b077c613..ae509b22eb9f7 100644 --- a/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/IntroduceVariable/IntroduceVariableCodeRefactoringProvider.cs @@ -27,7 +27,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; var service = document.GetRequiredLanguageService(); - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(context.Options, context.CancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(context.CancellationToken).ConfigureAwait(false); var action = await service.IntroduceVariableAsync(document, textSpan, cleanupOptions, cancellationToken).ConfigureAwait(false); if (action != null) context.RegisterRefactoring(action, textSpan); diff --git a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs index 1d1eb003bddbe..3a03e5aebe762 100644 --- a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs @@ -38,8 +38,7 @@ public async Task AddSourceToAsync( generateMethodBodies: false, generateDocumentationComments: true, mergeAttributes: false, - autoInsertionLocation: false), - CodeAndImportGenerationOptions.GetDefault(document.Project.Services).CreateProvider()); + autoInsertionLocation: false)); // Add the interface of the symbol to the top of the root namespace document = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync( diff --git a/src/Features/Core/Portable/MoveStaticMembers/AbstractMoveStaticMembersRefactoringProvider.cs b/src/Features/Core/Portable/MoveStaticMembers/AbstractMoveStaticMembersRefactoringProvider.cs index 98a196c6091a7..dcbccc4e0f21e 100644 --- a/src/Features/Core/Portable/MoveStaticMembers/AbstractMoveStaticMembersRefactoringProvider.cs +++ b/src/Features/Core/Portable/MoveStaticMembers/AbstractMoveStaticMembersRefactoringProvider.cs @@ -59,7 +59,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte memberNodeSymbolPairs.First().node.FullSpan.Start, memberNodeSymbolPairs.Last().node.FullSpan.End); - var action = new MoveStaticMembersWithDialogCodeAction(document, service, containingType, context.Options, selectedMembers); + var action = new MoveStaticMembersWithDialogCodeAction(document, service, containingType, selectedMembers); context.RegisterRefactoring(action, memberSpan); } diff --git a/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs b/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs index 53f8121c9d6c5..556f6f5643e8e 100644 --- a/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs @@ -26,14 +26,12 @@ internal sealed class MoveStaticMembersWithDialogCodeAction( Document document, IMoveStaticMembersOptionsService service, INamedTypeSymbol selectedType, - CleanCodeGenerationOptionsProvider fallbackOptions, ImmutableArray selectedMembers) : CodeActionWithOptions { private readonly Document _document = document; private readonly ImmutableArray _selectedMembers = selectedMembers; private readonly INamedTypeSymbol _selectedType = selectedType; private readonly IMoveStaticMembersOptionsService _service = service; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; public override string Title => FeaturesResources.Move_static_members_to_another_type; @@ -109,7 +107,6 @@ protected override async Task> ComputeOperation sourceDoc.Folders, newType, sourceDoc, - _fallbackOptions, cancellationToken).ConfigureAwait(false); // get back type declaration in the newly created file @@ -133,7 +130,7 @@ protected override async Task> ComputeOperation .SelectAsArray(node => (semanticModel.GetDeclaredSymbol(node, cancellationToken), false)); var pullMembersUpOptions = PullMembersUpOptionsBuilder.BuildPullMembersUpOptions(newType, members); - var movedSolution = await MembersPuller.PullMembersUpAsync(sourceDoc, pullMembersUpOptions, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var movedSolution = await MembersPuller.PullMembersUpAsync(sourceDoc, pullMembersUpOptions, cancellationToken).ConfigureAwait(false); return [new ApplyChangesOperation(movedSolution)]; } @@ -159,7 +156,7 @@ private static TypeKind GetNewTypeKind(INamedTypeSymbol oldType) /// generic type arg indices to keep when refactoring generic class access to the new type. Empty if not relevant /// Id of the document where the mebers are being moved from /// The solution with references refactored and members moved to the newType - private async Task RefactorAndMoveAsync( + private static async Task RefactorAndMoveAsync( ImmutableArray selectedMembers, ImmutableArray oldMemberNodes, Solution oldSolution, @@ -213,7 +210,7 @@ private async Task RefactorAndMoveAsync( newType = (INamedTypeSymbol)newTypeSemanticModel.GetRequiredDeclaredSymbol(newTypeRoot.GetCurrentNode(newTypeNode)!, cancellationToken); var pullMembersUpOptions = PullMembersUpOptionsBuilder.BuildPullMembersUpOptions(newType, members); - return await MembersPuller.PullMembersUpAsync(sourceDoc, pullMembersUpOptions, _fallbackOptions, cancellationToken).ConfigureAwait(false); + return await MembersPuller.PullMembersUpAsync(sourceDoc, pullMembersUpOptions, cancellationToken).ConfigureAwait(false); } private static async Task RefactorReferencesAsync( diff --git a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs index 37daf96bef5d4..28fd071e5eca4 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs @@ -178,7 +178,7 @@ public Task MoveToNamespaceAsync( return analysisResult.Container switch { - MoveToNamespaceAnalysisResult.ContainerType.Namespace => MoveItemsInNamespaceAsync(analysisResult.Document, analysisResult.SyntaxNode, targetNamespace, fallbackOptions, cancellationToken), + MoveToNamespaceAnalysisResult.ContainerType.Namespace => MoveItemsInNamespaceAsync(analysisResult.Document, analysisResult.SyntaxNode, targetNamespace, cancellationToken), MoveToNamespaceAnalysisResult.ContainerType.NamedType => MoveTypeToNamespaceAsync(analysisResult.Document, analysisResult.SyntaxNode, targetNamespace, fallbackOptions, cancellationToken), _ => throw new InvalidOperationException(), }; @@ -210,7 +210,6 @@ private static async Task MoveItemsInNamespaceAsync( Document document, SyntaxNode container, string targetNamespace, - CodeCleanupOptionsProvider options, CancellationToken cancellationToken) { var memberSymbols = await GetMemberSymbolsAsync(document, container, cancellationToken).ConfigureAwait(false); @@ -229,7 +228,6 @@ private static async Task MoveItemsInNamespaceAsync( document, container, targetNamespace, - options, cancellationToken).ConfigureAwait(false); return new MoveToNamespaceResult(originalSolution, changedSolution, document.Id, newNameOriginalSymbolMapping); @@ -276,7 +274,6 @@ private static async Task MoveTypeToNamespaceAsync( mergedDocument, syntaxNode, targetNamespace, - fallbackOptions, cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs b/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs index 19ffa6526b5b5..9805e08ad8516 100644 --- a/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs +++ b/src/Features/Core/Portable/PreferFrameworkType/PreferFrameworkTypeCodeFixProvider.cs @@ -45,7 +45,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var generator = editor.Generator; var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/PullMemberUp/AbstractPullMemberUpRefactoringProvider.cs b/src/Features/Core/Portable/PullMemberUp/AbstractPullMemberUpRefactoringProvider.cs index 9ce4f0987ce8a..edcf4893199b1 100644 --- a/src/Features/Core/Portable/PullMemberUp/AbstractPullMemberUpRefactoringProvider.cs +++ b/src/Features/Core/Portable/PullMemberUp/AbstractPullMemberUpRefactoringProvider.cs @@ -79,9 +79,9 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; } - var allActions = allDestinations.Select(destination => MembersPuller.TryComputeCodeAction(document, selectedMembers, destination, context.Options)) + var allActions = allDestinations.Select(destination => MembersPuller.TryComputeCodeAction(document, selectedMembers, destination)) .WhereNotNull() - .Concat(new PullMemberUpWithDialogCodeAction(document, selectedMembers, _service, context.Options)) + .Concat(new PullMemberUpWithDialogCodeAction(document, selectedMembers, _service)) .ToImmutableArray(); var title = selectedMembers.IsSingle() diff --git a/src/Features/Core/Portable/PullMemberUp/Dialog/PullMemberUpWithDialogCodeAction.cs b/src/Features/Core/Portable/PullMemberUp/Dialog/PullMemberUpWithDialogCodeAction.cs index a384fe63cfa64..74fb1bbecc84b 100644 --- a/src/Features/Core/Portable/PullMemberUp/Dialog/PullMemberUpWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/PullMemberUp/Dialog/PullMemberUpWithDialogCodeAction.cs @@ -19,8 +19,7 @@ internal abstract partial class AbstractPullMemberUpRefactoringProvider private sealed class PullMemberUpWithDialogCodeAction( Document document, ImmutableArray selectedMembers, - IPullMemberUpOptionsService service, - CleanCodeGenerationOptionsProvider fallbackOptions) : CodeActionWithOptions + IPullMemberUpOptionsService service) : CodeActionWithOptions { /// /// Member which user initially selects. It will be selected initially when the dialog pops up. @@ -28,7 +27,6 @@ private sealed class PullMemberUpWithDialogCodeAction( private readonly ImmutableArray _selectedMembers = selectedMembers; private readonly Document _document = document; private readonly IPullMemberUpOptionsService _service = service; - private readonly CleanCodeGenerationOptionsProvider _fallbackOptions = fallbackOptions; public override string Title => FeaturesResources.Pull_members_up_to_base_type; @@ -42,7 +40,7 @@ protected override async Task> ComputeOperation { if (options is PullMembersUpOptions pullMemberUpOptions) { - var changedSolution = await MembersPuller.PullMembersUpAsync(_document, pullMemberUpOptions, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var changedSolution = await MembersPuller.PullMembersUpAsync(_document, pullMemberUpOptions, cancellationToken).ConfigureAwait(false); return new[] { new ApplyChangesOperation(changedSolution) }; } else diff --git a/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs b/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs index 2639a70fb0215..f17ef72b7a1d2 100644 --- a/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs +++ b/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs @@ -37,8 +37,7 @@ internal static class MembersPuller public static CodeAction TryComputeCodeAction( Document document, ImmutableArray selectedMembers, - INamedTypeSymbol destination, - CleanCodeGenerationOptionsProvider fallbackOptions) + INamedTypeSymbol destination) { var result = PullMembersUpOptionsBuilder.BuildPullMembersUpOptions(destination, selectedMembers.SelectAsArray(m => (member: m, makeAbstract: false))); @@ -55,21 +54,20 @@ public static CodeAction TryComputeCodeAction( return SolutionChangeAction.Create( title, - cancellationToken => PullMembersUpAsync(document, result, fallbackOptions, cancellationToken), + cancellationToken => PullMembersUpAsync(document, result, cancellationToken), title); } public static Task PullMembersUpAsync( Document document, PullMembersUpOptions pullMembersUpOptions, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { return pullMembersUpOptions.Destination.TypeKind switch { - TypeKind.Interface => PullMembersIntoInterfaceAsync(document, pullMembersUpOptions, fallbackOptions, cancellationToken), + TypeKind.Interface => PullMembersIntoInterfaceAsync(document, pullMembersUpOptions, cancellationToken), // We can treat VB modules as a static class - TypeKind.Class or TypeKind.Module => PullMembersIntoClassAsync(document, pullMembersUpOptions, fallbackOptions, cancellationToken), + TypeKind.Class or TypeKind.Module => PullMembersIntoClassAsync(document, pullMembersUpOptions, cancellationToken), _ => throw ExceptionUtilities.UnexpectedValue(pullMembersUpOptions.Destination), }; } @@ -95,7 +93,6 @@ private static IMethodSymbol MakePublicAccessor(IMethodSymbol getterOrSetter) private static async Task PullMembersIntoInterfaceAsync( Document document, PullMembersUpOptions pullMemberUpOptions, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var solution = document.Project.Solution; @@ -115,7 +112,7 @@ private static async Task PullMembersIntoInterfaceAsync( generateMethodBodies: false, generateMembers: false); - var info = await destinationEditor.OriginalDocument.GetCodeGenerationInfoAsync(context, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await destinationEditor.OriginalDocument.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); var destinationWithMembersAdded = info.Service.AddMembers(destinationSyntaxNode, symbolsToPullUp, info, cancellationToken); destinationEditor.ReplaceNode(destinationSyntaxNode, (syntaxNode, generator) => destinationWithMembersAdded); @@ -274,7 +271,6 @@ private static void ChangeEventToPublicAndNonStatic( private static async Task PullMembersIntoClassAsync( Document document, PullMembersUpOptions result, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var solution = document.Project.Solution; @@ -309,7 +305,7 @@ private static async Task PullMembersIntoClassAsync( reuseSyntax: true, generateMethodBodies: false); - var options = await destinationEditor.OriginalDocument.GetCleanCodeGenerationOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await destinationEditor.OriginalDocument.GetCleanCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var info = codeGenerationService.GetInfo(context, options.GenerationOptions, destinationEditor.OriginalDocument.Project.ParseOptions); var newDestination = codeGenerationService diff --git a/src/Features/Core/Portable/RemoveUnusedVariable/AbstractRemoveUnusedVariableCodeFixProvider.cs b/src/Features/Core/Portable/RemoveUnusedVariable/AbstractRemoveUnusedVariableCodeFixProvider.cs index b45d4c0ef3ce7..746685cc0c1a1 100644 --- a/src/Features/Core/Portable/RemoveUnusedVariable/AbstractRemoveUnusedVariableCodeFixProvider.cs +++ b/src/Features/Core/Portable/RemoveUnusedVariable/AbstractRemoveUnusedVariableCodeFixProvider.cs @@ -57,7 +57,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor syntaxEditor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + protected override async Task FixAllAsync(Document document, ImmutableArray diagnostics, SyntaxEditor syntaxEditor, CancellationToken cancellationToken) { var nodesToRemove = new HashSet(); diff --git a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs index d46f18607c8b7..cd2b4c3b137de 100644 --- a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs @@ -68,7 +68,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // Looks good! context.RegisterRefactoring(CodeAction.Create( string.Format(FeaturesResources.Replace_0_with_property, methodName), - c => ReplaceMethodsWithPropertyAsync(document, propertyName, nameChanged, methodSymbol, setMethod: null, context.Options, cancellationToken: c), + c => ReplaceMethodsWithPropertyAsync(document, propertyName, nameChanged, methodSymbol, setMethod: null, cancellationToken: c), methodName), methodDeclaration.Span); @@ -81,7 +81,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte { context.RegisterRefactoring(CodeAction.Create( string.Format(FeaturesResources.Replace_0_and_1_with_property, methodName, setMethod.Name), - c => ReplaceMethodsWithPropertyAsync(document, propertyName, nameChanged, methodSymbol, setMethod, context.Options, cancellationToken: c), + c => ReplaceMethodsWithPropertyAsync(document, propertyName, nameChanged, methodSymbol, setMethod, cancellationToken: c), methodName + "-get/set"), methodDeclaration.Span); } @@ -154,7 +154,6 @@ private static async Task ReplaceMethodsWithPropertyAsync( bool nameChanged, IMethodSymbol getMethod, IMethodSymbol? setMethod, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -181,7 +180,7 @@ private static async Task ReplaceMethodsWithPropertyAsync( var updatedSolution = originalSolution; updatedSolution = await UpdateReferencesAsync(updatedSolution, propertyName, nameChanged, getReferencesByDocument, setReferencesByDocument, cancellationToken).ConfigureAwait(false); - updatedSolution = await ReplaceGetMethodsAndRemoveSetMethodsAsync(originalSolution, updatedSolution, propertyName, nameChanged, getMethodReferences, setMethodReferences, updateSetMethod: setMethod != null, fallbackOptions, cancellationToken).ConfigureAwait(false); + updatedSolution = await ReplaceGetMethodsAndRemoveSetMethodsAsync(originalSolution, updatedSolution, propertyName, nameChanged, getMethodReferences, setMethodReferences, updateSetMethod: setMethod != null, cancellationToken).ConfigureAwait(false); return updatedSolution; } @@ -317,7 +316,6 @@ private static async Task ReplaceGetMethodsAndRemoveSetMethodsAsync( IEnumerable getMethodReferences, IEnumerable setMethodReferences, bool updateSetMethod, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var getDefinitionsByDocumentId = await GetDefinitionsByDocumentIdAsync(originalSolution, getMethodReferences, cancellationToken).ConfigureAwait(false); @@ -332,7 +330,7 @@ private static async Task ReplaceGetMethodsAndRemoveSetMethodsAsync( var setDefinitions = setDefinitionsByDocumentId[documentId]; updatedSolution = await ReplaceGetMethodsAndRemoveSetMethodsAsync( - propertyName, nameChanged, updatedSolution, documentId, getDefinitions, setDefinitions, updateSetMethod, fallbackOptions, cancellationToken).ConfigureAwait(false); + propertyName, nameChanged, updatedSolution, documentId, getDefinitions, setDefinitions, updateSetMethod, cancellationToken).ConfigureAwait(false); } return updatedSolution; @@ -346,7 +344,6 @@ private static async Task ReplaceGetMethodsAndRemoveSetMethodsAsync( MultiDictionary.ValueSet originalGetDefinitions, MultiDictionary.ValueSet originalSetDefinitions, bool updateSetMethod, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var updatedDocument = await updatedSolution.GetRequiredDocumentAsync( @@ -366,7 +363,7 @@ private static async Task ReplaceGetMethodsAndRemoveSetMethodsAsync( var editor = new SyntaxEditor(root, updatedSolution.Services); - var codeGenerationOptions = await updatedDocument.GetCodeGenerationOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var codeGenerationOptions = await updatedDocument.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var parseOptions = syntaxTree.Options; // First replace all the get methods with properties. diff --git a/src/Features/Core/Portable/ReplacePropertyWithMethods/AbstractReplacePropertyWithMethodsService.cs b/src/Features/Core/Portable/ReplacePropertyWithMethods/AbstractReplacePropertyWithMethodsService.cs index cf856cb40a3bf..5a18b1e68b7a1 100644 --- a/src/Features/Core/Portable/ReplacePropertyWithMethods/AbstractReplacePropertyWithMethodsService.cs +++ b/src/Features/Core/Portable/ReplacePropertyWithMethods/AbstractReplacePropertyWithMethodsService.cs @@ -27,7 +27,7 @@ internal abstract class AbstractReplacePropertyWithMethodsService> GetReplacementMembersAsync( - Document document, IPropertySymbol property, SyntaxNode propertyDeclaration, IFieldSymbol propertyBackingField, string desiredGetMethodName, string desiredSetMethodName, CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Document document, IPropertySymbol property, SyntaxNode propertyDeclaration, IFieldSymbol propertyBackingField, string desiredGetMethodName, string desiredSetMethodName, CancellationToken cancellationToken); protected abstract TCrefSyntax? TryGetCrefSyntax(TIdentifierNameSyntax identifierName); protected abstract TCrefSyntax CreateCrefSyntax(TCrefSyntax originalCref, SyntaxToken identifierToken, SyntaxNode? parameterType); diff --git a/src/Features/Core/Portable/ReplacePropertyWithMethods/IReplacePropertyWithMethodsService.cs b/src/Features/Core/Portable/ReplacePropertyWithMethods/IReplacePropertyWithMethodsService.cs index 3dbd1c362d834..2c5511e7d5289 100644 --- a/src/Features/Core/Portable/ReplacePropertyWithMethods/IReplacePropertyWithMethodsService.cs +++ b/src/Features/Core/Portable/ReplacePropertyWithMethods/IReplacePropertyWithMethodsService.cs @@ -31,7 +31,6 @@ Task> GetReplacementMembersAsync( IFieldSymbol propertyBackingField, string desiredGetMethodName, string desiredSetMethodName, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); SyntaxNode GetPropertyNodeToReplace(SyntaxNode propertyDeclaration); diff --git a/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs index 32eecb93707fd..4ee3036711cf9 100644 --- a/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs @@ -67,7 +67,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring( CodeAction.Create( string.Format(resourceString, propertyName), - c => ReplacePropertyWithMethodsAsync(document, propertySymbol, context.Options, c), + c => ReplacePropertyWithMethodsAsync(document, propertySymbol, c), propertyName), propertyDeclaration.Span); } @@ -75,7 +75,6 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte private async Task ReplacePropertyWithMethodsAsync( Document document, IPropertySymbol propertySymbol, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var desiredMethodSuffix = NameGenerator.GenerateUniqueName(propertySymbol.Name, @@ -112,7 +111,7 @@ from loc in r.Locations updatedSolution = await ReplaceDefinitionsWithMethodsAsync( originalSolution, updatedSolution, propertyReferences, definitionToBackingField, - desiredGetMethodName, desiredSetMethodName, fallbackOptions, cancellationToken).ConfigureAwait(false); + desiredGetMethodName, desiredSetMethodName, cancellationToken).ConfigureAwait(false); return updatedSolution; } @@ -295,7 +294,6 @@ private static async Task ReplaceDefinitionsWithMethodsAsync( IEnumerable references, ImmutableDictionary definitionToBackingField, string desiredGetMethodName, string desiredSetMethodName, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var definitionsByDocumentId = await GetDefinitionsByDocumentIdAsync(originalSolution, references, cancellationToken).ConfigureAwait(false); @@ -306,7 +304,7 @@ private static async Task ReplaceDefinitionsWithMethodsAsync( updatedSolution = await ReplaceDefinitionsWithMethodsAsync( updatedSolution, documentId, definitions, definitionToBackingField, - desiredGetMethodName, desiredSetMethodName, fallbackOptions, cancellationToken).ConfigureAwait(false); + desiredGetMethodName, desiredSetMethodName, cancellationToken).ConfigureAwait(false); } return updatedSolution; @@ -346,7 +344,6 @@ private static async Task ReplaceDefinitionsWithMethodsAsync( MultiDictionary.ValueSet originalDefinitions, IDictionary definitionToBackingField, string desiredGetMethodName, string desiredSetMethodName, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var updatedDocument = updatedSolution.GetRequiredDocument(documentId); @@ -373,7 +370,6 @@ private static async Task ReplaceDefinitionsWithMethodsAsync( property, declaration, definitionToBackingField.GetValueOrDefault(property), desiredGetMethodName, desiredSetMethodName, - fallbackOptions, cancellationToken).ConfigureAwait(false); // Properly make the members fit within an interface if that's what diff --git a/src/Features/Core/Portable/Shared/Extensions/DocumentExtensions.cs b/src/Features/Core/Portable/Shared/Extensions/DocumentExtensions.cs index abeea5b502b25..cfcc7666beea3 100644 --- a/src/Features/Core/Portable/Shared/Extensions/DocumentExtensions.cs +++ b/src/Features/Core/Portable/Shared/Extensions/DocumentExtensions.cs @@ -99,15 +99,15 @@ public static async Task IsValidContextForDocumentOrLinkedDocumentsAsync( /// will only be used if the user hasn't specified a preference. /// public static async Task> GetNamingRulesAsync( - this Document document, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) + this Document document, CancellationToken cancellationToken) { - var options = await document.GetNamingStylePreferencesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetNamingStylePreferencesAsync(cancellationToken).ConfigureAwait(false); return options.CreateRules().NamingRules.AddRange(FallbackNamingRules.Default); } - public static async Task GetApplicableNamingRuleAsync(this Document document, ISymbol symbol, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) + public static async Task GetApplicableNamingRuleAsync(this Document document, ISymbol symbol, CancellationToken cancellationToken) { - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); foreach (var rule in rules) { if (rule.SymbolSpecification.AppliesTo(symbol)) @@ -118,9 +118,9 @@ public static async Task GetApplicableNamingRuleAsync(this Document } public static async Task GetApplicableNamingRuleAsync( - this Document document, SymbolKind symbolKind, Accessibility accessibility, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) + this Document document, SymbolKind symbolKind, Accessibility accessibility, CancellationToken cancellationToken) { - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); foreach (var rule in rules) { if (rule.SymbolSpecification.AppliesTo(symbolKind, accessibility)) @@ -131,9 +131,9 @@ public static async Task GetApplicableNamingRuleAsync( } public static async Task GetApplicableNamingRuleAsync( - this Document document, SymbolKindOrTypeKind kind, DeclarationModifiers modifiers, Accessibility? accessibility, NamingStylePreferencesProvider fallbackOptions, CancellationToken cancellationToken) + this Document document, SymbolKindOrTypeKind kind, DeclarationModifiers modifiers, Accessibility? accessibility, CancellationToken cancellationToken) { - var rules = await document.GetNamingRulesAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); foreach (var rule in rules) { if (rule.SymbolSpecification.AppliesTo(kind, modifiers, accessibility)) diff --git a/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs b/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs index fb6c7614baeab..c3f789ca60f6d 100644 --- a/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs +++ b/src/Features/Core/Portable/Shared/Utilities/ExtractTypeHelpers.cs @@ -26,14 +26,14 @@ namespace Microsoft.CodeAnalysis.Shared.Utilities; internal static class ExtractTypeHelpers { - public static async Task<(Document containingDocument, SyntaxAnnotation typeAnnotation)> AddTypeToExistingFileAsync(Document document, INamedTypeSymbol newType, AnnotatedSymbolMapping symbolMapping, CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public static async Task<(Document containingDocument, SyntaxAnnotation typeAnnotation)> AddTypeToExistingFileAsync(Document document, INamedTypeSymbol newType, AnnotatedSymbolMapping symbolMapping, CancellationToken cancellationToken) { var originalRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var typeDeclaration = originalRoot.GetAnnotatedNodes(symbolMapping.TypeNodeAnnotation).Single(); var editor = new SyntaxEditor(originalRoot, symbolMapping.AnnotatedSolution.Services); var context = new CodeGenerationContext(generateMethodBodies: true); - var info = await document.GetCodeGenerationInfoAsync(context, fallbackOptions, cancellationToken).ConfigureAwait(false); + var info = await document.GetCodeGenerationInfoAsync(context, cancellationToken).ConfigureAwait(false); var newTypeNode = info.Service.CreateNamedTypeDeclaration(newType, CodeGenerationDestination.Unspecified, info, cancellationToken) .WithAdditionalAnnotations(SimplificationHelpers.SimplifyModuleNameAnnotation); @@ -55,7 +55,6 @@ internal static class ExtractTypeHelpers IEnumerable folders, INamedTypeSymbol newSymbol, Document hintDocument, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var newDocumentId = DocumentId.CreateNewId(projectId, debugName: fileName); @@ -84,13 +83,12 @@ internal static class ExtractTypeHelpers var newTypeDocument = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync( new CodeGenerationSolutionContext( newDocument.Project.Solution, - context, - fallbackOptions), + context), newSemanticModel.GetEnclosingNamespace(0, cancellationToken), newSymbol.GenerateRootNamespaceOrType(namespaceParts.ToArray()), cancellationToken).ConfigureAwait(false); - var newCleanupOptions = await newTypeDocument.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var newCleanupOptions = await newTypeDocument.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var formattingService = newTypeDocument.GetLanguageService(); if (formattingService is not null) diff --git a/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeCodeFixProvider.cs b/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeCodeFixProvider.cs index 593c701e89aff..8f5fd015c2511 100644 --- a/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeCodeFixProvider.cs +++ b/src/Features/Core/Portable/SimplifyThisOrMe/AbstractSimplifyThisOrMeCodeFixProvider.cs @@ -41,7 +41,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) protected sealed override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/SimplifyTypeNames/AbstractSimplifyTypeNamesCodeFixProvider.cs b/src/Features/Core/Portable/SimplifyTypeNames/AbstractSimplifyTypeNamesCodeFixProvider.cs index 1959ce97852be..63b2d66662bb7 100644 --- a/src/Features/Core/Portable/SimplifyTypeNames/AbstractSimplifyTypeNamesCodeFixProvider.cs +++ b/src/Features/Core/Portable/SimplifyTypeNames/AbstractSimplifyTypeNamesCodeFixProvider.cs @@ -100,7 +100,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) protected override async Task FixAllAsync( Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + SyntaxEditor editor, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index fa87099bef9d6..b8ce95c38c466 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -150,7 +150,7 @@ private async Task CleanupDocumentAsync( { if (document.SupportsSyntaxTree) { - var addImportPlacementOptions = await document.GetAddImportPlacementOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); + var addImportPlacementOptions = await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); var simplifierOptions = await document.GetSimplifierOptionsAsync(cancellationToken).ConfigureAwait(false); var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs index a6a50f11e9981..08bd17a7fad6e 100644 --- a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs @@ -138,7 +138,7 @@ private async Task ProcessResultAsync(CodeFixContext context, Diagnost var resolution = await filteredLocations.ResolveConflictsAsync( fieldSymbol, propertySymbol.Name, nonConflictSymbolKeys: [propertySymbol.GetSymbolKey(cancellationToken)], - context.Options, cancellationToken).ConfigureAwait(false); + cancellationToken).ConfigureAwait(false); Contract.ThrowIfFalse(resolution.IsSuccessful); diff --git a/src/Features/Core/Portable/Wrapping/AbstractWrappingCodeRefactoringProvider.cs b/src/Features/Core/Portable/Wrapping/AbstractWrappingCodeRefactoringProvider.cs index 20f7e6c8bff6b..eb3f4395eb587 100644 --- a/src/Features/Core/Portable/Wrapping/AbstractWrappingCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/Wrapping/AbstractWrappingCodeRefactoringProvider.cs @@ -31,7 +31,7 @@ protected AbstractWrappingCodeRefactoringProvider( _wrappers = wrappers; } - protected abstract SyntaxWrappingOptions GetWrappingOptions(IOptionsReader options, CodeActionOptions ideOptions); + protected abstract SyntaxWrappingOptions GetWrappingOptions(IOptionsReader options); public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { @@ -44,7 +44,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var token = root.FindToken(position); var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - var options = GetWrappingOptions(configOptions, context.Options.GetOptions(document.Project.Services)); + var options = GetWrappingOptions(configOptions); foreach (var node in token.GetRequiredParent().AncestorsAndSelf()) { diff --git a/src/Features/ExternalAccess/AspNetCore/AddPackage/AspNetCoreAddPackageCodeAction.cs b/src/Features/ExternalAccess/AspNetCore/AddPackage/AspNetCoreAddPackageCodeAction.cs index 6cbefdbeb8dd3..aae5a5888f982 100644 --- a/src/Features/ExternalAccess/AspNetCore/AddPackage/AspNetCoreAddPackageCodeAction.cs +++ b/src/Features/ExternalAccess/AspNetCore/AddPackage/AspNetCoreAddPackageCodeAction.cs @@ -63,7 +63,7 @@ private static async Task> GetTextChangesAsync( var updatedDocument = await AddImportAsync(document, position, generator, importDirective, cancellationToken).ConfigureAwait(false); // Clean things up after adding (this is what normal add-package-import does). - var codeCleanupOptions = await document.GetCodeCleanupOptionsAsync(CodeCleanupOptions.GetDefault(document.Project.Services), cancellationToken).ConfigureAwait(false); + var codeCleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var cleanedDocument = await CodeAction.CleanupDocumentAsync( updatedDocument, codeCleanupOptions, cancellationToken).ConfigureAwait(false); @@ -78,7 +78,7 @@ private static async Task AddImportAsync(Document document, int positi var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - var addImportOptions = await document.GetAddImportPlacementOptionsAsync(AddImportPlacementOptions.Default, cancellationToken).ConfigureAwait(false); + var addImportOptions = await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); var service = document.GetRequiredLanguageService(); diff --git a/src/Features/ExternalAccess/OmniSharp/Rename/OmniSharpRenamer.cs b/src/Features/ExternalAccess/OmniSharp/Rename/OmniSharpRenamer.cs index 2f40e4e84f515..badcd77216474 100644 --- a/src/Features/ExternalAccess/OmniSharp/Rename/OmniSharpRenamer.cs +++ b/src/Features/ExternalAccess/OmniSharp/Rename/OmniSharpRenamer.cs @@ -26,7 +26,7 @@ public static async Task RenameSymbolAsync( CancellationToken cancellationToken) { var nonConflictSymbolsKeys = nonConflictSymbols is null ? default : nonConflictSymbols.SelectAsArray(s => s.GetSymbolKey(cancellationToken)); - var resolution = await Renamer.RenameSymbolAsync(solution, symbol, newName, options.ToRenameOptions(), CodeActionOptions.DefaultProvider, nonConflictSymbolsKeys, cancellationToken).ConfigureAwait(false); + var resolution = await Renamer.RenameSymbolAsync(solution, symbol, newName, options.ToRenameOptions(), nonConflictSymbolsKeys, cancellationToken).ConfigureAwait(false); return new RenameResult(resolution.NewSolution, resolution.ErrorMessage); } } diff --git a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb index e4144cbdb1143..45fc7e1c99aaa 100644 --- a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb +++ b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb @@ -277,7 +277,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature potentiallyUpdatedNode As SyntaxNode, originalNode As SyntaxNode, updatedSignature As SignatureChange, - fallbackOptions As LineFormattingOptionsProvider, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Dim vbnode = DirectCast(potentiallyUpdatedNode, VisualBasicSyntaxNode) @@ -291,7 +290,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature vbnode.IsKind(SyntaxKind.EventBlock) OrElse vbnode.IsKind(SyntaxKind.EventStatement) Then - Dim updatedLeadingTrivia = Await UpdateParamNodesInLeadingTriviaAsync(document, vbnode, declarationSymbol, updatedSignature, fallbackOptions, cancellationToken).ConfigureAwait(False) + Dim updatedLeadingTrivia = Await UpdateParamNodesInLeadingTriviaAsync(document, vbnode, declarationSymbol, updatedSignature, cancellationToken).ConfigureAwait(False) vbnode = vbnode.WithLeadingTrivia(updatedLeadingTrivia) End If @@ -608,7 +607,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature node As VisualBasicSyntaxNode, declarationSymbol As ISymbol, updatedSignature As SignatureChange, - fallbackOptions As LineFormattingOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of SyntaxTrivia)) If Not node.HasLeadingTrivia Then @@ -627,7 +625,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature Return node.GetLeadingTrivia().ToImmutableArray() End If - Dim options = Await document.GetLineFormattingOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(False) + Dim options = Await document.GetLineFormattingOptionsAsync(cancellationToken).ConfigureAwait(False) Return GetPermutedDocCommentTrivia(node, permutedParamNodes, document.Project.Services, options) End Function diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb index 3c6e5efe9c2ce..408486abd861d 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEnumMember/GenerateEnumMemberCodeFixProvider.vb @@ -32,9 +32,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEnumMember End Get End Property - Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, fallbackOptions As CleanCodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) + Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) Dim service = document.GetLanguageService(Of IGenerateEnumMemberService)() - Return service.GenerateEnumMemberAsync(document, node, fallbackOptions, cancellationToken) + Return service.GenerateEnumMemberAsync(document, node, cancellationToken) End Function Protected Overrides Function IsCandidate(node As SyntaxNode, token As SyntaxToken, diagnostic As Diagnostic) As Boolean diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.CodeAction.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.CodeAction.vb index be371df651dd6..86c111846bc6f 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.CodeAction.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.CodeAction.vb @@ -15,18 +15,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent Private ReadOnly _targetSymbol As INamedTypeSymbol Private ReadOnly _generatedEvent As IEventSymbol Private ReadOnly _codeGenService As ICodeGenerationService - Private ReadOnly _fallbackOptions As CodeAndImportGenerationOptionsProvider Public Sub New(solution As Solution, targetSymbol As INamedTypeSymbol, generatedEvent As IEventSymbol, - codeGenService As ICodeGenerationService, - fallbackOptions As CodeAndImportGenerationOptionsProvider) + codeGenService As ICodeGenerationService) _solution = solution _targetSymbol = targetSymbol _generatedEvent = generatedEvent _codeGenService = codeGenService - _fallbackOptions = fallbackOptions End Sub Public Overrides ReadOnly Property Title As String @@ -39,8 +36,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent Return _codeGenService.AddEventAsync( New CodeGenerationSolutionContext( _solution, - CodeGenerationContext.Default, - _fallbackOptions), + CodeGenerationContext.Default), _targetSymbol, _generatedEvent, cancellationToken) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb index c4f207d21b477..f7360c29dfa7e 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb @@ -155,7 +155,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent ' instead of an 'As' clause. delegateType.AssociatedSymbol = generatedEvent - Return New GenerateEventCodeAction(document.Project.Solution, targetType, generatedEvent, codeGenService, fallbackOptions) + Return New GenerateEventCodeAction(document.Project.Solution, targetType, generatedEvent, codeGenService) End Function Private Shared Function GetHandlerExpression(handlerStatement As AddRemoveHandlerStatementSyntax) As ExpressionSyntax @@ -304,11 +304,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent ' instead of an 'As' clause. eventHandlerType.AssociatedSymbol = generatedEvent - Return New GenerateEventCodeAction(document.Project.Solution, targetType, generatedEvent, codeGenService, fallbackOptions) + Return New GenerateEventCodeAction(document.Project.Solution, targetType, generatedEvent, codeGenService) Else ' Event with no parameters. Dim generatedMember = CodeGenerationSymbolFactory.CreateEventSymbol(boundEvent, name:=actualEventName) - Return New GenerateEventCodeAction(document.Project.Solution, targetType, generatedMember, codeGenService, fallbackOptions) + Return New GenerateEventCodeAction(document.Project.Solution, targetType, generatedMember, codeGenService) End If End Function @@ -404,7 +404,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent delegateType.AssociatedSymbol = generatedEvent Return New GenerateEventCodeAction( - document.Project.Solution, originalTargetType, generatedEvent, codeGenService, fallbackOptions) + document.Project.Solution, originalTargetType, generatedEvent, codeGenService) End Function End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb index cd765a87427d0..66f6f65869b15 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateConversionCodeFixProvider.vb @@ -32,9 +32,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateMethod End Get End Property - Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, fallbackOptions As CleanCodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) + Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) Dim service = document.GetLanguageService(Of IGenerateConversionService)() - Return service.GenerateConversionAsync(document, node, fallbackOptions, cancellationToken) + Return service.GenerateConversionAsync(document, node, cancellationToken) End Function Protected Overrides Function IsCandidate(node As SyntaxNode, token As SyntaxToken, diagnostic As Diagnostic) As Boolean diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb index 84af5d9e3c77d..a4306b7efc38b 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateParameterizedMember/GenerateParameterizedMemberCodeFixProvider.vb @@ -51,9 +51,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateMethod End Get End Property - Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, fallbackOptions As CleanCodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) + Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) Dim service = document.GetLanguageService(Of IGenerateParameterizedMemberService)() - Return service.GenerateMethodAsync(document, node, fallbackOptions, cancellationToken) + Return service.GenerateMethodAsync(document, node, cancellationToken) End Function Protected Overrides Function IsCandidate(node As SyntaxNode, token As SyntaxToken, diagnostic As Diagnostic) As Boolean diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb index 46a81e7a1d719..5ed4108e524b2 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.vb @@ -40,9 +40,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateType End Get End Property - Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, fallbackOptions As CleanCodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) + Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) Dim service = document.GetLanguageService(Of IGenerateTypeService)() - Return service.GenerateTypeAsync(document, node, fallbackOptions, cancellationToken) + Return service.GenerateTypeAsync(document, node, cancellationToken) End Function Protected Overrides Function IsCandidate(node As SyntaxNode, token As SyntaxToken, diagnostic As Diagnostic) As Boolean diff --git a/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb b/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb index 6af04744a6e8e..5c6c307ee0f81 100644 --- a/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb +++ b/src/Features/VisualBasic/Portable/ConvertAutoPropertyToFullProperty/VisualBasicConvertAutoPropertyToFullProperty.vb @@ -31,7 +31,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertAutoPropertyToFullProperty ''' name preceded by an underscore. We will use this as the field name so we don't mess up ''' any existing references to this field. ''' - Protected Overrides Function GetFieldNameAsync(document As Document, propertySymbol As IPropertySymbol, fallbackOptions As NamingStylePreferencesProvider, cancellationToken As CancellationToken) As Task(Of String) + Protected Overrides Function GetFieldNameAsync(document As Document, propertySymbol As IPropertySymbol, cancellationToken As CancellationToken) As Task(Of String) Return Task.FromResult(Underscore + propertySymbol.Name) End Function diff --git a/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb b/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb index 2c494217af6cb..5a0bb2cc393ba 100644 --- a/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb +++ b/src/Features/VisualBasic/Portable/EncapsulateField/VisualBasicEncapsulateFieldService.vb @@ -27,7 +27,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EncapsulateField makePrivate As Boolean, document As Document, declarationAnnotation As SyntaxAnnotation, - fallbackOptions As CodeAndImportGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of SyntaxNode) Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) diff --git a/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb b/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb index f751c90724cdf..850b3ec580a61 100644 --- a/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/GenerateConstructor/GenerateConstructorCodeFixProvider.vb @@ -32,9 +32,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor End Get End Property - Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, fallbackOptions As CleanCodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) + Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) Dim service = document.GetLanguageService(Of IGenerateConstructorService)() - Return service.GenerateConstructorAsync(document, node, fallbackOptions, cancellationToken) + Return service.GenerateConstructorAsync(document, node, cancellationToken) End Function Protected Overrides Function GetTargetNode(node As SyntaxNode) As SyntaxNode diff --git a/src/Features/VisualBasic/Portable/GenerateConstructorFromMembers/VisualBasicGenerateConstructorFromMembersCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/GenerateConstructorFromMembers/VisualBasicGenerateConstructorFromMembersCodeRefactoringProvider.vb index 87eeba3fe9f48..7c7983dddbe40 100644 --- a/src/Features/VisualBasic/Portable/GenerateConstructorFromMembers/VisualBasicGenerateConstructorFromMembersCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/GenerateConstructorFromMembers/VisualBasicGenerateConstructorFromMembersCodeRefactoringProvider.vb @@ -39,7 +39,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructorFromMembers Return SymbolDisplay.ToDisplayString(parameter, format) End Function - Protected Overrides Function PrefersThrowExpressionAsync(document As Document, fallbackOptions As SimplifierOptionsProvider, cancellationToken As CancellationToken) As ValueTask(Of Boolean) + Protected Overrides Function PrefersThrowExpressionAsync(document As Document, cancellationToken As CancellationToken) As ValueTask(Of Boolean) ' No throw expression preference option is defined for VB because it doesn't support throw expressions. Return ValueTaskFactory.FromResult(False) End Function diff --git a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb index c5ea754cfb486..ec54305a08db7 100644 --- a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb +++ b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb @@ -626,7 +626,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateType document As Document, simpleName As SimpleNameSyntax, includeUsingsOrImports As String, - fallbackOptions As AddImportPlacementOptionsProvider, cancellationToken As CancellationToken) As Task(Of Solution) ' Nothing to include @@ -672,7 +671,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateType Return updatedSolution End If - Dim addImportOptions = Await document.GetAddImportPlacementOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(False) + Dim addImportOptions = Await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(False) Dim addedCompilationRoot = compilationRoot.AddImportsStatement(newImport, addImportOptions.PlaceSystemNamespaceFirst, Formatter.Annotation, Simplifier.Annotation) updatedSolution = updatedSolution.WithDocumentSyntaxRoot(document.Id, addedCompilationRoot, PreservationMode.PreserveIdentity) End If diff --git a/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb b/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb index ae7311d89a27c..b5b81092baacc 100644 --- a/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/GenerateVariable/VisualBasicGenerateVariableCodeFixProvider.vb @@ -35,9 +35,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateVariable End Get End Property - Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, fallbackOptions As CleanCodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) + Protected Overrides Function GetCodeActionsAsync(document As Document, node As SyntaxNode, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of CodeAction)) Dim service = document.GetLanguageService(Of IGenerateVariableService)() - Return service.GenerateVariableAsync(document, node, fallbackOptions, cancellationToken) + Return service.GenerateVariableAsync(document, node, cancellationToken) End Function Protected Overrides Function IsCandidate(node As SyntaxNode, token As SyntaxToken, diagnostic As Diagnostic) As Boolean diff --git a/src/Features/VisualBasic/Portable/RemoveSharedFromModuleMembers/VisualBasicRemoveSharedFromModuleMembersCodeFixProvider.vb b/src/Features/VisualBasic/Portable/RemoveSharedFromModuleMembers/VisualBasicRemoveSharedFromModuleMembersCodeFixProvider.vb index 826fe2f44ecfa..169662f8fdb3c 100644 --- a/src/Features/VisualBasic/Portable/RemoveSharedFromModuleMembers/VisualBasicRemoveSharedFromModuleMembersCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/RemoveSharedFromModuleMembers/VisualBasicRemoveSharedFromModuleMembersCodeFixProvider.vb @@ -59,7 +59,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.RemoveSharedFromModuleMembers Return Task.CompletedTask End Function - Protected Overrides Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, fallbackOptions As CodeActionOptionsProvider, cancellationToken As CancellationToken) As Task + Protected Overrides Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic), editor As SyntaxEditor, cancellationToken As CancellationToken) As Task For Each diagnostic In diagnostics Dim node = diagnostic.Location.FindNode(cancellationToken) Dim newNode = GetReplacement(document, node) diff --git a/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb b/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb index 7a137bf14f375..822aca823e272 100644 --- a/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb +++ b/src/Features/VisualBasic/Portable/ReplacePropertyWithMethods/VisualBasicReplacePropertyWithMethods.vb @@ -30,7 +30,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.ReplaceMethodWithP propertyBackingField As IFieldSymbol, desiredGetMethodName As String, desiredSetMethodName As String, - fallbackOptions As CodeGenerationOptionsProvider, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of SyntaxNode)) Dim propertyStatement = TryCast(propertyDeclarationNode, PropertyStatementSyntax) diff --git a/src/Features/VisualBasic/Portable/Wrapping/VisualBasicSyntaxWrappingOptions.vb b/src/Features/VisualBasic/Portable/Wrapping/VisualBasicSyntaxWrappingOptions.vb index 2c3f0e0f2ef6a..208eb02146516 100644 --- a/src/Features/VisualBasic/Portable/Wrapping/VisualBasicSyntaxWrappingOptions.vb +++ b/src/Features/VisualBasic/Portable/Wrapping/VisualBasicSyntaxWrappingOptions.vb @@ -4,10 +4,9 @@ Imports Microsoft.CodeAnalysis.CodeActions Imports Microsoft.CodeAnalysis.CodeStyle -Imports Microsoft.CodeAnalysis.Wrapping -Imports Microsoft.CodeAnalysis.Diagnostics -Imports Microsoft.CodeAnalysis.VisualBasic.Formatting Imports Microsoft.CodeAnalysis.Options +Imports Microsoft.CodeAnalysis.VisualBasic.Formatting +Imports Microsoft.CodeAnalysis.Wrapping Namespace Microsoft.CodeAnalysis.VisualBasic.Wrapping @@ -21,10 +20,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Wrapping MyBase.New(formattingOptions, operatorPlacement) End Sub - Public Shared Function Create(options As IOptionsReader, fallbackOptions As CodeActionOptions) As VisualBasicSyntaxWrappingOptions + Public Shared Function Create(options As IOptionsReader) As VisualBasicSyntaxWrappingOptions Return New VisualBasicSyntaxWrappingOptions( - formattingOptions:=New VisualBasicSyntaxFormattingOptions(options, DirectCast(fallbackOptions.CleanupOptions.FormattingOptions, VisualBasicSyntaxFormattingOptions)), - operatorPlacement:=options.GetOption(CodeStyleOptions2.OperatorPlacementWhenWrapping, fallbackOptions.CodeStyleOptions.OperatorPlacementWhenWrapping)) + formattingOptions:=New VisualBasicSyntaxFormattingOptions(options), + operatorPlacement:=options.GetOption(CodeStyleOptions2.OperatorPlacementWhenWrapping)) End Function End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb index 8fc1329dfde96..ffa3ba31ba2f3 100644 --- a/src/Features/VisualBasic/Portable/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/Wrapping/VisualBasicWrappingCodeRefactoringProvider.vb @@ -33,8 +33,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Wrapping MyBase.New(s_wrappers) End Sub - Protected Overrides Function GetWrappingOptions(options As IOptionsReader, ideOptions As CodeActionOptions) As SyntaxWrappingOptions - Return VisualBasicSyntaxWrappingOptions.Create(options, ideOptions) + Protected Overrides Function GetWrappingOptions(options As IOptionsReader) As SyntaxWrappingOptions + Return VisualBasicSyntaxWrappingOptions.Create(options) End Function End Class End Namespace diff --git a/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs b/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs index 6dfb370319944..ecb2e80929404 100644 --- a/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs +++ b/src/LanguageServer/Protocol/ExternalAccess/Razor/FormatNewFileHandler.cs @@ -64,7 +64,7 @@ public FormatNewFileHandler(IGlobalOptionService globalOptions) if (formattingService is not null) { var hintDocument = project.Documents.FirstOrDefault(); - var cleanupOptions = await document.GetCodeCleanupOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false); + var cleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); document = await formattingService.FormatNewDocumentAsync(document, hintDocument, cleanupOptions, cancellationToken).ConfigureAwait(false); } diff --git a/src/LanguageServer/Protocol/Features/Options/AddImportPlacementOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/AddImportPlacementOptionsStorage.cs deleted file mode 100644 index 30f2bb119e7ea..0000000000000 --- a/src/LanguageServer/Protocol/Features/Options/AddImportPlacementOptionsStorage.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.AddImport; - -internal static class AddImportPlacementOptionsStorage -{ - public static ValueTask GetAddImportPlacementOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetAddImportPlacementOptionsAsync(globalOptions.GetAddImportPlacementOptions(document.Project.Services), cancellationToken); - - public static AddImportPlacementOptions GetAddImportPlacementOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) - => globalOptions.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions: null, fallbackOptions: null); -} diff --git a/src/LanguageServer/Protocol/Features/Options/CodeCleanupOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/CodeCleanupOptionsStorage.cs deleted file mode 100644 index 8c8cd99c569e9..0000000000000 --- a/src/LanguageServer/Protocol/Features/Options/CodeCleanupOptionsStorage.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.CodeCleanup; - -internal static class CodeCleanupOptionsStorage -{ - public static ValueTask GetCodeCleanupOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetCodeCleanupOptionsAsync(globalOptions.GetCodeCleanupOptions(document.Project.Services), cancellationToken); - - public static CodeCleanupOptions GetCodeCleanupOptions(this IOptionsReader globalOptions, LanguageServices languageServices) - => globalOptions.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions: null, fallbackOptions: null); -} diff --git a/src/LanguageServer/Protocol/Features/Options/CodeGenerationOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/CodeGenerationOptionsStorage.cs deleted file mode 100644 index 4ae067d065db9..0000000000000 --- a/src/LanguageServer/Protocol/Features/Options/CodeGenerationOptionsStorage.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.CodeGeneration; - -internal static class CodeGenerationOptionsStorage -{ - public static ValueTask GetCodeGenerationOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetCodeGenerationOptionsAsync(globalOptions.GetCodeGenerationOptions(document.Project.Services), cancellationToken); - - public static ValueTask GetCleanCodeGenerationOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetCleanCodeGenerationOptionsAsync(globalOptions.GetCleanCodeGenerationOptions(document.Project.Services), cancellationToken); - - public static CodeGenerationOptions GetCodeGenerationOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) - => globalOptions.GetCodeGenerationOptions(languageServices, fallbackOptions: null); - - public static CodeAndImportGenerationOptions GetCodeAndImportGenerationOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) - => globalOptions.GetCodeAndImportGenerationOptions(languageServices, allowImportsInHiddenRegions: null, fallbackOptions: null); - - public static CleanCodeGenerationOptions GetCleanCodeGenerationOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) - => globalOptions.GetCleanCodeGenerationOptions(languageServices, allowImportsInHiddenRegions: null, fallbackOptions: null); -} diff --git a/src/LanguageServer/Protocol/Features/Options/CompletionOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/CompletionOptionsStorage.cs index 6d921ba2dd16b..78b3e5b4b596f 100644 --- a/src/LanguageServer/Protocol/Features/Options/CompletionOptionsStorage.cs +++ b/src/LanguageServer/Protocol/Features/Options/CompletionOptionsStorage.cs @@ -33,7 +33,6 @@ public static CompletionOptions GetCompletionOptions(this IGlobalOptionService o ProvideDateAndTimeCompletions = options.GetOption(ProvideDateAndTimeCompletions, language), ProvideRegexCompletions = options.GetOption(ProvideRegexCompletions, language), ForceExpandedCompletionIndexCreation = options.GetOption(ForceExpandedCompletionIndexCreation), - NamingStyleFallbackOptions = options.GetNamingStylePreferences(language), ShowNewSnippetExperienceUserOption = options.GetOption(ShowNewSnippetExperienceUserOption, language), ShowNewSnippetExperienceFeatureFlag = options.GetOption(ShowNewSnippetExperienceFeatureFlag) }; diff --git a/src/LanguageServer/Protocol/Features/Options/DocumentFormattingOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/DocumentFormattingOptionsStorage.cs deleted file mode 100644 index 6cf1bac6ddf81..0000000000000 --- a/src/LanguageServer/Protocol/Features/Options/DocumentFormattingOptionsStorage.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.Formatting; - -internal static class DocumentFormattingOptionsStorage -{ - public static ValueTask GetDocumentFormattingOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetDocumentFormattingOptionsAsync(globalOptions.GetDocumentFormattingOptions(), cancellationToken); - - public static DocumentFormattingOptions GetDocumentFormattingOptions(this IGlobalOptionService globalOptions) - => globalOptions.GetDocumentFormattingOptions(fallbackOptions: null); -} - diff --git a/src/LanguageServer/Protocol/Features/Options/GlobalCodeActionOptionsProvider.cs b/src/LanguageServer/Protocol/Features/Options/GlobalCodeActionOptionsProvider.cs index 5217e63350ad3..3b7e20ca6e9e1 100644 --- a/src/LanguageServer/Protocol/Features/Options/GlobalCodeActionOptionsProvider.cs +++ b/src/LanguageServer/Protocol/Features/Options/GlobalCodeActionOptionsProvider.cs @@ -55,7 +55,7 @@ ValueTask OptionsProvider.GetOptionsAsync( => ValueTaskFactory.FromResult(_globalOptions.GetSimplifierOptions(languageServices)); ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(_globalOptions.GetAddImportPlacementOptions(languageServices)); + => ValueTaskFactory.FromResult(_globalOptions.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions: null)); ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) => ValueTaskFactory.FromResult(_globalOptions.GetOrganizeImportsOptions(languageServices.Language)); diff --git a/src/LanguageServer/Protocol/Features/Options/LineFormattingOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/LineFormattingOptionsStorage.cs deleted file mode 100644 index 71732183198af..0000000000000 --- a/src/LanguageServer/Protocol/Features/Options/LineFormattingOptionsStorage.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.Formatting; - -internal static class LineFormattingOptionsStorage -{ - public static ValueTask GetLineFormattingOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetLineFormattingOptionsAsync(globalOptions.GetLineFormattingOptions(document.Project.Language), cancellationToken); - - public static LineFormattingOptions GetLineFormattingOptions(this IGlobalOptionService globalOptions, string language) - => globalOptions.GetLineFormattingOptions(language, fallbackOptions: null); -} - diff --git a/src/LanguageServer/Protocol/Handler/Rename/RenameHandler.cs b/src/LanguageServer/Protocol/Handler/Rename/RenameHandler.cs index be0490a297ad4..7cf1853dcd594 100644 --- a/src/LanguageServer/Protocol/Handler/Rename/RenameHandler.cs +++ b/src/LanguageServer/Protocol/Handler/Rename/RenameHandler.cs @@ -8,7 +8,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Rename; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; @@ -20,26 +19,19 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler { [ExportCSharpVisualBasicStatelessLspService(typeof(RenameHandler)), Shared] [Method(LSP.Methods.TextDocumentRenameName)] - internal class RenameHandler : ILspServiceDocumentRequestHandler + [method: ImportingConstructor] + [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + internal sealed class RenameHandler() : ILspServiceDocumentRequestHandler { - private readonly IGlobalOptionService _optionsService; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RenameHandler(IGlobalOptionService optionsService) - { - _optionsService = optionsService; - } - public bool MutatesSolutionState => false; public bool RequiresLSPSolution => true; public TextDocumentIdentifier GetTextDocumentIdentifier(RenameParams request) => request.TextDocument; public Task HandleRequestAsync(RenameParams request, RequestContext context, CancellationToken cancellationToken) - => GetRenameEditAsync(_optionsService, context.GetRequiredDocument(), ProtocolConversions.PositionToLinePosition(request.Position), request.NewName, cancellationToken); + => GetRenameEditAsync(context.GetRequiredDocument(), ProtocolConversions.PositionToLinePosition(request.Position), request.NewName, cancellationToken); - internal static async Task GetRenameEditAsync(IGlobalOptionService globalOptionsService, Document document, LinePosition linePosition, string newName, CancellationToken cancellationToken) + internal static async Task GetRenameEditAsync(Document document, LinePosition linePosition, string newName, CancellationToken cancellationToken) { var oldSolution = document.Project.Solution; var position = await document.GetPositionFromLinePositionAsync(linePosition, cancellationToken).ConfigureAwait(false); @@ -63,7 +55,7 @@ public RenameHandler(IGlobalOptionService optionsService) var renameReplacementInfo = await renameLocationSet.ResolveConflictsAsync( symbolicRenameInfo.Symbol, symbolicRenameInfo.GetFinalSymbolName(newName), - nonConflictSymbolKeys: default, globalOptionsService.CreateProvider(), + nonConflictSymbolKeys: default, cancellationToken).ConfigureAwait(false); if (!renameReplacementInfo.IsSuccessful || diff --git a/src/LanguageServer/ProtocolUnitTests/Options/LspOptionsTests.cs b/src/LanguageServer/ProtocolUnitTests/Options/LspOptionsTests.cs index 15c215169df82..c9830769737fe 100644 --- a/src/LanguageServer/ProtocolUnitTests/Options/LspOptionsTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/Options/LspOptionsTests.cs @@ -30,7 +30,7 @@ public async Task TestCanRetrieveCSharpOptionsWithOnlyLspLayer(bool mutatingLspW await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace); var globalOptions = testLspServer.TestWorkspace.ExportProvider.GetExportedValue(); var project = testLspServer.GetCurrentSolution().Projects.Single().Services; - Assert.NotNull(globalOptions.GetAddImportPlacementOptions(project)); + Assert.NotNull(globalOptions.GetAddImportPlacementOptions(project, allowInHiddenRegions: null)); Assert.NotNull(globalOptions.GetCodeGenerationOptions(project)); Assert.NotNull(globalOptions.GetCodeStyleOptions(project)); Assert.NotNull(globalOptions.GetSyntaxFormattingOptions(project)); @@ -44,7 +44,7 @@ public async Task TestCanRetrieveVisualBasicOptionsWithOnlyLspLayer(bool mutatin await using var testLspServer = await CreateVisualBasicTestLspServerAsync(markup, mutatingLspWorkspace); var globalOptions = testLspServer.TestWorkspace.ExportProvider.GetExportedValue(); var project = testLspServer.GetCurrentSolution().Projects.Single().Services; - Assert.NotNull(globalOptions.GetAddImportPlacementOptions(project)); + Assert.NotNull(globalOptions.GetAddImportPlacementOptions(project, allowInHiddenRegions: null)); Assert.NotNull(globalOptions.GetCodeGenerationOptions(project)); Assert.NotNull(globalOptions.GetCodeStyleOptions(project)); Assert.NotNull(globalOptions.GetSyntaxFormattingOptions(project)); diff --git a/src/Tools/ExternalAccess/Razor/Cohost/Handlers/Rename.cs b/src/Tools/ExternalAccess/Razor/Cohost/Handlers/Rename.cs index 23cd3e6ced9f2..c6feae0bab8e9 100644 --- a/src/Tools/ExternalAccess/Razor/Cohost/Handlers/Rename.cs +++ b/src/Tools/ExternalAccess/Razor/Cohost/Handlers/Rename.cs @@ -5,7 +5,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.LanguageServer.Handler; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; using Roslyn.LanguageServer.Protocol; @@ -17,9 +16,5 @@ internal static class Rename => PrepareRenameHandler.GetRenameRangeAsync(document, linePosition, cancellationToken); public static Task GetRenameEditAsync(Document document, LinePosition linePosition, string newName, CancellationToken cancellationToken) - { - var globalOptions = document.Project.Solution.Services.ExportProvider.GetService(); - - return RenameHandler.GetRenameEditAsync(globalOptions, document, linePosition, newName, cancellationToken); - } + => RenameHandler.GetRenameEditAsync(document, linePosition, newName, cancellationToken); } diff --git a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs index 3e1e71ccc4634..b8c6e5739410a 100644 --- a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs @@ -336,8 +336,7 @@ private async Task FormatDocumentCreatedFromTemplateAsync(IVsHierarchy hierarchy var addedDocument = forkedSolution.GetRequiredDocument(documentId); - var globalOptions = _componentModel.GetService(); - var cleanupOptions = await addedDocument.GetCodeCleanupOptionsAsync(globalOptions, cancellationToken).ConfigureAwait(true); + var cleanupOptions = await addedDocument.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(true); // Call out to various new document formatters to tweak what they want var formattingService = addedDocument.GetLanguageService(); diff --git a/src/VisualStudio/Core/Def/Venus/ContainedLanguage.IVsContainedLanguageCodeSupport.cs b/src/VisualStudio/Core/Def/Venus/ContainedLanguage.IVsContainedLanguageCodeSupport.cs index 07596b0273e55..41ae4f456fbb3 100644 --- a/src/VisualStudio/Core/Def/Venus/ContainedLanguage.IVsContainedLanguageCodeSupport.cs +++ b/src/VisualStudio/Core/Def/Venus/ContainedLanguage.IVsContainedLanguageCodeSupport.cs @@ -30,7 +30,7 @@ public int CreateUniqueEventName(string pszClassName, string pszObjectName, stri allowCancellation: false, showProgress: false, action: c => - result = ContainedLanguageCodeSupport.CreateUniqueEventName(GetThisDocument(), GlobalOptions, pszClassName, pszObjectName, pszNameOfEvent, c.UserCancellationToken)); + result = ContainedLanguageCodeSupport.CreateUniqueEventName(GetThisDocument(), pszClassName, pszObjectName, pszNameOfEvent, c.UserCancellationToken)); pbstrEventHandlerName = result; return VSConstants.S_OK; @@ -75,7 +75,6 @@ public int EnsureEventHandler( itemidInsertionPoint, useHandlesClause: false, additionalFormattingRule: targetDocument.Project.Services.GetService().GetAdditionalCodeGenerationRule(), - GlobalOptions, cancellationToken: c.UserCancellationToken)); pbstrUniqueMemberID = idBodyAndInsertionPoint.Item1; @@ -155,7 +154,7 @@ public int GetMemberNavigationPoint(string pszClassName, string pszUniqueMemberI showProgress: false, action: c => { - if (ContainedLanguageCodeSupport.TryGetMemberNavigationPoint(GetThisDocument(), GlobalOptions, pszClassName, pszUniqueMemberID, out textSpan, out var targetDocument, c.UserCancellationToken)) + if (ContainedLanguageCodeSupport.TryGetMemberNavigationPoint(GetThisDocument(), pszClassName, pszUniqueMemberID, out textSpan, out var targetDocument, c.UserCancellationToken)) { succeeded = true; itemId = this.ContainedDocument.FindItemIdOfDocument(targetDocument); diff --git a/src/VisualStudio/Core/Def/Venus/ContainedLanguageCodeSupport.cs b/src/VisualStudio/Core/Def/Venus/ContainedLanguageCodeSupport.cs index 091bb01bbda55..08c7c22dc6219 100644 --- a/src/VisualStudio/Core/Def/Venus/ContainedLanguageCodeSupport.cs +++ b/src/VisualStudio/Core/Def/Venus/ContainedLanguageCodeSupport.cs @@ -55,7 +55,7 @@ public static bool TryGetBaseClassName(Document document, string className, Canc } public static string CreateUniqueEventName( - Document document, IGlobalOptionService globalOptions, string className, string objectName, string nameOfEvent, CancellationToken cancellationToken) + Document document, string className, string objectName, string nameOfEvent, CancellationToken cancellationToken) { var type = document.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult_Venus(cancellationToken).GetTypeByMetadataName(className); var name = objectName + "_" + nameOfEvent; @@ -65,7 +65,7 @@ public static string CreateUniqueEventName( var tree = document.GetSyntaxTreeSynchronously(cancellationToken); var typeNode = type.DeclaringSyntaxReferences.Where(r => r.SyntaxTree == tree).Select(r => r.GetSyntax(cancellationToken)).First(); var codeModel = document.GetRequiredLanguageService(); - var options = document.GetLineFormattingOptionsAsync(globalOptions, cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); + var options = document.GetLineFormattingOptionsAsync(cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); var point = codeModel.GetStartPoint(typeNode, options, EnvDTE.vsCMPart.vsCMPartBody); var reservedNames = semanticModel.LookupSymbols(point.Value.Position, type).Select(m => m.Name); @@ -152,7 +152,6 @@ public static Tuple EnsureEventHandler( uint itemidInsertionPoint, bool useHandlesClause, AbstractFormattingRule additionalFormattingRule, - IGlobalOptionService globalOptions, CancellationToken cancellationToken) #pragma warning restore IDE0060 // Remove unused parameter { @@ -210,7 +209,7 @@ public static Tuple EnsureEventHandler( var position = type.Locations.First(loc => loc.SourceTree == targetSyntaxTree).SourceSpan.Start; var destinationType = syntaxFacts.GetContainingTypeDeclaration(targetSyntaxTree.GetRoot(cancellationToken), position); - var documentOptions = targetDocument.GetLineFormattingOptionsAsync(globalOptions, cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); + var documentOptions = targetDocument.GetLineFormattingOptionsAsync(cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); var insertionPoint = codeModel.GetEndPoint(destinationType, documentOptions, EnvDTE.vsCMPart.vsCMPartBody); if (insertionPoint == null) @@ -218,8 +217,7 @@ public static Tuple EnsureEventHandler( throw new InvalidOperationException(ServicesVSResources.Can_t_find_where_to_insert_member); } - var fallbackOptions = globalOptions.GetCleanCodeGenerationOptions(targetDocument.Project.Services); - var options = targetDocument.GetCleanCodeGenerationOptionsAsync(fallbackOptions, cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); + var options = targetDocument.GetCleanCodeGenerationOptionsAsync(cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); var info = codeGenerationService.GetInfo(new CodeGenerationContext(autoInsertionLocation: false), options.GenerationOptions, destinationType.SyntaxTree.Options); var newType = codeGenerationService.AddMethod(destinationType, newMethod, info, cancellationToken); @@ -251,7 +249,6 @@ public static Tuple EnsureEventHandler( public static bool TryGetMemberNavigationPoint( Document thisDocument, - IGlobalOptionService globalOptions, string className, string uniqueMemberID, out VsTextSpan textSpan, @@ -274,7 +271,7 @@ public static bool TryGetMemberNavigationPoint( if (memberNode != null) { var memberNodeDocument = thisDocument.Project.Solution.GetDocument(memberNode.SyntaxTree); - var options = memberNodeDocument.GetLineFormattingOptionsAsync(globalOptions, cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); + var options = memberNodeDocument.GetLineFormattingOptionsAsync(cancellationToken).AsTask().WaitAndGetResult_Venus(cancellationToken); var navigationPoint = codeModel.GetStartPoint(memberNode, options, EnvDTE.vsCMPart.vsCMPartNavigate); if (navigationPoint != null) { diff --git a/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs b/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs index 6837a3f4123b7..d4de1304ce2e1 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/FileCodeModel.cs @@ -98,9 +98,6 @@ internal ITextManagerAdapter TextManagerAdapter get; set; } - internal IGlobalOptionService GlobalOptions - => State.ProjectCodeModelFactory.GlobalOptions; - /// /// Internally, we store the DocumentId for the document that the FileCodeModel represents. If the underlying file /// is renamed, the DocumentId will become invalid because the Roslyn VS workspace treats file renames as a remove/add pair. @@ -447,7 +444,7 @@ internal CodeGenerationOptions GetDocumentOptions() => State.ThreadingContext.JoinableTaskFactory.Run(() => { return GetDocument() - .GetCodeGenerationOptionsAsync(GlobalOptions, CancellationToken.None).AsTask(); + .GetCodeGenerationOptionsAsync(CancellationToken.None).AsTask(); }); internal Compilation GetCompilation() diff --git a/src/VisualStudio/Core/Impl/CodeModel/InternalElements/AbstractCodeElement.cs b/src/VisualStudio/Core/Impl/CodeModel/InternalElements/AbstractCodeElement.cs index 8ee898fcbaf2c..de85623793764 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/InternalElements/AbstractCodeElement.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/InternalElements/AbstractCodeElement.cs @@ -51,9 +51,6 @@ protected SemanticModel GetSemanticModel() protected ProjectId GetProjectId() => FileCodeModel.GetProjectId(); - internal IGlobalOptionService GlobalOptions - => FileCodeModel.GlobalOptions; - internal bool IsValidNode() { if (!TryLookupNode(out var node)) @@ -143,7 +140,7 @@ public virtual EnvDTE.CodeElements Collection } private LineFormattingOptions GetLineFormattingOptions() - => State.ThreadingContext.JoinableTaskFactory.Run(() => GetDocument().GetLineFormattingOptionsAsync(GlobalOptions, CancellationToken.None).AsTask()); + => State.ThreadingContext.JoinableTaskFactory.Run(() => GetDocument().GetLineFormattingOptionsAsync(CancellationToken.None).AsTask()); public EnvDTE.TextPoint StartPoint { diff --git a/src/VisualStudio/Core/Impl/CodeModel/ProjectCodeModelFactory.cs b/src/VisualStudio/Core/Impl/CodeModel/ProjectCodeModelFactory.cs index 3c1acd9e7c9aa..ff6bf3c323b41 100644 --- a/src/VisualStudio/Core/Impl/CodeModel/ProjectCodeModelFactory.cs +++ b/src/VisualStudio/Core/Impl/CodeModel/ProjectCodeModelFactory.cs @@ -35,21 +35,17 @@ internal sealed class ProjectCodeModelFactory : IProjectCodeModelFactory private readonly AsyncBatchingWorkQueue _documentsToFireEventsFor; - public readonly IGlobalOptionService GlobalOptions; - [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public ProjectCodeModelFactory( VisualStudioWorkspace visualStudioWorkspace, [Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider, - IGlobalOptionService globalOptions, IThreadingContext threadingContext, IAsynchronousOperationListenerProvider listenerProvider) { _visualStudioWorkspace = visualStudioWorkspace; _serviceProvider = serviceProvider; _threadingContext = threadingContext; - GlobalOptions = globalOptions; Listener = listenerProvider.GetListener(FeatureAttribute.CodeModel); diff --git a/src/VisualStudio/Core/Test/Venus/CSharpContainedLanguageSupportTests.vb b/src/VisualStudio/Core/Test/Venus/CSharpContainedLanguageSupportTests.vb index dcf2db91bc9ce..3424c5471b4f2 100644 --- a/src/VisualStudio/Core/Test/Venus/CSharpContainedLanguageSupportTests.vb +++ b/src/VisualStudio/Core/Test/Venus/CSharpContainedLanguageSupportTests.vb @@ -163,7 +163,6 @@ public partial class _Default : System.Web.UI.Page Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -193,7 +192,6 @@ public class _Default : System.Web.UI.Page Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -220,7 +218,6 @@ public class _Default : System.Web.UI.Page Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -249,7 +246,6 @@ public partial class _Default Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -281,7 +277,6 @@ public class MyBaseClass Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -548,7 +543,6 @@ public class _Default itemidInsertionPoint:=0, useHandlesClause:=False, additionalFormattingRule:=BlankLineInGeneratedMethodFormattingRule.Instance, - workspace.GlobalOptions, cancellationToken:=Nothing) ' Since a valid handler exists, item2 and item3 of the tuple returned must be nothing @@ -598,7 +592,6 @@ protected void Button1_Click(object sender, EventArgs e) itemidInsertionPoint:=0, useHandlesClause:=False, additionalFormattingRule:=BlankLineInGeneratedMethodFormattingRule.Instance, - workspace.GlobalOptions, cancellationToken:=Nothing) Assert.Equal("Button1_Click(object,System.EventArgs)", eventHandlerIdTextPosition.Item1) @@ -649,7 +642,6 @@ public class _Default Dim actualSpan As TextSpan = Nothing If Not ContainedLanguageCodeSupport.TryGetMemberNavigationPoint( thisDocument:=document, - workspace.GlobalOptions, className:="_Default", uniqueMemberID:="Button1_Click(object,System.EventArgs)", textSpan:=actualSpan, diff --git a/src/VisualStudio/Core/Test/Venus/VisualBasicContainedLanguageSupportTests.vb b/src/VisualStudio/Core/Test/Venus/VisualBasicContainedLanguageSupportTests.vb index e9838f49f72aa..f142815dc2844 100644 --- a/src/VisualStudio/Core/Test/Venus/VisualBasicContainedLanguageSupportTests.vb +++ b/src/VisualStudio/Core/Test/Venus/VisualBasicContainedLanguageSupportTests.vb @@ -201,7 +201,6 @@ End Class Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -230,7 +229,6 @@ End Class Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -257,7 +255,6 @@ End Class.Value Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -285,7 +282,6 @@ End Class.Value Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -315,7 +311,6 @@ End Class.Value Dim document = GetDocument(workspace) Dim eventName = ContainedLanguageCodeSupport.CreateUniqueEventName( document:=document, - workspace.GlobalOptions, className:="_Default", objectName:="Button1", nameOfEvent:="Click", @@ -561,7 +556,6 @@ End Class.Value itemidInsertionPoint:=0, useHandlesClause:=True, additionalFormattingRule:=LineAdjustmentFormattingRule.Instance, - workspace.GlobalOptions, cancellationToken:=Nothing) ' Since a valid handler exists, item2 and item3 of the tuple returned must be nothing @@ -606,7 +600,6 @@ End Sub.NormalizedValue itemidInsertionPoint:=0, useHandlesClause:=True, additionalFormattingRule:=LineAdjustmentFormattingRule.Instance, - workspace.GlobalOptions, cancellationToken:=Nothing) Assert.Equal("Button1_Click(Object,System.EventArgs)", eventHandlerIdTextPosition.Item1) @@ -650,7 +643,6 @@ End Sub" itemidInsertionPoint:=0, useHandlesClause:=True, additionalFormattingRule:=LineAdjustmentFormattingRule.Instance, - workspace.GlobalOptions, cancellationToken:=Nothing) Assert.Equal("Page_Load(Object,System.EventArgs)", eventHandlerIdTextPosition.Item1) @@ -697,7 +689,6 @@ End Class.Value Dim actualSpan As TextSpan = Nothing If Not ContainedLanguageCodeSupport.TryGetMemberNavigationPoint( thisDocument:=document, - workspace.GlobalOptions, className:="_Default", uniqueMemberID:="Button1_Click(Object,System.EventArgs)", textSpan:=actualSpan, diff --git a/src/VisualStudio/VisualBasic/Impl/Venus/VisualBasicContainedLanguage.vb b/src/VisualStudio/VisualBasic/Impl/Venus/VisualBasicContainedLanguage.vb index bff16aebe7dc0..69dd87973d03b 100644 --- a/src/VisualStudio/VisualBasic/Impl/Venus/VisualBasicContainedLanguage.vb +++ b/src/VisualStudio/VisualBasic/Impl/Venus/VisualBasicContainedLanguage.vb @@ -100,7 +100,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Venus itemidInsertionPoint, useHandlesClause:=True, additionalFormattingRule:=LineAdjustmentFormattingRule.Instance, - GlobalOptions, cancellationToken:=Nothing) pbstrUniqueMemberID = idBodyAndInsertionPoint.Item1 diff --git a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs index d83fd71346b56..fb48ff3897859 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs @@ -47,7 +47,7 @@ public override SimplifierOptions DefaultOptions => CSharpSimplifierOptions.Default; public override SimplifierOptions GetSimplifierOptions(IOptionsReader options) - => new CSharpSimplifierOptions(options, fallbackOptions: null); + => new CSharpSimplifierOptions(options); public override SyntaxNode Expand(SyntaxNode node, SemanticModel semanticModel, SyntaxAnnotation? annotationForReplacedAliasIdentifier, Func? expandInsideNode, bool expandParameter, CancellationToken cancellationToken) { diff --git a/src/Workspaces/Core/Portable/ChangeNamespace/IChangeNamespaceService.cs b/src/Workspaces/Core/Portable/ChangeNamespace/IChangeNamespaceService.cs index 4719f71d0064f..c02cef62400ab 100644 --- a/src/Workspaces/Core/Portable/ChangeNamespace/IChangeNamespaceService.cs +++ b/src/Workspaces/Core/Portable/ChangeNamespace/IChangeNamespaceService.cs @@ -53,11 +53,11 @@ internal interface IChangeNamespaceService : ILanguageService /// If the declared namespace for is already identical to , then it will be /// a no-op and original solution will be returned. /// - Task ChangeNamespaceAsync(Document document, SyntaxNode container, string targetNamespace, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task ChangeNamespaceAsync(Document document, SyntaxNode container, string targetNamespace, CancellationToken cancellationToken); /// /// Using only the top level namespace declarations of a document, change all of them to the target namespace. Will only /// use namespace containers considered valid by /// - Task TryChangeTopLevelNamespacesAsync(Document document, string targetNamespace, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task TryChangeTopLevelNamespacesAsync(Document document, string targetNamespace, CancellationToken cancellationToken); } diff --git a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs index dac6f076718ea..925eef02d7e7b 100644 --- a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs +++ b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs @@ -463,9 +463,7 @@ private static async Task PostProcessChangesAsync( // points. originalSolution ??= changedSolution.Workspace.CurrentSolution; - var globalOptions = changedSolution.Services.GetService(); - var fallbackOptions = globalOptions?.Provider ?? CodeActionOptions.DefaultProvider; - return await CleanSyntaxAndSemanticsAsync(originalSolution, changedSolution, fallbackOptions, CodeAnalysisProgress.None, cancellationToken).ConfigureAwait(false); + return await CleanSyntaxAndSemanticsAsync(originalSolution, changedSolution, CodeAnalysisProgress.None, cancellationToken).ConfigureAwait(false); } /// @@ -480,11 +478,7 @@ protected virtual async Task PostProcessChangesAsync(Document document { if (document.SupportsSyntaxTree) { - // TODO: avoid ILegacyGlobalCodeActionOptionsWorkspaceService https://github.com/dotnet/roslyn/issues/60777 - var globalOptions = document.Project.Solution.Services.GetService(); - var fallbackOptions = globalOptions?.Provider ?? CodeActionOptions.DefaultProvider; - - var options = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); return await CleanupDocumentAsync(document, options, cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Core/Portable/CodeActions/CodeAction_Cleanup.cs b/src/Workspaces/Core/Portable/CodeActions/CodeAction_Cleanup.cs index 216faaf1df4dc..d29c7ecb0dad5 100644 --- a/src/Workspaces/Core/Portable/CodeActions/CodeAction_Cleanup.cs +++ b/src/Workspaces/Core/Portable/CodeActions/CodeAction_Cleanup.cs @@ -72,7 +72,6 @@ internal static ImmutableArray GetAllChangedOrAddedDocumentIds( internal static async Task CleanSyntaxAndSemanticsAsync( Solution originalSolution, Solution changedSolution, - CodeCleanupOptionsProvider optionsProvider, IProgress progress, CancellationToken cancellationToken) { @@ -95,7 +94,7 @@ internal static async Task CleanSyntaxAndSemanticsAsync( // Only care about documents that support syntax. Non-C#/VB files can't be cleaned. if (document.SupportsSyntaxTree) { - var codeActionOptions = await document.GetCodeCleanupOptionsAsync(optionsProvider, cancellationToken).ConfigureAwait(false); + var codeActionOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); documentIdsAndOptions.Add((documentId, codeActionOptions)); } } diff --git a/src/Workspaces/Core/Portable/CodeFixesAndRefactorings/DocumentBasedFixAllProviderHelpers.cs b/src/Workspaces/Core/Portable/CodeFixesAndRefactorings/DocumentBasedFixAllProviderHelpers.cs index 4815968dbdfb9..bf8e25f0f5484 100644 --- a/src/Workspaces/Core/Portable/CodeFixesAndRefactorings/DocumentBasedFixAllProviderHelpers.cs +++ b/src/Workspaces/Core/Portable/CodeFixesAndRefactorings/DocumentBasedFixAllProviderHelpers.cs @@ -47,7 +47,6 @@ internal static class DocumentBasedFixAllProviderHelpers var cleanedSolution = await CodeAction.CleanSyntaxAndSemanticsAsync( originalSolution, dirtySolution, - originalFixAllContext.State.CodeActionOptionsProvider, progressTracker, cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/Core/Portable/Editing/ImportAdder.cs b/src/Workspaces/Core/Portable/Editing/ImportAdder.cs index a929ed1eb54e5..4f8fb106f5a6c 100644 --- a/src/Workspaces/Core/Portable/Editing/ImportAdder.cs +++ b/src/Workspaces/Core/Portable/Editing/ImportAdder.cs @@ -61,7 +61,7 @@ private static async Task AddImportsFromSyntaxesAsync(Document documen } // Since no public options affect the behavior we can ignore options parameter and pass no fallback options: - var addImportOptions = await document.GetAddImportPlacementOptionsAsync(CodeActionOptions.DefaultProvider, cancellationToken).ConfigureAwait(false); + var addImportOptions = await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); return await service.AddImportsAsync(document, spans, ImportAdderService.Strategy.AddImportsFromSyntaxes, addImportOptions, cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs b/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs index cb15da3617f68..8d8f093a6d32e 100644 --- a/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs +++ b/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs @@ -60,9 +60,9 @@ public static async ValueTask GetExtractMethodGe return new ExtractMethodGenerationOptions() { - CodeGenerationOptions = await document.GetCodeGenerationOptionsAsync(fallbackOptions.Value.CodeGenerationOptions, cancellationToken).ConfigureAwait(false), + CodeGenerationOptions = await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false), ExtractOptions = fallbackOptions.Value.ExtractOptions, - CodeCleanupOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions.Value.CodeCleanupOptions, cancellationToken).ConfigureAwait(false), + CodeCleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false), }; } diff --git a/src/Workspaces/Core/Portable/Formatting/Formatter.cs b/src/Workspaces/Core/Portable/Formatting/Formatter.cs index 8741477c480fe..f8740a7d29618 100644 --- a/src/Workspaces/Core/Portable/Formatting/Formatter.cs +++ b/src/Workspaces/Core/Portable/Formatting/Formatter.cs @@ -338,7 +338,7 @@ internal static SyntaxFormattingOptions GetFormattingOptions(Workspace workspace else { syntaxFormattingOptions = null; - lineFormattingOptions = optionSet.GetLineFormattingOptions(document.Project.Language, fallbackOptions: null); + lineFormattingOptions = optionSet.GetLineFormattingOptions(document.Project.Language); } return (syntaxFormattingOptions, lineFormattingOptions); diff --git a/src/Workspaces/Core/Portable/Formatting/VisualBasic/VisualBasicSyntaxFormattingOptions.cs b/src/Workspaces/Core/Portable/Formatting/VisualBasic/VisualBasicSyntaxFormattingOptions.cs index 62b1381fe4635..4ad53c5aa718c 100644 --- a/src/Workspaces/Core/Portable/Formatting/VisualBasic/VisualBasicSyntaxFormattingOptions.cs +++ b/src/Workspaces/Core/Portable/Formatting/VisualBasic/VisualBasicSyntaxFormattingOptions.cs @@ -19,8 +19,8 @@ internal VisualBasicSyntaxFormattingOptions() { } - internal VisualBasicSyntaxFormattingOptions(IOptionsReader options, VisualBasicSyntaxFormattingOptions? fallbackOptions) - : base(options, fallbackOptions ?? Default, LanguageNames.VisualBasic) + internal VisualBasicSyntaxFormattingOptions(IOptionsReader options) + : base(options, LanguageNames.VisualBasic) { } } diff --git a/src/Workspaces/Core/Portable/Options/ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService.cs b/src/Workspaces/Core/Portable/Options/ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService.cs deleted file mode 100644 index 72b610b6153b1..0000000000000 --- a/src/Workspaces/Core/Portable/Options/ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CodeAnalysis.CodeGeneration; -using Microsoft.CodeAnalysis.Host; - -namespace Microsoft.CodeAnalysis.Options; - -/// -/// Enables legacy APIs to access global options from workspace. -/// Not available OOP. Only use in client code and when IGlobalOptionService can't be MEF imported. -/// Removal tracked by https://github.com/dotnet/roslyn/issues/60786 -/// -internal interface ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService : IWorkspaceService -{ - public CleanCodeGenerationOptionsProvider Provider { get; } -} diff --git a/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs b/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs deleted file mode 100644 index 586ca3474750a..0000000000000 --- a/src/Workspaces/Core/Portable/Options/LegacyGlobalCodeActionOptionsWorkspaceService.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Composition; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.AddImport; -using Microsoft.CodeAnalysis.CodeCleanup; -using Microsoft.CodeAnalysis.CodeGeneration; -using Microsoft.CodeAnalysis.CodeStyle; -using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles; -using Microsoft.CodeAnalysis.Formatting; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Simplification; -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.Options; - -/// -/// Enables legacy APIs to access global options from workspace. -/// -[ExportWorkspaceService(typeof(ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService)), Shared] -[method: ImportingConstructor] -[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class LegacyGlobalCleanCodeGenerationOptionsWorkspaceService(IGlobalOptionService globalOptions) : ILegacyGlobalCleanCodeGenerationOptionsWorkspaceService -{ - public CleanCodeGenerationOptionsProvider Provider { get; } = new ProviderImpl(globalOptions); - - private sealed class ProviderImpl(IOptionsReader options) : CleanCodeGenerationOptionsProvider - { - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetLineFormattingOptions(languageServices.Language, fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetDocumentFormattingOptions(fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetSyntaxFormattingOptions(languageServices)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetSimplifierOptions(languageServices)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetAddImportPlacementOptions(languageServices, allowInHiddenRegions: null, fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions: null, fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetCleanCodeGenerationOptions(languageServices, allowImportsInHiddenRegions: null, fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetCodeAndImportGenerationOptions(languageServices, allowImportsInHiddenRegions: null, fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetCodeGenerationOptions(languageServices, fallbackOptions: null)); - - ValueTask OptionsProvider.GetOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => ValueTaskFactory.FromResult(options.GetOption(NamingStyleOptions.NamingPreferences, languageServices.Language)); - } -} diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs index e9905374e7520..61bad38afbe05 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs @@ -49,14 +49,12 @@ private class Session public Session( SymbolicRenameLocations renameLocationSet, - CodeCleanupOptionsProvider fallbackOptions, Location renameSymbolDeclarationLocation, string replacementText, ImmutableArray nonConflictSymbolKeys, CancellationToken cancellationToken) { _renameLocationSet = renameLocationSet; - this.FallbackOptions = fallbackOptions; _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation; _originalText = renameLocationSet.Symbol.Name; _replacementText = replacementText; @@ -72,7 +70,6 @@ public Session( } private SymbolRenameOptions RenameOptions => _renameLocationSet.Options; - private CodeCleanupOptionsProvider FallbackOptions { get; } private readonly struct ConflictLocationInfo { @@ -206,7 +203,7 @@ .. conflictResolution.RelatedLocations } // Step 3: Simplify the project - conflictResolution.UpdateCurrentSolution(await renamedSpansTracker.SimplifyAsync(conflictResolution.CurrentSolution, documentsByProject, _replacementTextValid, _renameAnnotations, FallbackOptions, _cancellationToken).ConfigureAwait(false)); + conflictResolution.UpdateCurrentSolution(await renamedSpansTracker.SimplifyAsync(conflictResolution.CurrentSolution, documentsByProject, _replacementTextValid, _renameAnnotations, _cancellationToken).ConfigureAwait(false)); intermediateSolution = await conflictResolution.RemoveAllRenameAnnotationsAsync( intermediateSolution, documentsByProject, _renameAnnotations, _cancellationToken).ConfigureAwait(false); conflictResolution.UpdateCurrentSolution(intermediateSolution); diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index f2662fd3ba2ff..fdbcd2a022040 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -54,7 +54,6 @@ internal static async Task ResolveLightweightConflictsAsync( LightweightRenameLocations lightweightRenameLocations, string replacementText, ImmutableArray nonConflictSymbolKeys, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -70,8 +69,7 @@ internal static async Task ResolveLightweightConflictsAsync( var result = await client.TryInvokeAsync( solution, - (service, solutionInfo, callbackId, cancellationToken) => service.ResolveConflictsAsync(solutionInfo, callbackId, serializableSymbol, serializableLocationSet, replacementText, nonConflictSymbolKeys, cancellationToken), - callbackTarget: new RemoteOptionsProvider(solution.Services, fallbackOptions), + (service, solutionInfo, cancellationToken) => service.ResolveConflictsAsync(solutionInfo, serializableSymbol, serializableLocationSet, replacementText, nonConflictSymbolKeys, cancellationToken), cancellationToken).ConfigureAwait(false); if (result.HasValue && result.Value != null) @@ -86,7 +84,7 @@ internal static async Task ResolveLightweightConflictsAsync( return new ConflictResolution(WorkspacesResources.Failed_to_resolve_rename_conflicts); return await ResolveSymbolicLocationConflictsInCurrentProcessAsync( - heavyweightLocations, replacementText, nonConflictSymbolKeys, fallbackOptions, cancellationToken).ConfigureAwait(false); + heavyweightLocations, replacementText, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); } /// @@ -97,7 +95,6 @@ internal static async Task ResolveSymbolicLocationConflictsI SymbolicRenameLocations renameLocations, string replacementText, ImmutableArray nonConflictSymbolKeys, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // when someone e.g. renames a symbol from metadata through the API (IDE blocks this), we need to return @@ -109,14 +106,13 @@ internal static async Task ResolveSymbolicLocationConflictsI } var resolution = await ResolveMutableConflictsAsync( - renameLocations, fallbackOptions, renameSymbolDeclarationLocation, replacementText, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); + renameLocations, renameSymbolDeclarationLocation, replacementText, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); return resolution.ToConflictResolution(); } private static Task ResolveMutableConflictsAsync( SymbolicRenameLocations renameLocationSet, - CodeCleanupOptionsProvider fallbackOptions, Location renameSymbolDeclarationLocation, string replacementText, ImmutableArray nonConflictSymbolKeys, @@ -124,7 +120,7 @@ private static Task ResolveMutableConflictsAsync( { cancellationToken.ThrowIfCancellationRequested(); var session = new Session( - renameLocationSet, fallbackOptions, renameSymbolDeclarationLocation, replacementText, nonConflictSymbolKeys, cancellationToken); + renameLocationSet, renameSymbolDeclarationLocation, replacementText, nonConflictSymbolKeys, cancellationToken); return session.ResolveConflictsAsync(); } diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs index 7a71e5dd2b9a3..e4f4ef001984b 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs @@ -143,7 +143,7 @@ public IEnumerable DocumentIds } } - internal async Task SimplifyAsync(Solution solution, IEnumerable documentIds, bool replacementTextValid, AnnotationTable renameAnnotations, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + internal async Task SimplifyAsync(Solution solution, IEnumerable documentIds, bool replacementTextValid, AnnotationTable renameAnnotations, CancellationToken cancellationToken) { foreach (var documentId in documentIds) { @@ -153,7 +153,7 @@ internal async Task SimplifyAsync(Solution solution, IEnumerable - { - } - /// /// Runs the entire rename operation OOP and returns the final result. More efficient (due to less back and /// forth marshaling) when the intermediary results of rename are not needed. To get the individual parts of @@ -32,7 +28,6 @@ internal interface ICallback : IRemoteOptionsCallback /// ValueTask RenameSymbolAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, SerializableSymbolAndProjectId symbolAndProjectId, string replacementText, SymbolRenameOptions options, @@ -47,7 +42,6 @@ internal interface ICallback : IRemoteOptionsCallback ValueTask ResolveConflictsAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, SerializableSymbolAndProjectId symbolAndProjectId, SerializableRenameLocations renameLocationSet, string replacementText, @@ -55,19 +49,6 @@ internal interface ICallback : IRemoteOptionsCallback CancellationToken cancellationToken); } -[ExportRemoteServiceCallbackDispatcher(typeof(IRemoteRenamerService)), Shared] -internal sealed class RemoteRenamerServiceCallbackDispatcher : RemoteServiceCallbackDispatcher, IRemoteRenamerService.ICallback -{ - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RemoteRenamerServiceCallbackDispatcher() - { - } - - public ValueTask GetOptionsAsync(RemoteServiceCallbackId callbackId, string language, CancellationToken cancellationToken) - => ((RemoteOptionsProvider)GetCallback(callbackId)).GetOptionsAsync(language, cancellationToken); -} - [DataContract] internal readonly struct SerializableRenameLocation( TextSpan location, diff --git a/src/Workspaces/Core/Portable/Rename/LightweightRenameLocations.cs b/src/Workspaces/Core/Portable/Rename/LightweightRenameLocations.cs index bb8be6c42a690..15d6b885e6b8b 100644 --- a/src/Workspaces/Core/Portable/Rename/LightweightRenameLocations.cs +++ b/src/Workspaces/Core/Portable/Rename/LightweightRenameLocations.cs @@ -115,8 +115,8 @@ public static async Task FindRenameLocationsAsync( renameLocations.ReferencedSymbols.SelectAsArray(sym => SerializableSymbolAndProjectId.Dehydrate(solution, sym, cancellationToken))); } - public Task ResolveConflictsAsync(ISymbol symbol, string replacementText, ImmutableArray nonConflictSymbolKeys, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) - => ConflictResolver.ResolveLightweightConflictsAsync(symbol, this, replacementText, nonConflictSymbolKeys, fallbackOptions, cancellationToken); + public Task ResolveConflictsAsync(ISymbol symbol, string replacementText, ImmutableArray nonConflictSymbolKeys, CancellationToken cancellationToken) + => ConflictResolver.ResolveLightweightConflictsAsync(symbol, this, replacementText, nonConflictSymbolKeys, cancellationToken); public LightweightRenameLocations Filter(Func filter) => new( diff --git a/src/Workspaces/Core/Portable/Rename/Renamer.SyncNamespaceDocumentAction.cs b/src/Workspaces/Core/Portable/Rename/Renamer.SyncNamespaceDocumentAction.cs index 869e15d3728cf..dcb74146489ce 100644 --- a/src/Workspaces/Core/Portable/Rename/Renamer.SyncNamespaceDocumentAction.cs +++ b/src/Workspaces/Core/Portable/Rename/Renamer.SyncNamespaceDocumentAction.cs @@ -27,13 +27,11 @@ public static partial class Renamer internal sealed class SyncNamespaceDocumentAction : RenameDocumentAction { private readonly AnalysisResult _analysis; - private readonly CodeCleanupOptionsProvider _fallbackOptions; - private SyncNamespaceDocumentAction(AnalysisResult analysis, CodeCleanupOptionsProvider fallbackOptions) + private SyncNamespaceDocumentAction(AnalysisResult analysis) : base([]) { _analysis = analysis; - _fallbackOptions = fallbackOptions; } public override string GetDescription(CultureInfo? culture) @@ -42,7 +40,7 @@ public override string GetDescription(CultureInfo? culture) internal override async Task GetModifiedSolutionAsync(Document document, DocumentRenameOptions options, CancellationToken cancellationToken) { var changeNamespaceService = document.GetRequiredLanguageService(); - var solution = await changeNamespaceService.TryChangeTopLevelNamespacesAsync(document, _analysis.TargetNamespace, _fallbackOptions, cancellationToken).ConfigureAwait(false); + var solution = await changeNamespaceService.TryChangeTopLevelNamespacesAsync(document, _analysis.TargetNamespace, cancellationToken).ConfigureAwait(false); // If the solution fails to update fail silently. The user will see no large // negative impact from not doing this modification, and it's possible the document @@ -50,13 +48,13 @@ internal override async Task GetModifiedSolutionAsync(Document documen return solution ?? document.Project.Solution; } - public static SyncNamespaceDocumentAction? TryCreate(Document document, IReadOnlyList newFolders, CodeCleanupOptionsProvider fallbackOptions) + public static SyncNamespaceDocumentAction? TryCreate(Document document, IReadOnlyList newFolders) { var analysisResult = Analyze(document, newFolders); if (analysisResult.HasValue) { - return new SyncNamespaceDocumentAction(analysisResult.Value, fallbackOptions); + return new SyncNamespaceDocumentAction(analysisResult.Value); } return null; diff --git a/src/Workspaces/Core/Portable/Rename/Renamer.cs b/src/Workspaces/Core/Portable/Rename/Renamer.cs index 74704761139a6..1684a8d1f27e1 100644 --- a/src/Workspaces/Core/Portable/Rename/Renamer.cs +++ b/src/Workspaces/Core/Portable/Rename/Renamer.cs @@ -52,7 +52,7 @@ public static async Task RenameSymbolAsync( if (string.IsNullOrEmpty(newName)) throw new ArgumentException(WorkspacesResources._0_must_be_a_non_null_and_non_empty_string, nameof(newName)); - var resolution = await RenameSymbolAsync(solution, symbol, newName, options, CodeActionOptions.DefaultProvider, nonConflictSymbolKeys: default, cancellationToken).ConfigureAwait(false); + var resolution = await RenameSymbolAsync(solution, symbol, newName, options, nonConflictSymbolKeys: default, cancellationToken).ConfigureAwait(false); if (resolution.IsSuccessful) { @@ -96,24 +96,16 @@ public static Task RenameDocumentAsync( /// The new name for the document. Pass null or the same name to keep unchanged. /// Options used to configure rename of a type contained in the document that matches the document's name. /// The new set of folders for the property - public static Task RenameDocumentAsync( + public static async Task RenameDocumentAsync( Document document, DocumentRenameOptions options, string? newDocumentName, IReadOnlyList? newDocumentFolders = null, CancellationToken cancellationToken = default) { - return RenameDocumentAsync(document ?? throw new ArgumentNullException(nameof(document)), options, CodeActionOptions.DefaultProvider, newDocumentName, newDocumentFolders, cancellationToken); - } + if (document == null) + throw new ArgumentNullException(nameof(document)); - internal static async Task RenameDocumentAsync( - Document document, - DocumentRenameOptions options, - CodeCleanupOptionsProvider fallbackOptions, - string? newDocumentName, - IReadOnlyList? newDocumentFolders, - CancellationToken cancellationToken) - { if (document.Services.GetService() != null) { // Don't advertise that we can file rename generated documents that map to a different file. @@ -130,7 +122,7 @@ internal static async Task RenameDocumentAsync( if (newDocumentFolders != null && !newDocumentFolders.SequenceEqual(document.Folders)) { - var action = SyncNamespaceDocumentAction.TryCreate(document, newDocumentFolders, fallbackOptions); + var action = SyncNamespaceDocumentAction.TryCreate(document, newDocumentFolders); actions.AddIfNotNull(action); } @@ -154,7 +146,6 @@ internal static async Task RenameSymbolAsync( ISymbol symbol, string newName, SymbolRenameOptions options, - CodeCleanupOptionsProvider fallbackOptions, ImmutableArray nonConflictSymbolKeys, CancellationToken cancellationToken) { @@ -173,15 +164,13 @@ internal static async Task RenameSymbolAsync( { var result = await client.TryInvokeAsync( solution, - (service, solutionInfo, callbackId, cancellationToken) => service.RenameSymbolAsync( + (service, solutionInfo, cancellationToken) => service.RenameSymbolAsync( solutionInfo, - callbackId, serializedSymbol, newName, options, nonConflictSymbolKeys, cancellationToken), - callbackTarget: new RemoteOptionsProvider(solution.Services, fallbackOptions), cancellationToken).ConfigureAwait(false); if (result.HasValue && result.Value != null) @@ -193,7 +182,7 @@ internal static async Task RenameSymbolAsync( } return await RenameSymbolInCurrentProcessAsync( - solution, symbol, newName, options, fallbackOptions, + solution, symbol, newName, options, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); } @@ -202,7 +191,6 @@ private static async Task RenameSymbolInCurrentProcessAsync( ISymbol symbol, string newName, SymbolRenameOptions options, - CodeCleanupOptionsProvider cleanupOptions, ImmutableArray nonConflictSymbolKeys, CancellationToken cancellationToken) { @@ -217,6 +205,6 @@ private static async Task RenameSymbolInCurrentProcessAsync( // without having to go through any intermediary LightweightTypes. var renameLocations = await SymbolicRenameLocations.FindLocationsInCurrentProcessAsync(symbol, solution, options, cancellationToken).ConfigureAwait(false); return await ConflictResolver.ResolveSymbolicLocationConflictsInCurrentProcessAsync( - renameLocations, newName, nonConflictSymbolKeys, cleanupOptions, cancellationToken).ConfigureAwait(false); + renameLocations, newName, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); } } diff --git a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs index e6c461f6aa2af..548781a5a2745 100644 --- a/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs +++ b/src/Workspaces/CoreTestUtilities/Workspaces/TestWorkspace`1.cs @@ -116,6 +116,9 @@ internal TestWorkspace( } } + /// + /// Use to set specified editorconfig options as . + /// public void SetAnalyzerFallbackOptions(string language, params (string name, string value)[] options) { SetCurrentSolution( diff --git a/src/Workspaces/Remote/Core/ServiceDescriptors.cs b/src/Workspaces/Remote/Core/ServiceDescriptors.cs index 8364dc78227d4..cc577e5aecbef 100644 --- a/src/Workspaces/Remote/Core/ServiceDescriptors.cs +++ b/src/Workspaces/Remote/Core/ServiceDescriptors.cs @@ -57,13 +57,13 @@ internal sealed class ServiceDescriptors (typeof(IRemoteAssetSynchronizationService), null), (typeof(IRemoteAsynchronousOperationListenerService), null), (typeof(IRemoteCodeLensReferencesService), null), - (typeof(IRemoteConvertTupleToStructCodeRefactoringService), typeof(IRemoteConvertTupleToStructCodeRefactoringService.ICallback)), + (typeof(IRemoteConvertTupleToStructCodeRefactoringService), null), (typeof(IRemoteDependentTypeFinderService), null), (typeof(IRemoteDesignerAttributeDiscoveryService), typeof(IRemoteDesignerAttributeDiscoveryService.ICallback)), (typeof(IRemoteDiagnosticAnalyzerService), null), (typeof(IRemoteDocumentHighlightsService), null), (typeof(IRemoteEditAndContinueService), typeof(IRemoteEditAndContinueService.ICallback)), - (typeof(IRemoteEncapsulateFieldService), typeof(IRemoteEncapsulateFieldService.ICallback)), + (typeof(IRemoteEncapsulateFieldService), null), (typeof(IRemoteExtensionMethodImportCompletionService), null), (typeof(IRemoteFindUsagesService), typeof(IRemoteFindUsagesService.ICallback)), (typeof(IRemoteFullyQualifyService), null), @@ -74,7 +74,7 @@ internal sealed class ServiceDescriptors (typeof(IRemoteNavigateToSearchService), typeof(IRemoteNavigateToSearchService.ICallback)), (typeof(IRemoteNavigationBarItemService), null), (typeof(IRemoteProcessTelemetryService), null), - (typeof(IRemoteRenamerService), typeof(IRemoteRenamerService.ICallback)), + (typeof(IRemoteRenamerService), null), (typeof(IRemoteSemanticClassificationService), null), (typeof(IRemoteSemanticSearchService), typeof(IRemoteSemanticSearchService.ICallback)), (typeof(IRemoteSourceGenerationService), null), diff --git a/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs b/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs index ac81e67205803..132962f789182 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/ConvertTupleToStructCodeRefactoringProvider/RemoteConvertTupleToStructCodeRefactoringService.cs @@ -18,18 +18,17 @@ namespace Microsoft.CodeAnalysis.Remote { - internal sealed class RemoteConvertTupleToStructCodeRefactoringService(in BrokeredServiceBase.ServiceConstructionArguments arguments, RemoteCallback callback) + internal sealed class RemoteConvertTupleToStructCodeRefactoringService(in BrokeredServiceBase.ServiceConstructionArguments arguments) : BrokeredServiceBase(arguments), IRemoteConvertTupleToStructCodeRefactoringService { - internal sealed class Factory : FactoryBase + internal sealed class Factory : FactoryBase { - protected override IRemoteConvertTupleToStructCodeRefactoringService CreateService(in ServiceConstructionArguments arguments, RemoteCallback callback) - => new RemoteConvertTupleToStructCodeRefactoringService(arguments, callback); + protected override IRemoteConvertTupleToStructCodeRefactoringService CreateService(in ServiceConstructionArguments arguments) + => new RemoteConvertTupleToStructCodeRefactoringService(arguments); } public ValueTask ConvertToStructAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, DocumentId documentId, TextSpan span, Scope scope, @@ -41,11 +40,10 @@ public ValueTask ConvertToStructAsync( var document = solution.GetRequiredDocument(documentId); var service = document.GetRequiredLanguageService(); - var fallbackOptions = GetClientOptionsProvider(callback, callbackId).ToCleanCodeGenerationOptionsProvider(); - var updatedSolution = await service.ConvertToStructAsync(document, span, scope, fallbackOptions, isRecord, cancellationToken).ConfigureAwait(false); + var updatedSolution = await service.ConvertToStructAsync(document, span, scope, isRecord, cancellationToken).ConfigureAwait(false); - var cleanedSolution = await CleanupAsync(solution, updatedSolution, fallbackOptions, cancellationToken).ConfigureAwait(false); + var cleanedSolution = await CleanupAsync(solution, updatedSolution, cancellationToken).ConfigureAwait(false); var documentTextChanges = await RemoteUtilities.GetDocumentTextChangesAsync( solution, cleanedSolution, cancellationToken).ConfigureAwait(false); @@ -75,25 +73,24 @@ public ValueTask ConvertToStructAsync( throw ExceptionUtilities.Unreachable(); } - private static async Task CleanupAsync(Solution oldSolution, Solution newSolution, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private static async Task CleanupAsync(Solution oldSolution, Solution newSolution, CancellationToken cancellationToken) { var changes = newSolution.GetChangedDocuments(oldSolution); var final = newSolution; var changedDocuments = await ProducerConsumer<(DocumentId documentId, SyntaxNode newRoot)>.RunParallelAsync( source: changes, - produceItems: static async (docId, callback, args, cancellationToken) => + produceItems: static async (docId, callback, newSolution, cancellationToken) => { - var (newSolution, fallbackOptions) = args; var document = newSolution.GetRequiredDocument(docId); - var options = await document.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false); var cleaned = await CodeAction.CleanupDocumentAsync(document, options, cancellationToken).ConfigureAwait(false); var cleanedRoot = await cleaned.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); callback((docId, cleanedRoot)); }, - args: (newSolution, fallbackOptions), + args: newSolution, cancellationToken).ConfigureAwait(false); return newSolution.WithDocumentSyntaxRoots(changedDocuments); diff --git a/src/Workspaces/Remote/ServiceHub/Services/EncapsulateField/RemoteEncapsulateFieldService.cs b/src/Workspaces/Remote/ServiceHub/Services/EncapsulateField/RemoteEncapsulateFieldService.cs index 0879780f6b6e8..846177c6f65b8 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/EncapsulateField/RemoteEncapsulateFieldService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/EncapsulateField/RemoteEncapsulateFieldService.cs @@ -14,18 +14,17 @@ namespace Microsoft.CodeAnalysis.Remote { - internal sealed class RemoteEncapsulateFieldService(in BrokeredServiceBase.ServiceConstructionArguments arguments, RemoteCallback callback) + internal sealed class RemoteEncapsulateFieldService(in BrokeredServiceBase.ServiceConstructionArguments arguments) : BrokeredServiceBase(arguments), IRemoteEncapsulateFieldService { - internal sealed class Factory : FactoryBase + internal sealed class Factory : FactoryBase { - protected override IRemoteEncapsulateFieldService CreateService(in ServiceConstructionArguments arguments, RemoteCallback callback) - => new RemoteEncapsulateFieldService(arguments, callback); + protected override IRemoteEncapsulateFieldService CreateService(in ServiceConstructionArguments arguments) + => new RemoteEncapsulateFieldService(arguments); } public ValueTask)>> EncapsulateFieldsAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, DocumentId documentId, ImmutableArray fieldSymbolKeys, bool updateReferences, @@ -48,10 +47,9 @@ protected override IRemoteEncapsulateFieldService CreateService(in ServiceConstr } var service = document.GetRequiredLanguageService(); - var fallbackOptions = GetClientOptionsProvider(callback, callbackId).ToCleanCodeGenerationOptionsProvider(); var newSolution = await service.EncapsulateFieldsAsync( - document, fields.ToImmutable(), fallbackOptions, updateReferences, cancellationToken).ConfigureAwait(false); + document, fields.ToImmutable(), updateReferences, cancellationToken).ConfigureAwait(false); return await RemoteUtilities.GetDocumentTextChangesAsync( solution, newSolution, cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/Remote/ServiceHub/Services/Renamer/RemoteRenamerService.cs b/src/Workspaces/Remote/ServiceHub/Services/Renamer/RemoteRenamerService.cs index 9b875a22f48d7..25496392fd701 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/Renamer/RemoteRenamerService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/Renamer/RemoteRenamerService.cs @@ -5,24 +5,22 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.Rename; using Microsoft.CodeAnalysis.Rename.ConflictEngine; namespace Microsoft.CodeAnalysis.Remote { - internal sealed partial class RemoteRenamerService(in BrokeredServiceBase.ServiceConstructionArguments arguments, RemoteCallback callback) + internal sealed partial class RemoteRenamerService(in BrokeredServiceBase.ServiceConstructionArguments arguments) : BrokeredServiceBase(arguments), IRemoteRenamerService { - internal sealed class Factory : FactoryBase + internal sealed class Factory : FactoryBase { - protected override IRemoteRenamerService CreateService(in ServiceConstructionArguments arguments, RemoteCallback callback) - => new RemoteRenamerService(arguments, callback); + protected override IRemoteRenamerService CreateService(in ServiceConstructionArguments arguments) + => new RemoteRenamerService(arguments); } public ValueTask RenameSymbolAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, SerializableSymbolAndProjectId symbolAndProjectId, string newName, SymbolRenameOptions options, @@ -37,10 +35,8 @@ protected override IRemoteRenamerService CreateService(in ServiceConstructionArg if (symbol == null) return null; - var fallbackOptions = GetClientOptionsProvider(callback, callbackId).ToCodeCleanupOptionsProvider(); - var result = await Renamer.RenameSymbolAsync( - solution, symbol, newName, options, fallbackOptions, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); + solution, symbol, newName, options, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); return await result.DehydrateAsync(cancellationToken).ConfigureAwait(false); }, cancellationToken); @@ -73,7 +69,6 @@ protected override IRemoteRenamerService CreateService(in ServiceConstructionArg public ValueTask ResolveConflictsAsync( Checksum solutionChecksum, - RemoteServiceCallbackId callbackId, SerializableSymbolAndProjectId symbolAndProjectId, SerializableRenameLocations serializableLocations, string replacementText, @@ -91,10 +86,8 @@ protected override IRemoteRenamerService CreateService(in ServiceConstructionArg if (locations is null) return null; - var fallbackOptions = GetClientOptionsProvider(callback, callbackId).ToCodeCleanupOptionsProvider(); - var result = await ConflictResolver.ResolveSymbolicLocationConflictsInCurrentProcessAsync( - locations, replacementText, nonConflictSymbolKeys, fallbackOptions, cancellationToken).ConfigureAwait(false); + locations, replacementText, nonConflictSymbolKeys, cancellationToken).ConfigureAwait(false); return await result.DehydrateAsync(cancellationToken).ConfigureAwait(false); }, cancellationToken); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeGeneration/CSharpCodeGenerationOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeGeneration/CSharpCodeGenerationOptions.cs index 1ca9ab3a4f5d8..a428cc68f2dde 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeGeneration/CSharpCodeGenerationOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeGeneration/CSharpCodeGenerationOptions.cs @@ -48,18 +48,18 @@ public CSharpCodeGenerationOptions() { } - internal CSharpCodeGenerationOptions(IOptionsReader options, CSharpCodeGenerationOptions? fallbackOptions) - : base(options, fallbackOptions ??= Default, LanguageNames.CSharp) + internal CSharpCodeGenerationOptions(IOptionsReader options) + : base(options, LanguageNames.CSharp) { - PreferExpressionBodiedMethods = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedMethods, fallbackOptions.PreferExpressionBodiedMethods); - PreferExpressionBodiedAccessors = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, fallbackOptions.PreferExpressionBodiedAccessors); - PreferExpressionBodiedProperties = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, fallbackOptions.PreferExpressionBodiedProperties); - PreferExpressionBodiedIndexers = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, fallbackOptions.PreferExpressionBodiedIndexers); - PreferExpressionBodiedConstructors = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, fallbackOptions.PreferExpressionBodiedConstructors); - PreferExpressionBodiedOperators = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, fallbackOptions.PreferExpressionBodiedOperators); - PreferExpressionBodiedLocalFunctions = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, fallbackOptions.PreferExpressionBodiedLocalFunctions); - PreferExpressionBodiedLambdas = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, fallbackOptions.PreferExpressionBodiedLambdas); - PreferStaticLocalFunction = options.GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction, fallbackOptions.PreferStaticLocalFunction); - NamespaceDeclarations = options.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations, fallbackOptions.NamespaceDeclarations); + PreferExpressionBodiedMethods = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedMethods); + PreferExpressionBodiedAccessors = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors); + PreferExpressionBodiedProperties = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties); + PreferExpressionBodiedIndexers = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers); + PreferExpressionBodiedConstructors = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors); + PreferExpressionBodiedOperators = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedOperators); + PreferExpressionBodiedLocalFunctions = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions); + PreferExpressionBodiedLambdas = options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas); + PreferStaticLocalFunction = options.GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction); + NamespaceDeclarations = options.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs index d8572dffba6c5..78defd27df2ce 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormatting.cs @@ -40,7 +40,7 @@ public override SyntaxFormattingOptions DefaultOptions => CSharpSyntaxFormattingOptions.Default; public override SyntaxFormattingOptions GetFormattingOptions(IOptionsReader options) - => new CSharpSyntaxFormattingOptions(options, fallbackOptions: null); + => new CSharpSyntaxFormattingOptions(options); protected override IFormattingResult CreateAggregatedFormattingResult(SyntaxNode node, IList results, TextSpanMutableIntervalTree? formattingSpans = null) => new AggregatedFormattingResult(node, results, formattingSpans); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormattingOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormattingOptions.cs index e2bc3c1462812..fdedddbada910 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormattingOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/CSharpSyntaxFormattingOptions.cs @@ -67,51 +67,51 @@ public CSharpSyntaxFormattingOptions() { } - public CSharpSyntaxFormattingOptions(IOptionsReader options, CSharpSyntaxFormattingOptions? fallbackOptions) - : base(options, fallbackOptions ??= Default, LanguageNames.CSharp) + public CSharpSyntaxFormattingOptions(IOptionsReader options) + : base(options, LanguageNames.CSharp) { Spacing = - (options.GetOption(CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, fallbackOptions.Spacing.HasFlag(SpacePlacement.IgnoreAroundVariableDeclaration)) ? SpacePlacement.IgnoreAroundVariableDeclaration : 0) | - (options.GetOption(CSharpFormattingOptions2.SpacingAfterMethodDeclarationName, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterMethodDeclarationName)) ? SpacePlacement.AfterMethodDeclarationName : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBetweenEmptyMethodDeclarationParentheses, fallbackOptions.Spacing.HasFlag(SpacePlacement.BetweenEmptyMethodDeclarationParentheses)) ? SpacePlacement.BetweenEmptyMethodDeclarationParentheses : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceWithinMethodDeclarationParenthesis, fallbackOptions.Spacing.HasFlag(SpacePlacement.WithinMethodDeclarationParenthesis)) ? SpacePlacement.WithinMethodDeclarationParenthesis : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterMethodCallName, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterMethodCallName)) ? SpacePlacement.AfterMethodCallName : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, fallbackOptions.Spacing.HasFlag(SpacePlacement.BetweenEmptyMethodCallParentheses)) ? SpacePlacement.BetweenEmptyMethodCallParentheses : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, fallbackOptions.Spacing.HasFlag(SpacePlacement.WithinMethodCallParentheses)) ? SpacePlacement.WithinMethodCallParentheses : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterControlFlowStatementKeyword, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterControlFlowStatementKeyword)) ? SpacePlacement.AfterControlFlowStatementKeyword : 0) | - options.GetOption(CSharpFormattingOptions2.SpaceBetweenParentheses, fallbackOptions.Spacing.ToSpacingWithinParentheses()).ToSpacePlacement() | - (options.GetOption(CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement, fallbackOptions.Spacing.HasFlag(SpacePlacement.BeforeSemicolonsInForStatement)) ? SpacePlacement.BeforeSemicolonsInForStatement : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterSemicolonsInForStatement)) ? SpacePlacement.AfterSemicolonsInForStatement : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterCast, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterCast)) ? SpacePlacement.AfterCast : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBeforeOpenSquareBracket, fallbackOptions.Spacing.HasFlag(SpacePlacement.BeforeOpenSquareBracket)) ? SpacePlacement.BeforeOpenSquareBracket : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBetweenEmptySquareBrackets, fallbackOptions.Spacing.HasFlag(SpacePlacement.BetweenEmptySquareBrackets)) ? SpacePlacement.BetweenEmptySquareBrackets : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceWithinSquareBrackets, fallbackOptions.Spacing.HasFlag(SpacePlacement.WithinSquareBrackets)) ? SpacePlacement.WithinSquareBrackets : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterColonInBaseTypeDeclaration, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterColonInBaseTypeDeclaration)) ? SpacePlacement.AfterColonInBaseTypeDeclaration : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBeforeColonInBaseTypeDeclaration, fallbackOptions.Spacing.HasFlag(SpacePlacement.BeforeColonInBaseTypeDeclaration)) ? SpacePlacement.BeforeColonInBaseTypeDeclaration : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterComma, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterComma)) ? SpacePlacement.AfterComma : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBeforeComma, fallbackOptions.Spacing.HasFlag(SpacePlacement.BeforeComma)) ? SpacePlacement.BeforeComma : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceAfterDot, fallbackOptions.Spacing.HasFlag(SpacePlacement.AfterDot)) ? SpacePlacement.AfterDot : 0) | - (options.GetOption(CSharpFormattingOptions2.SpaceBeforeDot, fallbackOptions.Spacing.HasFlag(SpacePlacement.BeforeDot)) ? SpacePlacement.BeforeDot : 0); - SpacingAroundBinaryOperator = options.GetOption(CSharpFormattingOptions2.SpacingAroundBinaryOperator, fallbackOptions.SpacingAroundBinaryOperator); + (options.GetOption(CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration) ? SpacePlacement.IgnoreAroundVariableDeclaration : 0) | + (options.GetOption(CSharpFormattingOptions2.SpacingAfterMethodDeclarationName) ? SpacePlacement.AfterMethodDeclarationName : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBetweenEmptyMethodDeclarationParentheses) ? SpacePlacement.BetweenEmptyMethodDeclarationParentheses : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceWithinMethodDeclarationParenthesis) ? SpacePlacement.WithinMethodDeclarationParenthesis : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterMethodCallName) ? SpacePlacement.AfterMethodCallName : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses) ? SpacePlacement.BetweenEmptyMethodCallParentheses : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceWithinMethodCallParentheses) ? SpacePlacement.WithinMethodCallParentheses : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterControlFlowStatementKeyword) ? SpacePlacement.AfterControlFlowStatementKeyword : 0) | + options.GetOption(CSharpFormattingOptions2.SpaceBetweenParentheses).ToSpacePlacement() | + (options.GetOption(CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement) ? SpacePlacement.BeforeSemicolonsInForStatement : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement) ? SpacePlacement.AfterSemicolonsInForStatement : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterCast) ? SpacePlacement.AfterCast : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBeforeOpenSquareBracket) ? SpacePlacement.BeforeOpenSquareBracket : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBetweenEmptySquareBrackets) ? SpacePlacement.BetweenEmptySquareBrackets : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceWithinSquareBrackets) ? SpacePlacement.WithinSquareBrackets : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterColonInBaseTypeDeclaration) ? SpacePlacement.AfterColonInBaseTypeDeclaration : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBeforeColonInBaseTypeDeclaration) ? SpacePlacement.BeforeColonInBaseTypeDeclaration : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterComma) ? SpacePlacement.AfterComma : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBeforeComma) ? SpacePlacement.BeforeComma : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceAfterDot) ? SpacePlacement.AfterDot : 0) | + (options.GetOption(CSharpFormattingOptions2.SpaceBeforeDot) ? SpacePlacement.BeforeDot : 0); + SpacingAroundBinaryOperator = options.GetOption(CSharpFormattingOptions2.SpacingAroundBinaryOperator); NewLines = - (options.GetOption(CSharpFormattingOptions2.NewLineForMembersInObjectInit, fallbackOptions.NewLines.HasFlag(NewLinePlacement.BeforeMembersInObjectInitializers)) ? NewLinePlacement.BeforeMembersInObjectInitializers : 0) | - (options.GetOption(CSharpFormattingOptions2.NewLineForMembersInAnonymousTypes, fallbackOptions.NewLines.HasFlag(NewLinePlacement.BeforeMembersInAnonymousTypes)) ? NewLinePlacement.BeforeMembersInAnonymousTypes : 0) | - (options.GetOption(CSharpFormattingOptions2.NewLineForElse, fallbackOptions.NewLines.HasFlag(NewLinePlacement.BeforeElse)) ? NewLinePlacement.BeforeElse : 0) | - (options.GetOption(CSharpFormattingOptions2.NewLineForCatch, fallbackOptions.NewLines.HasFlag(NewLinePlacement.BeforeCatch)) ? NewLinePlacement.BeforeCatch : 0) | - (options.GetOption(CSharpFormattingOptions2.NewLineForFinally, fallbackOptions.NewLines.HasFlag(NewLinePlacement.BeforeFinally)) ? NewLinePlacement.BeforeFinally : 0) | - options.GetOption(CSharpFormattingOptions2.NewLineBeforeOpenBrace, fallbackOptions.NewLines.ToNewLineBeforeOpenBracePlacement()).ToNewLinePlacement() | - (options.GetOption(CSharpFormattingOptions2.NewLineForClausesInQuery, fallbackOptions.NewLines.HasFlag(NewLinePlacement.BetweenQueryExpressionClauses)) ? NewLinePlacement.BetweenQueryExpressionClauses : 0); - LabelPositioning = options.GetOption(CSharpFormattingOptions2.LabelPositioning, fallbackOptions.LabelPositioning); + (options.GetOption(CSharpFormattingOptions2.NewLineForMembersInObjectInit) ? NewLinePlacement.BeforeMembersInObjectInitializers : 0) | + (options.GetOption(CSharpFormattingOptions2.NewLineForMembersInAnonymousTypes) ? NewLinePlacement.BeforeMembersInAnonymousTypes : 0) | + (options.GetOption(CSharpFormattingOptions2.NewLineForElse) ? NewLinePlacement.BeforeElse : 0) | + (options.GetOption(CSharpFormattingOptions2.NewLineForCatch) ? NewLinePlacement.BeforeCatch : 0) | + (options.GetOption(CSharpFormattingOptions2.NewLineForFinally) ? NewLinePlacement.BeforeFinally : 0) | + options.GetOption(CSharpFormattingOptions2.NewLineBeforeOpenBrace).ToNewLinePlacement() | + (options.GetOption(CSharpFormattingOptions2.NewLineForClausesInQuery) ? NewLinePlacement.BetweenQueryExpressionClauses : 0); + LabelPositioning = options.GetOption(CSharpFormattingOptions2.LabelPositioning); Indentation = - (options.GetOption(CSharpFormattingOptions2.IndentBraces, fallbackOptions.Indentation.HasFlag(IndentationPlacement.Braces)) ? IndentationPlacement.Braces : 0) | - (options.GetOption(CSharpFormattingOptions2.IndentBlock, fallbackOptions.Indentation.HasFlag(IndentationPlacement.BlockContents)) ? IndentationPlacement.BlockContents : 0) | - (options.GetOption(CSharpFormattingOptions2.IndentSwitchCaseSection, fallbackOptions.Indentation.HasFlag(IndentationPlacement.SwitchCaseContents)) ? IndentationPlacement.SwitchCaseContents : 0) | - (options.GetOption(CSharpFormattingOptions2.IndentSwitchCaseSectionWhenBlock, fallbackOptions.Indentation.HasFlag(IndentationPlacement.SwitchCaseContentsWhenBlock)) ? IndentationPlacement.SwitchCaseContentsWhenBlock : 0) | - (options.GetOption(CSharpFormattingOptions2.IndentSwitchSection, fallbackOptions.Indentation.HasFlag(IndentationPlacement.SwitchSection)) ? IndentationPlacement.SwitchSection : 0); - WrappingKeepStatementsOnSingleLine = options.GetOption(CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, fallbackOptions.WrappingKeepStatementsOnSingleLine); - WrappingPreserveSingleLine = options.GetOption(CSharpFormattingOptions2.WrappingPreserveSingleLine, fallbackOptions.WrappingPreserveSingleLine); - NamespaceDeclarations = options.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations, fallbackOptions.NamespaceDeclarations); - PreferTopLevelStatements = options.GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements, fallbackOptions.PreferTopLevelStatements); - CollectionExpressionWrappingLength = options.GetOption(CSharpFormattingOptions2.CollectionExpressionWrappingLength, fallbackOptions.CollectionExpressionWrappingLength); + (options.GetOption(CSharpFormattingOptions2.IndentBraces) ? IndentationPlacement.Braces : 0) | + (options.GetOption(CSharpFormattingOptions2.IndentBlock) ? IndentationPlacement.BlockContents : 0) | + (options.GetOption(CSharpFormattingOptions2.IndentSwitchCaseSection) ? IndentationPlacement.SwitchCaseContents : 0) | + (options.GetOption(CSharpFormattingOptions2.IndentSwitchCaseSectionWhenBlock) ? IndentationPlacement.SwitchCaseContentsWhenBlock : 0) | + (options.GetOption(CSharpFormattingOptions2.IndentSwitchSection) ? IndentationPlacement.SwitchSection : 0); + WrappingKeepStatementsOnSingleLine = options.GetOption(CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine); + WrappingPreserveSingleLine = options.GetOption(CSharpFormattingOptions2.WrappingPreserveSingleLine); + NamespaceDeclarations = options.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations); + PreferTopLevelStatements = options.GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements); + CollectionExpressionWrappingLength = options.GetOption(CSharpFormattingOptions2.CollectionExpressionWrappingLength); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplification.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplification.cs index 5eace49fe5914..be301178243cb 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplification.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplification.cs @@ -15,5 +15,5 @@ public override SimplifierOptions DefaultOptions => CSharpSimplifierOptions.Default; public override SimplifierOptions GetSimplifierOptions(IOptionsReader options) - => new CSharpSimplifierOptions(options, fallbackOptions: null); + => new CSharpSimplifierOptions(options); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplifierOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplifierOptions.cs index 89d9f49b61beb..e52fe6aa0b0eb 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplifierOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/CSharpSimplifierOptions.cs @@ -33,16 +33,16 @@ public CSharpSimplifierOptions() { } - public CSharpSimplifierOptions(IOptionsReader options, CSharpSimplifierOptions? fallbackOptions) - : base(options, fallbackOptions ??= Default, LanguageNames.CSharp) + public CSharpSimplifierOptions(IOptionsReader options) + : base(options, LanguageNames.CSharp) { - VarForBuiltInTypes = options.GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes, fallbackOptions.VarForBuiltInTypes); - VarWhenTypeIsApparent = options.GetOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent, fallbackOptions.VarWhenTypeIsApparent); - VarElsewhere = options.GetOption(CSharpCodeStyleOptions.VarElsewhere, fallbackOptions.VarElsewhere); - PreferSimpleDefaultExpression = options.GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression, fallbackOptions.PreferSimpleDefaultExpression); - AllowEmbeddedStatementsOnSameLine = options.GetOption(CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, fallbackOptions.AllowEmbeddedStatementsOnSameLine); - PreferBraces = options.GetOption(CSharpCodeStyleOptions.PreferBraces, fallbackOptions.PreferBraces); - PreferThrowExpression = options.GetOption(CSharpCodeStyleOptions.PreferThrowExpression, fallbackOptions.PreferThrowExpression); + VarForBuiltInTypes = options.GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes); + VarWhenTypeIsApparent = options.GetOption(CSharpCodeStyleOptions.VarWhenTypeIsApparent); + VarElsewhere = options.GetOption(CSharpCodeStyleOptions.VarElsewhere); + PreferSimpleDefaultExpression = options.GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression); + AllowEmbeddedStatementsOnSameLine = options.GetOption(CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine); + PreferBraces = options.GetOption(CSharpCodeStyleOptions.PreferBraces); + PreferThrowExpression = options.GetOption(CSharpCodeStyleOptions.PreferThrowExpression); } public UseVarPreference GetUseVarPreference() diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/AddImport/AddImportPlacementOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/AddImport/AddImportPlacementOptions.cs index 50e629b94c2bf..6311026c4d17e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/AddImport/AddImportPlacementOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/AddImport/AddImportPlacementOptions.cs @@ -49,13 +49,13 @@ internal interface AddImportPlacementOptionsProvider internal static partial class AddImportPlacementOptionsProviders { #if !CODE_STYLE - public static AddImportPlacementOptions GetAddImportPlacementOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowInHiddenRegions, AddImportPlacementOptions? fallbackOptions) - => languageServices.GetRequiredService().GetAddImportOptions(options, allowInHiddenRegions ?? AddImportPlacementOptions.Default.AllowInHiddenRegions, fallbackOptions); + public static AddImportPlacementOptions GetAddImportPlacementOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowInHiddenRegions) + => languageServices.GetRequiredService().GetAddImportOptions(options, allowInHiddenRegions ?? AddImportPlacementOptions.Default.AllowInHiddenRegions); - public static async ValueTask GetAddImportPlacementOptionsAsync(this Document document, AddImportPlacementOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetAddImportPlacementOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetAddImportPlacementOptions(document.Project.Services, document.AllowImportsInHiddenRegions(), fallbackOptions); + return configOptions.GetAddImportPlacementOptions(document.Project.Services, document.AllowImportsInHiddenRegions()); } // Normally we don't allow generation into a hidden region in the file. However, if we have a @@ -63,8 +63,5 @@ public static async ValueTask GetAddImportPlacementOp // our edit to their domain appropriate. public static bool AllowImportsInHiddenRegions(this Document document) => document.Services.GetService()?.SupportsMappingImportDirectives == true; - - public static async ValueTask GetAddImportPlacementOptionsAsync(this Document document, AddImportPlacementOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await GetAddImportPlacementOptionsAsync(document, await fallbackOptionsProvider.GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); #endif } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs index 6ea3b329423cb..adbddd1473239 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeCleanup/CodeCleanupOptions.cs @@ -84,32 +84,20 @@ async ValueTask OptionsProvider new() { FormattingOptions = options.GetSyntaxFormattingOptions(languageServices), SimplifierOptions = options.GetSimplifierOptions(languageServices), - AddImportOptions = options.GetAddImportPlacementOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions?.AddImportOptions), - DocumentFormattingOptions = options.GetDocumentFormattingOptions(fallbackOptions?.DocumentFormattingOptions), + AddImportOptions = options.GetAddImportPlacementOptions(languageServices, allowImportsInHiddenRegions), + DocumentFormattingOptions = options.GetDocumentFormattingOptions(), }; - public static async ValueTask GetCodeCleanupOptionsAsync(this Document document, CodeCleanupOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetCodeCleanupOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetCodeCleanupOptions(document.Project.Services, document.AllowImportsInHiddenRegions(), fallbackOptions); + return configOptions.GetCodeCleanupOptions(document.Project.Services, document.AllowImportsInHiddenRegions()); } - - public static async ValueTask GetCodeCleanupOptionsAsync(this Document document, CodeCleanupOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await document.GetCodeCleanupOptionsAsync(await ((OptionsProvider)fallbackOptionsProvider).GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); - - private sealed class Provider(OptionsProvider provider) : AbstractCodeCleanupOptionsProvider - { - public override ValueTask GetCodeCleanupOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => provider.GetOptionsAsync(languageServices, cancellationToken); - } - - public static CodeCleanupOptionsProvider ToCodeCleanupOptionsProvider(this OptionsProvider provider) - => new Provider(provider); #endif } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CleanCodeGenerationOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CleanCodeGenerationOptions.cs index 888a817226cc8..344c67e28c7c5 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CleanCodeGenerationOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CleanCodeGenerationOptions.cs @@ -73,23 +73,11 @@ async ValueTask OptionsProvider. internal static class CleanCodeGenerationOptionsProviders { - public static async ValueTask GetCleanCodeGenerationOptionsAsync(this Document document, CleanCodeGenerationOptions fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetCleanCodeGenerationOptionsAsync(this Document document, CancellationToken cancellationToken) => new() { - GenerationOptions = await document.GetCodeGenerationOptionsAsync(fallbackOptions.GenerationOptions, cancellationToken).ConfigureAwait(false), - CleanupOptions = await document.GetCodeCleanupOptionsAsync(fallbackOptions.CleanupOptions, cancellationToken).ConfigureAwait(false) + GenerationOptions = await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false), + CleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false) }; - - public static async ValueTask GetCleanCodeGenerationOptionsAsync(this Document document, CleanCodeGenerationOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await document.GetCleanCodeGenerationOptionsAsync(await ((OptionsProvider)fallbackOptionsProvider).GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); - - private sealed class Provider(OptionsProvider provider) : AbstractCleanCodeGenerationOptionsProvider - { - public override ValueTask GetCleanCodeGenerationOptionsAsync(LanguageServices languageServices, CancellationToken cancellationToken) - => provider.GetOptionsAsync(languageServices, cancellationToken); - } - - public static CleanCodeGenerationOptionsProvider ToCleanCodeGenerationOptionsProvider(this OptionsProvider provider) - => new Provider(provider); } #endif diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CodeGenerationOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CodeGenerationOptions.cs index 39332a9f6ceee..bdfaf6d61257b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CodeGenerationOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeGeneration/CodeGenerationOptions.cs @@ -34,9 +34,9 @@ private protected CodeGenerationOptions() { } - private protected CodeGenerationOptions(IOptionsReader options, CodeGenerationOptions fallbackOptions, string language) + private protected CodeGenerationOptions(IOptionsReader options, string language) { - NamingStyle = options.GetOption(NamingStyleOptions.NamingPreferences, language, fallbackOptions.NamingStyle); + NamingStyle = options.GetOption(NamingStyleOptions.NamingPreferences, language); } #if !CODE_STYLE @@ -102,37 +102,34 @@ internal interface CodeAndImportGenerationOptionsProvider : internal static class CodeGenerationOptionsProviders { #if !CODE_STYLE - public static CodeGenerationOptions GetCodeGenerationOptions(this IOptionsReader options, LanguageServices languageServices, CodeGenerationOptions? fallbackOptions) - => languageServices.GetRequiredService().GetCodeGenerationOptions(options, fallbackOptions); + public static CodeGenerationOptions GetCodeGenerationOptions(this IOptionsReader options, LanguageServices languageServices) + => languageServices.GetRequiredService().GetCodeGenerationOptions(options); - public static CodeAndImportGenerationOptions GetCodeAndImportGenerationOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowImportsInHiddenRegions, CodeAndImportGenerationOptions? fallbackOptions) + public static CodeAndImportGenerationOptions GetCodeAndImportGenerationOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowImportsInHiddenRegions = null) => new() { - GenerationOptions = options.GetCodeGenerationOptions(languageServices, fallbackOptions?.GenerationOptions), - AddImportOptions = options.GetAddImportPlacementOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions?.AddImportOptions) + GenerationOptions = options.GetCodeGenerationOptions(languageServices), + AddImportOptions = options.GetAddImportPlacementOptions(languageServices, allowImportsInHiddenRegions) }; - public static CleanCodeGenerationOptions GetCleanCodeGenerationOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowImportsInHiddenRegions, CleanCodeGenerationOptions? fallbackOptions) + public static CleanCodeGenerationOptions GetCleanCodeGenerationOptions(this IOptionsReader options, LanguageServices languageServices, bool? allowImportsInHiddenRegions = null) => new() { - GenerationOptions = options.GetCodeGenerationOptions(languageServices, fallbackOptions?.GenerationOptions), - CleanupOptions = options.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions, fallbackOptions?.CleanupOptions) + GenerationOptions = options.GetCodeGenerationOptions(languageServices), + CleanupOptions = options.GetCodeCleanupOptions(languageServices, allowImportsInHiddenRegions) }; - public static async ValueTask GetCodeGenerationOptionsAsync(this Document document, CodeGenerationOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetCodeGenerationOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetCodeGenerationOptions(document.Project.Services, fallbackOptions); + return configOptions.GetCodeGenerationOptions(document.Project.Services); } - public static async ValueTask GetCodeGenerationOptionsAsync(this Document document, CodeGenerationOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await GetCodeGenerationOptionsAsync(document, await ((OptionsProvider)fallbackOptionsProvider).GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); - - public static async ValueTask GetCodeGenerationInfoAsync(this Document document, CodeGenerationContext context, CodeGenerationOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) + public static async ValueTask GetCodeGenerationInfoAsync(this Document document, CodeGenerationContext context, CancellationToken cancellationToken) { Contract.ThrowIfNull(document.Project.ParseOptions); - var options = await GetCodeGenerationOptionsAsync(document, fallbackOptionsProvider, cancellationToken).ConfigureAwait(false); + var options = await GetCodeGenerationOptionsAsync(document, cancellationToken).ConfigureAwait(false); var service = document.Project.Services.GetRequiredService(); return service.GetInfo(context, options, document.Project.ParseOptions); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/DocumentFormattingOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/DocumentFormattingOptions.cs index f18a374f8e932..d3d82026a590b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/DocumentFormattingOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/DocumentFormattingOptions.cs @@ -5,11 +5,8 @@ using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeStyle; -using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.Formatting; @@ -31,25 +28,18 @@ internal interface DocumentFormattingOptionsProvider internal static class DocumentFormattingOptionsProviders { - public static DocumentFormattingOptions GetDocumentFormattingOptions(this IOptionsReader options, DocumentFormattingOptions? fallbackOptions) - { - fallbackOptions ??= DocumentFormattingOptions.Default; - - return new() + public static DocumentFormattingOptions GetDocumentFormattingOptions(this IOptionsReader options) + => new() { - FileHeaderTemplate = options.GetOption(CodeStyleOptions2.FileHeaderTemplate, fallbackOptions.FileHeaderTemplate), - InsertFinalNewLine = options.GetOption(FormattingOptions2.InsertFinalNewLine, fallbackOptions.InsertFinalNewLine) + FileHeaderTemplate = options.GetOption(CodeStyleOptions2.FileHeaderTemplate), + InsertFinalNewLine = options.GetOption(FormattingOptions2.InsertFinalNewLine) }; - } #if !CODE_STYLE - public static async ValueTask GetDocumentFormattingOptionsAsync(this Document document, DocumentFormattingOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetDocumentFormattingOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetDocumentFormattingOptions(fallbackOptions); + return configOptions.GetDocumentFormattingOptions(); } - - public static async ValueTask GetDocumentFormattingOptionsAsync(this Document document, DocumentFormattingOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await document.GetDocumentFormattingOptionsAsync(await fallbackOptionsProvider.GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); #endif } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/LineFormattingOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/LineFormattingOptions.cs index a856c70921e94..27624ca8c0c33 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/LineFormattingOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/LineFormattingOptions.cs @@ -31,28 +31,21 @@ internal interface LineFormattingOptionsProvider internal static partial class LineFormattingOptionsProviders { - public static LineFormattingOptions GetLineFormattingOptions(this IOptionsReader options, string language, LineFormattingOptions? fallbackOptions) - { - fallbackOptions ??= LineFormattingOptions.Default; - - return new() + public static LineFormattingOptions GetLineFormattingOptions(this IOptionsReader options, string language) + => new() { - UseTabs = options.GetOption(FormattingOptions2.UseTabs, language, fallbackOptions.UseTabs), - TabSize = options.GetOption(FormattingOptions2.TabSize, language, fallbackOptions.TabSize), - IndentationSize = options.GetOption(FormattingOptions2.IndentationSize, language, fallbackOptions.IndentationSize), - NewLine = options.GetOption(FormattingOptions2.NewLine, language, fallbackOptions.NewLine), + UseTabs = options.GetOption(FormattingOptions2.UseTabs, language), + TabSize = options.GetOption(FormattingOptions2.TabSize, language), + IndentationSize = options.GetOption(FormattingOptions2.IndentationSize, language), + NewLine = options.GetOption(FormattingOptions2.NewLine, language), }; - } #if !CODE_STYLE - public static async ValueTask GetLineFormattingOptionsAsync(this Document document, LineFormattingOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetLineFormattingOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetLineFormattingOptions(document.Project.Language, fallbackOptions); + return configOptions.GetLineFormattingOptions(document.Project.Language); } - - public static async ValueTask GetLineFormattingOptionsAsync(this Document document, LineFormattingOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - => await GetLineFormattingOptionsAsync(document, await fallbackOptionsProvider.GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); #endif } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs index 28fa9f8675fc6..4eecbfe3eb783 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/SyntaxFormattingOptions.cs @@ -3,14 +3,13 @@ // See the LICENSE file in the project root for more information. using System.Runtime.Serialization; -using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeStyle; -using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Options; #if !CODE_STYLE +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; #endif @@ -33,13 +32,13 @@ private protected SyntaxFormattingOptions() { } - private protected SyntaxFormattingOptions(IOptionsReader options, SyntaxFormattingOptions fallbackOptions, string language) + private protected SyntaxFormattingOptions(IOptionsReader options, string language) { - LineFormatting = options.GetLineFormattingOptions(language, fallbackOptions.LineFormatting); - SeparateImportDirectiveGroups = options.GetOption(GenerationOptions.SeparateImportDirectiveGroups, language, fallbackOptions.SeparateImportDirectiveGroups); - AccessibilityModifiersRequired = options.GetOptionValue(CodeStyleOptions2.AccessibilityModifiersRequired, language, fallbackOptions.AccessibilityModifiersRequired); - WrappingColumn = options.GetOption(FormattingOptions2.WrappingColumn, language, fallbackOptions.WrappingColumn); - ConditionalExpressionWrappingLength = options.GetOption(FormattingOptions2.ConditionalExpressionWrappingLength, language, fallbackOptions.ConditionalExpressionWrappingLength); + LineFormatting = options.GetLineFormattingOptions(language); + SeparateImportDirectiveGroups = options.GetOption(GenerationOptions.SeparateImportDirectiveGroups, language); + AccessibilityModifiersRequired = options.GetOptionValue(CodeStyleOptions2.AccessibilityModifiersRequired, language); + WrappingColumn = options.GetOption(FormattingOptions2.WrappingColumn, language); + ConditionalExpressionWrappingLength = options.GetOption(FormattingOptions2.ConditionalExpressionWrappingLength, language); } public bool UseTabs => LineFormatting.UseTabs; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyleOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyleOptions.cs index 7e7b9c0f4ff54..a317ecb0a3637 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyleOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyleOptions.cs @@ -37,21 +37,10 @@ internal interface NamingStylePreferencesProvider #if !CODE_STYLE internal static class NamingStylePreferencesProviders { - public static async ValueTask GetNamingStylePreferencesAsync(this Document document, NamingStylePreferences? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetNamingStylePreferencesAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return configOptions.GetEditorConfigOption(NamingStyleOptions.NamingPreferences, fallbackOptions ?? NamingStylePreferences.Default); - } - - public static async ValueTask GetNamingStylePreferencesAsync(this Document document, NamingStylePreferencesProvider fallbackOptionsProvider, CancellationToken cancellationToken) - { - var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - if (configOptions.TryGetEditorConfigOption(NamingStyleOptions.NamingPreferences, out var value)) - { - return value; - } - - return await fallbackOptionsProvider.GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false); + return configOptions.GetEditorConfigOption(NamingStyleOptions.NamingPreferences, NamingStylePreferences.Default); } } #endif diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/EditorConfigValueSerializer`1.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/EditorConfigValueSerializer`1.cs index 4ca77dfbcd140..75a7fd29b7226 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/EditorConfigValueSerializer`1.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/EditorConfigValueSerializer`1.cs @@ -55,6 +55,9 @@ public string GetEditorConfigStringValue(T value) return editorConfigStringForValue; } - public string Serialize(object? value) + public string Serialize(T value) + => serializeValue(value); + + string IEditorConfigValueSerializer.Serialize(object? value) => GetEditorConfigStringValue((T)value!); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/IOptionReader.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/IOptionReader.cs index 249b399bd8c17..078b8430ad7c2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/IOptionReader.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Options/IOptionReader.cs @@ -41,9 +41,15 @@ public static T GetOption(this IOptionsReader options, PerLanguageOption2 public static T GetOption(this IOptionsReader options, PerLanguageOption2 option, string language, T defaultValue) => options.TryGetOption(new OptionKey2(option, language), out var value) ? value! : defaultValue; + public static T GetOptionValue(this IOptionsReader options, Option2> option) + => GetOptionValue(options, option, option.DefaultValue.Value); + public static T GetOptionValue(this IOptionsReader options, Option2> option, T defaultValue) => options.TryGetOption>(new OptionKey2(option), out var style) ? style!.Value : defaultValue; + public static T GetOptionValue(this IOptionsReader options, PerLanguageOption2> option, string language) + => GetOptionValue(options, option, language, option.DefaultValue.Value); + public static T GetOptionValue(this IOptionsReader options, PerLanguageOption2> option, string language, T defaultValue) => options.TryGetOption>(new OptionKey2(option, language), out var style) ? style!.Value : defaultValue; } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/SimplifierOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/SimplifierOptions.cs index db49116604628..ba47f590961f4 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/SimplifierOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/SimplifierOptions.cs @@ -35,14 +35,14 @@ private protected SimplifierOptions() { } - private protected SimplifierOptions(IOptionsReader options, SimplifierOptions fallbackOptions, string language) + private protected SimplifierOptions(IOptionsReader options, string language) { - QualifyFieldAccess = options.GetOption(CodeStyleOptions2.QualifyFieldAccess, language, fallbackOptions.QualifyFieldAccess); - QualifyPropertyAccess = options.GetOption(CodeStyleOptions2.QualifyPropertyAccess, language, fallbackOptions.QualifyPropertyAccess); - QualifyMethodAccess = options.GetOption(CodeStyleOptions2.QualifyMethodAccess, language, fallbackOptions.QualifyMethodAccess); - QualifyEventAccess = options.GetOption(CodeStyleOptions2.QualifyEventAccess, language, fallbackOptions.QualifyEventAccess); - PreferPredefinedTypeKeywordInMemberAccess = options.GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, language, fallbackOptions.PreferPredefinedTypeKeywordInMemberAccess); - PreferPredefinedTypeKeywordInDeclaration = options.GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, language, fallbackOptions.PreferPredefinedTypeKeywordInDeclaration); + QualifyFieldAccess = options.GetOption(CodeStyleOptions2.QualifyFieldAccess, language); + QualifyPropertyAccess = options.GetOption(CodeStyleOptions2.QualifyPropertyAccess, language); + QualifyMethodAccess = options.GetOption(CodeStyleOptions2.QualifyMethodAccess, language); + QualifyEventAccess = options.GetOption(CodeStyleOptions2.QualifyEventAccess, language); + PreferPredefinedTypeKeywordInMemberAccess = options.GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, language); + PreferPredefinedTypeKeywordInDeclaration = options.GetOption(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, language); } public bool TryGetQualifyMemberAccessOption(SymbolKind symbolKind, [NotNullWhen(true)] out CodeStyleOption2? option) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/VisualBasic/VisualBasicSimplifierOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/VisualBasic/VisualBasicSimplifierOptions.cs index 85176db9be591..273edc5dc2399 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/VisualBasic/VisualBasicSimplifierOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Simplification/VisualBasic/VisualBasicSimplifierOptions.cs @@ -18,8 +18,8 @@ public VisualBasicSimplifierOptions() { } - public VisualBasicSimplifierOptions(IOptionsReader options, VisualBasicSimplifierOptions? fallbackOptions) - : base(options, fallbackOptions ?? Default, LanguageNames.VisualBasic) + public VisualBasicSimplifierOptions(IOptionsReader options) + : base(options, LanguageNames.VisualBasic) { } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicSimplification.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicSimplification.vb index 7eb08356f3d1f..e82f2b4561f7e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicSimplification.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicSimplification.vb @@ -19,7 +19,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification End Property Public Overrides Function GetSimplifierOptions(options As IOptionsReader) As SimplifierOptions - Return New VisualBasicSimplifierOptions(options, fallbackOptions:=Nothing) + Return New VisualBasicSimplifierOptions(options) End Function End Class End Namespace diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeActions/CSharpCodeFixOptionsProvider.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeActions/CSharpCodeFixOptionsProvider.cs index 9b3dff2099510..985ac67a657e5 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeActions/CSharpCodeFixOptionsProvider.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeActions/CSharpCodeFixOptionsProvider.cs @@ -15,112 +15,51 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; -// to avoid excessive #ifdefs -#pragma warning disable CA1822 // Mark members as static -#pragma warning disable IDE0052 // Remove unread private members - namespace Microsoft.CodeAnalysis.CodeActions; -internal readonly struct CSharpCodeFixOptionsProvider +internal readonly struct CSharpCodeFixOptionsProvider(IOptionsReader options, HostLanguageServices languageServices) { - /// - /// Document editorconfig options. - /// - private readonly IOptionsReader _options; - - /// - /// C# language services. - /// - private readonly HostLanguageServices _languageServices; - - /// - /// Fallback options provider - default options provider in Code Style layer. - /// - private readonly CodeActionOptionsProvider _fallbackOptions; - - public CSharpCodeFixOptionsProvider(IOptionsReader options, CodeActionOptionsProvider fallbackOptions, HostLanguageServices languageServices) - { - _options = options; - _fallbackOptions = fallbackOptions; - _languageServices = languageServices; - } - // LineFormattingOptions - public string NewLine => GetOption(FormattingOptions2.NewLine, FallbackLineFormattingOptions.NewLine); + public string NewLine => GetOption(FormattingOptions2.NewLine); // SimplifierOptions - public CodeStyleOption2 VarForBuiltInTypes => GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes, FallbackSimplifierOptions.VarForBuiltInTypes); - public CodeStyleOption2 VarElsewhere => GetOption(CSharpCodeStyleOptions.VarElsewhere, FallbackSimplifierOptions.VarElsewhere); + public CodeStyleOption2 VarForBuiltInTypes => GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes); + public CodeStyleOption2 VarElsewhere => GetOption(CSharpCodeStyleOptions.VarElsewhere); public SimplifierOptions GetSimplifierOptions() - => new CSharpSimplifierOptions(_options, FallbackSimplifierOptions); + => new CSharpSimplifierOptions(options); // FormattingOptions - public CodeStyleOption2 NamespaceDeclarations => GetOption(CSharpCodeStyleOptions.NamespaceDeclarations, FallbackSyntaxFormattingOptions.NamespaceDeclarations); - public CodeStyleOption2 PreferTopLevelStatements => GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements, FallbackSyntaxFormattingOptions.PreferTopLevelStatements); + public CodeStyleOption2 NamespaceDeclarations => GetOption(CSharpCodeStyleOptions.NamespaceDeclarations); + public CodeStyleOption2 PreferTopLevelStatements => GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements); internal CSharpSyntaxFormattingOptions GetFormattingOptions() - => new(_options, FallbackSyntaxFormattingOptions); + => new(options); // AddImportPlacementOptions - public CodeStyleOption2 UsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, FallbackAddImportPlacementOptions.UsingDirectivePlacement); + public CodeStyleOption2 UsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement); // CodeStyleOptions - public CodeStyleOption2 PreferredModifierOrder => GetOption(CSharpCodeStyleOptions.PreferredModifierOrder, FallbackCodeStyleOptions.PreferredModifierOrder); - public CodeStyleOption2 AccessibilityModifiersRequired => GetOption(CodeStyleOptions2.AccessibilityModifiersRequired, FallbackCodeStyleOptions.AccessibilityModifiersRequired); - - private TValue GetOption(Option2 option, TValue defaultValue) - => _options.GetOption(option, defaultValue); - - private TValue GetOption(PerLanguageOption2 option, TValue defaultValue) - => _options.GetOption(option, _languageServices.Language, defaultValue); - - private CSharpIdeCodeStyleOptions FallbackCodeStyleOptions -#if CODE_STYLE - => CSharpIdeCodeStyleOptions.Default; -#else - => (CSharpIdeCodeStyleOptions)_fallbackOptions.GetOptions(_languageServices.LanguageServices).CodeStyleOptions; -#endif - - private CSharpSimplifierOptions FallbackSimplifierOptions -#if CODE_STYLE - => CSharpSimplifierOptions.Default; -#else - => (CSharpSimplifierOptions)_fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.SimplifierOptions; -#endif - - private CSharpSyntaxFormattingOptions FallbackSyntaxFormattingOptions -#if CODE_STYLE - => CSharpSyntaxFormattingOptions.Default; -#else - => (CSharpSyntaxFormattingOptions)_fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.FormattingOptions; -#endif - - private LineFormattingOptions FallbackLineFormattingOptions -#if CODE_STYLE - => LineFormattingOptions.Default; -#else - => _fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.FormattingOptions.LineFormatting; -#endif - - private AddImportPlacementOptions FallbackAddImportPlacementOptions -#if CODE_STYLE - => AddImportPlacementOptions.Default; -#else - => _fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.AddImportOptions; -#endif + public CodeStyleOption2 PreferredModifierOrder => GetOption(CSharpCodeStyleOptions.PreferredModifierOrder); + public CodeStyleOption2 AccessibilityModifiersRequired => GetOption(CodeStyleOptions2.AccessibilityModifiersRequired); + + private TValue GetOption(Option2 option) + => options.GetOption(option); + + private TValue GetOption(PerLanguageOption2 option) + => options.GetOption(option, languageServices.Language); } internal static class CSharpCodeFixOptionsProviders { - public static async ValueTask GetCSharpCodeFixOptionsProviderAsync(this Document document, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetCSharpCodeFixOptionsProviderAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return new CSharpCodeFixOptionsProvider(configOptions.GetOptionsReader(), fallbackOptions, document.Project.GetExtendedLanguageServices()); + return new CSharpCodeFixOptionsProvider(configOptions.GetOptionsReader(), document.Project.GetExtendedLanguageServices()); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs index 8df5ceefaca7f..e642587180e98 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs @@ -35,8 +35,8 @@ public CSharpCodeGenerationService(LanguageServices languageServices) public override CodeGenerationOptions DefaultOptions => CSharpCodeGenerationOptions.Default; - public override CodeGenerationOptions GetCodeGenerationOptions(IOptionsReader options, CodeGenerationOptions? fallbackOptions) - => new CSharpCodeGenerationOptions(options, (CSharpCodeGenerationOptions?)fallbackOptions); + public override CodeGenerationOptions GetCodeGenerationOptions(IOptionsReader options) + => new CSharpCodeGenerationOptions(options); public override CSharpCodeGenerationContextInfo GetInfo(CodeGenerationContext context, CodeGenerationOptions options, ParseOptions parseOptions) => new(context, (CSharpCodeGenerationOptions)options, this, ((CSharpParseOptions)parseOptions).LanguageVersion); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpAddImportsService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpAddImportsService.cs index 0e389b930d2ee..e99db49e025e5 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpAddImportsService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpAddImportsService.cs @@ -33,8 +33,8 @@ public CSharpAddImportsService() protected override string Language => LanguageNames.CSharp; - public override CodeStyleOption2 GetUsingDirectivePlacementCodeStyleOption(IOptionsReader configOptions, CodeStyleOption2 fallbackValue) - => configOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, fallbackValue); + public override CodeStyleOption2 GetUsingDirectivePlacementCodeStyleOption(IOptionsReader configOptions) + => configOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement); // C# doesn't have global imports. protected override ImmutableArray GetGlobalImports(Compilation compilation, SyntaxGenerator generator) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/AddImport/AddImportPlacementOptionsProviders.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/AddImport/AddImportPlacementOptionsProviders.cs index 7cb64c67fb684..44ee410c56294 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/AddImport/AddImportPlacementOptionsProviders.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/AddImport/AddImportPlacementOptionsProviders.cs @@ -11,14 +11,14 @@ namespace Microsoft.CodeAnalysis.AddImport; internal static partial class AddImportPlacementOptionsProviders { - internal static async ValueTask GetAddImportPlacementOptionsAsync(this Document document, IAddImportsService addImportsService, AddImportPlacementOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) + internal static async ValueTask GetAddImportPlacementOptionsAsync(this Document document, IAddImportsService addImportsService, CancellationToken cancellationToken) { #if CODE_STYLE var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var configOptions = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree).GetOptionsReader(); - return addImportsService.GetAddImportOptions(configOptions, allowInHiddenRegions: false, fallbackOptions: null); + return addImportsService.GetAddImportOptions(configOptions, allowInHiddenRegions: false); #else - return await document.GetAddImportPlacementOptionsAsync(fallbackOptionsProvider, cancellationToken).ConfigureAwait(false); + return await document.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); #endif } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs index 39bcea51a4d08..521f11283500d 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeActions/CodeFixOptionsProvider.cs @@ -2,85 +2,40 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeStyle; -using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Formatting; -using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; -// to avoid excessive #ifdefs -#pragma warning disable CA1822 // Mark members as static -#pragma warning disable IDE0052 // Remove unread private members - namespace Microsoft.CodeAnalysis.CodeActions; -internal readonly struct CodeFixOptionsProvider +internal readonly struct CodeFixOptionsProvider(IOptionsReader options, string language) { - /// - /// Document editorconfig options. - /// - private readonly IOptionsReader _options; - - /// - /// C# language services. - /// - private readonly HostLanguageServices _languageServices; - - /// - /// Fallback options provider - default options provider in Code Style layer. - /// - private readonly CodeActionOptionsProvider _fallbackOptions; - - public CodeFixOptionsProvider(IOptionsReader options, CodeActionOptionsProvider fallbackOptions, HostLanguageServices languageServices) - { - _options = options; - _fallbackOptions = fallbackOptions; - _languageServices = languageServices; - } - // LineFormattingOptions - public string NewLine => GetOption(FormattingOptions2.NewLine, FallbackLineFormattingOptions.NewLine); + public string NewLine => GetOption(FormattingOptions2.NewLine); public LineFormattingOptions GetLineFormattingOptions() - => _options.GetLineFormattingOptions(_languageServices.Language, FallbackLineFormattingOptions); + => options.GetLineFormattingOptions(language); // SyntaxFormattingOptions public SyntaxFormattingOptions GetFormattingOptions(ISyntaxFormatting formatting) - => formatting.GetFormattingOptions(_options); - - public AccessibilityModifiersRequired AccessibilityModifiersRequired => _options.GetOptionValue(CodeStyleOptions2.AccessibilityModifiersRequired, _languageServices.Language, FallbackCommonSyntaxFormattingOptions.AccessibilityModifiersRequired); - - private TValue GetOption(PerLanguageOption2 option, TValue defaultValue) - => _options.GetOption(option, _languageServices.Language, defaultValue); + => formatting.GetFormattingOptions(options); - private LineFormattingOptions FallbackLineFormattingOptions -#if CODE_STYLE - => LineFormattingOptions.Default; -#else - => _fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.FormattingOptions.LineFormatting; -#endif + public AccessibilityModifiersRequired AccessibilityModifiersRequired => options.GetOptionValue(CodeStyleOptions2.AccessibilityModifiersRequired, language); - private SyntaxFormattingOptions FallbackCommonSyntaxFormattingOptions -#if CODE_STYLE - => SyntaxFormattingOptions.CommonDefaults; -#else - => _fallbackOptions.GetOptions(_languageServices.LanguageServices).CleanupOptions.FormattingOptions; -#endif + private TValue GetOption(PerLanguageOption2 option) + => options.GetOption(option, language); } internal static class CodeFixOptionsProviders { - public static async ValueTask GetCodeFixOptionsAsync(this Document document, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetCodeFixOptionsAsync(this Document document, CancellationToken cancellationToken) { var configOptions = await document.GetAnalyzerConfigOptionsAsync(cancellationToken).ConfigureAwait(false); - return new CodeFixOptionsProvider(configOptions.GetOptionsReader(), fallbackOptions, document.Project.GetExtendedLanguageServices()); + return new CodeFixOptionsProvider(configOptions.GetOptionsReader(), document.Project.Language); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs index dda3054036db9..90cae65a5d562 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs @@ -39,7 +39,6 @@ internal abstract class ForkingSyntaxEditorBasedCodeFixProvider protected abstract Task FixAsync( Document document, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, TDiagnosticNode diagnosticNode, ImmutableDictionary properties, CancellationToken cancellationToken); @@ -59,7 +58,6 @@ protected sealed override async Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, - CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var originalRoot = editor.OriginalRoot; @@ -91,7 +89,6 @@ protected sealed override async Task FixAllAsync( await FixAsync( semanticDocument.Document, subEditor, - fallbackOptions, diagnosticNode, diagnostic.Properties, cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/SyntaxEditorBasedCodeFixProvider.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/SyntaxEditorBasedCodeFixProvider.cs index bfc4abc054969..5d96c89405d29 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/SyntaxEditorBasedCodeFixProvider.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/SyntaxEditorBasedCodeFixProvider.cs @@ -40,7 +40,7 @@ internal abstract partial class SyntaxEditorBasedCodeFixProvider(bool supportsFi if (filteredDiagnostics.Length == 0) return document; - return await FixAllAsync(document, filteredDiagnostics, fixAllContext.GetOptionsProvider(), fixAllContext.CancellationToken).ConfigureAwait(false); + return await FixAllAsync(document, filteredDiagnostics, fixAllContext.CancellationToken).ConfigureAwait(false); }, s_defaultSupportedFixAllScopes); } @@ -54,15 +54,15 @@ protected void RegisterCodeFix(CodeFixContext context, string title, string equi protected Func> GetDocumentUpdater(CodeFixContext context, Diagnostic? diagnostic = null) { var diagnostics = ImmutableArray.Create(diagnostic ?? context.Diagnostics[0]); - return cancellationToken => FixAllAsync(context.Document, diagnostics, context.GetOptionsProvider(), cancellationToken); + return cancellationToken => FixAllAsync(context.Document, diagnostics, cancellationToken); } private Task FixAllAsync( - Document document, ImmutableArray diagnostics, CodeActionOptionsProvider options, CancellationToken cancellationToken) + Document document, ImmutableArray diagnostics, CancellationToken cancellationToken) { return FixAllWithEditorAsync( document, - editor => FixAllAsync(document, diagnostics, editor, options, cancellationToken), + editor => FixAllAsync(document, diagnostics, editor, cancellationToken), cancellationToken); } @@ -83,11 +83,10 @@ internal static async Task FixAllWithEditorAsync( /// /// Fixes all in the specified . /// The fixes are applied to the 's syntax tree via . - /// The implementation may query options of any document in the 's solution - /// with providing default values for options not specified explicitly in the corresponding editorconfig. + /// The implementation may query options of any document in the 's solution. /// protected abstract Task FixAllAsync( - Document document, ImmutableArray diagnostics, SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken); /// /// Whether or not this diagnostic should be included when performing a FixAll. This is useful for providers that diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/AbstractCodeGenerationService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/AbstractCodeGenerationService.cs index 9d3cb3850ad9c..0c95e62352596 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/AbstractCodeGenerationService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/AbstractCodeGenerationService.cs @@ -37,7 +37,7 @@ protected AbstractCodeGenerationService( public LanguageServices LanguageServices { get; } public abstract CodeGenerationOptions DefaultOptions { get; } - public abstract CodeGenerationOptions GetCodeGenerationOptions(IOptionsReader options, CodeGenerationOptions? fallbackOptions); + public abstract CodeGenerationOptions GetCodeGenerationOptions(IOptionsReader options); public abstract TCodeGenerationContextInfo GetInfo(CodeGenerationContext context, CodeGenerationOptions options, ParseOptions parseOptions); CodeGenerationContextInfo ICodeGenerationService.GetInfo(CodeGenerationContext context, CodeGenerationOptions options, ParseOptions parseOptions) @@ -246,7 +246,7 @@ private async Task GetEditAsync( #if CODE_STYLE var codeGenOptions = CodeGenerationOptions.CommonDefaults; #else - var codeGenOptions = await oldDocument.GetCodeGenerationOptionsAsync(context.FallbackOptions, cancellationToken).ConfigureAwait(false); + var codeGenOptions = await oldDocument.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); #endif var info = GetInfo(context.Context, codeGenOptions, destinationDeclaration.SyntaxTree.Options); var transformedDeclaration = declarationTransform(destinationDeclaration, info, availableIndices, cancellationToken); @@ -259,7 +259,7 @@ private async Task GetEditAsync( #if !CODE_STYLE if (context.Context.AddImports) { - var addImportsOptions = await newDocument.GetAddImportPlacementOptionsAsync(context.FallbackOptions, cancellationToken).ConfigureAwait(false); + var addImportsOptions = await newDocument.GetAddImportPlacementOptionsAsync(cancellationToken).ConfigureAwait(false); newDocument = await ImportAdder.AddImportsFromSymbolAnnotationAsync(newDocument, addImportsOptions, cancellationToken).ConfigureAwait(false); } #endif diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationContext.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationContext.cs index 75ab6c7c49581..0a0d845c4be3f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationContext.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationContext.cs @@ -4,17 +4,13 @@ using System; using System.Collections.Generic; -using Microsoft.CodeAnalysis.AddImport; -using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Simplification; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeGeneration; internal readonly record struct CodeGenerationSolutionContext( Solution Solution, - CodeGenerationContext Context, - CodeAndImportGenerationOptionsProvider FallbackOptions); + CodeGenerationContext Context); /// /// General options for controlling the code produced by the that apply to all documents. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/ICodeGenerationService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/ICodeGenerationService.cs index 1d436688b42e6..350d306bc434b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/ICodeGenerationService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/ICodeGenerationService.cs @@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.CodeGeneration; internal interface ICodeGenerationService : ILanguageService { CodeGenerationOptions DefaultOptions { get; } - CodeGenerationOptions GetCodeGenerationOptions(IOptionsReader options, CodeGenerationOptions? fallbackOptions); + CodeGenerationOptions GetCodeGenerationOptions(IOptionsReader options); CodeGenerationContextInfo GetInfo(CodeGenerationContext context, CodeGenerationOptions options, ParseOptions parseOptions); /// diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/VisualBasic/VisualBasicCodeGenerationOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/VisualBasic/VisualBasicCodeGenerationOptions.cs index 41d28864bf6c5..1265e51cd8a9f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/VisualBasic/VisualBasicCodeGenerationOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/VisualBasic/VisualBasicCodeGenerationOptions.cs @@ -17,8 +17,8 @@ public VisualBasicCodeGenerationOptions() { } - internal VisualBasicCodeGenerationOptions(IOptionsReader options, VisualBasicCodeGenerationOptions? fallbackOptions) - : base(options, fallbackOptions ?? Default, LanguageNames.VisualBasic) + internal VisualBasicCodeGenerationOptions(IOptionsReader options) + : base(options, LanguageNames.VisualBasic) { } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs index d5524bf1a9afe..5c38e016c3970 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs @@ -33,19 +33,15 @@ protected AbstractAddImportsService() protected abstract SyntaxList GetExterns(SyntaxNode node); protected abstract bool IsStaticUsing(TUsingOrAliasSyntax usingOrAlias); - public AddImportPlacementOptions GetAddImportOptions(IOptionsReader configOptions, bool allowInHiddenRegions, AddImportPlacementOptions? fallbackOptions) - { - fallbackOptions ??= AddImportPlacementOptions.Default; - - return new() + public AddImportPlacementOptions GetAddImportOptions(IOptionsReader configOptions, bool allowInHiddenRegions) + => new() { - PlaceSystemNamespaceFirst = configOptions.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, Language, fallbackOptions.PlaceSystemNamespaceFirst), - UsingDirectivePlacement = GetUsingDirectivePlacementCodeStyleOption(configOptions, fallbackOptions.UsingDirectivePlacement), + PlaceSystemNamespaceFirst = configOptions.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, Language), + UsingDirectivePlacement = GetUsingDirectivePlacementCodeStyleOption(configOptions), AllowInHiddenRegions = allowInHiddenRegions }; - } - public abstract CodeStyleOption2 GetUsingDirectivePlacementCodeStyleOption(IOptionsReader configOptions, CodeStyleOption2 fallbackValue); + public abstract CodeStyleOption2 GetUsingDirectivePlacementCodeStyleOption(IOptionsReader configOptions); private bool IsSimpleUsing(TUsingOrAliasSyntax usingOrAlias) => !IsAlias(usingOrAlias) && !IsStaticUsing(usingOrAlias); private bool IsAlias(TUsingOrAliasSyntax usingOrAlias) => GetAlias(usingOrAlias) != null; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/IAddImportsService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/IAddImportsService.cs index 9de5f16f87215..628274b8720bc 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/IAddImportsService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/IAddImportsService.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.AddImport; internal interface IAddImportsService : ILanguageService { - AddImportPlacementOptions GetAddImportOptions(IOptionsReader configOptions, bool allowInHiddenRegions, AddImportPlacementOptions? fallbackOptions); + AddImportPlacementOptions GetAddImportOptions(IOptionsReader configOptions, bool allowInHiddenRegions); /// /// Returns true if the tree already has an existing import syntactically equivalent to diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Utilities/ParsedDocument.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Utilities/ParsedDocument.cs index b3f3db3086555..abd63a0705eb1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Utilities/ParsedDocument.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Utilities/ParsedDocument.cs @@ -7,6 +7,7 @@ using System.Reflection.Metadata; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicAddImportsService.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicAddImportsService.vb index 112c815cf4bb5..29919d098b506 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicAddImportsService.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicAddImportsService.vb @@ -66,9 +66,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddImports FirstOrDefault()?.Alias End Function - Public Overrides Function GetUsingDirectivePlacementCodeStyleOption(configOptions As IOptionsReader, fallbackValue As CodeStyleOption2(Of AddImportPlacement)) As CodeStyleOption2(Of AddImportPlacement) + Public Overrides Function GetUsingDirectivePlacementCodeStyleOption(configOptions As IOptionsReader) As CodeStyleOption2(Of AddImportPlacement) ' Visual Basic doesn't support imports inside namespaces - Return fallbackValue + Return AddImportPlacementOptions.Default.UsingDirectivePlacement End Function Protected Overrides Function IsStaticUsing(usingOrAlias As ImportsStatementSyntax) As Boolean diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb index 1c092cc708157..b1298c0f3ed96 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb @@ -31,8 +31,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Get End Property - Public Overrides Function GetCodeGenerationOptions(options As IOptionsReader, fallbackOptions As CodeGenerationOptions) As CodeGenerationOptions - Return New VisualBasicCodeGenerationOptions(options, DirectCast(fallbackOptions, VisualBasicCodeGenerationOptions)) + Public Overrides Function GetCodeGenerationOptions(options As IOptionsReader) As CodeGenerationOptions + Return New VisualBasicCodeGenerationOptions(options) End Function Public Overrides Function GetInfo(context As CodeGenerationContext, options As CodeGenerationOptions, parseOptions As ParseOptions) As VisualBasicCodeGenerationContextInfo diff --git a/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb b/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb index 9a13c1e0b8da1..b18158661bcd0 100644 --- a/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb +++ b/src/Workspaces/VisualBasic/Portable/Formatting/VisualBasicSyntaxFormatting.vb @@ -36,7 +36,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting End Property Public Overrides Function GetFormattingOptions(options As IOptionsReader) As SyntaxFormattingOptions - Return New VisualBasicSyntaxFormattingOptions(options, fallbackOptions:=Nothing) + Return New VisualBasicSyntaxFormattingOptions(options) End Function Protected Overrides Function CreateAggregatedFormattingResult(node As SyntaxNode, results As IList(Of AbstractFormattingResult), Optional formattingSpans As TextSpanMutableIntervalTree = Nothing) As IFormattingResult diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.vb b/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.vb index 1b43d7563f8a2..03743561920e9 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.vb @@ -45,7 +45,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification End Property Public Overrides Function GetSimplifierOptions(options As IOptionsReader) As SimplifierOptions - Return New VisualBasicSimplifierOptions(options, fallbackOptions:=Nothing) + Return New VisualBasicSimplifierOptions(options) End Function Public Overrides Function Expand(node As SyntaxNode, semanticModel As SemanticModel, aliasReplacementAnnotation As SyntaxAnnotation, expandInsideNode As Func(Of SyntaxNode, Boolean), expandParameter As Boolean, cancellationToken As CancellationToken) As SyntaxNode From 8b9f855402e3ea9496fd586d590b82947d68e859 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Tue, 9 Jul 2024 14:03:29 -0700 Subject: [PATCH 53/59] Review feedback --- .../AbstractRequestScope.cs | 4 +- .../IQueueItem.cs | 10 ++--- .../QueueItem.cs | 45 +++++++++++++++---- .../RequestExecutionQueue.cs | 28 +++++++----- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs index 1ab7c81174844..a676aca30b044 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractRequestScope.cs @@ -21,9 +21,9 @@ internal abstract class AbstractRequestScope(string name) : IDisposable public abstract void RecordExecutionStart(); /// - /// Sets the language for the request once it has been determined + /// Updates the telemetry metrics for the request with the handler's language. /// - public void UpdateLanguage(string language) + public void RecordHandlerLanguage(string language) { Language = language; } diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs index 60c78f614788d..8ff5899ec5eba 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs @@ -32,14 +32,10 @@ internal interface IQueueItem /// Note - this method is always called serially inside the queue before /// running the actual request in /// Throwing in this method will cause the server to shutdown. + /// + /// If there was a recoverable failure in creating the request, this will return null and the caller should stop processing the request. /// - Task CreateRequestContextAsync(TRequest deserializedRequest, IMethodHandler handler, CancellationToken cancellationToken); - - /// - /// Attempts to deserialize the request. If the request cannot be deserialized, ensures that the exception is returned as the result. - /// If the request is mutating, the exception will bubble up so the queue can handle it and shutdown. - /// - public TRequest? TryDeserializeRequest(AbstractLanguageServer languageServer, RequestHandlerMetadata requestHandlerMetadata, bool isMutating); + Task<(TRequestContext, TRequest)?> CreateRequestContextAsync(IMethodHandler handler, RequestHandlerMetadata requestHandlerMetadata, AbstractLanguageServer languageServer, CancellationToken cancellationToken); /// /// Provides access to LSP services. diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs index b037e60610fd4..8b04b82bc394c 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Frozen; using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Contracts; using System.Linq; using System.Reflection; using System.Threading; @@ -79,25 +80,53 @@ public static (IQueueItem, Task) Create( return (queueItem, queueItem._completionSource.Task); } - public async Task CreateRequestContextAsync(TRequest request, IMethodHandler handler, CancellationToken cancellationToken) + public async Task<(TRequestContext, TRequest)?> CreateRequestContextAsync(IMethodHandler handler, RequestHandlerMetadata requestHandlerMetadata, AbstractLanguageServer languageServer, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _requestTelemetryScope?.RecordExecutionStart(); + // Report to telemetry which handler language we're using for this request. + _requestTelemetryScope?.RecordHandlerLanguage(requestHandlerMetadata.Language); + + if (!TryDeserializeRequest(languageServer, requestHandlerMetadata, handler.MutatesSolutionState, out var deserializedRequest)) + { + // Failures are already logged in TryDeserializeRequest, just need to stop processing this item now. + return null; + } + var requestContextFactory = LspServices.GetRequiredService>(); - var context = await requestContextFactory.CreateRequestContextAsync(this, handler, request, cancellationToken).ConfigureAwait(false); - return context; + var context = await requestContextFactory.CreateRequestContextAsync(this, handler, deserializedRequest, cancellationToken).ConfigureAwait(false); + return (context, deserializedRequest); } - public TRequest? TryDeserializeRequest(AbstractLanguageServer languageServer, RequestHandlerMetadata requestHandlerMetadata, bool isMutating) + /// + /// Deserializes the request into the concrete type. If the deserialization fails we will fail the request and call TrySetException on the + /// so that the client can observe the failure. If this is a mutating request, we will also let the exception bubble up so that the queue can handle it. + /// + /// The caller is expected to return immediately and stop processing the request if this returns false. + /// + private bool TryDeserializeRequest( + AbstractLanguageServer languageServer, + RequestHandlerMetadata requestHandlerMetadata, + bool isMutating, + [MaybeNullWhen(false)] out TRequest request) { try { - return languageServer.DeserializeRequest(SerializedRequest, requestHandlerMetadata); + request = languageServer.DeserializeRequest(SerializedRequest, requestHandlerMetadata); + // We successfully deserialized, but we have not yet completed the request. Updating the _completionSource will be handled by StartRequestAsync. + return true; } catch (Exception ex) { + if (ex is OperationCanceledException) + { + throw new InvalidOperationException("Cancellation exception is not expected here"); + } + + // Deserialization failed which means the request has failed. Record the exception and update the _completionSource. + // Report the exception to logs / telemetry _requestTelemetryScope?.RecordException(ex); _logger.LogException(ex); @@ -109,14 +138,15 @@ public async Task CreateRequestContextAsync(TRequest _requestTelemetryScope?.Dispose(); _logger.LogEndContext($"{MethodName}"); - // If the request is mutating, bubble the exception out so the queue shutsdown. + // If the request is mutating, bubble the exception out so the queue shuts down. if (isMutating) { throw; } else { - return default; + request = default; + return false; } } } @@ -129,7 +159,6 @@ public async Task CreateRequestContextAsync(TRequest public async Task StartRequestAsync(TRequest request, TRequestContext? context, IMethodHandler handler, string language, CancellationToken cancellationToken) { _logger.LogStartContext($"{MethodName}"); - _requestTelemetryScope?.UpdateLanguage(language); try { diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs index 13ccb40530c94..d4f4b0cda53c0 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs @@ -239,7 +239,13 @@ private async Task ProcessQueueAsync() // Restore our activity id so that logging/tracking works across asynchronous calls. Trace.CorrelationManager.ActivityId = activityId; - // Determine which language is appropriate for handling the request. + + // Serially in the queue determine which language is appropriate for handling the request (based on the request URI). + // + // The client can send us the language associated with a URI in the didOpen notification. It is important that all prior didOpen + // notifications have been completed by the time we attempt to determine the language, so we have the up to date map of URI to language. + // Since didOpen notifications are marked as mutating, the queue will not advance to the next request until the server has finished processing + // the didOpen, ensuring that this line will only run once all prior didOpens have completed. var language = _languageServer.GetLanguageForRequest(work.MethodName, work.SerializedRequest); // Now that we know the actual language, we can deserialize the request and start creating the request context. @@ -287,8 +293,13 @@ private async Task InvokeProcessCoreAsync( CancellationTokenSource? currentWorkCts, CancellationToken cancellationToken) { - var task = methodInfo.Invoke(this, [work, handler, metadata, concurrentlyExecutingTasks, currentWorkCts, cancellationToken]) as Task - ?? throw new InvalidOperationException($"ProcessQueueCoreAsync result task cannot be null"); + var result = methodInfo.Invoke(this, [work, handler, metadata, concurrentlyExecutingTasks, currentWorkCts, cancellationToken]); + if (result is null) + { + throw new InvalidOperationException($"ProcessQueueCoreAsync result task cannot be null"); + } + + var task = (Task)result; await task.ConfigureAwait(false); } @@ -304,17 +315,12 @@ private async Task ProcessQueueCoreAsync( CancellationTokenSource? currentWorkCts, CancellationToken cancellationToken) { - var deserializedRequest = work.TryDeserializeRequest(_languageServer, metadata, handler.MutatesSolutionState); - if (deserializedRequest == null) - { - return; - } - // The request context must be created serially inside the queue to so that requests always run // on the correct snapshot as of the last request. - var context = await work.CreateRequestContextAsync(deserializedRequest, handler, cancellationToken).ConfigureAwait(false); + var contextInfo = await work.CreateRequestContextAsync(handler, metadata, _languageServer, cancellationToken).ConfigureAwait(false); + var (context, deserializedRequest) = contextInfo.Value; - // Run anything in before request before we start handliung the request (for example setting the UI culture). + // Run anything in before request before we start handling the request (for example setting the UI culture). BeforeRequest(deserializedRequest); if (handler.MutatesSolutionState) From 38cce4794de04f6c1d0e5a4eb2e129a54ca41808 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Tue, 9 Jul 2024 14:28:08 -0700 Subject: [PATCH 54/59] Style warnings --- .../IQueueItem.cs | 2 +- .../RequestExecutionQueue.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs index 8ff5899ec5eba..f49d36b7b13ed 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/IQueueItem.cs @@ -20,7 +20,7 @@ internal interface IQueueItem /// Executes the work specified by this queue item. /// /// The request parameters. - /// The context created by . + /// The context created by . /// The handler to use to execute the request. /// The language for the request. /// diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs index d4f4b0cda53c0..6b7b7b3fe1695 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs @@ -239,7 +239,6 @@ private async Task ProcessQueueAsync() // Restore our activity id so that logging/tracking works across asynchronous calls. Trace.CorrelationManager.ActivityId = activityId; - // Serially in the queue determine which language is appropriate for handling the request (based on the request URI). // // The client can send us the language associated with a URI in the didOpen notification. It is important that all prior didOpen From 235d31bc18bbdfbdb3ff94378c2e1c0ed42d6743 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Tue, 9 Jul 2024 14:31:07 -0700 Subject: [PATCH 55/59] fix --- .../RequestExecutionQueue.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs index 6b7b7b3fe1695..edbbc2d4297d4 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs @@ -317,6 +317,12 @@ private async Task ProcessQueueCoreAsync( // The request context must be created serially inside the queue to so that requests always run // on the correct snapshot as of the last request. var contextInfo = await work.CreateRequestContextAsync(handler, metadata, _languageServer, cancellationToken).ConfigureAwait(false); + if (contextInfo is null) + { + // We failed to create the context in a non-mutating request, we can't process this item so just return. + return; + } + var (context, deserializedRequest) = contextInfo.Value; // Run anything in before request before we start handling the request (for example setting the UI culture). From ecd48921948c027bbbf0d62fdc41b55ca8b91ac5 Mon Sep 17 00:00:00 2001 From: Giovanni Braconi Date: Wed, 10 Jul 2024 03:24:56 +0200 Subject: [PATCH 56/59] Improve wording in Roslyn-Overview.md (#74059) --- docs/wiki/Roslyn-Overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/wiki/Roslyn-Overview.md b/docs/wiki/Roslyn-Overview.md index 345d7e9700a8d..76f067ffa901f 100644 --- a/docs/wiki/Roslyn-Overview.md +++ b/docs/wiki/Roslyn-Overview.md @@ -49,7 +49,7 @@ Each phase of this pipeline is now a separate component. First the parse phase, ![compiler pipeline api](images/compiler-pipeline-api.png) -Corresponding to each of those phases, an object model is surfaced that allows access to the information at that phase. The parsing phase is exposed as a syntax tree, the declaration phase as a hierarchical symbol table, the binding phase as a model that exposes the result of the compiler’s semantic analysis and the emit phase as an API that produces IL byte codes. +Corresponding to each of those phases, an object model that allows access to the information at that phase is surfaced. The parsing phase is exposed as a syntax tree, the declaration phase as a hierarchical symbol table, the binding phase as a model that exposes the result of the compiler’s semantic analysis and the emit phase as an API that produces IL byte codes. ![compiler api lang service](images/compiler-pipeline-lang-svc.png) @@ -69,7 +69,7 @@ The compiler layer contains the object models that correspond with information e #### Diagnostic APIs -As part of their analysis the compiler may produce a set of diagnostics covering everything from syntax, semantic, and definite assignment errors to various warnings and informational diagnostics. The Compiler API layer exposes diagnostics through an extensible API allowing for user-defined analyzers to be plugged into a Compilation and user-defined diagnostics, such as those produced by tools like StyleCop or FxCop, to be produced alongside compiler-defined diagnostics. Producing diagnostics in this way has the benefit of integrating naturally with tools such as MSBuild and Visual Studio which depend on diagnostics for experiences such as halting a build based on policy and showing live squiggles in the editor and suggesting code fixes. +As part of their analysis the compiler may produce a set of diagnostics covering everything from syntax, semantic, and definite assignment errors to various warnings and informational diagnostics. The Compiler API layer exposes diagnostics through an extensible API allowing for user-defined analyzers to be plugged into a Compilation and user-defined diagnostics, such as those produced by tools like StyleCop or FxCop, to be produced alongside compiler-defined diagnostics. Producing diagnostics in this way has the benefit of integrating naturally with tools such as MSBuild and Visual Studio which depend on diagnostics for experiences such as halting a build based on policy, showing live squiggles in the editor and suggesting code fixes. #### Scripting APIs From 6d1db018164e02e9bc409ede715f9e20a766ed88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Tue, 9 Jul 2024 19:38:50 -0700 Subject: [PATCH 57/59] Remove fallbacks (2) (#74319) --- .../ExtractInterfaceCommandHandler.cs | 3 +- .../MoveType/MoveTypeTests.MoveScope.cs | 2 +- .../ExtractMethod/ExtractMethodBase.cs | 21 ++-- .../ExtractMethod/ExtractMethodTests.cs | 37 +----- .../MoveToNamespace/MoveToNamespaceTests.cs | 1 - .../IntelliCode/IntentProcessor.cs | 8 +- .../AbstractExtractInterfaceCommandHandler.cs | 6 +- .../ExtractMethodCommandHandler.cs | 53 +------- .../AbstractMoveToNamespaceTests.cs | 1 - .../Test/Options/GlobalOptionsTests.cs | 1 - .../ExtractInterfaceTestState.cs | 6 +- .../TestExtractInterfaceOptions.cs | 4 +- .../ExtractInterfaceCommandHandler.vb | 7 +- .../ExtractInterface/ExtractInterfaceTests.vb | 4 +- .../ExtractMethodTests.DataFlowAnalysis.vb | 116 ------------------ .../ExtractMethodTests.LanguageInteraction.vb | 32 +---- .../ExtractMethod/ExtractMethodTests.vb | 26 ++-- ...gularConstructorCodeRefactoringProvider.cs | 5 +- ...tringToRawStringCodeRefactoringProvider.cs | 1 - .../CSharpExtractMethodService.cs | 4 +- .../CSharpSelectionResult.ExpressionResult.cs | 3 +- .../CSharpSelectionResult.StatementResult.cs | 3 +- .../ExtractMethod/CSharpSelectionResult.cs | 8 +- .../ExtractMethod/CSharpSelectionValidator.cs | 4 +- ...tructorParameterCodeRefactoringProvider.cs | 9 +- ...ParameterCodeRefactoringProvider_Update.cs | 3 - ...calForExpressionCodeRefactoringProvider.cs | 1 - ...actExtractMethodCodeRefactoringProvider.cs | 2 +- .../MoveType/AbstractMoveTypeService.State.cs | 9 +- .../MoveType/AbstractMoveTypeService.cs | 16 +-- .../MoveType/IMoveTypeService.cs | 4 +- .../MoveTypeCodeRefactoringProvider.cs | 2 +- .../AbstractExtractInterfaceService.cs | 16 +-- .../ExtractInterfaceCodeAction.cs | 1 - ...ExtractInterfaceCodeRefactoringProvider.cs | 2 +- .../ExtractInterfaceOptionsResult.cs | 5 +- .../ExtractInterfaceTypeAnalysisResult.cs | 6 +- .../IExtractInterfaceOptionsService.cs | 1 - .../AbstractExtractMethodService.cs | 4 +- .../ExtractMethod/MethodExtractor.Analyzer.cs | 32 ----- .../Portable/ExtractMethod/SelectionResult.cs | 3 - .../ExtractMethod/SelectionValidator.cs | 4 +- ...terfaceService.DisposePatternCodeAction.cs | 27 +--- ...ddParameterCheckCodeRefactoringProvider.cs | 2 - ...erCodeRefactoringProviderMemberCreation.cs | 3 +- ...tializeParameterCodeRefactoringProvider.cs | 6 +- .../Portable/Intents/IntentDataProvider.cs | 6 +- ...calForExpressionCodeRefactoringProvider.cs | 9 +- ...deAction.MoveItemsToNamespaceCodeAction.cs | 6 +- ...odeAction.MoveTypeToNamespaceCodeAction.cs | 6 +- .../AbstractMoveToNamespaceCodeAction.cs | 11 +- .../AbstractMoveToNamespaceService.cs | 12 +- .../MoveToNamespaceCodeActionProvider.cs | 2 +- ...OmniSharpExtractInterfaceOptionsService.cs | 4 +- .../VisualBasicExtractMethodService.vb | 3 +- .../VisualBasicSelectionResult.vb | 4 - .../VisualBasicSelectionValidator.vb | 6 +- ...calForExpressionCodeRefactoringProvider.vb | 2 +- .../Options/CodeActionOptionsStorage.cs | 1 - .../Options/ExtractMethodOptionsStorage.cs | 15 --- .../Options/AdvancedOptionPageControl.xaml.cs | 3 - .../AutomationObject.ExtractMethod.cs | 6 - ...ualStudioExtractInterfaceOptionsService.cs | 4 +- .../Def/Options/VisualStudioOptionStorage.cs | 1 - .../Options/AdvancedOptionPageControl.xaml | 8 -- .../Options/AdvancedOptionPageControl.xaml.vb | 3 - .../AutomationObject.ExtractMethod.vb | 9 -- .../ExtractMethod/ExtractMethodOptions.cs | 22 +--- .../CoreTest/Remote/ServiceDescriptorTests.cs | 1 - .../CoreTestUtilities/VBOptionsFactory.cs | 5 +- .../Core/CodeFixes/CodeActionOptions.cs | 2 - 71 files changed, 106 insertions(+), 559 deletions(-) diff --git a/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs b/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs index 5e43d72ea629c..07bbb3bed9a43 100644 --- a/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs @@ -8,7 +8,6 @@ using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ExtractInterface; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Utilities; @@ -19,6 +18,6 @@ namespace Microsoft.CodeAnalysis.CSharp.ExtractInterface; [Name(PredefinedCommandHandlerNames.ExtractInterface)] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class ExtractInterfaceCommandHandler(IThreadingContext threadingContext, IGlobalOptionService globalOptions) : AbstractExtractInterfaceCommandHandler(threadingContext, globalOptions) +internal sealed class ExtractInterfaceCommandHandler(IThreadingContext threadingContext) : AbstractExtractInterfaceCommandHandler(threadingContext) { } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveScope.cs b/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveScope.cs index 8455401641543..fa203ef7f5a51 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveScope.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveScope.cs @@ -921,7 +921,7 @@ private async Task TestNamespaceMove(string originalCode, string expectedCode, b var moveTypeService = documentToModify.GetLanguageService(); Assert.NotNull(moveTypeService); - var modifiedSolution = await moveTypeService.GetModifiedSolutionAsync(documentToModify, textSpan, MoveTypeOperationKind.MoveTypeNamespaceScope, CodeActionOptions.DefaultProvider, CancellationToken.None).ConfigureAwait(false); + var modifiedSolution = await moveTypeService.GetModifiedSolutionAsync(documentToModify, textSpan, MoveTypeOperationKind.MoveTypeNamespaceScope, CancellationToken.None).ConfigureAwait(false); if (expectOperation) { diff --git a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodBase.cs b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodBase.cs index dbf74460c43ef..c370c7cf0e1e5 100644 --- a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodBase.cs +++ b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodBase.cs @@ -24,7 +24,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ExtractMethod; [UseExportProvider] public class ExtractMethodBase { - protected static async Task ExpectExtractMethodToFailAsync(string codeWithMarker, bool dontPutOutOrRefOnStruct = true, string[] features = null) + protected static async Task ExpectExtractMethodToFailAsync(string codeWithMarker, string[] features = null) { ParseOptions parseOptions = null; if (features != null) @@ -36,20 +36,19 @@ protected static async Task ExpectExtractMethodToFailAsync(string codeWithMarker using var workspace = EditorTestWorkspace.CreateCSharp(codeWithMarker, parseOptions: parseOptions); var testDocument = workspace.Documents.First(); var textSpan = testDocument.SelectedSpans.Single(); - var treeAfterExtractMethod = await ExtractMethodAsync(workspace, testDocument, succeed: false, dontPutOutOrRefOnStruct: dontPutOutOrRefOnStruct); + var treeAfterExtractMethod = await ExtractMethodAsync(workspace, testDocument, succeed: false); } protected static async Task ExpectExtractMethodToFailAsync( string codeWithMarker, string expected, - bool dontPutOutOrRefOnStruct = true, CSharpParseOptions parseOptions = null) { using var workspace = EditorTestWorkspace.CreateCSharp(codeWithMarker, parseOptions: parseOptions); var testDocument = workspace.Documents.Single(); var subjectBuffer = testDocument.GetTextBuffer(); - var tree = await ExtractMethodAsync(workspace, testDocument, succeed: false, dontPutOutOrRefOnStruct: dontPutOutOrRefOnStruct); + var tree = await ExtractMethodAsync(workspace, testDocument, succeed: false); using (var edit = subjectBuffer.CreateEdit()) { @@ -77,7 +76,6 @@ protected static async Task TestExtractMethodAsync( string codeWithMarker, string expected, bool temporaryFailing = false, - bool dontPutOutOrRefOnStruct = true, CSharpParseOptions parseOptions = null) { using var workspace = EditorTestWorkspace.CreateCSharp(codeWithMarker, parseOptions: parseOptions); @@ -85,8 +83,7 @@ protected static async Task TestExtractMethodAsync( var subjectBuffer = testDocument.GetTextBuffer(); var tree = await ExtractMethodAsync( - workspace, testDocument, - dontPutOutOrRefOnStruct: dontPutOutOrRefOnStruct); + workspace, testDocument); using (var edit = subjectBuffer.CreateEdit()) { @@ -116,8 +113,7 @@ protected static async Task TestExtractMethodAsync( protected static async Task ExtractMethodAsync( EditorTestWorkspace workspace, EditorTestHostDocument testDocument, - bool succeed = true, - bool dontPutOutOrRefOnStruct = true) + bool succeed = true) { var document = workspace.CurrentSolution.GetDocument(testDocument.Id); Assert.NotNull(document); @@ -126,11 +122,10 @@ protected static async Task ExtractMethodAsync( { CodeGenerationOptions = CodeGenerationOptions.GetDefault(document.Project.Services), CodeCleanupOptions = CodeCleanupOptions.GetDefault(document.Project.Services), - ExtractOptions = new() { DoNotPutOutOrRefOnStruct = dontPutOutOrRefOnStruct } }; var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None); - var validator = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), options.ExtractOptions, localFunction: false); + var validator = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), localFunction: false); var (selectedCode, status) = await validator.GetValidSelectionAsync(CancellationToken.None); if (!succeed && status.Failed) @@ -173,7 +168,7 @@ protected static async Task TestSelectionAsync(string codeWithMarker, bool expec Assert.NotNull(document); var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None); - var validator = new CSharpSelectionValidator(semanticDocument, textSpanOverride ?? namedSpans["b"].Single(), ExtractMethodOptions.Default, localFunction: false); + var validator = new CSharpSelectionValidator(semanticDocument, textSpanOverride ?? namedSpans["b"].Single(), localFunction: false); var (result, status) = await validator.GetValidSelectionAsync(CancellationToken.None); if (expectedFail) @@ -201,7 +196,7 @@ protected static async Task IterateAllAsync(string code) foreach (var node in iterator) { - var validator = new CSharpSelectionValidator(semanticDocument, node.Span, ExtractMethodOptions.Default, localFunction: false); + var validator = new CSharpSelectionValidator(semanticDocument, node.Span, localFunction: false); var (_, status) = await validator.GetValidSelectionAsync(CancellationToken.None); // check the obvious case diff --git a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs index 2ace095ac04fb..6b59deb117a8e 100644 --- a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs @@ -10973,41 +10973,6 @@ public async Task Hello() await ExpectExtractMethodToFailAsync(code); } - [Fact] - public async Task TestDoNotPutOutOrRefForStructOff() - { - var code = - """ - using System.Threading.Tasks; - - namespace ClassLibrary9 - { - public struct S - { - public int I; - } - - public class Class1 - { - private async Task Test() - { - S s = new S(); - s.I = 10; - - [|int i = await Task.Run(() => - { - var i2 = s.I; - return Test(); - });|] - - return i; - } - } - } - """; - await ExpectExtractMethodToFailAsync(code, dontPutOutOrRefOnStruct: false); - } - [Fact] public async Task TestDoNotPutOutOrRefForStructOn() { @@ -11075,7 +11040,7 @@ private async Task NewMethod(S s) } """; - await TestExtractMethodAsync(code, expected, dontPutOutOrRefOnStruct: true); + await TestExtractMethodAsync(code, expected); } [Theory] diff --git a/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs b/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs index 255ed90b7cea8..9fd69aa3ff078 100644 --- a/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs +++ b/src/EditorFeatures/CSharpTest/MoveToNamespace/MoveToNamespaceTests.cs @@ -1259,7 +1259,6 @@ void Method() { } var actions = await testState.MoveToNamespaceService.GetCodeActionsAsync( testState.InvocationDocument, testState.TestInvocationDocument.SelectedSpans.Single(), - CodeActionOptions.DefaultProvider, CancellationToken.None); Assert.Empty(actions); diff --git a/src/EditorFeatures/Core/ExternalAccess/IntelliCode/IntentProcessor.cs b/src/EditorFeatures/Core/ExternalAccess/IntelliCode/IntentProcessor.cs index a203d93579f91..13af115a66219 100644 --- a/src/EditorFeatures/Core/ExternalAccess/IntelliCode/IntentProcessor.cs +++ b/src/EditorFeatures/Core/ExternalAccess/IntelliCode/IntentProcessor.cs @@ -23,11 +23,9 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.IntelliCode; [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal class IntentSourceProvider( - [ImportMany] IEnumerable> lazyIntentProviders, - IGlobalOptionService globalOptions) : IIntentSourceProvider + [ImportMany] IEnumerable> lazyIntentProviders) : IIntentSourceProvider { private readonly ImmutableDictionary<(string LanguageName, string IntentName), Lazy> _lazyIntentProviders = CreateProviderMap(lazyIntentProviders); - private readonly IGlobalOptionService _globalOptions = globalOptions; private static ImmutableDictionary<(string LanguageName, string IntentName), Lazy> CreateProviderMap( IEnumerable> lazyIntentProviders) @@ -66,9 +64,7 @@ public async Task> ComputeIntentsAsync(IntentReques originalDocument, selectionTextSpan, currentDocument, - new IntentDataProvider( - intentRequestContext.IntentData, - _globalOptions.CreateProvider()), + new IntentDataProvider(intentRequestContext.IntentData), cancellationToken).ConfigureAwait(false); if (results.IsDefaultOrEmpty) diff --git a/src/EditorFeatures/Core/ExtractInterface/AbstractExtractInterfaceCommandHandler.cs b/src/EditorFeatures/Core/ExtractInterface/AbstractExtractInterfaceCommandHandler.cs index e8d41a90a87a8..da0268fd88eea 100644 --- a/src/EditorFeatures/Core/ExtractInterface/AbstractExtractInterfaceCommandHandler.cs +++ b/src/EditorFeatures/Core/ExtractInterface/AbstractExtractInterfaceCommandHandler.cs @@ -9,7 +9,6 @@ using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Notification; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text; @@ -20,12 +19,10 @@ namespace Microsoft.CodeAnalysis.ExtractInterface; internal abstract class AbstractExtractInterfaceCommandHandler : ICommandHandler { private readonly IThreadingContext _threadingContext; - private readonly IGlobalOptionService _globalOptions; - protected AbstractExtractInterfaceCommandHandler(IThreadingContext threadingContext, IGlobalOptionService globalOptions) + protected AbstractExtractInterfaceCommandHandler(IThreadingContext threadingContext) { _threadingContext = threadingContext; - _globalOptions = globalOptions; } public string DisplayName => EditorFeaturesResources.Extract_Interface; @@ -71,7 +68,6 @@ public bool ExecuteCommand(ExtractInterfaceCommandArgs args, CommandExecutionCon var result = await extractInterfaceService.ExtractInterfaceAsync( document, caretPoint.Value.Position, - _globalOptions.CreateProvider(), (errorMessage, severity) => workspace.Services.GetService().SendNotification(errorMessage, severity: severity), CancellationToken.None).ConfigureAwait(true); diff --git a/src/EditorFeatures/Core/ExtractMethod/ExtractMethodCommandHandler.cs b/src/EditorFeatures/Core/ExtractMethod/ExtractMethodCommandHandler.cs index 496c549a99e77..6d08010693760 100644 --- a/src/EditorFeatures/Core/ExtractMethod/ExtractMethodCommandHandler.cs +++ b/src/EditorFeatures/Core/ExtractMethod/ExtractMethodCommandHandler.cs @@ -139,13 +139,13 @@ private async Task ExecuteWorkerAsync( if (document is null) return; - var options = await document.GetExtractMethodGenerationOptionsAsync(_globalOptions, cancellationToken).ConfigureAwait(false); + var options = await document.GetExtractMethodGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var result = await ExtractMethodService.ExtractMethodAsync( document, span, localFunction: false, options, cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(result); result = await NotifyUserIfNecessaryAsync( - document, span, options, result, cancellationToken).ConfigureAwait(false); + document, result, cancellationToken).ConfigureAwait(false); if (result is null) return; @@ -186,7 +186,7 @@ private void ApplyChange_OnUIThread( } private async Task NotifyUserIfNecessaryAsync( - Document document, TextSpan span, ExtractMethodGenerationOptions options, ExtractMethodResult result, CancellationToken cancellationToken) + Document document, ExtractMethodResult result, CancellationToken cancellationToken) { // If we succeeded without any problems, just proceed without notifying the user. if (result is { Succeeded: true, Reasons.Length: 0 }) @@ -198,31 +198,9 @@ private void ApplyChange_OnUIThread( if (notificationService is null) return null; - // The initial extract method failed, or it succeeded with warning reasons. Attempt again with - // different options to see if we get better results. - var alternativeResult = await TryWithoutMakingValueTypesRefAsync( - document, span, result, options, cancellationToken).ConfigureAwait(false); - // We're about to show an notification to the user. Switch to the ui thread to do so. await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - if (alternativeResult is { Succeeded: true, Reasons.Length: 0 }) - { - if (!notificationService.ConfirmMessageBox( - EditorFeaturesResources.Extract_method_encountered_the_following_issues + Environment.NewLine + Environment.NewLine + - string.Join(Environment.NewLine, result.Reasons) + Environment.NewLine + Environment.NewLine + - EditorFeaturesResources.We_can_fix_the_error_by_not_making_struct_out_ref_parameter_s_Do_you_want_to_proceed, - title: EditorFeaturesResources.Extract_Method, - severity: NotificationSeverity.Error)) - { - // We handled the command, displayed a notification and did not produce code. - return null; - } - - // Otherwise, prefer the new approach that has less problems. - return alternativeResult; - } - // The alternative approach wasn't better. If we failed, just let the user know and bail out. Otherwise, // if we succeeded with messages, tell the user and let them decide if they want to proceed or not. if (!result.Succeeded) @@ -253,29 +231,4 @@ private void ApplyChange_OnUIThread( return result; } - - private static async Task TryWithoutMakingValueTypesRefAsync( - Document document, TextSpan span, ExtractMethodResult result, ExtractMethodGenerationOptions options, CancellationToken cancellationToken) - { - if (options.ExtractOptions.DoNotPutOutOrRefOnStruct || !result.Reasons.IsSingle()) - return null; - - var reason = result.Reasons.FirstOrDefault(); - var length = FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.IndexOf(':'); - if (reason != null && length > 0 && reason.IndexOf(FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket[..length], 0, length, StringComparison.Ordinal) >= 0) - { - var newResult = await ExtractMethodService.ExtractMethodAsync( - document, - span, - localFunction: false, - options with { ExtractOptions = options.ExtractOptions with { DoNotPutOutOrRefOnStruct = true } }, - cancellationToken).ConfigureAwait(false); - - // retry succeeded, return new result - if (newResult.Succeeded) - return newResult; - } - - return null; - } } diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.cs b/src/EditorFeatures/DiagnosticsTestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.cs index 391982e60e319..75395d6d39b86 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/MoveToNamespace/AbstractMoveToNamespaceTests.cs @@ -48,7 +48,6 @@ public async Task TestMoveToNamespaceAsync( var actions = await testState.MoveToNamespaceService.GetCodeActionsAsync( testState.InvocationDocument, testState.TestInvocationDocument.SelectedSpans.Single(), - CodeActionOptions.DefaultProvider, CancellationToken.None); var operationTasks = actions diff --git a/src/EditorFeatures/Test/Options/GlobalOptionsTests.cs b/src/EditorFeatures/Test/Options/GlobalOptionsTests.cs index 2c874f7679800..cd13e03ce2f14 100644 --- a/src/EditorFeatures/Test/Options/GlobalOptionsTests.cs +++ b/src/EditorFeatures/Test/Options/GlobalOptionsTests.cs @@ -191,7 +191,6 @@ public void ReadingOptionsFromGlobalOptions(string language) VerifyDataMembersHaveNonDefaultValues(globalOptions.GetAutoFormattingOptions(language), AutoFormattingOptions.Default, language); VerifyDataMembersHaveNonDefaultValues(globalOptions.GetBlockStructureOptions(language, isMetadataAsSource: false), BlockStructureOptions.Default, language); VerifyDataMembersHaveNonDefaultValues(globalOptions.GetDocumentationCommentOptions(globalOptions.GetLineFormattingOptions(language), language), DocumentationCommentOptions.Default, language); - VerifyDataMembersHaveNonDefaultValues(globalOptions.GetExtractMethodOptions(language), ExtractMethodOptions.Default, language); VerifyDataMembersHaveNonDefaultValues(globalOptions.GetImplementTypeOptions(language), ImplementTypeOptions.Default, language); VerifyDataMembersHaveNonDefaultValues(globalOptions.GetMetadataAsSourceOptions(), MetadataAsSourceOptions.Default, language); VerifyDataMembersHaveNonDefaultValues(globalOptions.GetSignatureHelpOptions(language), SignatureHelpOptions.Default, language); diff --git a/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs b/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs index c466125a9c7ac..1874449ca25d0 100644 --- a/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs +++ b/src/EditorFeatures/TestUtilities/ExtractInterface/ExtractInterfaceTestState.cs @@ -77,7 +77,6 @@ public Task GetTypeAnalysisResultAsync(TypeD ExtractFromDocument, _testDocument.CursorPosition.Value, typeDiscoveryRule, - Workspace.GlobalOptions.CreateProvider(), CancellationToken.None); } @@ -86,7 +85,6 @@ public Task ExtractViaCommandAsync() return ExtractInterfaceService.ExtractInterfaceAsync( ExtractFromDocument, _testDocument.CursorPosition.Value, - Workspace.GlobalOptions.CreateProvider(), (errorMessage, severity) => { this.ErrorMessage = errorMessage; @@ -100,7 +98,6 @@ public async Task ExtractViaCodeAction() var actions = await ExtractInterfaceService.GetExtractInterfaceCodeActionAsync( ExtractFromDocument, new TextSpan(_testDocument.CursorPosition.Value, 1), - Workspace.GlobalOptions.CreateProvider(), CancellationToken.None); var action = actions.Single(); @@ -111,8 +108,7 @@ public async Task ExtractViaCodeAction() options.IncludedMembers, options.InterfaceName, options.FileName, - ExtractInterfaceOptionsResult.ExtractLocation.SameFile, - options.FallbackOptions); + ExtractInterfaceOptionsResult.ExtractLocation.SameFile); var operations = await action.GetOperationsAsync( this.OriginalSolution, changedOptions, CodeAnalysisProgress.None, CancellationToken.None); diff --git a/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs b/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs index 1bb576e0423d2..01a72da76d171 100644 --- a/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs +++ b/src/EditorFeatures/TestUtilities/ExtractInterface/TestExtractInterfaceOptions.cs @@ -47,7 +47,6 @@ public Task GetExtractInterfaceOptionsAsync( string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { this.AllExtractableMembers = extractableMembers; @@ -63,8 +62,7 @@ public Task GetExtractInterfaceOptionsAsync( includedMembers: (ChosenMembers ?? AllExtractableMembers).AsImmutable(), interfaceName: ChosenInterfaceName ?? defaultInterfaceName, fileName: ChosenFileName ?? defaultInterfaceName, - location: SameFile ? ExtractInterfaceOptionsResult.ExtractLocation.SameFile : ExtractInterfaceOptionsResult.ExtractLocation.NewFile, - fallbackOptions); + location: SameFile ? ExtractInterfaceOptionsResult.ExtractLocation.SameFile : ExtractInterfaceOptionsResult.ExtractLocation.NewFile); return Task.FromResult(result); } diff --git a/src/EditorFeatures/VisualBasic/ExtractInterface/ExtractInterfaceCommandHandler.vb b/src/EditorFeatures/VisualBasic/ExtractInterface/ExtractInterfaceCommandHandler.vb index 9bd7809a0a15d..a28b8d6d11934 100644 --- a/src/EditorFeatures/VisualBasic/ExtractInterface/ExtractInterfaceCommandHandler.vb +++ b/src/EditorFeatures/VisualBasic/ExtractInterface/ExtractInterfaceCommandHandler.vb @@ -4,12 +4,11 @@ Imports System.ComponentModel.Composition Imports System.Diagnostics.CodeAnalysis -Imports Microsoft.CodeAnalysis.ExtractInterface Imports Microsoft.CodeAnalysis.Editor Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities +Imports Microsoft.CodeAnalysis.ExtractInterface Imports Microsoft.VisualStudio.Commanding Imports Microsoft.VisualStudio.Utilities -Imports Microsoft.CodeAnalysis.Options Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractInterface @@ -20,8 +19,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractInterface - Public Sub New(threadingContext As IThreadingContext, globalOptions As IGlobalOptionService) - MyBase.New(threadingContext, globalOptions) + Public Sub New(threadingContext As IThreadingContext) + MyBase.New(threadingContext) End Sub End Class End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/ExtractInterface/ExtractInterfaceTests.vb b/src/EditorFeatures/VisualBasicTest/ExtractInterface/ExtractInterfaceTests.vb index f225b6ba7f82e..ec1f5bfb377b1 100644 --- a/src/EditorFeatures/VisualBasicTest/ExtractInterface/ExtractInterfaceTests.vb +++ b/src/EditorFeatures/VisualBasicTest/ExtractInterface/ExtractInterfaceTests.vb @@ -1286,9 +1286,7 @@ End Namespace Dim textView = workspace.Documents.Single().GetTextView() - Dim handler = New ExtractInterfaceCommandHandler( - workspace.GetService(Of IThreadingContext), - workspace.GlobalOptions) + Dim handler = New ExtractInterfaceCommandHandler(workspace.GetService(Of IThreadingContext)) Dim state = handler.GetCommandState(New ExtractInterfaceCommandArgs(textView, textView.TextBuffer)) Assert.True(state.IsUnspecified) diff --git a/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.DataFlowAnalysis.vb b/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.DataFlowAnalysis.vb index ca4c71b7864ee..5cd0b172040b1 100644 --- a/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.DataFlowAnalysis.vb +++ b/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.DataFlowAnalysis.vb @@ -5831,122 +5831,6 @@ End Module Await TestExtractMethodAsync(code, expected) End Function - - - Public Async Function TestStructure1() As Task - Dim code = Structure XType - Public Y As YType -End Structure - -Structure YType - Public Z As ZType -End Structure - -Structure ZType - Public Value As Integer -End Structure - -Module Program - Sub Main(args As String()) - Dim x As XType - - Dim value = [|x.Y|].Z.Value - With x - .Y.Z.Value += 1 - End With - End Sub -End Module - Dim expected = Structure XType - Public Y As YType -End Structure - -Structure YType - Public Z As ZType -End Structure - -Structure ZType - Public Value As Integer -End Structure - -Module Program - Sub Main(args As String()) - Dim x As XType - - Dim value = GetY(x).Z.Value - With x - .Y.Z.Value += 1 - End With - End Sub - - Private Function GetY(ByRef x As XType) As YType - Return x.Y - End Function -End Module - Await TestExtractMethodAsync(code, expected, dontPutOutOrRefOnStruct:=False) - End Function - - - Public Async Function TestStructure2() As Task - Dim code = Imports System -Imports System.Collections.Generic -Imports System.Linq - -Structure SSSS3 - Public A As String - Public B As Integer -End Structure - -Structure SSSS2 - Public S3 As SSSS3 -End Structure - -Structure SSSS - Public S2 As SSSS2 -End Structure - -Structure SSS - Public S As SSSS -End Structure - -Class Clazz - Sub TEST() - Dim x As New SSS() - [|x.S|].S2.S3.A = "1" - End Sub -End Class - Dim expected = Imports System -Imports System.Collections.Generic -Imports System.Linq - -Structure SSSS3 - Public A As String - Public B As Integer -End Structure - -Structure SSSS2 - Public S3 As SSSS3 -End Structure - -Structure SSSS - Public S2 As SSSS2 -End Structure - -Structure SSS - Public S As SSSS -End Structure - -Class Clazz - Sub TEST() - Dim x As New SSS() - GetS(x).S2.S3.A = "1" - End Sub - - Private Shared Function GetS(ByRef x As SSS) As SSSS - Return x.S - End Function -End Class - Await TestExtractMethodAsync(code, expected, dontPutOutOrRefOnStruct:=False) - End Function End Class End Class End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.LanguageInteraction.vb b/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.LanguageInteraction.vb index b2aa1f15e63ea..60c7582d541a0 100644 --- a/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.LanguageInteraction.vb +++ b/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.LanguageInteraction.vb @@ -3247,36 +3247,6 @@ End Module Await TestExtractMethodAsync(code, expected) End Function - - Public Async Function TestDoNotPutOutOrRefOnStructOff() As Task - Dim code = - -Imports System.Threading.Tasks - -Namespace ClassLibrary9 - Public Structure S - Public I As Integer - End Structure - - Public Class Class1 - Public Async Function Test() As Task(Of Integer) - Dim s = New S() - s.I = 10 - - [|Dim i = Await Task.Run(Function() - Dim i2 = s.I - Return Test() - End Function)|] - - Return i - End Function - End Class -End Namespace - - - Await ExpectExtractMethodToFailAsync(code, dontPutOutOrRefOnStruct:=False) - End Function - Public Async Function TestDoNotPutOutOrRefOnStructOn() As Task Dim code = @@ -3332,7 +3302,7 @@ Namespace ClassLibrary9 End Class End Namespace - Await TestExtractMethodAsync(code, expected, dontPutOutOrRefOnStruct:=True) + Await TestExtractMethodAsync(code, expected) End Function diff --git a/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.vb b/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.vb index 90cc85ab1c821..ef0e156145c7a 100644 --- a/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.vb +++ b/src/EditorFeatures/VisualBasicTest/ExtractMethod/ExtractMethodTests.vb @@ -8,8 +8,6 @@ Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.CodeGeneration Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions -Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces -Imports Microsoft.CodeAnalysis.ExtractMethod Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.Text.Shared.Extensions Imports Microsoft.CodeAnalysis.UnitTests @@ -20,13 +18,13 @@ Imports Microsoft.VisualStudio.Text Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ExtractMethod <[UseExportProvider]> Partial Public Class ExtractMethodTests - Protected Shared Async Function ExpectExtractMethodToFailAsync(codeWithMarker As XElement, Optional dontPutOutOrRefOnStruct As Boolean = True) As Tasks.Task + Protected Shared Async Function ExpectExtractMethodToFailAsync(codeWithMarker As XElement) As Tasks.Task Dim codeWithoutMarker As String = Nothing Dim textSpan As TextSpan MarkupTestFile.GetSpan(codeWithMarker.NormalizedValue, codeWithoutMarker, textSpan) Using workspace = EditorTestWorkspace.CreateVisualBasic(codeWithoutMarker) - Dim treeAfterExtractMethod = Await ExtractMethodAsync(workspace, workspace.Documents.First(), textSpan, succeeded:=False, dontPutOutOrRefOnStruct:=dontPutOutOrRefOnStruct) + Dim treeAfterExtractMethod = Await ExtractMethodAsync(workspace, workspace.Documents.First(), textSpan, succeeded:=False) End Using End Function @@ -46,7 +44,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ExtractMethod codeWithMarker As String, expected As String, Optional temporaryFailing As Boolean = False, - Optional dontPutOutOrRefOnStruct As Boolean = True, Optional metadataReference As String = Nothing ) As Tasks.Task @@ -58,7 +55,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ExtractMethod Dim subjectBuffer = document.GetTextBuffer() Dim textSpan = document.SelectedSpans.First() - Dim tree = Await ExtractMethodAsync(workspace, workspace.Documents.First(), textSpan, dontPutOutOrRefOnStruct:=dontPutOutOrRefOnStruct) + Dim tree = Await ExtractMethodAsync(workspace, workspace.Documents.First(), textSpan) Using edit = subjectBuffer.CreateEdit() edit.Replace(0, edit.Snapshot.Length, tree.ToFullString()) @@ -81,28 +78,24 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ExtractMethod codeWithMarker As XElement, expected As XElement, Optional temporaryFailing As Boolean = False, - Optional dontPutOutOrRefOnStruct As Boolean = True, Optional metadataReference As String = Nothing ) As Tasks.Task - Await TestExtractMethodAsync(codeWithMarker.NormalizedValue, expected.NormalizedValue, temporaryFailing, dontPutOutOrRefOnStruct, metadataReference) + Await TestExtractMethodAsync(codeWithMarker.NormalizedValue, expected.NormalizedValue, temporaryFailing, metadataReference) End Function Private Shared Async Function ExtractMethodAsync( workspace As EditorTestWorkspace, testDocument As EditorTestHostDocument, textSpan As TextSpan, - Optional succeeded As Boolean = True, - Optional dontPutOutOrRefOnStruct As Boolean = True) As Tasks.Task(Of SyntaxNode) + Optional succeeded As Boolean = True) As Task(Of SyntaxNode) Dim snapshotSpan = textSpan.ToSnapshotSpan(testDocument.GetTextBuffer().CurrentSnapshot) Dim document = workspace.CurrentSolution.GetDocument(testDocument.Id) Assert.NotNull(document) - Dim extractOptions = New ExtractMethodOptions() With {.DoNotPutOutOrRefOnStruct = dontPutOutOrRefOnStruct} - Dim sdocument = Await SemanticDocument.CreateAsync(document, CancellationToken.None) - Dim validator = New VisualBasicSelectionValidator(sdocument, snapshotSpan.Span.ToTextSpan(), extractOptions) + Dim validator = New VisualBasicSelectionValidator(sdocument, snapshotSpan.Span.ToTextSpan()) Dim tuple = Await validator.GetValidSelectionAsync(CancellationToken.None) Dim selectedCode = tuple.Item1 @@ -114,8 +107,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ExtractMethod ' extract method Dim extractGenerationOptions = VBOptionsFactory.CreateExtractMethodGenerationOptions( CodeGenerationOptions.GetDefault(document.Project.Services), - CodeCleanupOptions.GetDefault(document.Project.Services), - extractOptions) + CodeCleanupOptions.GetDefault(document.Project.Services)) Dim extractor = New VisualBasicMethodExtractor(selectedCode, extractGenerationOptions) Dim result = extractor.ExtractMethod(status, CancellationToken.None) @@ -145,7 +137,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ExtractMethod Assert.NotNull(document) Dim sdocument = Await SemanticDocument.CreateAsync(document, CancellationToken.None) - Dim validator = New VisualBasicSelectionValidator(sdocument, namedSpans("b").Single(), ExtractMethodOptions.Default) + Dim validator = New VisualBasicSelectionValidator(sdocument, namedSpans("b").Single()) Dim tuple = Await validator.GetValidSelectionAsync(CancellationToken.None) Dim result = tuple.Item1 Dim status = tuple.Item2 @@ -180,7 +172,7 @@ End Class For Each node In iterator Try - Dim validator = New VisualBasicSelectionValidator(sdocument, node.Span, ExtractMethodOptions.Default) + Dim validator = New VisualBasicSelectionValidator(sdocument, node.Span) Dim tuple = Await validator.GetValidSelectionAsync(CancellationToken.None) Dim result = tuple.Item1 Dim status = tuple.Item2 diff --git a/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs index f602fc0a057ac..83c9afc98ef22 100644 --- a/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertPrimaryToRegularConstructor/ConvertPrimaryToRegularConstructorCodeRefactoringProvider.cs @@ -57,7 +57,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte context.RegisterRefactoring(CodeAction.Create( CSharpFeaturesResources.Convert_to_regular_constructor, - cancellationToken => ConvertAsync(document, typeDeclaration, typeDeclaration.ParameterList, context.Options, cancellationToken), + cancellationToken => ConvertAsync(document, typeDeclaration, typeDeclaration.ParameterList, cancellationToken), nameof(CSharpFeaturesResources.Convert_to_regular_constructor)), triggerSpan); } @@ -66,7 +66,6 @@ private static async Task ConvertAsync( Document document, TypeDeclarationSyntax typeDeclaration, ParameterListSyntax parameterList, - CodeActionOptionsProvider optionsProvider, CancellationToken cancellationToken) { var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); @@ -75,6 +74,7 @@ private static async Task ConvertAsync( var semanticModel = await GetSemanticModelAsync(document).ConfigureAwait(false); var contextInfo = await document.GetCodeGenerationInfoAsync(CodeGenerationContext.Default, cancellationToken).ConfigureAwait(false); + var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); // The naming rule we need to follow if we synthesize new private fields. var fieldNameRule = await document.GetApplicableNamingRuleAsync( @@ -379,7 +379,6 @@ async Task RewritePrimaryConstructorParameterReferencesAsync() void FixParameterAndBaseArgumentListIndentation() { var currentRoot = mainDocumentEditor.GetChangedRoot(); - var formattingOptions = optionsProvider.GetOptions(document.Project.Services).CleanupOptions.FormattingOptions; var indentationOptions = new IndentationOptions(formattingOptions); var formattedRoot = Formatter.Format(currentRoot, SyntaxAnnotation.ElasticAnnotation, solution.Services, formattingOptions, cancellationToken); diff --git a/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs index fb7e0ac174695..90c1735d4be85 100644 --- a/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertToRawString/ConvertStringToRawStringCodeRefactoringProvider.cs @@ -76,7 +76,6 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (token.Parent is not ExpressionSyntax parentExpression) return; - var options = context.Options; var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var parsedDocument = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpExtractMethodService.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpExtractMethodService.cs index f3f4f4e58269e..3d44fda77430b 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpExtractMethodService.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpExtractMethodService.cs @@ -22,8 +22,8 @@ internal sealed class CSharpExtractMethodService() : AbstractExtractMethodServic StatementSyntax, ExpressionSyntax> { - protected override CSharpSelectionValidator CreateSelectionValidator(SemanticDocument document, TextSpan textSpan, ExtractMethodOptions options, bool localFunction) - => new(document, textSpan, options, localFunction); + protected override CSharpSelectionValidator CreateSelectionValidator(SemanticDocument document, TextSpan textSpan, bool localFunction) + => new(document, textSpan, localFunction); protected override CSharpMethodExtractor CreateMethodExtractor(CSharpSelectionResult selectionResult, ExtractMethodGenerationOptions options, bool localFunction) => new(selectionResult, options, localFunction); diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.ExpressionResult.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.ExpressionResult.cs index 03124561276a5..46fc988d86f19 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.ExpressionResult.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.ExpressionResult.cs @@ -18,13 +18,12 @@ internal partial class CSharpSelectionResult private class ExpressionResult( TextSpan originalSpan, TextSpan finalSpan, - ExtractMethodOptions options, bool selectionInExpression, SemanticDocument document, SyntaxAnnotation firstTokenAnnotation, SyntaxAnnotation lastTokenAnnotation, bool selectionChanged) : CSharpSelectionResult( - originalSpan, finalSpan, options, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation, selectionChanged) + originalSpan, finalSpan, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation, selectionChanged) { public override bool ContainingScopeHasAsyncKeyword() => false; diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs index 72feb50438609..6a5d7d34f4ab0 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs @@ -18,13 +18,12 @@ internal partial class CSharpSelectionResult private class StatementResult( TextSpan originalSpan, TextSpan finalSpan, - ExtractMethodOptions options, bool selectionInExpression, SemanticDocument document, SyntaxAnnotation firstTokenAnnotation, SyntaxAnnotation lastTokenAnnotation, bool selectionChanged) : CSharpSelectionResult( - originalSpan, finalSpan, options, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation, selectionChanged) + originalSpan, finalSpan, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation, selectionChanged) { public override bool ContainingScopeHasAsyncKeyword() { diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.cs index 32625c75f94ce..dc66109b8074d 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.cs @@ -24,7 +24,6 @@ internal abstract partial class CSharpSelectionResult : SelectionResult CreateAsync( TextSpan originalSpan, TextSpan finalSpan, - ExtractMethodOptions options, bool selectionInExpression, SemanticDocument document, SyntaxToken firstToken, @@ -49,13 +48,13 @@ public static async Task CreateAsync( if (selectionInExpression) { return new ExpressionResult( - originalSpan, finalSpan, options, selectionInExpression, + originalSpan, finalSpan, selectionInExpression, newDocument, firstTokenAnnotation, lastTokenAnnotation, selectionChanged); } else { return new StatementResult( - originalSpan, finalSpan, options, selectionInExpression, + originalSpan, finalSpan, selectionInExpression, newDocument, firstTokenAnnotation, lastTokenAnnotation, selectionChanged); } } @@ -63,13 +62,12 @@ public static async Task CreateAsync( protected CSharpSelectionResult( TextSpan originalSpan, TextSpan finalSpan, - ExtractMethodOptions options, bool selectionInExpression, SemanticDocument document, SyntaxAnnotation firstTokenAnnotation, SyntaxAnnotation lastTokenAnnotation, bool selectionChanged) - : base(originalSpan, finalSpan, options, selectionInExpression, + : base(originalSpan, finalSpan, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation, selectionChanged) { } diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionValidator.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionValidator.cs index 1e0195d297e03..d1588027fd7b5 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionValidator.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionValidator.cs @@ -23,8 +23,7 @@ namespace Microsoft.CodeAnalysis.CSharp.ExtractMethod; internal partial class CSharpSelectionValidator( SemanticDocument document, TextSpan textSpan, - ExtractMethodOptions options, - bool localFunction) : SelectionValidator(document, textSpan, options) + bool localFunction) : SelectionValidator(document, textSpan) { private readonly bool _localFunction = localFunction; @@ -75,7 +74,6 @@ internal partial class CSharpSelectionValidator( var result = await CSharpSelectionResult.CreateAsync( selectionInfo.OriginalSpan, selectionInfo.FinalSpan, - Options, selectionInfo.SelectionInExpression, doc, selectionInfo.FirstTokenInFinalSpan, diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs index 07158eeb295dc..39c7e84ef890e 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs @@ -68,7 +68,6 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // Haven't initialized any fields/properties with this parameter. Offer to assign to an existing matching // field/prop if we can find one, or add a new field/prop if we can't. - var fallbackOptions = context.Options; var rules = await document.GetNamingRulesAsync(cancellationToken).ConfigureAwait(false); var parameterNameParts = IdentifierNameParts.CreateIdentifierNameParts(parameter, rules); if (parameterNameParts.BaseName == "") @@ -157,10 +156,10 @@ IEnumerable HandleNoExistingFieldOrProperty() var fieldAction = CreateCodeAction( string.Format(FeaturesResources.Create_and_assign_field_0, field.Name), - cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, [parameter], [field], fallbackOptions, cancellationToken)); + cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, [parameter], [field], cancellationToken)); var propertyAction = CreateCodeAction( string.Format(FeaturesResources.Create_and_assign_property_0, property.Name), - cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, [parameter], [property], fallbackOptions, cancellationToken)); + cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, [parameter], [property], cancellationToken)); yield return siblingFieldOrProperty is IFieldSymbol ? fieldAction : propertyAction; yield return siblingFieldOrProperty is IFieldSymbol ? propertyAction : fieldAction; @@ -170,10 +169,10 @@ IEnumerable HandleNoExistingFieldOrProperty() { var allFieldsAction = CodeAction.Create( FeaturesResources.Create_and_assign_remaining_as_fields, - cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, parameters, parameters.SelectAsArray(CreateField), fallbackOptions, cancellationToken)); + cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, parameters, parameters.SelectAsArray(CreateField), cancellationToken)); var allPropertiesAction = CodeAction.Create( FeaturesResources.Create_and_assign_remaining_as_properties, - cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, parameters, parameters.SelectAsArray(CreateProperty), fallbackOptions, cancellationToken)); + cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, parameters, parameters.SelectAsArray(CreateProperty), cancellationToken)); yield return siblingFieldOrProperty is IFieldSymbol ? allFieldsAction : allPropertiesAction; yield return siblingFieldOrProperty is IFieldSymbol ? allPropertiesAction : allFieldsAction; diff --git a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs index 9cd99f371eedd..21de8b268e97f 100644 --- a/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs +++ b/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider_Update.cs @@ -30,7 +30,6 @@ private static async Task AddMultipleMembersAsync( TypeDeclarationSyntax typeDeclaration, ImmutableArray parameters, ImmutableArray fieldsOrProperties, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { Debug.Assert(parameters.Length >= 1); @@ -66,7 +65,6 @@ private static async Task AddMultipleMembersAsync( currentTypeDeclaration, currentParameter, fieldOrProperty, - fallbackOptions, cancellationToken).ConfigureAwait(false); } @@ -81,7 +79,6 @@ static async Task AddSingleMemberAsync( TypeDeclarationSyntax typeDeclaration, IParameterSymbol parameter, ISymbol fieldOrProperty, - CodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var project = document.Project; diff --git a/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceLocalForExpressionCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceLocalForExpressionCodeRefactoringProvider.cs index ad85222af598f..7d96adc036d07 100644 --- a/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceLocalForExpressionCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceLocalForExpressionCodeRefactoringProvider.cs @@ -88,7 +88,6 @@ protected override ExpressionStatementSyntax FixupDeconstruction( protected override async Task CreateTupleDeconstructionAsync( Document document, - CodeActionOptionsProvider optionsProvider, INamedTypeSymbol tupleType, ExpressionSyntax expression, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs index e58d370f34b55..65f019826fb69 100644 --- a/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs @@ -47,7 +47,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (cancellationToken.IsCancellationRequested) return; - var extractOptions = await document.GetExtractMethodGenerationOptionsAsync(context.Options, cancellationToken).ConfigureAwait(false); + var extractOptions = await document.GetExtractMethodGenerationOptionsAsync(cancellationToken).ConfigureAwait(false); var actions = await GetCodeActionsAsync(document, textSpan, extractOptions, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); diff --git a/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.State.cs b/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.State.cs index c3df9cc5a74c4..3de31e50f3ba9 100644 --- a/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.State.cs +++ b/src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.State.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using System.Threading; -using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -18,24 +17,22 @@ internal abstract partial class AbstractMoveTypeService public static SyntaxAnnotation NamespaceScopeMovedAnnotation = new(nameof(MoveTypeOperationKind.MoveTypeNamespaceScope)); - public abstract Task GetModifiedSolutionAsync(Document document, TextSpan textSpan, MoveTypeOperationKind operationKind, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); - public abstract Task> GetRefactoringAsync(Document document, TextSpan textSpan, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + public abstract Task GetModifiedSolutionAsync(Document document, TextSpan textSpan, MoveTypeOperationKind operationKind, CancellationToken cancellationToken); + public abstract Task> GetRefactoringAsync(Document document, TextSpan textSpan, CancellationToken cancellationToken); } internal abstract partial class AbstractMoveTypeService : @@ -42,9 +42,9 @@ internal abstract partial class AbstractMoveTypeService> GetRefactoringAsync( - Document document, TextSpan textSpan, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, TextSpan textSpan, CancellationToken cancellationToken) { - var state = await CreateStateAsync(document, textSpan, fallbackOptions, cancellationToken).ConfigureAwait(false); + var state = await CreateStateAsync(document, textSpan, cancellationToken).ConfigureAwait(false); if (state == null) { @@ -55,9 +55,9 @@ public override async Task> GetRefactoringAsync( return actions; } - public override async Task GetModifiedSolutionAsync(Document document, TextSpan textSpan, MoveTypeOperationKind operationKind, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public override async Task GetModifiedSolutionAsync(Document document, TextSpan textSpan, MoveTypeOperationKind operationKind, CancellationToken cancellationToken) { - var state = await CreateStateAsync(document, textSpan, fallbackOptions, cancellationToken).ConfigureAwait(false); + var state = await CreateStateAsync(document, textSpan, cancellationToken).ConfigureAwait(false); if (state == null) { @@ -79,7 +79,7 @@ public override async Task GetModifiedSolutionAsync(Document document, protected abstract Task GetRelevantNodeAsync(Document document, TextSpan textSpan, CancellationToken cancellationToken); - private async Task CreateStateAsync(Document document, TextSpan textSpan, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private async Task CreateStateAsync(Document document, TextSpan textSpan, CancellationToken cancellationToken) { var nodeToAnalyze = await GetRelevantNodeAsync(document, textSpan, cancellationToken).ConfigureAwait(false); if (nodeToAnalyze == null) @@ -88,7 +88,7 @@ private async Task CreateStateAsync(Document document, TextSpan textSpan, } var semanticDocument = await SemanticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); - return State.Generate(semanticDocument, nodeToAnalyze, fallbackOptions, cancellationToken); + return State.Generate(semanticDocument, nodeToAnalyze, cancellationToken); } private ImmutableArray CreateActions(State state, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/CodeRefactorings/MoveType/IMoveTypeService.cs b/src/Features/Core/Portable/CodeRefactorings/MoveType/IMoveTypeService.cs index bec8a8a4f3846..23c02bfa1ca52 100644 --- a/src/Features/Core/Portable/CodeRefactorings/MoveType/IMoveTypeService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/MoveType/IMoveTypeService.cs @@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.CodeRefactorings.MoveType; internal interface IMoveTypeService : ILanguageService { - Task> GetRefactoringAsync(Document document, TextSpan textSpan, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task> GetRefactoringAsync(Document document, TextSpan textSpan, CancellationToken cancellationToken); - Task GetModifiedSolutionAsync(Document document, TextSpan textSpan, MoveTypeOperationKind operationKind, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task GetModifiedSolutionAsync(Document document, TextSpan textSpan, MoveTypeOperationKind operationKind, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs b/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs index c33cb8c371203..acf73a0697624 100644 --- a/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs @@ -29,7 +29,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte return; var service = document.GetRequiredLanguageService(); - var actions = await service.GetRefactoringAsync(document, textSpan, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await service.GetRefactoringAsync(document, textSpan, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index 757f30f9b1531..a87d8135ad542 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -48,9 +48,9 @@ protected abstract Task UpdateMembersWithExplicitImplementationsAsync( internal abstract bool ShouldIncludeAccessibilityModifier(SyntaxNode typeNode); - public async Task> GetExtractInterfaceCodeActionAsync(Document document, TextSpan span, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public async Task> GetExtractInterfaceCodeActionAsync(Document document, TextSpan span, CancellationToken cancellationToken) { - var typeAnalysisResult = await AnalyzeTypeAtPositionAsync(document, span.Start, TypeDiscoveryRule.TypeNameOnly, fallbackOptions, cancellationToken).ConfigureAwait(false); + var typeAnalysisResult = await AnalyzeTypeAtPositionAsync(document, span.Start, TypeDiscoveryRule.TypeNameOnly, cancellationToken).ConfigureAwait(false); return typeAnalysisResult.CanExtractInterface ? [new ExtractInterfaceCodeAction(this, typeAnalysisResult)] @@ -60,7 +60,6 @@ public async Task> GetExtractInterfac public async Task ExtractInterfaceAsync( Document documentWithTypeToExtractFrom, int position, - CleanCodeGenerationOptionsProvider fallbackOptions, Action errorHandler, CancellationToken cancellationToken) { @@ -68,7 +67,6 @@ public async Task ExtractInterfaceAsync( documentWithTypeToExtractFrom, position, TypeDiscoveryRule.TypeDeclaration, - fallbackOptions, cancellationToken).ConfigureAwait(false); if (!typeAnalysisResult.CanExtractInterface) @@ -77,14 +75,13 @@ public async Task ExtractInterfaceAsync( return new ExtractInterfaceResult(succeeded: false); } - return await ExtractInterfaceFromAnalyzedTypeAsync(typeAnalysisResult, fallbackOptions, cancellationToken).ConfigureAwait(false); + return await ExtractInterfaceFromAnalyzedTypeAsync(typeAnalysisResult, cancellationToken).ConfigureAwait(false); } public async Task AnalyzeTypeAtPositionAsync( Document document, int position, TypeDiscoveryRule typeDiscoveryRule, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var typeNode = await GetTypeDeclarationAsync(document, position, typeDiscoveryRule, cancellationToken).ConfigureAwait(false); @@ -110,10 +107,10 @@ public async Task AnalyzeTypeAtPositionAsync return new ExtractInterfaceTypeAnalysisResult(errorMessage); } - return new ExtractInterfaceTypeAnalysisResult(document, typeNode, typeToExtractFrom, extractableMembers, fallbackOptions); + return new ExtractInterfaceTypeAnalysisResult(document, typeNode, typeToExtractFrom, extractableMembers); } - public async Task ExtractInterfaceFromAnalyzedTypeAsync(ExtractInterfaceTypeAnalysisResult refactoringResult, CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + public async Task ExtractInterfaceFromAnalyzedTypeAsync(ExtractInterfaceTypeAnalysisResult refactoringResult, CancellationToken cancellationToken) { var containingNamespaceDisplay = refactoringResult.TypeToExtractFrom.ContainingNamespace.IsGlobalNamespace ? string.Empty @@ -124,7 +121,6 @@ public async Task ExtractInterfaceFromAnalyzedTypeAsync( refactoringResult.TypeToExtractFrom, refactoringResult.ExtractableMembers, containingNamespaceDisplay, - fallbackOptions, cancellationToken).ConfigureAwait(false); if (extractInterfaceOptions.IsCancelled) @@ -261,7 +257,6 @@ internal static async Task GetExtractInterfaceOpt INamedTypeSymbol type, IEnumerable extractableMembers, string containingNamespace, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var conflictingTypeNames = type.ContainingNamespace.GetAllTypes(cancellationToken).Select(t => t.Name); @@ -282,7 +277,6 @@ internal static async Task GetExtractInterfaceOpt containingNamespace, generatedNameTypeParameterSuffix, document.Project.Language, - fallbackOptions, cancellationToken).ConfigureAwait(false); } diff --git a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeAction.cs b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeAction.cs index c1aa2679f3f9a..c64eefa52fa33 100644 --- a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeAction.cs +++ b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeAction.cs @@ -27,7 +27,6 @@ public override object GetOptions(CancellationToken cancellationToken) _typeAnalysisResult.TypeToExtractFrom, _typeAnalysisResult.ExtractableMembers, containingNamespaceDisplay, - _typeAnalysisResult.FallbackOptions, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); } diff --git a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs index f91cd107aebe2..94d92966ba688 100644 --- a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceCodeRefactoringProvider.cs @@ -27,7 +27,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex { var (document, textSpan, cancellationToken) = context; var service = document.GetLanguageService(); - var actions = await service.GetExtractInterfaceCodeActionAsync(document, textSpan, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await service.GetExtractInterfaceCodeActionAsync(document, textSpan, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceOptionsResult.cs b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceOptionsResult.cs index b2b0bf0b36726..f186245b92dc7 100644 --- a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceOptionsResult.cs +++ b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceOptionsResult.cs @@ -5,7 +5,6 @@ #nullable disable using System.Collections.Immutable; -using Microsoft.CodeAnalysis.CodeGeneration; namespace Microsoft.CodeAnalysis.ExtractInterface; @@ -24,15 +23,13 @@ public enum ExtractLocation public string InterfaceName { get; } public string FileName { get; } public ExtractLocation Location { get; } - public CleanCodeGenerationOptionsProvider FallbackOptions { get; } - public ExtractInterfaceOptionsResult(bool isCancelled, ImmutableArray includedMembers, string interfaceName, string fileName, ExtractLocation location, CleanCodeGenerationOptionsProvider fallbackOptions) + public ExtractInterfaceOptionsResult(bool isCancelled, ImmutableArray includedMembers, string interfaceName, string fileName, ExtractLocation location) { IsCancelled = isCancelled; IncludedMembers = includedMembers; InterfaceName = interfaceName; Location = location; - FallbackOptions = fallbackOptions; FileName = fileName; } diff --git a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs index e8f4f5035db1b..de7bc70976ace 100644 --- a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs +++ b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs @@ -5,7 +5,6 @@ #nullable disable using System.Collections.Generic; -using Microsoft.CodeAnalysis.CodeGeneration; namespace Microsoft.CodeAnalysis.ExtractInterface; @@ -16,22 +15,19 @@ internal sealed class ExtractInterfaceTypeAnalysisResult public readonly SyntaxNode TypeNode; public readonly INamedTypeSymbol TypeToExtractFrom; public readonly IEnumerable ExtractableMembers; - public readonly CleanCodeGenerationOptionsProvider FallbackOptions; public readonly string ErrorMessage; public ExtractInterfaceTypeAnalysisResult( Document documentToExtractFrom, SyntaxNode typeNode, INamedTypeSymbol typeToExtractFrom, - IEnumerable extractableMembers, - CleanCodeGenerationOptionsProvider fallbackOptions) + IEnumerable extractableMembers) { CanExtractInterface = true; DocumentToExtractFrom = documentToExtractFrom; TypeNode = typeNode; TypeToExtractFrom = typeToExtractFrom; ExtractableMembers = extractableMembers; - FallbackOptions = fallbackOptions; } public ExtractInterfaceTypeAnalysisResult(string errorMessage) diff --git a/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs b/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs index eb4f5821eb6ea..321916dd932b3 100644 --- a/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs +++ b/src/Features/Core/Portable/ExtractInterface/IExtractInterfaceOptionsService.cs @@ -25,6 +25,5 @@ Task GetExtractInterfaceOptionsAsync( string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); } diff --git a/src/Features/Core/Portable/ExtractMethod/AbstractExtractMethodService.cs b/src/Features/Core/Portable/ExtractMethod/AbstractExtractMethodService.cs index 233276566dab2..e29634f9a690d 100644 --- a/src/Features/Core/Portable/ExtractMethod/AbstractExtractMethodService.cs +++ b/src/Features/Core/Portable/ExtractMethod/AbstractExtractMethodService.cs @@ -20,7 +20,7 @@ internal abstract class AbstractExtractMethodService< where TStatementSyntax : SyntaxNode where TExpressionSyntax : SyntaxNode { - protected abstract TValidator CreateSelectionValidator(SemanticDocument document, TextSpan textSpan, ExtractMethodOptions options, bool localFunction); + protected abstract TValidator CreateSelectionValidator(SemanticDocument document, TextSpan textSpan, bool localFunction); protected abstract TExtractor CreateMethodExtractor(TSelectionResult selectionResult, ExtractMethodGenerationOptions options, bool localFunction); public async Task ExtractMethodAsync( @@ -32,7 +32,7 @@ public async Task ExtractMethodAsync( { var semanticDocument = await SemanticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); - var validator = CreateSelectionValidator(semanticDocument, textSpan, options.ExtractOptions, localFunction); + var validator = CreateSelectionValidator(semanticDocument, textSpan, localFunction); var (selectionResult, status) = await validator.GetValidSelectionAsync(cancellationToken).ConfigureAwait(false); if (selectionResult is null) diff --git a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs index 1e284257313db..6bf5825826a19 100644 --- a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs +++ b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs @@ -589,12 +589,6 @@ private bool TryGetVariableStyle( return true; } - if (UserDefinedValueType(model.Compilation, type) && !SelectionResult.Options.DoNotPutOutOrRefOnStruct) - { - variableStyle = AlwaysReturn(variableStyle); - return true; - } - // for captured variable, never try to move the decl into extracted method if (captured && variableStyle == VariableStyle.MoveIn) { @@ -653,32 +647,6 @@ private bool SelectionContainsOnlyIdentifierWithSameType(ITypeSymbol type) return type.Equals(SelectionResult.GetContainingScopeType()); } - private static bool UserDefinedValueType(Compilation compilation, ITypeSymbol type) - { - if (!type.IsValueType || type is IPointerTypeSymbol || type.IsEnumType()) - { - return false; - } - - return type.OriginalDefinition.SpecialType == SpecialType.None && !WellKnownFrameworkValueType(compilation, type); - } - - private static bool WellKnownFrameworkValueType(Compilation compilation, ITypeSymbol type) - { - if (!type.IsValueType) - { - return false; - } - - var cancellationTokenType = compilation.GetTypeByMetadataName(typeof(CancellationToken).FullName!); - if (cancellationTokenType != null && cancellationTokenType.Equals(type)) - { - return true; - } - - return false; - } - protected virtual ITypeSymbol GetSymbolType(SemanticModel model, ISymbol symbol) => symbol switch { diff --git a/src/Features/Core/Portable/ExtractMethod/SelectionResult.cs b/src/Features/Core/Portable/ExtractMethod/SelectionResult.cs index 4e13e4cacc33b..63f9bc8fe2e2e 100644 --- a/src/Features/Core/Portable/ExtractMethod/SelectionResult.cs +++ b/src/Features/Core/Portable/ExtractMethod/SelectionResult.cs @@ -24,7 +24,6 @@ internal abstract class SelectionResult protected SelectionResult( TextSpan originalSpan, TextSpan finalSpan, - ExtractMethodOptions options, bool selectionInExpression, SemanticDocument document, SyntaxAnnotation firstTokenAnnotation, @@ -35,7 +34,6 @@ protected SelectionResult( FinalSpan = finalSpan; SelectionInExpression = selectionInExpression; - Options = options; FirstTokenAnnotation = firstTokenAnnotation; LastTokenAnnotation = lastTokenAnnotation; @@ -67,7 +65,6 @@ public ITypeSymbol GetContainingScopeType() public TextSpan OriginalSpan { get; } public TextSpan FinalSpan { get; } - public ExtractMethodOptions Options { get; } public bool SelectionInExpression { get; } public SemanticDocument SemanticDocument { get; private set; } public SyntaxAnnotation FirstTokenAnnotation { get; } diff --git a/src/Features/Core/Portable/ExtractMethod/SelectionValidator.cs b/src/Features/Core/Portable/ExtractMethod/SelectionValidator.cs index 5c542469702a4..9b78f4bc5cb5d 100644 --- a/src/Features/Core/Portable/ExtractMethod/SelectionValidator.cs +++ b/src/Features/Core/Portable/ExtractMethod/SelectionValidator.cs @@ -21,14 +21,12 @@ internal abstract partial class SelectionValidator< TSelectionResult, TStatementSyntax>( SemanticDocument document, - TextSpan textSpan, - ExtractMethodOptions options) + TextSpan textSpan) where TSelectionResult : SelectionResult where TStatementSyntax : SyntaxNode { protected readonly SemanticDocument SemanticDocument = document; protected readonly TextSpan OriginalSpan = textSpan; - protected readonly ExtractMethodOptions Options = options; public bool ContainsValidSelection => !OriginalSpan.IsEmpty; diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs index 2a4a3598d0c5e..53e7d8f5634a1 100644 --- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs +++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.DisposePatternCodeAction.cs @@ -318,27 +318,7 @@ private IMethodSymbol CreateDisposeInterfaceMethod( return result; } - /// - /// This helper is implementing access to the editorconfig option. This would usually be done via but - /// we do not have access to here since the code action implementation is also used to implement . - /// TODO: remove - see https://github.com/dotnet/roslyn/issues/60990. - /// - public async ValueTask GetAccessibilityModifiersRequiredAsync(Document document, CancellationToken cancellationToken) - { - var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - var configOptions = document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree); - - if (configOptions.TryGetEditorConfigOption>(CodeStyleOptions2.AccessibilityModifiersRequired, out var value)) - { - return value.Value; - } - - var fallbackFormattingOptions = await ((OptionsProvider)Options.FallbackOptions).GetOptionsAsync(document.Project.Services, cancellationToken).ConfigureAwait(false); - - return fallbackFormattingOptions.AccessibilityModifiersRequired; - } - - private async Task CreateDisposedValueFieldAsync( + private static async Task CreateDisposedValueFieldAsync( Document document, INamedTypeSymbol containingType, CancellationToken cancellationToken) @@ -346,11 +326,10 @@ private async Task CreateDisposedValueFieldAsync( var rule = await document.GetApplicableNamingRuleAsync( SymbolKind.Field, Accessibility.Private, cancellationToken).ConfigureAwait(false); - var requireAccessiblity = await GetAccessibilityModifiersRequiredAsync(document, cancellationToken).ConfigureAwait(false); - + var options = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var boolType = compilation.GetSpecialType(SpecialType.System_Boolean); - var accessibilityLevel = requireAccessiblity is AccessibilityModifiersRequired.Never or AccessibilityModifiersRequired.OmitIfDefault + var accessibilityLevel = options.AccessibilityModifiersRequired is AccessibilityModifiersRequired.Never or AccessibilityModifiersRequired.OmitIfDefault ? Accessibility.NotApplicable : Accessibility.Private; diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs b/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs index 6bf4ec9fcb46e..3fb4cc930394f 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs @@ -55,7 +55,6 @@ protected override async Task> GetRefactoringsForAllP IBlockOperation? blockStatementOpt, ImmutableArray listOfParameterNodes, TextSpan parameterSpan, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // List to keep track of the valid parameters @@ -87,7 +86,6 @@ protected override async Task> GetRefactoringsForSing SyntaxNode functionDeclaration, IMethodSymbol methodSymbol, IBlockOperation? blockStatementOpt, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs index 4007137e18a60..20f2aff096efe 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs @@ -52,7 +52,7 @@ internal abstract partial class AbstractInitializeMemberFromParameterCodeRefacto protected sealed override Task> GetRefactoringsForAllParametersAsync( Document document, SyntaxNode functionDeclaration, IMethodSymbol method, IBlockOperation? blockStatementOpt, ImmutableArray listOfParameterNodes, TextSpan parameterSpan, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) + CancellationToken cancellationToken) { return SpecializedTasks.EmptyImmutableArray(); } @@ -64,7 +64,6 @@ protected sealed override async Task> GetRefactorings SyntaxNode constructorDeclaration, IMethodSymbol method, IBlockOperation? blockStatement, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // Only supported for constructor parameters. diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs index b0865227daffa..cbdfd876cbb9c 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs @@ -42,7 +42,6 @@ protected abstract Task> GetRefactoringsForAllParamet IBlockOperation? blockStatement, ImmutableArray listOfParameterNodes, TextSpan parameterSpan, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); protected abstract Task> GetRefactoringsForSingleParameterAsync( @@ -52,7 +51,6 @@ protected abstract Task> GetRefactoringsForSinglePara SyntaxNode functionDeclaration, IMethodSymbol methodSymbol, IBlockOperation? blockStatement, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken); protected abstract void InsertStatement( @@ -104,7 +102,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // Ok. Looks like the selected parameter could be refactored. Defer to subclass to // actually determine if there are any viable refactorings here. var refactorings = await GetRefactoringsForSingleParameterAsync( - document, selectedParameter, parameter, functionDeclaration, methodSymbol, blockStatementOpt, context.Options, cancellationToken).ConfigureAwait(false); + document, selectedParameter, parameter, functionDeclaration, methodSymbol, blockStatementOpt, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(refactorings, context.Span); } @@ -125,7 +123,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte // actually determine if there are any viable refactorings here. var refactorings = await GetRefactoringsForAllParametersAsync( document, functionDeclaration, methodSymbol, blockStatementOpt, - listOfPotentiallyValidParametersNodes.ToImmutable(), selectedParameter.Span, context.Options, cancellationToken).ConfigureAwait(false); + listOfPotentiallyValidParametersNodes.ToImmutable(), selectedParameter.Span, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(refactorings, context.Span); } diff --git a/src/Features/Core/Portable/Intents/IntentDataProvider.cs b/src/Features/Core/Portable/Intents/IntentDataProvider.cs index 1b7c06fa111e5..737a21de6ccfd 100644 --- a/src/Features/Core/Portable/Intents/IntentDataProvider.cs +++ b/src/Features/Core/Portable/Intents/IntentDataProvider.cs @@ -5,14 +5,12 @@ using System; using System.Text.Json; using System.Text.Json.Serialization; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.ErrorReporting; namespace Microsoft.CodeAnalysis.Features.Intents; internal sealed class IntentDataProvider( - string? serializedIntentData, - CleanCodeGenerationOptionsProvider fallbackOptions) + string? serializedIntentData) { private static readonly Lazy s_serializerOptions = new Lazy(() => { @@ -24,8 +22,6 @@ internal sealed class IntentDataProvider( return serializerOptions; }); - public readonly CleanCodeGenerationOptionsProvider FallbackOptions = fallbackOptions; - private readonly string? _serializedIntentData = serializedIntentData; public T? GetIntentData() where T : class diff --git a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceLocalForExpressionCodeRefactoringProvider.cs b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceLocalForExpressionCodeRefactoringProvider.cs index a2ca5e25247a8..7805add83558e 100644 --- a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceLocalForExpressionCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceLocalForExpressionCodeRefactoringProvider.cs @@ -28,7 +28,7 @@ internal abstract class AbstractIntroduceLocalForExpressionCodeRefactoringProvid protected abstract TLocalDeclarationStatementSyntax FixupLocalDeclaration(TExpressionStatementSyntax expressionStatement, TLocalDeclarationStatementSyntax localDeclaration); protected abstract TExpressionStatementSyntax FixupDeconstruction(TExpressionStatementSyntax expressionStatement, TExpressionStatementSyntax localDeclaration); protected abstract Task CreateTupleDeconstructionAsync( - Document document, CodeActionOptionsProvider optionsProvider, INamedTypeSymbol tupleType, TExpressionSyntax expression, CancellationToken cancellationToken); + Document document, INamedTypeSymbol tupleType, TExpressionSyntax expression, CancellationToken cancellationToken); public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { @@ -55,7 +55,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex context.RegisterRefactoring( CodeAction.Create( string.Format(FeaturesResources.Deconstruct_locals_for_0, nodeString), - cancellationToken => IntroduceLocalAsync(document, context.Options, expressionStatement, type, deconstruct: true, cancellationToken), + cancellationToken => IntroduceLocalAsync(document, expressionStatement, type, deconstruct: true, cancellationToken), nameof(FeaturesResources.Deconstruct_locals_for_0) + "_" + nodeString), expressionStatement.Span); } @@ -63,7 +63,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex context.RegisterRefactoring( CodeAction.Create( string.Format(FeaturesResources.Introduce_local_for_0, nodeString), - cancellationToken => IntroduceLocalAsync(document, context.Options, expressionStatement, type, deconstruct: false, cancellationToken), + cancellationToken => IntroduceLocalAsync(document, expressionStatement, type, deconstruct: false, cancellationToken), nameof(FeaturesResources.Introduce_local_for_0) + "_" + nodeString), expressionStatement.Span); } @@ -78,7 +78,6 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex private async Task IntroduceLocalAsync( Document document, - CodeActionOptionsProvider optionsProvider, TExpressionStatementSyntax expressionStatement, ITypeSymbol type, bool deconstruct, @@ -112,7 +111,7 @@ async Task CreateLocalDeclarationAsync() { Contract.ThrowIfNull(type); return await this.CreateTupleDeconstructionAsync( - document, optionsProvider, (INamedTypeSymbol)type, expression, cancellationToken).ConfigureAwait(false); + document, (INamedTypeSymbol)type, expression, cancellationToken).ConfigureAwait(false); } else { diff --git a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveItemsToNamespaceCodeAction.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveItemsToNamespaceCodeAction.cs index 1e71055214629..6982779ebe024 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveItemsToNamespaceCodeAction.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveItemsToNamespaceCodeAction.cs @@ -2,14 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis.CodeCleanup; - namespace Microsoft.CodeAnalysis.MoveToNamespace; internal abstract partial class AbstractMoveToNamespaceCodeAction { - private sealed class MoveItemsToNamespaceCodeAction(IMoveToNamespaceService changeNamespaceService, MoveToNamespaceAnalysisResult analysisResult, CodeCleanupOptionsProvider cleanupOptions) - : AbstractMoveToNamespaceCodeAction(changeNamespaceService, analysisResult, cleanupOptions) + private sealed class MoveItemsToNamespaceCodeAction(IMoveToNamespaceService changeNamespaceService, MoveToNamespaceAnalysisResult analysisResult) + : AbstractMoveToNamespaceCodeAction(changeNamespaceService, analysisResult) { public override string Title => FeaturesResources.Move_contents_to_namespace; } diff --git a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveTypeToNamespaceCodeAction.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveTypeToNamespaceCodeAction.cs index 92ae0fd4a6584..9cb514dc1950e 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveTypeToNamespaceCodeAction.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.MoveTypeToNamespaceCodeAction.cs @@ -2,14 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis.CodeCleanup; - namespace Microsoft.CodeAnalysis.MoveToNamespace; internal abstract partial class AbstractMoveToNamespaceCodeAction { - private class MoveTypeToNamespaceCodeAction(IMoveToNamespaceService changeNamespaceService, MoveToNamespaceAnalysisResult analysisResult, CodeCleanupOptionsProvider cleanupOptions) - : AbstractMoveToNamespaceCodeAction(changeNamespaceService, analysisResult, cleanupOptions) + private class MoveTypeToNamespaceCodeAction(IMoveToNamespaceService changeNamespaceService, MoveToNamespaceAnalysisResult analysisResult) + : AbstractMoveToNamespaceCodeAction(changeNamespaceService, analysisResult) { public override string Title => FeaturesResources.Move_to_namespace; } diff --git a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.cs index 92160bfe57ea4..2f6670716e166 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceCodeAction.cs @@ -17,12 +17,10 @@ namespace Microsoft.CodeAnalysis.MoveToNamespace; internal abstract partial class AbstractMoveToNamespaceCodeAction( IMoveToNamespaceService moveToNamespaceService, - MoveToNamespaceAnalysisResult analysisResult, - CodeCleanupOptionsProvider cleanupOptions) : CodeActionWithOptions + MoveToNamespaceAnalysisResult analysisResult) : CodeActionWithOptions { private readonly IMoveToNamespaceService _moveToNamespaceService = moveToNamespaceService; private readonly MoveToNamespaceAnalysisResult _moveToNamespaceAnalysisResult = analysisResult; - private readonly CodeCleanupOptionsProvider _cleanupOptions = cleanupOptions; /// /// This code action does notify clients about the rename it performs. However, this is an optional part of @@ -50,7 +48,6 @@ protected sealed override async Task> ComputeOp var moveToNamespaceResult = await _moveToNamespaceService.MoveToNamespaceAsync( _moveToNamespaceAnalysisResult, moveToNamespaceOptions.Namespace, - _cleanupOptions, cancellationToken).ConfigureAwait(false); if (moveToNamespaceResult.Succeeded) @@ -89,11 +86,11 @@ private static ImmutableArray CreateRenameOperations(MoveTo return operations.ToImmutableAndClear(); } - public static AbstractMoveToNamespaceCodeAction Generate(IMoveToNamespaceService changeNamespaceService, MoveToNamespaceAnalysisResult analysisResult, CodeCleanupOptionsProvider cleanupOptions) + public static AbstractMoveToNamespaceCodeAction Generate(IMoveToNamespaceService changeNamespaceService, MoveToNamespaceAnalysisResult analysisResult) => analysisResult.Container switch { - MoveToNamespaceAnalysisResult.ContainerType.NamedType => new MoveTypeToNamespaceCodeAction(changeNamespaceService, analysisResult, cleanupOptions), - MoveToNamespaceAnalysisResult.ContainerType.Namespace => new MoveItemsToNamespaceCodeAction(changeNamespaceService, analysisResult, cleanupOptions), + MoveToNamespaceAnalysisResult.ContainerType.NamedType => new MoveTypeToNamespaceCodeAction(changeNamespaceService, analysisResult), + MoveToNamespaceAnalysisResult.ContainerType.Namespace => new MoveItemsToNamespaceCodeAction(changeNamespaceService, analysisResult), _ => throw ExceptionUtilities.UnexpectedValue(analysisResult.Container) }; } diff --git a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs index 28fd071e5eca4..ef0bc9927970e 100644 --- a/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs +++ b/src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs @@ -25,9 +25,9 @@ namespace Microsoft.CodeAnalysis.MoveToNamespace; internal interface IMoveToNamespaceService : ILanguageService { - Task> GetCodeActionsAsync(Document document, TextSpan span, CodeCleanupOptionsProvider options, CancellationToken cancellationToken); + Task> GetCodeActionsAsync(Document document, TextSpan span, CancellationToken cancellationToken); Task AnalyzeTypeAtPositionAsync(Document document, int position, CancellationToken cancellationToken); - Task MoveToNamespaceAsync(MoveToNamespaceAnalysisResult analysisResult, string targetNamespace, CodeCleanupOptionsProvider options, CancellationToken cancellationToken); + Task MoveToNamespaceAsync(MoveToNamespaceAnalysisResult analysisResult, string targetNamespace, CancellationToken cancellationToken); MoveToNamespaceOptionsResult GetChangeNamespaceOptions(Document document, string defaultNamespace, ImmutableArray namespaces); IMoveToNamespaceOptionsService OptionsService { get; } } @@ -50,7 +50,6 @@ protected AbstractMoveToNamespaceService(IMoveToNamespaceOptionsService moveToNa public async Task> GetCodeActionsAsync( Document document, TextSpan span, - CodeCleanupOptionsProvider cleanupOptions, CancellationToken cancellationToken) { // Code actions cannot be completed without the options needed @@ -61,7 +60,7 @@ public async Task> GetCodeActi if (typeAnalysisResult.CanPerform) { - return [AbstractMoveToNamespaceCodeAction.Generate(this, typeAnalysisResult, cleanupOptions)]; + return [AbstractMoveToNamespaceCodeAction.Generate(this, typeAnalysisResult)]; } } @@ -168,7 +167,6 @@ private static bool ContainsMultipleTypesInSpine(SyntaxNode node) public Task MoveToNamespaceAsync( MoveToNamespaceAnalysisResult analysisResult, string targetNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { if (!analysisResult.CanPerform) @@ -179,7 +177,7 @@ public Task MoveToNamespaceAsync( return analysisResult.Container switch { MoveToNamespaceAnalysisResult.ContainerType.Namespace => MoveItemsInNamespaceAsync(analysisResult.Document, analysisResult.SyntaxNode, targetNamespace, cancellationToken), - MoveToNamespaceAnalysisResult.ContainerType.NamedType => MoveTypeToNamespaceAsync(analysisResult.Document, analysisResult.SyntaxNode, targetNamespace, fallbackOptions, cancellationToken), + MoveToNamespaceAnalysisResult.ContainerType.NamedType => MoveTypeToNamespaceAsync(analysisResult.Document, analysisResult.SyntaxNode, targetNamespace, cancellationToken), _ => throw new InvalidOperationException(), }; } @@ -237,7 +235,6 @@ private static async Task MoveTypeToNamespaceAsync( Document document, SyntaxNode container, string targetNamespace, - CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var moveTypeService = document.GetLanguageService(); @@ -254,7 +251,6 @@ private static async Task MoveTypeToNamespaceAsync( document, moveSpan, MoveTypeOperationKind.MoveTypeNamespaceScope, - fallbackOptions, cancellationToken).ConfigureAwait(false); var modifiedDocument = modifiedSolution.GetDocument(document.Id); diff --git a/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs b/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs index 69f0f92755726..fff1e8a521add 100644 --- a/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs +++ b/src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeActionProvider.cs @@ -27,7 +27,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte { var (document, textSpan, cancellationToken) = context; var moveToNamespaceService = document.GetLanguageService(); - var actions = await moveToNamespaceService.GetCodeActionsAsync(document, textSpan, context.Options, cancellationToken).ConfigureAwait(false); + var actions = await moveToNamespaceService.GetCodeActionsAsync(document, textSpan, cancellationToken).ConfigureAwait(false); context.RegisterRefactorings(actions); } } diff --git a/src/Features/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs b/src/Features/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs index 13fc5e88d8888..2c9fd983a6aa3 100644 --- a/src/Features/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs +++ b/src/Features/ExternalAccess/OmniSharp/Internal/ExtractInterface/OmniSharpExtractInterfaceOptionsService.cs @@ -43,7 +43,6 @@ public async Task GetExtractInterfaceOptionsAsync string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { var result = await _omniSharpExtractInterfaceOptionsService.GetExtractInterfaceOptionsAsync(extractableMembers, defaultInterfaceName).ConfigureAwait(false); @@ -52,8 +51,7 @@ public async Task GetExtractInterfaceOptionsAsync result.IncludedMembers, result.InterfaceName, result.FileName, - (ExtractInterfaceOptionsResult.ExtractLocation)result.Location, - fallbackOptions); + (ExtractInterfaceOptionsResult.ExtractLocation)result.Location); } } } diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb index 34f796db8974e..46be28488cb77 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicExtractMethodService.vb @@ -25,9 +25,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Protected Overrides Function CreateSelectionValidator(document As SemanticDocument, textSpan As TextSpan, - options As ExtractMethodOptions, localFunction As Boolean) As VisualBasicSelectionValidator - Return New VisualBasicSelectionValidator(document, textSpan, options) + Return New VisualBasicSelectionValidator(document, textSpan) End Function Protected Overrides Function CreateMethodExtractor(selectionResult As VisualBasicSelectionResult, options As ExtractMethodGenerationOptions, localFunction As Boolean) As VisualBasicMethodExtractor diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb index 8324b7c4b49b4..41804ce0d728a 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb @@ -20,7 +20,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Public Shared Async Function CreateResultAsync( originalSpan As TextSpan, finalSpan As TextSpan, - options As ExtractMethodOptions, selectionInExpression As Boolean, document As SemanticDocument, firstToken As SyntaxToken, @@ -40,7 +39,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Return New VisualBasicSelectionResult( originalSpan, finalSpan, - options, selectionInExpression, newDocument, firstAnnotation, @@ -51,7 +49,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Private Sub New( originalSpan As TextSpan, finalSpan As TextSpan, - options As ExtractMethodOptions, selectionInExpression As Boolean, document As SemanticDocument, firstTokenAnnotation As SyntaxAnnotation, @@ -61,7 +58,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod MyBase.New( originalSpan, finalSpan, - options, selectionInExpression, document, firstTokenAnnotation, diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb index 9c8c2bce8415b..2e2493d1c85f9 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb @@ -16,9 +16,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Inherits SelectionValidator(Of VisualBasicSelectionResult, ExecutableStatementSyntax) Public Sub New(document As SemanticDocument, - textSpan As TextSpan, - options As ExtractMethodOptions) - MyBase.New(document, textSpan, options) + textSpan As TextSpan) + MyBase.New(document, textSpan) End Sub Public Overrides Async Function GetValidSelectionAsync(cancellationToken As CancellationToken) As Task(Of (VisualBasicSelectionResult, OperationStatus)) @@ -65,7 +64,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Dim result = Await VisualBasicSelectionResult.CreateResultAsync( selectionInfo.OriginalSpan, selectionInfo.FinalSpan, - Me.Options, selectionInfo.SelectionInExpression, Me.SemanticDocument, selectionInfo.FirstTokenInFinalSpan, diff --git a/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceLocalForExpressionCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceLocalForExpressionCodeRefactoringProvider.vb index 26d7f0c62c887..5f3a1ce573cfe 100644 --- a/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceLocalForExpressionCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceLocalForExpressionCodeRefactoringProvider.vb @@ -48,7 +48,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable Throw ExceptionUtilities.Unreachable() End Function - Protected Overrides Function CreateTupleDeconstructionAsync(document As Document, optionsProvider As CodeActionOptionsProvider, tupleType As INamedTypeSymbol, expression As ExpressionSyntax, cancellationToken As CancellationToken) As Task(Of ExpressionStatementSyntax) + Protected Overrides Function CreateTupleDeconstructionAsync(document As Document, tupleType As INamedTypeSymbol, expression As ExpressionSyntax, cancellationToken As CancellationToken) As Task(Of ExpressionStatementSyntax) Throw New NotImplementedException() End Function End Class diff --git a/src/LanguageServer/Protocol/Features/Options/CodeActionOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/CodeActionOptionsStorage.cs index 920cef56787a6..36c8c144b80b7 100644 --- a/src/LanguageServer/Protocol/Features/Options/CodeActionOptionsStorage.cs +++ b/src/LanguageServer/Protocol/Features/Options/CodeActionOptionsStorage.cs @@ -25,7 +25,6 @@ public static CodeActionOptions GetCodeActionOptions(this IGlobalOptionService g CodeStyleOptions = globalOptions.GetCodeStyleOptions(languageServices), SearchOptions = globalOptions.GetSymbolSearchOptions(languageServices.Language), ImplementTypeOptions = globalOptions.GetImplementTypeOptions(languageServices.Language), - ExtractMethodOptions = globalOptions.GetExtractMethodOptions(languageServices.Language), HideAdvancedMembers = globalOptions.GetOption(CompletionOptionsStorage.HideAdvancedMembers, languageServices.Language), }; diff --git a/src/LanguageServer/Protocol/Features/Options/ExtractMethodOptionsStorage.cs b/src/LanguageServer/Protocol/Features/Options/ExtractMethodOptionsStorage.cs index 2f42247133d35..b90833ba6f108 100644 --- a/src/LanguageServer/Protocol/Features/Options/ExtractMethodOptionsStorage.cs +++ b/src/LanguageServer/Protocol/Features/Options/ExtractMethodOptionsStorage.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeCleanup; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Host; @@ -13,23 +11,10 @@ namespace Microsoft.CodeAnalysis.ExtractMethod; internal static class ExtractMethodOptionsStorage { - public static ExtractMethodOptions GetExtractMethodOptions(this IGlobalOptionService globalOptions, string language) - => new() - { - DoNotPutOutOrRefOnStruct = globalOptions.GetOption(DoNotPutOutOrRefOnStruct, language) - }; - public static ExtractMethodGenerationOptions GetExtractMethodGenerationOptions(this IGlobalOptionService globalOptions, LanguageServices languageServices) => new() { CodeGenerationOptions = globalOptions.GetCodeGenerationOptions(languageServices), CodeCleanupOptions = globalOptions.GetCodeCleanupOptions(languageServices), - ExtractOptions = globalOptions.GetExtractMethodOptions(languageServices.Language), }; - - public static ValueTask GetExtractMethodGenerationOptionsAsync(this Document document, IGlobalOptionService globalOptions, CancellationToken cancellationToken) - => document.GetExtractMethodGenerationOptionsAsync(globalOptions.GetExtractMethodGenerationOptions(document.Project.Services), cancellationToken); - - public static readonly PerLanguageOption2 DoNotPutOutOrRefOnStruct = new( - "dotnet_extract_method_no_ref_or_out_structs", ExtractMethodOptions.Default.DoNotPutOutOrRefOnStruct); } diff --git a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs index e1f3a16d5540a..bc1f1776e0b25 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AdvancedOptionPageControl.xaml.cs @@ -169,9 +169,6 @@ public AdvancedOptionPageControl(OptionStore optionStore, IComponentModel compon // Classifications BindToOption(Editor_color_scheme, ColorSchemeOptionsStorage.ColorScheme); - // Extract Method - BindToOption(DontPutOutOrRefOnStruct, ExtractMethodOptionsStorage.DoNotPutOutOrRefOnStruct, LanguageNames.CSharp); - // Implement Interface or Abstract Class BindToOption(with_other_members_of_the_same_kind, ImplementTypeOptionsStorage.InsertionBehavior, ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind, LanguageNames.CSharp); BindToOption(at_the_end, ImplementTypeOptionsStorage.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd, LanguageNames.CSharp); diff --git a/src/VisualStudio/CSharp/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.cs b/src/VisualStudio/CSharp/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.cs index 79e9089b91f1b..9a549d8adc5ff 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.cs @@ -13,11 +13,5 @@ public int ExtractMethod_AllowBestEffort get { return GetBooleanOption(ExtractMethodPresentationOptionsStorage.AllowBestEffort); } set { SetBooleanOption(ExtractMethodPresentationOptionsStorage.AllowBestEffort, value); } } - - public int ExtractMethod_DoNotPutOutOrRefOnStruct - { - get { return GetBooleanOption(ExtractMethodOptionsStorage.DoNotPutOutOrRefOnStruct); } - set { SetBooleanOption(ExtractMethodOptionsStorage.DoNotPutOutOrRefOnStruct, value); } - } } } diff --git a/src/VisualStudio/Core/Def/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs b/src/VisualStudio/Core/Def/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs index f41f6fde4282d..fd7fb9dcead35 100644 --- a/src/VisualStudio/Core/Def/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs +++ b/src/VisualStudio/Core/Def/ExtractInterface/VisualStudioExtractInterfaceOptionsService.cs @@ -50,7 +50,6 @@ public async Task GetExtractInterfaceOptionsAsync string defaultNamespace, string generatedNameTypeParameterSuffix, string languageName, - CleanCodeGenerationOptionsProvider fallbackOptions, CancellationToken cancellationToken) { using var cancellationTokenSource = new CancellationTokenSource(); @@ -90,8 +89,7 @@ public async Task GetExtractInterfaceOptionsAsync includedMembers: includedMembers.AsImmutable(), interfaceName: viewModel.DestinationViewModel.TypeName.Trim(), fileName: viewModel.DestinationViewModel.FileName.Trim(), - location: GetLocation(viewModel.DestinationViewModel.Destination), - fallbackOptions); + location: GetLocation(viewModel.DestinationViewModel.Destination)); } else { diff --git a/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs b/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs index ce33d7af247db..472f357e941a6 100644 --- a/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs +++ b/src/VisualStudio/Core/Def/Options/VisualStudioOptionStorage.cs @@ -277,7 +277,6 @@ public bool TryFetch(LocalUserRegistryOptionPersister persister, OptionKey2 opti {"dotnet_enable_code_refactorings", new LocalUserProfileStorage(@"Roslyn\Internal\OnOff\Components", "Code Refactorings")}, {"dotnet_enable_editor_tagger", new LocalUserProfileStorage(@"Roslyn\Internal\OnOff\Components", "Tagger")}, {"dotnet_allow_best_effort_when_extracting_method", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.Allow Best Effort")}, - {"dotnet_extract_method_no_ref_or_out_structs", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.Don't Put Out Or Ref On Strcut")}, {"dotnet_fade_out_unreachable_code", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.FadeOutUnreachableCode")}, {"dotnet_fade_out_unused_imports", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.FadeOutUnusedImports")}, {"dotnet_add_imports_on_paste", new RoamingProfileStorage("TextEditor.%LANGUAGE%.Specific.AddImportsOnPaste2")}, diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml index 4d71c1c21df4e..f68871213d596 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml +++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml @@ -281,14 +281,6 @@ - - - - - - diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb index 652a983b99296..b83171035715c 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb +++ b/src/VisualStudio/VisualBasic/Impl/Options/AdvancedOptionPageControl.xaml.vb @@ -162,9 +162,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options ' Editor color scheme BindToOption(Editor_color_scheme, ColorSchemeOptionsStorage.ColorScheme) - ' Extract method - BindToOption(DontPutOutOrRefOnStruct, ExtractMethodOptionsStorage.DoNotPutOutOrRefOnStruct, LanguageNames.VisualBasic) - ' Implement Interface or Abstract Class BindToOption(with_other_members_of_the_same_kind, ImplementTypeOptionsStorage.InsertionBehavior, ImplementTypeInsertionBehavior.WithOtherMembersOfTheSameKind, LanguageNames.VisualBasic) BindToOption(at_the_end, ImplementTypeOptionsStorage.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd, LanguageNames.VisualBasic) diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.vb b/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.vb index 4f3631cc2a832..ba33a7ba11940 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.vb +++ b/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject/AutomationObject.ExtractMethod.vb @@ -14,14 +14,5 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options SetBooleanOption(ExtractMethodPresentationOptionsStorage.AllowBestEffort, value) End Set End Property - - Public Property ExtractMethod_DoNotPutOutOrRefOnStruct As Boolean - Get - Return GetBooleanOption(ExtractMethodOptionsStorage.DoNotPutOutOrRefOnStruct) - End Get - Set(value As Boolean) - SetBooleanOption(ExtractMethodOptionsStorage.DoNotPutOutOrRefOnStruct, value) - End Set - End Property End Class End Namespace diff --git a/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs b/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs index 8d8f093a6d32e..1eab0a3867d8f 100644 --- a/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs +++ b/src/Workspaces/Core/Portable/ExtractMethod/ExtractMethodOptions.cs @@ -14,28 +14,14 @@ namespace Microsoft.CodeAnalysis.ExtractMethod; -[DataContract] -internal readonly record struct ExtractMethodOptions -{ - [DataMember] public bool DoNotPutOutOrRefOnStruct { get; init; } = true; - - public ExtractMethodOptions() - { - } - - public static readonly ExtractMethodOptions Default = new(); -} - /// /// All options needed to perform method extraction. -/// Combines global with document specific code generation options. /// [DataContract] internal readonly record struct ExtractMethodGenerationOptions { [DataMember] public required CodeGenerationOptions CodeGenerationOptions { get; init; } [DataMember] public required CodeCleanupOptions CodeCleanupOptions { get; init; } - [DataMember] public ExtractMethodOptions ExtractOptions { get; init; } = ExtractMethodOptions.Default; public static ExtractMethodGenerationOptions GetDefault(LanguageServices languageServices) => new() @@ -54,18 +40,12 @@ public ExtractMethodGenerationOptions() internal static class ExtractMethodGenerationOptionsProviders { - public static async ValueTask GetExtractMethodGenerationOptionsAsync(this Document document, ExtractMethodGenerationOptions? fallbackOptions, CancellationToken cancellationToken) + public static async ValueTask GetExtractMethodGenerationOptionsAsync(this Document document, CancellationToken cancellationToken) { - fallbackOptions ??= ExtractMethodGenerationOptions.GetDefault(document.Project.Services); - return new ExtractMethodGenerationOptions() { CodeGenerationOptions = await document.GetCodeGenerationOptionsAsync(cancellationToken).ConfigureAwait(false), - ExtractOptions = fallbackOptions.Value.ExtractOptions, CodeCleanupOptions = await document.GetCodeCleanupOptionsAsync(cancellationToken).ConfigureAwait(false), }; } - - public static ValueTask GetExtractMethodGenerationOptionsAsync(this Document document, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) - => document.GetExtractMethodGenerationOptionsAsync(fallbackOptions.GetExtractMethodGenerationOptions(document.Project.Services), cancellationToken); } diff --git a/src/Workspaces/CoreTest/Remote/ServiceDescriptorTests.cs b/src/Workspaces/CoreTest/Remote/ServiceDescriptorTests.cs index ff80b1dd7e4a0..108d7b4727fc4 100644 --- a/src/Workspaces/CoreTest/Remote/ServiceDescriptorTests.cs +++ b/src/Workspaces/CoreTest/Remote/ServiceDescriptorTests.cs @@ -201,7 +201,6 @@ public void OptionsAreMessagePackSerializable_LanguageAgnostic() var messagePackOptions = MessagePackSerializerOptions.Standard.WithResolver(MessagePackFormatters.DefaultResolver); var options = new object[] { - ExtractMethodOptions.Default, AddImportPlacementOptions.Default, LineFormattingOptions.Default, DocumentFormattingOptions.Default, diff --git a/src/Workspaces/CoreTestUtilities/VBOptionsFactory.cs b/src/Workspaces/CoreTestUtilities/VBOptionsFactory.cs index 1f78244e5a48d..41217b64c8ed8 100644 --- a/src/Workspaces/CoreTestUtilities/VBOptionsFactory.cs +++ b/src/Workspaces/CoreTestUtilities/VBOptionsFactory.cs @@ -14,11 +14,10 @@ namespace Microsoft.CodeAnalysis.UnitTests; /// internal static class VBOptionsFactory { - public static ExtractMethodGenerationOptions CreateExtractMethodGenerationOptions(CodeGenerationOptions codeGenerationOptions, CodeCleanupOptions codeCleanupOptions, ExtractMethodOptions extractOptions) + public static ExtractMethodGenerationOptions CreateExtractMethodGenerationOptions(CodeGenerationOptions codeGenerationOptions, CodeCleanupOptions codeCleanupOptions) => new() { CodeGenerationOptions = codeGenerationOptions, - CodeCleanupOptions = codeCleanupOptions, - ExtractOptions = extractOptions + CodeCleanupOptions = codeCleanupOptions }; } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs index 7434e59e70668..3039a2f85a65a 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs @@ -42,7 +42,6 @@ internal sealed record class CodeActionOptions [DataMember] public required IdeCodeStyleOptions CodeStyleOptions { get; init; } [DataMember] public SymbolSearchOptions SearchOptions { get; init; } = SymbolSearchOptions.Default; [DataMember] public ImplementTypeOptions ImplementTypeOptions { get; init; } = ImplementTypeOptions.Default; - [DataMember] public ExtractMethodOptions ExtractMethodOptions { get; init; } = ExtractMethodOptions.Default; [DataMember] public bool HideAdvancedMembers { get; init; } = false; public static CodeActionOptions GetDefault(LanguageServices languageServices) @@ -163,7 +162,6 @@ public static ExtractMethodGenerationOptions GetExtractMethodGenerationOptions(t { CodeGenerationOptions = codeActionOptions.CodeGenerationOptions, CodeCleanupOptions = codeActionOptions.CleanupOptions, - ExtractOptions = codeActionOptions.ExtractMethodOptions, }; } #endif From 8e692752658006bb0229fec6df5eaccaacc8d10a Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Wed, 10 Jul 2024 08:52:19 +0200 Subject: [PATCH 58/59] Avoid more large string constant fields (#74307) * Avoid more large string constant fields * Make initializers run in correct order --- .../Test/Core/InstrumentationChecker.cs | 6 +- .../Test/Utilities/CSharp/CSharpTestBase.cs | 64 +++++++++---------- .../Utilities/CSharp/CompilingTestBase.cs | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Compilers/Test/Core/InstrumentationChecker.cs b/src/Compilers/Test/Core/InstrumentationChecker.cs index af481314a1fb4..8691cf0134f16 100644 --- a/src/Compilers/Test/Core/InstrumentationChecker.cs +++ b/src/Compilers/Test/Core/InstrumentationChecker.cs @@ -81,7 +81,7 @@ private static string GetTermination(int index, int length) return (index == length - 1) ? ";" : ""; } - public const string InstrumentationHelperSource = @" + public static readonly string InstrumentationHelperSource = @" namespace Microsoft.CodeAnalysis.Runtime { public static class Instrumentation @@ -216,8 +216,7 @@ private static string GetTermination(int index, int length) return (index == length - 1) ? "" : "."; } - public static readonly XElement InstrumentationHelperSource = new XElement("file", new XAttribute("name", "c.vb"), InstrumentationHelperSourceStr); - public const string InstrumentationHelperSourceStr = @" + public static readonly string InstrumentationHelperSourceStr = @" Namespace Microsoft.CodeAnalysis.Runtime Public Class Instrumentation @@ -271,6 +270,7 @@ End Function End Class End Namespace "; + public static readonly XElement InstrumentationHelperSource = new XElement("file", new XAttribute("name", "c.vb"), InstrumentationHelperSourceStr); } public abstract class BaseInstrumentationChecker diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 2c22b59dac227..d0b2f1396974e 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -38,7 +38,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities { public abstract class CSharpTestBase : CommonTestBase { - protected const string NullableAttributeDefinition = @" + protected static readonly string NullableAttributeDefinition = @" namespace System.Runtime.CompilerServices { [System.AttributeUsage(AttributeTargets.Event | // The type of the event is nullable, or has a nullable reference type as one of its constituents @@ -60,7 +60,7 @@ public NullableAttribute(byte[] transformFlags) } "; - protected const string NullableContextAttributeDefinition = @" + protected static readonly string NullableContextAttributeDefinition = @" namespace System.Runtime.CompilerServices { [System.AttributeUsage( @@ -81,7 +81,7 @@ public NullableContextAttribute(byte flag) } }"; - protected const string NullablePublicOnlyAttributeDefinition = @" + protected static readonly string NullablePublicOnlyAttributeDefinition = @" namespace System.Runtime.CompilerServices { [System.AttributeUsage(AttributeTargets.Module, AllowMultiple = false)] @@ -97,7 +97,7 @@ public NullablePublicOnlyAttribute(bool includesInternals) // Nullable flow analysis attributes are defined at // https://github.com/dotnet/coreclr/blob/4a1275434fff99206f2a28f5f0e87f124069eb7f/src/System.Private.CoreLib/shared/System/Diagnostics/CodeAnalysis/NullableAttributes.cs - protected const string AllowNullAttributeDefinition = @" + protected static readonly string AllowNullAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)] @@ -106,7 +106,7 @@ public sealed class AllowNullAttribute : Attribute } }"; - protected const string DisallowNullAttributeDefinition = @" + protected static readonly string DisallowNullAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)] @@ -115,7 +115,7 @@ public sealed class DisallowNullAttribute : Attribute } }"; - protected const string MaybeNullAttributeDefinition = @" + protected static readonly string MaybeNullAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)] @@ -125,7 +125,7 @@ public sealed class MaybeNullAttribute : Attribute } "; - protected const string MaybeNullWhenAttributeDefinition = @" + protected static readonly string MaybeNullWhenAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] @@ -136,7 +136,7 @@ public MaybeNullWhenAttribute(bool when) { } } "; - protected const string NotNullAttributeDefinition = @" + protected static readonly string NotNullAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)] @@ -146,7 +146,7 @@ public sealed class NotNullAttribute : Attribute } "; - protected const string NotNullWhenAttributeDefinition = @" + protected static readonly string NotNullWhenAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] @@ -157,7 +157,7 @@ public NotNullWhenAttribute(bool when) { } } "; - protected const string MemberNotNullAttributeDefinition = @" + protected static readonly string MemberNotNullAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] @@ -169,7 +169,7 @@ public MemberNotNullAttribute(string member) { } } "; - protected const string MemberNotNullWhenAttributeDefinition = @" + protected static readonly string MemberNotNullWhenAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] @@ -181,7 +181,7 @@ public MemberNotNullWhenAttribute(bool when, string member) { } } "; - protected const string DoesNotReturnIfAttributeDefinition = @" + protected static readonly string DoesNotReturnIfAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] @@ -192,7 +192,7 @@ public DoesNotReturnIfAttribute(bool condition) { } } "; - protected const string DoesNotReturnAttributeDefinition = @" + protected static readonly string DoesNotReturnAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] @@ -203,7 +203,7 @@ public DoesNotReturnAttribute() { } } "; - protected const string NotNullIfNotNullAttributeDefinition = @" + protected static readonly string NotNullIfNotNullAttributeDefinition = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] @@ -214,7 +214,7 @@ public NotNullIfNotNullAttribute(string parameterName) { } } "; - protected const string IsExternalInitTypeDefinition = @" + protected static readonly string IsExternalInitTypeDefinition = @" namespace System.Runtime.CompilerServices { public static class IsExternalInit @@ -223,7 +223,7 @@ public static class IsExternalInit } "; - protected const string IAsyncDisposableDefinition = @" + protected static readonly string IAsyncDisposableDefinition = @" namespace System { public interface IAsyncDisposable @@ -233,7 +233,7 @@ public interface IAsyncDisposable } "; - protected const string NonDisposableAsyncEnumeratorDefinition = @" + protected static readonly string NonDisposableAsyncEnumeratorDefinition = @" #nullable disable namespace System.Collections.Generic @@ -246,7 +246,7 @@ public interface IAsyncEnumerator } "; - protected const string DisposableAsyncEnumeratorDefinition = @" + protected static readonly string DisposableAsyncEnumeratorDefinition = @" #nullable disable namespace System.Collections.Generic @@ -259,9 +259,7 @@ public interface IAsyncEnumerator : System.IAsyncDisposable } " + IAsyncDisposableDefinition; - protected const string AsyncStreamsTypes = DisposableAsyncEnumeratorDefinition + CommonAsyncStreamsTypes; - - protected const string CommonAsyncStreamsTypes = @" + protected static readonly string CommonAsyncStreamsTypes = @" #nullable disable namespace System.Collections.Generic @@ -590,7 +588,9 @@ public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter } "; - protected const string EnumeratorCancellationAttributeType = @" + protected static readonly string AsyncStreamsTypes = DisposableAsyncEnumeratorDefinition + CommonAsyncStreamsTypes; + + protected static readonly string EnumeratorCancellationAttributeType = @" namespace System.Runtime.CompilerServices { [System.AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] @@ -601,7 +601,7 @@ public EnumeratorCancellationAttribute() { } } "; - protected const string NativeIntegerAttributeDefinition = + protected static readonly string NativeIntegerAttributeDefinition = @"using System.Collections.Generic; namespace System.Runtime.CompilerServices { @@ -629,7 +629,7 @@ public NativeIntegerAttribute(bool[] flags) } }"; - protected const string UnmanagedCallersOnlyAttributeDefinition = + protected static readonly string UnmanagedCallersOnlyAttributeDefinition = @"namespace System.Runtime.InteropServices { [AttributeUsage(AttributeTargets.Method, Inherited = false)] @@ -641,7 +641,7 @@ public UnmanagedCallersOnlyAttribute() { } } }"; - protected const string UnscopedRefAttributeDefinition = + protected static readonly string UnscopedRefAttributeDefinition = @"namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)] @@ -650,7 +650,7 @@ public sealed class UnscopedRefAttribute : Attribute } }"; - protected const string RefSafetyRulesAttributeDefinition = + protected static readonly string RefSafetyRulesAttributeDefinition = @"namespace System.Runtime.CompilerServices { public sealed class RefSafetyRulesAttribute : Attribute @@ -663,7 +663,7 @@ public sealed class RefSafetyRulesAttribute : Attribute protected static MetadataReference RefSafetyRulesAttributeLib => CreateCompilation(RefSafetyRulesAttributeDefinition).EmitToImageReference(); - protected const string RequiredMemberAttribute = @" + protected static readonly string RequiredMemberAttribute = @" namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] @@ -676,7 +676,7 @@ public RequiredMemberAttribute() } "; - protected const string SetsRequiredMembersAttribute = @" + protected static readonly string SetsRequiredMembersAttribute = @" namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] @@ -689,7 +689,7 @@ public SetsRequiredMembersAttribute() } "; - internal const string CompilerFeatureRequiredAttribute = """ + internal static readonly string CompilerFeatureRequiredAttribute = """ namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] @@ -705,7 +705,7 @@ public CompilerFeatureRequiredAttribute(string featureName) } """; - internal const string CollectionBuilderAttributeDefinition = """ + internal static readonly string CollectionBuilderAttributeDefinition = """ namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] @@ -2445,7 +2445,7 @@ void appendNonDefaultVariantsWithGenericAndType(string type, string generic, boo } } - internal const string InterpolatedStringHandlerAttribute = @" + internal static readonly string InterpolatedStringHandlerAttribute = @" namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] @@ -2503,7 +2503,7 @@ public static void Normalize() " + (includeOneTimeHelpers ? InterpolatedStringHandlerAttribute + cultureInfoHandler : ""); } - internal const string InterpolatedStringHandlerArgumentAttribute = @" + internal static readonly string InterpolatedStringHandlerArgumentAttribute = @" namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] diff --git a/src/Compilers/Test/Utilities/CSharp/CompilingTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CompilingTestBase.cs index 85521c110c80b..8a66590bfb1bb 100644 --- a/src/Compilers/Test/Utilities/CSharp/CompilingTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CompilingTestBase.cs @@ -41,7 +41,7 @@ internal static BoundBlock ParseAndBindMethodBody(string program, string typeNam return block; } - public const string LINQ = + public static readonly string LINQ = #region the string LINQ defines a complete LINQ API called List1 (for instance method) and List2 (for extension methods) @"using System; using System.Text; From 28f0ccf3e20521e9f05ff59a2f658f8fcc73d8c5 Mon Sep 17 00:00:00 2001 From: Jan Jones Date: Wed, 10 Jul 2024 10:16:23 +0200 Subject: [PATCH 59/59] Fix modification of readonly locals through ref fields (#74255) * Fix modification of readonly locals through ref fields * Extend tests * Improve check * Add query tests --- .../CSharp/Portable/BoundTree/Constructors.cs | 1 + .../Test/Emit/CodeGen/CodeGenForEachTests.cs | 249 ++++++++++++++++++ .../CodeGen/CodeGenUsingStatementTests.cs | 136 ++++++++++ .../Test/Semantic/Semantics/QueryTests.cs | 183 +++++++++++++ 4 files changed, 569 insertions(+) diff --git a/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs b/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs index d64b6cf5073bc..8d0500816c4fb 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Constructors.cs @@ -60,6 +60,7 @@ private static bool NeedsByValueFieldAccess(BoundExpression? receiver, FieldSymb { if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsValueType || + fieldSymbol.RefKind != RefKind.None || receiver == null) // receiver may be null in error cases { return false; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenForEachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenForEachTests.cs index f1ee673602927..fe3ac4dac44c2 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenForEachTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenForEachTests.cs @@ -5327,5 +5327,254 @@ public static class Extensions }"; CompileAndVerify(source, parseOptions: TestOptions.Regular9, expectedOutput: "123123"); } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_01( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + foreach (var r in new E(arr)) + { + r.V.F++; + } + + foreach (var v in arr) Console.Write(v.F); + + {{eRef}} struct E(V[] arr) + { + int i; + public E GetEnumerator() => this; + public R Current => new(ref arr[i - 1]); + public bool MoveNext() => i++ < arr.Length; + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + } + + struct V + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.Fails, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "111").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_02( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + foreach (var r in new E(arr)) + { + r.V.F += 2; + } + + foreach (var v in arr) Console.Write(v.F); + + {{eRef}} struct E(V[] arr) + { + int i; + public E GetEnumerator() => this; + public R Current => new(ref arr[i - 1]); + public bool MoveNext() => i++ < arr.Length; + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + } + + struct V + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.Fails, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "222").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_03( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + foreach (var r in new E(arr)) + { + r.V.S.Inc(); + } + + foreach (var v in arr) Console.Write(v.S.F); + + {{eRef}} struct E(V[] arr) + { + int i; + public E GetEnumerator() => this; + public R Current => new(ref arr[i - 1]); + public bool MoveNext() => i++ < arr.Length; + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + } + + struct V + { + public S S; + } + + struct S + { + public int F; + public void Inc() => F++; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.Fails, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "111").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_04( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + foreach (var r in new E(arr)) + { + r.V.F++; + } + + foreach (var v in arr) Console.Write(v.F); + + {{eRef}} struct E(V[] arr) + { + int i; + public E GetEnumerator() => this; + public R Current => new(ref arr[i - 1]); + public bool MoveNext() => i++ < arr.Length; + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref readonly V V = ref v; + } + + struct V + { + public int F; + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (7,5): error CS8332: Cannot assign to a member of field 'V' or use it as the right hand side of a ref assignment because it is a readonly variable + // r.V.F++; + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "r.V.F").WithArguments("field", "V").WithLocation(7, 5)); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_05( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + foreach (ref var r in new E(arr)) + { + r.S.F++; + } + + foreach (var v in arr) Console.Write(v.S.F); + + {{eRef}} struct E(V[] arr) + { + int i; + public E GetEnumerator() => this; + public {{vReadonly}} ref V Current => ref arr[i - 1]; + public bool MoveNext() => i++ < arr.Length; + } + + struct V + { + public S S; + } + + struct S + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.Skipped, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "111").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_06( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly, + [CombinatorialValues("readonly", "")] string vReadonlyInner) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + foreach (ref readonly var r in new E(arr)) + { + r.S.F++; + } + + foreach (var v in arr) Console.Write(v.S.F); + + {{eRef}} struct E(V[] arr) + { + int i; + public E GetEnumerator() => this; + public {{vReadonly}} ref {{vReadonlyInner}} V Current => ref arr[i - 1]; + public bool MoveNext() => i++ < arr.Length; + } + + struct V + { + public S S; + } + + struct S + { + public int F; + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (7,5): error CS1654: Cannot modify members of 'r' because it is a 'foreach iteration variable' + // r.S.F++; + Diagnostic(ErrorCode.ERR_AssgReadonlyLocal2Cause, "r.S.F").WithArguments("r", "foreach iteration variable").WithLocation(7, 5)); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenUsingStatementTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenUsingStatementTests.cs index a0775de65acd8..9f922cac43a54 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenUsingStatementTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenUsingStatementTests.cs @@ -4,6 +4,7 @@ #nullable disable +using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; @@ -3136,5 +3137,140 @@ ref struct S } } } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_01( + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V v = default; + + using (var d = new R(ref v)) + { + d.V.F++; + } + + Console.Write(v.F); + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + public void Dispose() { } + } + + struct V + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.FailsPEVerify, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "1").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_02( + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V v = default; + + using (var d = new R(ref v)) + { + d.V.F += 2; + } + + Console.Write(v.F); + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + public void Dispose() { } + } + + struct V + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.FailsPEVerify, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "2").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_03( + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V v = default; + + using (var d = new R(ref v)) + { + d.V.S.Inc(); + } + + Console.Write(v.S.F); + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + public void Dispose() { } + } + + struct V + { + public S S; + } + + struct S + { + public int F; + public void Inc() => F++; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.FailsPEVerify, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "1").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_04( + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V v = default; + + using (var d = new R(ref v)) + { + d.V.F++; + } + + Console.Write(v.F); + + ref struct R(ref V v) + { + public {{vReadonly}} ref readonly V V = ref v; + public void Dispose() { } + } + + struct V + { + public int F; + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (7,5): error CS8332: Cannot assign to a member of field 'V' or use it as the right hand side of a ref assignment because it is a readonly variable + // d.V.F++; + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "d.V.F").WithArguments("field", "V").WithLocation(7, 5)); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs index 34656039663f6..9cb7edb734d5d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs @@ -4556,5 +4556,188 @@ End Class Console.WriteLine(string.Join(string.Empty, test)); ", references: new[] { vb.EmitToImageReference() }, expectedOutput: "2"); } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_01( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + _ = from r in new E(arr) + select r.V.F++; + + foreach (var v in arr) Console.Write(v.F); + + delegate void D(R r); + + {{eRef}} struct E(V[] arr) + { + public int Select(D a) + { + for (var i = 0; i < arr.Length; i++) + { + a(new(ref arr[i])); + } + return 0; + } + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + } + + struct V + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.FailsPEVerify, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "111").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_02( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + _ = from r in new E(arr) + select r.V.F += 2; + + foreach (var v in arr) Console.Write(v.F); + + delegate void D(R r); + + {{eRef}} struct E(V[] arr) + { + public int Select(D a) + { + for (var i = 0; i < arr.Length; i++) + { + a(new(ref arr[i])); + } + return 0; + } + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + } + + struct V + { + public int F; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.FailsPEVerify, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "222").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_03( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + _ = from r in new E(arr) + select r.V.S.Inc(); + + foreach (var v in arr) Console.Write(v.S.F); + + delegate void D(R r); + + {{eRef}} struct E(V[] arr) + { + public int Select(D a) + { + for (var i = 0; i < arr.Length; i++) + { + a(new(ref arr[i])); + } + return 0; + } + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref V V = ref v; + } + + struct V + { + public S S; + } + + struct S + { + public int F; + public void Inc() => F++; + } + """; + CompileAndVerify(source, targetFramework: TargetFramework.Net70, + verify: Verification.FailsPEVerify, + expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "111").VerifyDiagnostics(); + } + + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/73741")] + public void MutatingThroughRefFields_04( + [CombinatorialValues("ref", "")] string eRef, + [CombinatorialValues("readonly", "")] string vReadonly) + { + var source = $$""" + using System; + + V[] arr = new V[3]; + + _ = from r in new E(arr) + select r.V.F++; + + foreach (var v in arr) Console.Write(v.F); + + delegate void D(R r); + + {{eRef}} struct E(V[] arr) + { + public int Select(D a) + { + for (var i = 0; i < arr.Length; i++) + { + a(new(ref arr[i])); + } + return 0; + } + } + + ref struct R(ref V v) + { + public {{vReadonly}} ref readonly V V = ref v; + } + + struct V + { + public int F; + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (6,12): error CS8332: Cannot assign to a member of field 'V' or use it as the right hand side of a ref assignment because it is a readonly variable + // select r.V.F++; + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "r.V.F").WithArguments("field", "V").WithLocation(6, 12)); + } } }