Skip to content

Commit 73ce445

Browse files
Bart KoelmanBart Koelman
authored andcommitted
Added .editorconfig support
1 parent 36928b8 commit 73ce445

File tree

13 files changed

+669
-158
lines changed

13 files changed

+669
-158
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ Note that you can broaden the suppression scope by removing the `Target` and/or
5555
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Maintainability", "AV1532:Loop statement contains nested loop", Justification = "<Pending>")]
5656
```
5757

58+
* In an .editorconfig file, which contains [rule severities](https://docs.microsoft.com/en-us/visualstudio/code-quality/use-roslyn-analyzers?view=vs-2019#set-rule-severity-in-an-editorconfig-file):
59+
60+
```ini
61+
root = true
62+
63+
[*.cs]
64+
dotnet_diagnostic.av1115.severity = error
65+
dotnet_diagnostic.av1130.severity = suggestion
66+
```
67+
5868
* In a custom .ruleset file, which contains Code Analysis settings:
5969

6070
Right-click your project, select **Properties**, tab **Code Analysis**. Click **Open**, expand **CSharpGuidelinesAnalyzers** and uncheck the rules you want to disable. When you save changes, a .ruleset file is added to your project.

docs/Configuration.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
# Rule configuration
22

3+
Rule behavior can be configured in [.editorconfig](https://editorconfig.org/) files, for example:
4+
5+
```ini
6+
root = true
7+
8+
[*.cs]
9+
dotnet_diagnostic.av1500.max_statement_count = 12
10+
dotnet_diagnostic.av1561.max_parameter_count = 5
11+
dotnet_diagnostic.av1561.max_constructor_parameter_count = 8
12+
```
13+
14+
Editorconfig settings are inherited from parent directories (unless `root = true`), which enables you to vary rule configuration per directory.
15+
Aside from rule-specific settings, you can set [severities](https://docs.microsoft.com/en-us/visualstudio/code-quality/use-roslyn-analyzers?view=vs-2019#set-rule-severity-in-an-editorconfig-file) for all rules in this file too:
16+
17+
```ini
18+
root = true
19+
20+
[*.cs]
21+
dotnet_diagnostic.av1115.severity = error
22+
dotnet_diagnostic.av1130.severity = suggestion
23+
```
24+
25+
# Legacy configuration support
26+
27+
Note: The method described here still exists for compatibility with earlier versions (editorconfig takes precedence), but will be removed in a future version.
28+
329
The behavior of rules can be customized by adding a file named `CSharpGuidelinesAnalyzer.config` to your C# project with the following structure:
430

531
```xml

src/CSharpGuidelinesAnalyzer/CSharpGuidelinesAnalyzer.Test/Specs/Maintainability/AvoidMemberWithManyStatementsSpecs.cs

Lines changed: 197 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2766,12 +2766,13 @@ class C
27662766
#region Non-default configuration
27672767

