diff --git a/ChangeLog.md b/ChangeLog.md index a635d58135..8bb10fd1ad 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix [RCS1169](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1169.md) ([#1092](https://github.com/JosefPihrt/Roslynator/pull/1092)). - Recognize more shapes of IAsyncEnumerable as being Async ([RCS1047](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1047.md)) ([#1084](https://github.com/josefpihrt/roslynator/pull/1084)). - Fix [RCS1197](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1197.md) ([#1093](https://github.com/JosefPihrt/Roslynator/pull/1093)). +- Fix [RCS1056](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1056.md) ([#1096](https://github.com/JosefPihrt/Roslynator/pull/1096)). ## [4.3.0] - 2023-04-24 diff --git a/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs b/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs index 3202a59dbc..2def63e6a4 100644 --- a/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs +++ b/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs @@ -91,6 +91,14 @@ internal static UsingDirectiveListInfo Create(NamespaceDeclarationSyntax namespa return new UsingDirectiveListInfo(namespaceDeclaration, namespaceDeclaration.Usings); } + internal static UsingDirectiveListInfo Create(FileScopedNamespaceDeclarationSyntax namespaceDeclaration) + { + if (namespaceDeclaration is null) + return default; + + return new UsingDirectiveListInfo(namespaceDeclaration, namespaceDeclaration.Usings); + } + internal static UsingDirectiveListInfo Create(CompilationUnitSyntax compilationUnit) { if (compilationUnit is null) @@ -113,6 +121,11 @@ internal static UsingDirectiveListInfo Create(SyntaxNode declaration) var namespaceDeclaration = (NamespaceDeclarationSyntax)declaration; return new UsingDirectiveListInfo(namespaceDeclaration, namespaceDeclaration.Usings); } + case SyntaxKind.FileScopedNamespaceDeclaration: + { + var fileScopedNamespaceDeclaration = (FileScopedNamespaceDeclarationSyntax)declaration; + return new UsingDirectiveListInfo(fileScopedNamespaceDeclaration, fileScopedNamespaceDeclaration.Usings); + } } return default; diff --git a/src/CSharp/CSharp/SyntaxInfo.cs b/src/CSharp/CSharp/SyntaxInfo.cs index 57eb21bc0f..5eec8bf8c7 100644 --- a/src/CSharp/CSharp/SyntaxInfo.cs +++ b/src/CSharp/CSharp/SyntaxInfo.cs @@ -1088,6 +1088,15 @@ public static UsingDirectiveListInfo UsingDirectiveListInfo(NamespaceDeclaration return Syntax.UsingDirectiveListInfo.Create(declaration); } + /// + /// Creates a new from the specified declaration. + /// + /// + public static UsingDirectiveListInfo UsingDirectiveListInfo(FileScopedNamespaceDeclarationSyntax declaration) + { + return Syntax.UsingDirectiveListInfo.Create(declaration); + } + /// /// Creates a new from the specified xml node. /// diff --git a/src/Tests/Analyzers.Tests/RCS1056AvoidUsageOfUsingAliasDirectiveTests.cs b/src/Tests/Analyzers.Tests/RCS1056AvoidUsageOfUsingAliasDirectiveTests.cs index 1337bdf7c1..0064422da6 100644 --- a/src/Tests/Analyzers.Tests/RCS1056AvoidUsageOfUsingAliasDirectiveTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1056AvoidUsageOfUsingAliasDirectiveTests.cs @@ -49,6 +49,64 @@ void M() string u2 = System.String.Empty; } } +"); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.AvoidUsageOfUsingAliasDirective)] + public async Task Test_FileScopedNamespaces() + { + await VerifyDiagnosticAndFixAsync(@" +namespace FileScopedNamespace; +[|using s = System;|] + +class C +{ + void M() + { + string u1 = s.String.Empty; + } +} +", @" +namespace FileScopedNamespace; + +class C +{ + void M() + { + string u1 = System.String.Empty; + } +} +"); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.AvoidUsageOfUsingAliasDirective)] + public async Task Test_BlockNamespaces() + { + await VerifyDiagnosticAndFixAsync(@" +namespace BlockNamespace +{ + [|using s = System;|] + + class C + { + void M() + { + string u1 = s.String.Empty; + } + } +} +", @" +namespace BlockNamespace +{ + + class C + { + void M() + { + string u1 = System.String.Empty; + } + } +} "); } } diff --git a/src/Workspaces.Common/CSharp/Refactorings/InlineAliasExpressionRefactoring.cs b/src/Workspaces.Common/CSharp/Refactorings/InlineAliasExpressionRefactoring.cs index e58698acee..f3c9f90d3a 100644 --- a/src/Workspaces.Common/CSharp/Refactorings/InlineAliasExpressionRefactoring.cs +++ b/src/Workspaces.Common/CSharp/Refactorings/InlineAliasExpressionRefactoring.cs @@ -22,7 +22,7 @@ public static async Task RefactorAsync( SyntaxNode parent = usingDirective.Parent; - Debug.Assert(parent.IsKind(SyntaxKind.CompilationUnit, SyntaxKind.NamespaceDeclaration), ""); + Debug.Assert(parent.IsKind(SyntaxKind.CompilationUnit, SyntaxKind.NamespaceDeclaration, SyntaxKind.FileScopedNamespaceDeclaration), ""); int index = SyntaxInfo.UsingDirectiveListInfo(parent).IndexOf(usingDirective); @@ -43,6 +43,8 @@ private static SyntaxNode RemoveUsingDirective(SyntaxNode node, int index) return compilationUnit.RemoveNode(compilationUnit.Usings[index]); case NamespaceDeclarationSyntax namespaceDeclaration: return namespaceDeclaration.RemoveNode(namespaceDeclaration.Usings[index]); + case FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclaration: + return fileScopedNamespaceDeclaration.RemoveNode(fileScopedNamespaceDeclaration.Usings[index]); } return node;