Skip to content

Commit 3f1a366

Browse files
authored
Fix RCS1060 (#1401)
1 parent 248e785 commit 3f1a366

File tree

8 files changed

+161
-31
lines changed

8 files changed

+161
-31
lines changed

ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Fix analyzer [RCS1159](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1159) ([PR](https://github.com/dotnet/roslynator/pull/1390))
2222
- Fix analyzer [RCS1019](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1019) ([PR](https://github.com/dotnet/roslynator/pull/1402))
2323
- Fix analyzer [RCS1250](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1250) ([PR](https://github.com/dotnet/roslynator/pull/1403))
24+
- Fix analyzer [RCS1060](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1060) ([PR](https://github.com/dotnet/roslynator/pull/1401))
2425
- Fix code fix for [CS8600](https://josefpihrt.github.io/docs/roslynator/fixes/CS8600) changing the wrong type when casts or `var` are involved ([PR](https://github.com/dotnet/roslynator/pull/1393) by @jroessel)
2526

2627
## [4.10.0] - 2024-01-24

src/Analyzers/CSharp/Analysis/DeclareEachTypeInSeparateFileAnalyzer.cs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ void Analyze(SyntaxList<MemberDeclarationSyntax> members)
5252
{
5353
foreach (MemberDeclarationSyntax member in members)
5454
{
55-
SyntaxKind kind = member.Kind();
56-
57-
if (kind == SyntaxKind.NamespaceDeclaration)
55+
#if ROSLYN_4_0
56+
if (member is BaseNamespaceDeclarationSyntax namespaceDeclaration)
57+
#else
58+
if (member is NamespaceDeclarationSyntax namespaceDeclaration)
59+
#endif
5860
{
59-
var namespaceDeclaration = (NamespaceDeclarationSyntax)member;
60-
6161
Analyze(namespaceDeclaration.Members);
6262
}
63-
else if (SyntaxFacts.IsTypeDeclaration(kind))
63+
else if (SyntaxFacts.IsTypeDeclaration(member.Kind()))
6464
{
6565
if (firstTypeDeclaration is null)
6666
{
@@ -93,16 +93,18 @@ private static void ReportDiagnostic(SyntaxNodeAnalysisContext context, MemberDe
9393

9494
private static bool ContainsSingleNamespaceWithSingleNonNamespaceMember(SyntaxList<MemberDeclarationSyntax> members)
9595
{
96-
MemberDeclarationSyntax member = members.SingleOrDefault(shouldThrow: false);
97-
98-
if (member?.Kind() != SyntaxKind.NamespaceDeclaration)
99-
return false;
100-
101-
var namespaceDeclaration = (NamespaceDeclarationSyntax)member;
96+
#if ROSLYN_4_0
97+
if (members.SingleOrDefault(shouldThrow: false) is BaseNamespaceDeclarationSyntax namespaceDeclaration)
98+
#else
99+
if (members.SingleOrDefault(shouldThrow: false) is NamespaceDeclarationSyntax namespaceDeclaration)
100+
#endif
101+
{
102+
MemberDeclarationSyntax member = namespaceDeclaration.Members.SingleOrDefault(shouldThrow: false);
102103

103-
member = namespaceDeclaration.Members.SingleOrDefault(shouldThrow: false);
104+
return member is not null
105+
&& member.Kind() != SyntaxKind.NamespaceDeclaration;
106+
}
104107

105-
return member is not null
106-
&& member.Kind() != SyntaxKind.NamespaceDeclaration;
108+
return false;
107109
}
108110
}

src/Refactorings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ if (y)
389389
<Syntax>while statement</Syntax>
390390
</Syntaxes>
391391
</Refactoring>
392-
<Refactoring Id="RR0046" Identifier="ExtractTypeDeclarationToNewFile" Title="Extract type declaration to a new file">
392+
<Refactoring Id="RR0046" Identifier="ExtractTypeDeclarationToNewFile" Title="Extract type declaration to a new file" IsEnabledByDefault="false">
393393
<OptionKey>extract_type_declaration_to_new_file</OptionKey>
394394
<Syntaxes>
395395
<Syntax>class declaration</Syntax>

src/Refactorings/CSharp/Refactorings/ExtractTypeDeclarationToNewFileRefactoring.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ public static void ComputeRefactorings(RefactoringContext context, DelegateDecla
4848
private static void ComputeRefactorings(RefactoringContext context, MemberDeclarationSyntax memberDeclaration, SyntaxToken identifier)
4949
{
5050
if (identifier.Span.Contains(context.Span)
51-
&& memberDeclaration.IsParentKind(SyntaxKind.NamespaceDeclaration, SyntaxKind.CompilationUnit)
51+
&& memberDeclaration.IsParentKind(
52+
SyntaxKind.NamespaceDeclaration,
53+
#if ROSLYN_4_0
54+
SyntaxKind.FileScopedNamespaceDeclaration,
55+
#endif
56+
SyntaxKind.CompilationUnit)
5257
&& context.IsRootCompilationUnit
5358
&& context.Workspace.Kind != WorkspaceKind.MiscellaneousFiles
5459
&& ExtractTypeDeclarationToNewDocumentRefactoring.GetNonNestedTypeDeclarations((CompilationUnitSyntax)context.Root).Skip(1).Any())
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
2+
3+
using System.Threading.Tasks;
4+
using Microsoft.CodeAnalysis;
5+
using Roslynator.CSharp.CodeFixes;
6+
using Roslynator.Testing.CSharp;
7+
using Xunit;
8+
9+
namespace Roslynator.CSharp.Analysis.Tests;
10+
11+
public class RCS1060DeclareEachTypeInSeparateFileTests : AbstractCSharpDiagnosticVerifier<DeclareEachTypeInSeparateFileAnalyzer, ExtractMemberToNewDocumentCodeFixProvider>
12+
{
13+
public override DiagnosticDescriptor Descriptor => DiagnosticRules.DeclareEachTypeInSeparateFile;
14+
15+
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.DeclareEachTypeInSeparateFile)]
16+
public async Task Test_Namespace()
17+
{
18+
await VerifyDiagnosticAndFixAsync("""
19+
namespace N
20+
{
21+
public class [|C1|]
22+
{
23+
}
24+
25+
public class [|C2|]
26+
{
27+
}
28+
}
29+
""", """
30+
namespace N
31+
{
32+
public class C2
33+
{
34+
}
35+
}
36+
""");
37+
}
38+
39+
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.DeclareEachTypeInSeparateFile)]
40+
public async Task Test_FileScopedNamespace()
41+
{
42+
await VerifyDiagnosticAndFixAsync("""
43+
namespace N;
44+
45+
public class [|C1|]
46+
{
47+
}
48+
49+
public class [|C2|]
50+
{
51+
}
52+
""", """
53+
namespace N;
54+
55+
public class C2
56+
{
57+
}
58+
""");
59+
}
60+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
2+
3+
using System.Threading.Tasks;
4+
using Roslynator.Testing.CSharp;
5+
using Xunit;
6+
7+
namespace Roslynator.CSharp.Refactorings.Tests;
8+
9+
public class RR0046ExtractTypeDeclarationToNewFileTests : AbstractCSharpRefactoringVerifier
10+
{
11+
public override string RefactoringId { get; } = RefactoringIdentifiers.ExtractTypeDeclarationToNewFile;
12+
13+
[Fact, Trait(Traits.Refactoring, RefactoringIdentifiers.ExtractTypeDeclarationToNewFile)]
14+
public async Task Test_Namespace()
15+
{
16+
await VerifyRefactoringAsync("""
17+
namespace N
18+
{
19+
public class C1
20+
{
21+
22+
}
23+
24+
public class [||]C2
25+
{
26+
27+
}
28+
}
29+
""", """
30+
namespace N
31+
{
32+
public class C1
33+
{
34+
35+
}
36+
}
37+
""", equivalenceKey: EquivalenceKey.Create(RefactoringId));
38+
}
39+
40+
[Fact, Trait(Traits.Refactoring, RefactoringIdentifiers.ExtractTypeDeclarationToNewFile)]
41+
public async Task Test_FileScopedNamespace()
42+
{
43+
await VerifyRefactoringAsync("""
44+
namespace N;
45+
46+
public class C1
47+
{
48+
}
49+
50+
public class [||]C2
51+
{
52+
}
53+
""", """
54+
namespace N;
55+
56+
public class C1
57+
{
58+
}
59+
60+
""", equivalenceKey: EquivalenceKey.Create(RefactoringId));
61+
}
62+
}

src/VisualStudio/.roslynatorconfig

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
is_global = true
22

3-
roslnator.max_line_length = 140
4-
roslynator.prefix_field_identifier_with_underscore = false
5-
6-
roslynator.refactoring.RR0010.enabled = false
7-
roslynator.refactoring.RR0012.enabled = false
8-
roslynator.refactoring.RR0066.enabled = false
9-
roslynator.refactoring.RR0088.enabled = false
10-
roslynator.refactoring.RR0138.enabled = false
11-
roslynator.refactoring.RR0171.enabled = false
12-
roslynator.refactoring.RR0188.enabled = false
3+
roslynator_refactoring.convert_foreach_to_for_and_reverse_loop.enabled = false
4+
roslynator_refactoring.expand_initializer.enabled = false
5+
roslynator_refactoring.extract_type_declaration_to_new_file.enabled = false
6+
roslynator_refactoring.introduce_constructor.enabled = false
7+
roslynator_refactoring.remove_all_documentation_comments.enabled = false
8+
roslynator_refactoring.replace_method_with_property.enabled = false
9+
roslynator_refactoring.use_string_empty_instead_of_empty_string_literal.enabled = false

src/Workspaces.Common/CSharp/Refactorings/ExtractTypeDeclarationToNewDocumentRefactoring.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ private static SyntaxNode RemoveNode(MemberDeclarationSyntax member)
5454

5555
int index = members.IndexOf(member);
5656

57-
if (index == 0
57+
if (member.IsParentKind(SyntaxKind.NamespaceDeclaration)
58+
&& index == 0
5859
&& index < members.Count - 1)
5960
{
6061
MemberDeclarationSyntax nextMember = newMemberList[index];
@@ -113,10 +114,12 @@ private static IEnumerable<MemberDeclarationSyntax> GetNonNestedTypeDeclarations
113114
{
114115
SyntaxKind kind = member.Kind();
115116

116-
if (kind == SyntaxKind.NamespaceDeclaration)
117+
#if ROSLYN_4_0
118+
if (member is BaseNamespaceDeclarationSyntax namespaceDeclaration)
119+
#else
120+
if (member is NamespaceDeclarationSyntax namespaceDeclaration)
121+
#endif
117122
{
118-
var namespaceDeclaration = (NamespaceDeclarationSyntax)member;
119-
120123
foreach (MemberDeclarationSyntax member2 in GetNonNestedTypeDeclarations(namespaceDeclaration.Members))
121124
yield return member2;
122125
}

0 commit comments

Comments
 (0)