27682768
[Fact]
2769-
internal void When_method_body_contains_seventeen_statements_it_must_be_reported()
2769+
internal void When_using_editor_config_setting_it_must_be_applied()
27702770
{
27712771
// Arrange
27722772
ParsedSourceCode source = new TypeSourceCodeBuilder()
2773-
.WithSettings(new AnalyzerSettingsBuilder()
2774-
.Including(DiagnosticId, "MaxStatementCount", "16"))
2773+
.WithOptions(new AnalyzerOptionsBuilder()
2774+
.ForEditorConfig(new EditorConfigSettingsBuilder()
2775+
.Including(DiagnosticId, "max_statement_count", "16")))
27752776
.InGlobalScope(@"
27762777
class C
27772778
{
@@ -2793,11 +2794,70 @@ class C
27932794
}
27942795

27952796
[Fact]
2796-
public void When_settings_are_corrupt_it_must_use_default_value()
2797+
internal void When_using_xml_config_setting_it_must_be_applied()
27972798
{
27982799
// Arrange
27992800
ParsedSourceCode source = new TypeSourceCodeBuilder()
2800-
.WithSettings("*** BAD XML ***")
2801+
.WithOptions(new AnalyzerOptionsBuilder()
2802+
.ForXmlSettings(new XmlSettingsBuilder()
2803+
.Including(DiagnosticId, "MaxStatementCount", "16")))
2804+
.InGlobalScope(@"
2805+
class C
2806+
{
2807+
int [|M|](string s)
2808+
{
2809+
; ; ; ;
2810+
; ; ; ;
2811+
; ; ; ;
2812+
; ; ; ;
2813+
throw null;
2814+
}
2815+
}
2816+
")
2817+
.Build();
2818+
2819+
// Act and assert
2820+
VerifyGuidelineDiagnostic(source,
2821+
"Method 'C.M(string)' contains 17 statements, which exceeds the maximum of 16 statements.");
2822+
}
2823+
2824+
[Fact]
2825+
internal void When_using_xml_and_editor_config_setting_it_must_use_editor_config_value()
2826+
{
2827+
// Arrange
2828+
ParsedSourceCode source = new TypeSourceCodeBuilder()
2829+
.WithOptions(new AnalyzerOptionsBuilder()
2830+
.ForXmlSettings(new XmlSettingsBuilder()
2831+
.Including(DiagnosticId, "MaxStatementCount", "12"))
2832+
.ForEditorConfig(new EditorConfigSettingsBuilder()
2833+
.Including(DiagnosticId, "max_statement_count", "16")))
2834+
.InGlobalScope(@"
2835+
class C
2836+
{
2837+
int [|M|](string s)
2838+
{
2839+
; ; ; ;
2840+
; ; ; ;
2841+
; ; ; ;
2842+
; ; ; ;
2843+
throw null;
2844+
}
2845+
}
2846+
")
2847+
.Build();
2848+
2849+
// Act and assert
2850+
VerifyGuidelineDiagnostic(source,
2851+
"Method 'C.M(string)' contains 17 statements, which exceeds the maximum of 16 statements.");
2852+
}
2853+
2854+
[Fact]
2855+
public void When_xml_file_is_corrupt_it_must_use_default_value()
2856+
{
2857+
// Arrange
2858+
ParsedSourceCode source = new TypeSourceCodeBuilder()
2859+
.WithOptions(new AnalyzerOptionsBuilder()
2860+
.ForXmlText("*** BAD XML ***"))
28012861
.InGlobalScope(@"
28022862
class C
28032863
{
@@ -2817,12 +2877,15 @@ class C
28172877
}
28182878

28192879
[Fact]
2820-
public void When_setting_is_missing_it_must_use_default_value()
2880+
public void When_settings_are_missing_it_must_use_default_value()
28212881
{
28222882
// Arrange
28232883
ParsedSourceCode source = new TypeSourceCodeBuilder()
2824-
.WithSettings(new AnalyzerSettingsBuilder()
2825-
.Including(DiagnosticId, "OtherUnusedSetting", "SomeValue"))
2884+
.WithOptions(new AnalyzerOptionsBuilder()
2885+
.ForEditorConfig(new EditorConfigSettingsBuilder()
2886+
.Including(DiagnosticId, "other-unused-setting", "some-value"))
2887+
.ForXmlSettings(new XmlSettingsBuilder()
2888+
.Including(DiagnosticId, "OtherUnusedSetting", "SomeValue")))
28262889
.InGlobalScope(@"
28272890
class C
28282891
{
@@ -2842,12 +2905,13 @@ class C
28422905
}
28432906

28442907
[Fact]
2845-
public void When_setting_value_is_missing_it_must_use_default_value()
2908+
public void When_xml_setting_value_is_missing_it_must_use_default_value()
28462909
{
28472910
// Arrange
28482911
ParsedSourceCode source = new TypeSourceCodeBuilder()
2849-
.WithSettings(new AnalyzerSettingsBuilder()
2850-
.Including(DiagnosticId, "MaxStatementCount", null))
2912+
.WithOptions(new AnalyzerOptionsBuilder()
2913+
.ForXmlSettings(new XmlSettingsBuilder()
2914+
.Including(DiagnosticId, "MaxStatementCount", null)))
28512915
.InGlobalScope(@"
28522916
class C
28532917
{
@@ -2867,12 +2931,129 @@ class C
28672931
}
28682932

28692933
[Fact]
2870-
public void When_setting_value_is_out_of_range_it_must_fail()
2934+
public void When_editor_config_setting_value_is_missing_it_must_use_default_value()
2935+
{
2936+
// Arrange
2937+
ParsedSourceCode source = new TypeSourceCodeBuilder()
2938+
.WithOptions(new AnalyzerOptionsBuilder()
2939+
.ForEditorConfig(new EditorConfigSettingsBuilder()
2940+
.Including(DiagnosticId, "max_statement_count", null)))
2941+
.InGlobalScope(@"
2942+
class C
2943+
{
2944+
int [|M|](string s)
2945+
{
2946+
; ; ; ;
2947+
; ; ;
2948+
throw null;
2949+
}
2950+
}
2951+
")
2952+
.Build();
2953+
2954+
// Act and assert
2955+
VerifyGuidelineDiagnostic(source,
2956+
"Method 'C.M(string)' contains 8 statements, which exceeds the maximum of 7 statements.");
2957+
}
2958+
2959+
[Fact]
2960+
public void When_xml_setting_value_is_invalid_it_must_fail()
2961+
{
2962+
// Arrange
2963+
ParsedSourceCode source = new TypeSourceCodeBuilder()
2964+
.WithOptions(new AnalyzerOptionsBuilder()
2965+
.ForXmlSettings(new XmlSettingsBuilder()
2966+
.Including(DiagnosticId, "MaxStatementCount", "bad")))
2967+
.InGlobalScope(@"
2968+
class C
2969+
{
2970+
int [|M|](string s)
2971+
{
2972+
; ; ; ;
2973+
; ; ;
2974+
throw null;
2975+
}
2976+
}
2977+
")
2978+
.Build();
2979+
2980+
// Act
2981+
Action action = () => VerifyGuidelineDiagnostic(source);
2982+
2983+
// Assert
2984+
action.Should().Throw<Exception>()
2985+
.WithMessage(
2986+
"*Value for 'AV1500:MaxStatementCount' in 'CSharpGuidelinesAnalyzer.config' must be in range 0-255.*");
2987+
}
2988+
2989+
[Fact]
2990+
public void When_editor_config_setting_value_is_invalid_it_must_fail()
2991+
{
2992+
// Arrange
2993+
ParsedSourceCode source = new TypeSourceCodeBuilder()
2994+
.WithOptions(new AnalyzerOptionsBuilder()
2995+
.ForEditorConfig(new EditorConfigSettingsBuilder()
2996+
.Including(DiagnosticId, "max_statement_count", "bad")))
2997+
.InGlobalScope(@"
2998+
class C
2999+
{
3000+
int [|M|](string s)
3001+
{
3002+
; ; ; ;
3003+
; ; ;
3004+
throw null;
3005+
}
3006+
}
3007+
")
3008+
.Build();
3009+
3010+
// Act
3011+
Action action = () => VerifyGuidelineDiagnostic(source);
3012+
3013+
// Assert
3014+
action.Should().Throw<Exception>()
3015+
.WithMessage(
3016+
"*Value for 'dotnet_diagnostic.av1500.max_statement_count' in '.editorconfig' must be in range 0-255.*");
3017+
}
3018+
3019+
[Fact]
3020+
public void When_xml_setting_value_is_out_of_range_it_must_fail()
3021+
{
3022+
// Arrange
3023+
ParsedSourceCode source = new TypeSourceCodeBuilder()
3024+
.WithOptions(new AnalyzerOptionsBuilder()
3025+
.ForXmlSettings(new XmlSettingsBuilder()
3026+
.Including(DiagnosticId, "MaxStatementCount", "-1")))
3027+
.InGlobalScope(@"
3028+
class C
3029+
{
3030+
int [|M|](string s)
3031+
{
3032+
; ; ; ;
3033+
; ; ;
3034+
throw null;
3035+
}
3036+
}
3037+
")
3038+
.Build();
3039+
3040+
// Act
3041+
Action action = () => VerifyGuidelineDiagnostic(source);
3042+
3043+
// Assert
3044+
action.Should().Throw<Exception>()
3045+
.WithMessage(
3046+
"*Value for 'AV1500:MaxStatementCount' in 'CSharpGuidelinesAnalyzer.config' must be in range 0-255.*");
3047+
}
3048+
3049+
[Fact]
3050+
public void When_editor_config_setting_value_is_out_of_range_it_must_fail()
28713051
{
28723052
// Arrange
28733053
ParsedSourceCode source = new TypeSourceCodeBuilder()
2874-
.WithSettings(new AnalyzerSettingsBuilder()
2875-
.Including(DiagnosticId, "MaxStatementCount", "-1"))
3054+
.WithOptions(new AnalyzerOptionsBuilder()
3055+
.ForEditorConfig(new EditorConfigSettingsBuilder()
3056+
.Including(DiagnosticId, "max_statement_count", "-1")))
28763057
.InGlobalScope(@"
28773058
class C
28783059
{
@@ -2891,7 +3072,8 @@ class C
28913072

28923073
// Assert
28933074
action.Should().Throw<Exception>()
2894-
.WithMessage("*Value for AV1500:MaxStatementCount configuration setting must be in range 0-255.*");
3075+
.WithMessage(
3076+
"*Value for 'dotnet_diagnostic.av1500.max_statement_count' in '.editorconfig' must be in range 0-255.*");
28953077
}
28963078

28973079
#endregion

0 commit comments

Comments
 (0)