Skip to content

Commit cc2cce6

Browse files
committed
Update SA1300 for file-scoped namespaces
1 parent e16de1d commit cc2cce6

3 files changed

Lines changed: 92 additions & 5 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/RenameToUpperCaseCodeFixProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace StyleCop.Analyzers.NamingRules
1414
using Microsoft.CodeAnalysis.CSharp;
1515
using Microsoft.CodeAnalysis.CSharp.Syntax;
1616
using StyleCop.Analyzers.Helpers;
17+
using StyleCop.Analyzers.Lightup;
1718

1819
/// <summary>
1920
/// Implements a code fix for all analyzers that require a symbol to be upper case.
@@ -60,7 +61,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
6061
var newName = baseName;
6162
var memberSyntax = RenameHelper.GetParentDeclaration(token);
6263

63-
if (memberSyntax is NamespaceDeclarationSyntax)
64+
if (BaseNamespaceDeclarationSyntaxWrapper.IsInstance(memberSyntax))
6465
{
6566
// namespaces are not symbols. So we are just renaming the namespace
6667
Task<Document> RenameNamespace(CancellationToken cancellationToken)

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,95 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp10.NamingRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp9.NamingRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.NamingRules.SA1300ElementMustBeginWithUpperCaseLetter,
13+
StyleCop.Analyzers.NamingRules.RenameToUpperCaseCodeFixProvider>;
714

815
public class SA1300CSharp10UnitTests : SA1300CSharp9UnitTests
916
{
17+
[Fact]
18+
public async Task TestUpperCaseFileScopedNamespaceAsync()
19+
{
20+
var testCode = @"namespace Test;";
21+
22+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
23+
}
24+
25+
[Fact]
26+
public async Task TestLowerCaseFileScopedNamespaceAsync()
27+
{
28+
var testCode = @"namespace {|#0:test|};";
29+
30+
var fixedCode = @"namespace Test;";
31+
32+
DiagnosticResult expected = Diagnostic().WithArguments("test").WithLocation(0);
33+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
34+
}
35+
36+
[Fact]
37+
public async Task TestAllowedLowerCaseFileScopedNamespaceIsNotReportedAsync()
38+
{
39+
var customTestSettings = @"
40+
{
41+
""settings"": {
42+
""namingRules"": {
43+
""allowedNamespaceComponents"": [ ""eBay"" ]
44+
}
45+
}
46+
}
47+
";
48+
49+
var testCode = @"namespace eBay;";
50+
51+
await new CSharpTest
52+
{
53+
TestCode = testCode,
54+
Settings = customTestSettings,
55+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
56+
}
57+
58+
[Fact]
59+
public async Task TestLowerCaseComlicatedFileScopedNamespaceAsync()
60+
{
61+
var testCode = @"namespace {|#0:test|}.{|#1:foo|}.{|#2:bar|};";
62+
63+
var fixedCode = @"namespace Test.Foo.Bar;";
64+
65+
DiagnosticResult[] expected = new[]
66+
{
67+
Diagnostic().WithArguments("test").WithLocation(0),
68+
Diagnostic().WithArguments("foo").WithLocation(1),
69+
Diagnostic().WithArguments("bar").WithLocation(2),
70+
};
71+
72+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
73+
}
74+
75+
[Fact]
76+
public async Task TestAllowedLowerCaseComplicatedFileScopedNamespaceIsNotReportedAsync()
77+
{
78+
var customTestSettings = @"
79+
{
80+
""settings"": {
81+
""namingRules"": {
82+
""allowedNamespaceComponents"": [ ""iPod"" ]
83+
}
84+
}
85+
}
86+
";
87+
88+
var testCode = @"namespace Apple.iPod.Library;";
89+
90+
await new CSharpTest
91+
{
92+
TestCode = testCode,
93+
Settings = customTestSettings,
94+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
95+
}
1096
}
1197
}

StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1300ElementMustBeginWithUpperCaseLetter.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ internal class SA1300ElementMustBeginWithUpperCaseLetter : DiagnosticAnalyzer
4949
private static readonly DiagnosticDescriptor Descriptor =
5050
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.NamingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
5151

52-
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> NamespaceDeclarationAction = HandleNamespaceDeclaration;
52+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration;
5353
private static readonly Action<SyntaxNodeAnalysisContext> ClassDeclarationAction = HandleClassDeclaration;
5454
private static readonly Action<SyntaxNodeAnalysisContext> RecordDeclarationAction = HandleRecordDeclaration;
5555
private static readonly Action<SyntaxNodeAnalysisContext> EnumDeclarationAction = HandleEnumDeclaration;
@@ -75,7 +75,7 @@ public override void Initialize(AnalysisContext context)
7575

7676
// Note: Interfaces are handled by SA1302
7777
// Note: Fields are handled by SA1303 through SA1311
78-
context.RegisterSyntaxNodeAction(NamespaceDeclarationAction, SyntaxKind.NamespaceDeclaration);
78+
context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration);
7979
context.RegisterSyntaxNodeAction(ClassDeclarationAction, SyntaxKind.ClassDeclaration);
8080
context.RegisterSyntaxNodeAction(RecordDeclarationAction, SyntaxKindEx.RecordDeclaration);
8181
context.RegisterSyntaxNodeAction(RecordDeclarationAction, SyntaxKindEx.RecordStructDeclaration);
@@ -91,9 +91,9 @@ public override void Initialize(AnalysisContext context)
9191
context.RegisterSyntaxNodeAction(ParameterAction, SyntaxKind.Parameter);
9292
}
9393

94-
private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
94+
private static void HandleBaseNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
9595
{
96-
NameSyntax nameSyntax = ((NamespaceDeclarationSyntax)context.Node).Name;
96+
NameSyntax nameSyntax = ((BaseNamespaceDeclarationSyntaxWrapper)context.Node).Name;
9797
CheckNamespaceNameSyntax(context, nameSyntax, settings);
9898
}
9999

0 commit comments

Comments
 (0)