roslynator icon indicating copy to clipboard operation
roslynator copied to clipboard

RR0064 (and probably others) don't respect .editorconfig rules

Open IanKemp opened this issue 6 years ago • 8 comments
trafficstars

My solution has a .editorconfig file in its root with the following rules defined:

[*.{cs,vb}]
dotnet_naming_rule.private_members_with_underscore.symbols  = private_fields
dotnet_naming_rule.private_members_with_underscore.style    = prefix_underscore
dotnet_naming_rule.private_members_with_underscore.severity = suggestion

dotnet_naming_symbols.private_fields.applicable_kinds           = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private

dotnet_naming_style.prefix_underscore.capitalization  = camel_case
dotnet_naming_style.prefix_underscore.required_prefix = _

Performing a refactoring on a constructor parameter in that solution yields the following:

image

Roslynator's "Introduce and initialize field" refactoring (RR0064) wants to generate a field name that doesn't begin with an underscore (i.e. the .editorconfig rules are ignored), while Visual Studio's built-in refactoring "Create and initialize field" produces the correct field name In my opinion, Roslynator should behave the same as Visual Studio in respecting the .editorconfig rules.

I'm aware of the Roslynator option "Prefix field identifier with underscore" but to my knowledge that applies to all fields, and it would be unnecessary if the editorconfig rules were used.

IanKemp avatar Dec 06 '18 10:12 IanKemp

I agree that Roslynator should work in compliance with editorconfig rules.

Unfortunately there is no API to access these editorconfig rules (at least none I know of).

josefpihrt avatar Dec 06 '18 15:12 josefpihrt

Looking at the Roslyn PR that added support for .editorconfig, it seems that:

  • Every analyzer gets passed a Microsoft.CodeAnalysis.Diagnostics.SyntaxNodeAnalysisContext that has an Options property of type Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions.

  • Then Microsoft.CodeAnalysis.Diagnostics.AnalyzerHelper has an extension method GetDocumentOptionSetAsync that takes in a Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions and returns a ValueTask<Microsoft.CodeAnalysis.Options.OptionSet>.

  • Microsoft.CodeAnalysis.Options.OptionSet has a GetOption method that allows you to ask for the value of a specific code style option. There is a predefined list of these options in various classes:

    • Microsoft.CodeAnalysis.CodeStyle.CodeStyleOptions
    • Microsoft.CodeAnalysis.CSharp.CodeStyle.CSharpCodeStyleOptions
    • Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions
    • Microsoft.CodeAnalysis.Formatting.FormattingOptions
    • Microsoft.CodeAnalysis.Simplification.SimplificationOptions

including ones that cover both the IDE and/or .editorconfig settings.

tl;dr: given a SyntaxNodeAnalysisContext instance context, and with the correct references and imports, you can write:

    var optionSet = context.Options.GetDocumentOptionSetAsync(context.Node.SyntaxTree, context.CancellationToken).GetAwaiter().GetResult();
    var option = optionSet.GetOption(CodeStyleOptions.<relevant-option-name>, <language>);
    // do something with option.Value

The relevant one that covers this particular case (RR0064) seems to be SimplificationOptions.NamingPreferences, but unfortunately that's declared as internal, as is the Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyle.NamingStylePreferences option it returns. So maybe the naming stuff isn't ready for primetime, but you could implement the ones that are, in some of your other refactorers.

IanKemp avatar Dec 07 '18 08:12 IanKemp

Regarding Editor config, if you could take a look at my comment on https://github.com/JosefPihrt/Roslynator/issues/427#issuecomment-445779308

wiz0u avatar Dec 14 '18 17:12 wiz0u

@wiz0u I reopened it.

josefpihrt avatar Dec 17 '18 09:12 josefpihrt

It's possible to set rule severity in .editorconfig now, but still not to configure them. Is this planned?

marcospgp avatar Jul 28 '21 07:07 marcospgp

@marcospgp It possible to configure rules using editorconfig. Here is a list of currently supported values:

roslynator.max_line_length = <MAX_LINE_LENGTH>
roslynator.RCS0011.invert = true
roslynator.RCS0015.invert = true
roslynator.RCS0027.invert = true
roslynator.RCS0028.invert = true
roslynator.RCS0032.invert = true
roslynator.RCS0051.invert = true
roslynator.RCS0052.invert = true
roslynator.RCS1014.invert = true
roslynator.RCS1014.use_implicit_type_when_obvious = true
roslynator.RCS1016.invert = true
roslynator.RCS1016.use_block_body_when_declaration_is_multiline = true
roslynator.RCS1016.use_block_body_when_expression_is_multiline = true
roslynator.RCS1018.invert = true
roslynator.RCS1036.remove_empty_line_between_closing_brace_and_switch_section = true
roslynator.RCS1045.suppress_when_field_is_static = true
roslynator.RCS1050.invert = true
roslynator.RCS1051.do_not_parenthesize_single_token = true
roslynator.RCS1078.invert = true
roslynator.RCS1090.invert = true
roslynator.RCS1096.invert = true
roslynator.RCS1104.suppress_when_condition_is_inverted = true
roslynator.RCS1207.invert = true
roslynator.RCS1213.suppress_unity_script_methods = true
roslynator.RCS1246.suppress_when_expression_is_invocation = true
roslynator.RCS1248.invert = true

josefpihrt avatar Jul 29 '21 17:07 josefpihrt

Awesome, was just checking back in to say that roslynator.max_line_length=80 worked. Thanks! Would be awesome if you could add this to the documentation here.

marcospgp avatar Jul 29 '21 17:07 marcospgp

@marcospgp 9f460dd9fd24c777e8cb7d545c48b81079305283

josefpihrt avatar Jul 29 '21 18:07 josefpihrt