Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ public static string Generate(

foreach ((var feature, var options) in groupedOptions)
{
AppendOptionsToEditorConfig(configOptions, feature, options, language, editorconfig);
if (!options.Contains(NamingStyleOptions.NamingPreferences))
{
AppendOptionsToEditorConfig(configOptions, feature, options, language, editorconfig);
}
}

if (configOptions.TryGetOption(new OptionKey2(NamingStyleOptions.NamingPreferences, language), out NamingStylePreferences namingStylePreferences))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ internal sealed class EditorConfigOptionsEnumerator(
yield return (WorkspacesResources.dot_NET_Coding_Conventions,
[
.. GenerationOptions.EditorConfigOptions,
.. CodeStyleOptions2.EditorConfigOptions
.. CodeStyleOptions2.EditorConfigOptions,
]);

yield return (CompilerExtensionsResources.Naming_styles, NamingStyleOptions.EditorConfigOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,7 @@ public StructuredAnalyzerConfigOptions GetOptions(string language)
foreach (var option in options)
{
var value = globalOptions.GetOption<object>(new OptionKey2(option, option.IsPerLanguage ? language : null));

var configName = option.Definition.ConfigName;
var configValue = option.Definition.Serializer.Serialize(value);

builder.Add(configName, configValue);
EditorConfigValueSerializer.Serialize(builder, option, language, value);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,8 @@ Solution UpdateOptions(Solution oldSolution)
}
}

// update changed values:
var configName = key.Option.Definition.ConfigName;
if (value is NamingStylePreferences preferences)
{
NamingStylePreferencesEditorConfigSerializer.WriteNamingStylePreferencesToEditorConfig(
preferences.SymbolSpecifications,
preferences.NamingStyles,
preferences.Rules.NamingRules,
language,
entryWriter: (name, value) => lazyBuilder[name] = value,
triviaWriter: null,
setPrioritiesToPreserveOrder: true);
}
else
{
lazyBuilder[configName] = key.Option.Definition.Serializer.Serialize(value);
}
// update changed value:
EditorConfigValueSerializer.Serialize(lazyBuilder, key.Option, language, value);
}

if (lazyBuilder != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ public void FlowsNamingStylePreferencesToWorkspace()
{
using var workspace = CreateWorkspace();

Assert.Empty(workspace.CurrentSolution.Projects);
var globalOptions = workspace.GetService<IGlobalOptionService>();

var initialPeferences = OptionsTestHelpers.CreateNamingStylePreferences(
([SymbolKind.Property], Capitalization.AllUpper, ReportDiagnostic.Error));

globalOptions.SetGlobalOption(NamingStyleOptions.NamingPreferences, LanguageNames.CSharp, initialPeferences);

var testProjectWithoutConfig = new TestHostProject(workspace, "proj_without_config", LanguageNames.CSharp);

testProjectWithoutConfig.AddDocument(new TestHostDocument("""
Expand Down Expand Up @@ -135,21 +143,28 @@ class MyClass2;
""",
filePath: Path.Combine(TempRoot.Root, "proj_with_config", "test.cs")));

// No fallback options before a project is added.
Assert.False(workspace.CurrentSolution.FallbackAnalyzerOptions.TryGetValue(LanguageNames.CSharp, out _));

workspace.AddTestProject(testProjectWithoutConfig);
workspace.AddTestProject(testProjectWithConfig);

var globalOptions = workspace.GetService<IGlobalOptionService>();
// Once a C# project is added the preferences stored in global options should be applied to fallback options:
Assert.True(workspace.CurrentSolution.FallbackAnalyzerOptions.TryGetValue(LanguageNames.CSharp, out var fallbackOptions));
AssertEx.SequenceEqual(
initialPeferences.Rules.NamingRules.Select(r => r.Inspect()),
fallbackOptions.GetNamingStylePreferences().Rules.NamingRules.Select(r => r.Inspect()));

var hostPeferences = OptionsTestHelpers.CreateNamingStylePreferences(
([MethodKind.Ordinary], Capitalization.PascalCase, ReportDiagnostic.Error),
([MethodKind.Ordinary, SymbolKind.Field], Capitalization.PascalCase, ReportDiagnostic.Error));

globalOptions.SetGlobalOption(NamingStyleOptions.NamingPreferences, LanguageNames.CSharp, hostPeferences);

Assert.True(workspace.CurrentSolution.FallbackAnalyzerOptions.TryGetValue(LanguageNames.CSharp, out var fallbackOptions));

// Initial preferences should be replaced by host preferences.
// Note: rules are ordered but symbol and naming style specifications are not.
AssertEx.Equal(
Assert.True(workspace.CurrentSolution.FallbackAnalyzerOptions.TryGetValue(LanguageNames.CSharp, out fallbackOptions));
AssertEx.SequenceEqual(
hostPeferences.Rules.NamingRules.Select(r => r.Inspect()),
fallbackOptions.GetNamingStylePreferences().Rules.NamingRules.Select(r => r.Inspect()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +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.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.Options;
using System.Collections.Immutable;

#if !CODE_STYLE
using Microsoft.CodeAnalysis.Host;
Expand All @@ -26,6 +25,11 @@ internal static class NamingStyleOptions
defaultValue: NamingStylePreferences.Default,
isEditorConfigOption: true,
serializer: EditorConfigValueSerializer<NamingStylePreferences>.Unsupported);

/// <summary>
/// Options that we expect the user to set in editorconfig.
/// </summary>
internal static readonly ImmutableArray<IOption2> EditorConfigOptions = [NamingPreferences];
}

internal interface NamingStylePreferencesProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Options;
Expand Down Expand Up @@ -170,4 +171,36 @@ private static bool TryParseEnum<T>(string str, out T result) where T : struct,

return Enum.TryParse(str, ignoreCase: true, out result);
}

/// <summary>
/// Serializes arbitrary editorconfig option value (including naming style preferences) into a given builder.
/// Replaces existing value if present.
/// </summary>
public static void Serialize(IDictionary<string, string> builder, IOption2 option, string language, object? value)
{
if (value is NamingStylePreferences preferences)
{
// remove existing naming style values:
foreach (var name in builder.Keys)
{
if (name.StartsWith("dotnet_naming_rule.") || name.StartsWith("dotnet_naming_symbols.") || name.StartsWith("dotnet_naming_style."))
{
builder.Remove(name);
}
}

NamingStylePreferencesEditorConfigSerializer.WriteNamingStylePreferencesToEditorConfig(
preferences.SymbolSpecifications,
preferences.NamingStyles,
preferences.Rules.NamingRules,
language,
entryWriter: (name, value) => builder[name] = value,
triviaWriter: null,
setPrioritiesToPreserveOrder: true);
}
else
{
builder[option.Definition.ConfigName] = option.Definition.Serializer.Serialize(value);
}
}
}
Loading