From b11a3edb5c055e385c75ae1fb47f4498a2719d26 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Mon, 31 Oct 2022 16:20:05 +0100 Subject: [PATCH] Do not make generic class static if it's inherited (RCS1102) (#978) --- ChangeLog.md | 1 + .../CSharp/Analysis/MakeClassStaticAnalyzer.cs | 15 ++++++++++++--- .../RCS1102MakeClassStaticTests.cs | 13 +++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index c7e4d3f48a..eadeaee95f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use explicit type from lambda expression ([RCS1008](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1008.md)) ([#967](https://github.com/josefpihrt/roslynator/pull/967). - Do not remove constructor if it is decorated with 'UsedImplicitlyAttribute' ([RCS1074](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1074.md)) ([#968](https://github.com/josefpihrt/roslynator/pull/968). - Detect argument null check in the form of `ArgumentNullException.ThrowIfNull` ([RR0025](https://github.com/JosefPihrt/Roslynator/blob/main/docs/refactorings/RR0025.md), [RCS1227](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1227.md)) ([#974](https://github.com/josefpihrt/roslynator/pull/974). +- Do not make generic class static if it's inherited ([RCS1102](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1102.md)) ([#978](https://github.com/josefpihrt/roslynator/pull/978). ----- diff --git a/src/Analyzers/CSharp/Analysis/MakeClassStaticAnalyzer.cs b/src/Analyzers/CSharp/Analysis/MakeClassStaticAnalyzer.cs index 0d4bd576b4..1b9869b4f7 100644 --- a/src/Analyzers/CSharp/Analysis/MakeClassStaticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/MakeClassStaticAnalyzer.cs @@ -190,7 +190,8 @@ protected override void VisitType(TypeSyntax node) { if (node is IdentifierNameSyntax identifierName) { - if (string.Equals(Symbol.Name, identifierName.Identifier.ValueText, StringComparison.Ordinal) + if (!identifierName.IsVar + && string.Equals(Symbol.Name, identifierName.Identifier.ValueText, StringComparison.Ordinal) && SymbolEqualityComparer.Default.Equals( SemanticModel.GetSymbol(identifierName, CancellationToken)?.OriginalDefinition, Symbol)) @@ -198,10 +199,18 @@ protected override void VisitType(TypeSyntax node) CanBeMadeStatic = false; } } - else + else if (node is GenericNameSyntax genericName) { - base.VisitType(node); + if (string.Equals(Symbol.Name, genericName.Identifier.ValueText, StringComparison.Ordinal) + && SymbolEqualityComparer.Default.Equals( + SemanticModel.GetSymbol(genericName, CancellationToken)?.OriginalDefinition, + Symbol)) + { + CanBeMadeStatic = false; + } } + + base.VisitType(node); } public static MakeClassStaticWalker GetInstance() diff --git a/src/Tests/Analyzers.Tests/RCS1102MakeClassStaticTests.cs b/src/Tests/Analyzers.Tests/RCS1102MakeClassStaticTests.cs index 6eb57f8ef5..20584d7242 100644 --- a/src/Tests/Analyzers.Tests/RCS1102MakeClassStaticTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1102MakeClassStaticTests.cs @@ -161,6 +161,19 @@ static C M() return null; } } +"); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.MakeClassStatic)] + public async Task TestNoDiagnostic_NestedClass() + { + await VerifyNoDiagnosticAsync(@" +public class Class1 +{ + public sealed class Class2 : Class1 + { + } +} "); } }