Skip to content

Commit 31cd1a5

Browse files
committed
Update SA1135 to support file-scoped namespaces
Fixes #3415
1 parent a6d0cb2 commit 31cd1a5

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1135CSharp10UnitTests.cs

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

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

815
public class SA1135CSharp10UnitTests : SA1135CSharp9UnitTests
916
{
17+
[Fact]
18+
[WorkItem(3415, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3415")]
19+
public async Task TestFileScopedNamespaceAsync()
20+
{
21+
var testCode = @"
22+
namespace TestNamespace
23+
{
24+
using KeyValue = System.Collections.Generic.KeyValuePair<string, object?>;
25+
}
26+
";
27+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
28+
await new CSharpTest
29+
{
30+
TestState =
31+
{
32+
Sources =
33+
{
34+
@"namespace A.B.C { }",
35+
@"namespace A.B.D;
36+
37+
[|using C;|]
38+
",
39+
},
40+
},
41+
FixedState =
42+
{
43+
Sources =
44+
{
45+
@"namespace A.B.C { }",
46+
@"namespace A.B.D;
47+
48+
using A.B.C;
49+
",
50+
},
51+
},
52+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
53+
}
1054
}
1155
}

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1135UsingDirectivesMustBeQualified.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ private static void HandleUsingDeclaration(SyntaxNodeAnalysisContext context)
6767

6868
private static void CheckUsingDeclaration(SyntaxNodeAnalysisContext context, UsingDirectiveSyntax usingDirective)
6969
{
70-
if (!usingDirective.Parent.IsKind(SyntaxKind.NamespaceDeclaration))
70+
if (!usingDirective.Parent.IsKind(SyntaxKind.NamespaceDeclaration)
71+
&& !usingDirective.Parent.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration))
7172
{
7273
// Usings outside of a namespace are always qualified.
7374
return;
@@ -104,7 +105,7 @@ private static void CheckUsingDeclaration(SyntaxNodeAnalysisContext context, Usi
104105
break;
105106

106107
case SymbolKind.NamedType:
107-
var containingNamespace = ((NamespaceDeclarationSyntax)usingDirective.Parent).Name.ToString();
108+
var containingNamespace = ((BaseNamespaceDeclarationSyntaxWrapper)usingDirective.Parent).Name.ToString();
108109
if (containingNamespace != symbol.ContainingNamespace.ToString())
109110
{
110111
context.ReportDiagnostic(Diagnostic.Create(DescriptorType, usingDirective.GetLocation(), symbolString));

0 commit comments

Comments
 (0)