diff --git a/src/LanguageServer/Protocol/Features/Options/SolutionAnalyzerConfigOptionsUpdater.cs b/src/LanguageServer/Protocol/Features/Options/SolutionAnalyzerConfigOptionsUpdater.cs index ff17fba9d34d7..d72125d612ed4 100644 --- a/src/LanguageServer/Protocol/Features/Options/SolutionAnalyzerConfigOptionsUpdater.cs +++ b/src/LanguageServer/Protocol/Features/Options/SolutionAnalyzerConfigOptionsUpdater.cs @@ -70,14 +70,17 @@ Solution UpdateOptions(Solution oldSolution) continue; } - lazyBuilder ??= ImmutableDictionary.CreateBuilder(AnalyzerConfigOptions.KeyComparer); - - // copy existing option values: - foreach (var oldKey in languageOptions.Keys) + if (lazyBuilder == null) { - if (languageOptions.TryGetValue(oldKey, out var oldValue)) + lazyBuilder = ImmutableDictionary.CreateBuilder(AnalyzerConfigOptions.KeyComparer); + + // copy existing option values: + foreach (var oldKey in languageOptions.Keys) { - lazyBuilder.Add(oldKey, oldValue); + if (languageOptions.TryGetValue(oldKey, out var oldValue)) + { + lazyBuilder.Add(oldKey, oldValue); + } } } diff --git a/src/LanguageServer/ProtocolUnitTests/Options/SolutionAnalyzerConfigOptionsUpdaterTests.cs b/src/LanguageServer/ProtocolUnitTests/Options/SolutionAnalyzerConfigOptionsUpdaterTests.cs index 2c4df16e4d0ba..9adfc0ca5040a 100644 --- a/src/LanguageServer/ProtocolUnitTests/Options/SolutionAnalyzerConfigOptionsUpdaterTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/Options/SolutionAnalyzerConfigOptionsUpdaterTests.cs @@ -2,10 +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 System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Options.UnitTests; @@ -32,8 +34,10 @@ public void FlowsGlobalOptionsToWorkspace() var globalOptions = workspace.GetService(); - // default value is false: + // default values: Assert.False(globalOptions.GetOption(FormattingOptions2.InsertFinalNewLine)); + Assert.Equal(4, globalOptions.GetOption(FormattingOptions2.IndentationSize, LanguageNames.CSharp)); + Assert.Equal(4, globalOptions.GetOption(FormattingOptions2.IndentationSize, LanguageNames.VisualBasic)); // C# project hasn't been loaded to the workspace yet: Assert.Empty(workspace.CurrentSolution.FallbackAnalyzerOptions); @@ -41,12 +45,19 @@ public void FlowsGlobalOptionsToWorkspace() var project = new TestHostProject(workspace, "proj1", LanguageNames.CSharp); workspace.AddTestProject(project); - AssertOptionValue(LanguageNames.CSharp, "false"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.CSharp, "false"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.CSharp, "4"); - globalOptions.SetGlobalOption(FormattingOptions2.InsertFinalNewLine, true); + globalOptions.SetGlobalOptions( + [ + new KeyValuePair(FormattingOptions2.InsertFinalNewLine, true), + new KeyValuePair(new OptionKey2(FormattingOptions2.IndentationSize, LanguageNames.CSharp), 3), + new KeyValuePair(new OptionKey2(FormattingOptions2.IndentationSize, LanguageNames.VisualBasic), 5) + ]); // editorconfig option set as a global option should flow to the solution snapshot: - AssertOptionValue(LanguageNames.CSharp, "true"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.CSharp, "true"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.CSharp, "3"); workspace.OnProjectRemoved(project.Id); @@ -55,7 +66,8 @@ public void FlowsGlobalOptionsToWorkspace() workspace.AddTestProject(new TestHostProject(workspace, "proj2", LanguageNames.VisualBasic)); - AssertOptionValue(LanguageNames.VisualBasic, "true"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.VisualBasic, "true"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.VisualBasic, "5"); Assert.False(workspace.CurrentSolution.FallbackAnalyzerOptions.TryGetValue(LanguageNames.CSharp, out _)); @@ -63,18 +75,22 @@ public void FlowsGlobalOptionsToWorkspace() workspace.AddTestProject(new TestHostProject(workspace, "proj3", LanguageNames.CSharp)); - AssertOptionValue(LanguageNames.VisualBasic, "true"); - AssertOptionValue(LanguageNames.CSharp, "true"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.VisualBasic, "true"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.CSharp, "true"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.VisualBasic, "5"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.CSharp, "3"); globalOptions.SetGlobalOption(FormattingOptions2.InsertFinalNewLine, false); - AssertOptionValue(LanguageNames.VisualBasic, "false"); - AssertOptionValue(LanguageNames.CSharp, "false"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.VisualBasic, "false"); + AssertOptionValue(FormattingOptions2.InsertFinalNewLine, LanguageNames.CSharp, "false"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.VisualBasic, "5"); + AssertOptionValue(FormattingOptions2.IndentationSize, LanguageNames.CSharp, "3"); - void AssertOptionValue(string language, string expectedValue) + void AssertOptionValue(IOption2 option, string language, string expectedValue) { Assert.True(workspace.CurrentSolution.FallbackAnalyzerOptions.TryGetValue(language, out var fallbackOptions)); - Assert.True(fallbackOptions!.TryGetValue(FormattingOptions2.InsertFinalNewLine.Definition.ConfigName, out var configValue)); + Assert.True(fallbackOptions!.TryGetValue(option.Definition.ConfigName, out var configValue)); Assert.Equal(expectedValue, configValue); } }