Skip to content

Commit e762730

Browse files
committed
SA1401 now ignores static readonly fields
1 parent 39b5c3f commit e762730

3 files changed

Lines changed: 30 additions & 6 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1401UnitTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,21 @@ public async Task TestClassWithConstFieldAsync()
7474
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
7575
}
7676

77+
[Theory]
78+
[InlineData("public")]
79+
[InlineData("protected")]
80+
[InlineData("protected internal")]
81+
public async Task TestClassWithStaticReadonlyFieldAsync(string accessModifier)
82+
{
83+
var testCode = $@"public class TestClass
84+
{{
85+
{accessModifier} static readonly string TestField = ""qwe"";
86+
}}
87+
";
88+
89+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
90+
}
91+
7792
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
7893
{
7994
yield return new SA1401FieldsMustBePrivate();

StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1401FieldsMustBePrivate.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace StyleCop.Analyzers.MaintainabilityRules
55
{
6+
using System;
67
using System.Collections.Immutable;
78
using Microsoft.CodeAnalysis;
89
using Microsoft.CodeAnalysis.Diagnostics;
@@ -49,14 +50,15 @@ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
4950
/// <inheritdoc/>
5051
public override void Initialize(AnalysisContext context)
5152
{
52-
context.RegisterSymbolAction(this.AnalyzeField, SymbolKind.Field);
53+
context.RegisterSymbolAction(AnalyzeField, SymbolKind.Field);
5354
}
5455

55-
private void AnalyzeField(SymbolAnalysisContext symbolAnalysisContext)
56+
private static void AnalyzeField(SymbolAnalysisContext symbolAnalysisContext)
5657
{
5758
var fieldDeclarationSyntax = (IFieldSymbol)symbolAnalysisContext.Symbol;
58-
if (!this.IsFieldPrivate(fieldDeclarationSyntax) &&
59-
this.IsParentAClass(fieldDeclarationSyntax) &&
59+
if (!IsFieldPrivate(fieldDeclarationSyntax) &&
60+
!IsStaticReadonly(fieldDeclarationSyntax) &&
61+
IsParentAClass(fieldDeclarationSyntax) &&
6062
!fieldDeclarationSyntax.IsConst)
6163
{
6264
foreach (var location in symbolAnalysisContext.Symbol.Locations)
@@ -77,12 +79,17 @@ private void AnalyzeField(SymbolAnalysisContext symbolAnalysisContext)
7779
}
7880
}
7981

80-
private bool IsFieldPrivate(IFieldSymbol fieldDeclarationSyntax)
82+
private static bool IsFieldPrivate(IFieldSymbol fieldDeclarationSyntax)
8183
{
8284
return fieldDeclarationSyntax.DeclaredAccessibility == Accessibility.Private;
8385
}
8486

85-
private bool IsParentAClass(IFieldSymbol fieldDeclarationSyntax)
87+
private static bool IsStaticReadonly(IFieldSymbol fieldDeclarationSyntax)
88+
{
89+
return fieldDeclarationSyntax.IsStatic && fieldDeclarationSyntax.IsReadOnly;
90+
}
91+
92+
private static bool IsParentAClass(IFieldSymbol fieldDeclarationSyntax)
8693
{
8794
if (fieldDeclarationSyntax.ContainingSymbol != null &&
8895
fieldDeclarationSyntax.ContainingSymbol.Kind == SymbolKind.NamedType)

documentation/SA1401.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ A violation of this rule occurs whenever a field in a class is given non-private
2525

2626
Fields located within C# structs are allowed to have any access level.
2727

28+
Fields that are static and readonly will not raise a violation. These kinds of fields are commonly used to represent a constant value when the `const` keyword cannot be used, and therefore they are exempt from this rule.
29+
2830
## How to fix violations
2931

3032
To fix a violation of this rule, make the field private and add a property to expose the field outside of the class.

0 commit comments

Comments
 (0)