diff --git a/ChangeLog.md b/ChangeLog.md index 0f8f0a1952..6489de7152 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [CLI] Fix loading of `slnf` files ([PR](https://github.com/dotnet/roslynator/pull/1447)) - [CLI] Fix `--severity-level` ([PR](https://github.com/dotnet/roslynator/pull/1449)) - Fix analyzer [RCS1246](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1246) ([PR](https://github.com/dotnet/roslynator/pull/1451)) +- Fix analyzer [RCS1208](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1208) ([PR](https://github.com/dotnet/roslynator/pull/1462)) ## [4.12.1] - 2024-04-15 diff --git a/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingAnalysis.cs b/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingAnalysis.cs index b05b7da339..f25c5e0e64 100644 --- a/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingAnalysis.cs +++ b/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingAnalysis.cs @@ -113,7 +113,7 @@ private static ReduceIfNestingAnalysisResult AnalyzeCore( return Success(jumpKind, parent); } - if (!IsFixable(ifStatement, statements, ref jumpKind)) + if (!IsFixable(ifStatement, statements, options, ref jumpKind)) return Fail(node); switch (parentKind) @@ -314,6 +314,7 @@ private static bool IsNestedFix(SyntaxNode node, SemanticModel semanticModel, Re private static bool IsFixable( IfStatementSyntax ifStatement, SyntaxList statements, + ReduceIfNestingOptions options, ref SyntaxKind jumpKind) { int i = statements.Count - 1; @@ -326,7 +327,7 @@ private static bool IsFixable( if (statements[i] == ifStatement) { - return true; + return (options & ReduceIfNestingOptions.AllowLastIf) != 0; } else if (IsFixableJumpStatement(statements[i], ref jumpKind)) { diff --git a/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingOptions.cs b/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingOptions.cs index 9c0209dde1..bb63832ee5 100644 --- a/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingOptions.cs +++ b/src/Common/CSharp/Analysis/ReduceIfNesting/ReduceIfNestingOptions.cs @@ -12,4 +12,5 @@ internal enum ReduceIfNestingOptions AllowIfInsideIfElse = 1 << 1, AllowLoop = 1 << 2, AllowSwitchSection = 1 << 3, + AllowLastIf = 1 << 4, } diff --git a/src/Refactorings/CSharp/Refactorings/IfStatementRefactoring.cs b/src/Refactorings/CSharp/Refactorings/IfStatementRefactoring.cs index 0dc3894886..81cabe56f5 100644 --- a/src/Refactorings/CSharp/Refactorings/IfStatementRefactoring.cs +++ b/src/Refactorings/CSharp/Refactorings/IfStatementRefactoring.cs @@ -137,7 +137,8 @@ public static async Task ComputeRefactoringsAsync(RefactoringContext context, If options: ReduceIfNestingOptions.AllowNestedFix | ReduceIfNestingOptions.AllowIfInsideIfElse | ReduceIfNestingOptions.AllowLoop - | ReduceIfNestingOptions.AllowSwitchSection, + | ReduceIfNestingOptions.AllowSwitchSection + | ReduceIfNestingOptions.AllowLastIf, cancellationToken: context.CancellationToken); if (analysis.Success) diff --git a/src/Tests/Analyzers.Tests/RCS1208ReduceIfNestingTests.cs b/src/Tests/Analyzers.Tests/RCS1208ReduceIfNestingTests.cs index ef0f749ead..4ebe2107aa 100644 --- a/src/Tests/Analyzers.Tests/RCS1208ReduceIfNestingTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1208ReduceIfNestingTests.cs @@ -15,12 +15,12 @@ public class RCS1208ReduceIfNestingTests : AbstractCSharpDiagnosticVerifier { - [|if|] (p) + if (p) { M2(); } @@ -209,40 +169,20 @@ void M2() { } } -", @" -class C -{ - void M(bool p) - { - var f = () => - { - if (!p) - { - return; - } - - M2(); - }; - } - - void M2() - { - } -} "); } [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] public async Task Test_WhenParentIsLocalFunction() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { void M(bool p) { void M3() { - [|if|] (p) + if (p) { M2(); } @@ -254,39 +194,18 @@ void M2() { } } -", @" -class C -{ - void M(bool p) - { - void M3() - { - if (!p) - { - return; - } - - M2(); - } - M3(); - } - - void M2() - { - } -} "); } [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] public async Task Test_WhenParentIsMethod() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { void M(bool p) { - [|if|] (p) + if (p) { M2(); } @@ -296,23 +215,6 @@ void M2() { } } -", @" -class C -{ - void M(bool p) - { - if (!p) - { - return; - } - - M2(); - } - - void M2() - { - } -} "); } @@ -346,12 +248,12 @@ void M2() [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] public async Task Test_InvertingCoalesceToFalse() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { void M(bool? p) { - [|if|] (p??false) + if (p??false) { M2(); } @@ -361,35 +263,18 @@ void M2() { } } -", @" -class C -{ - void M(bool? p) - { - if (p != true) - { - return; - } - - M2(); - } - - void M2() - { - } -} "); } [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] public async Task Test_InvertingCoalesceToTrue() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { void M(bool? p) { - [|if|] (p??true) + if (p??true) { M2(); } @@ -399,36 +284,19 @@ void M2() { } } -", @" -class C -{ - void M(bool? p) - { - if (p == false) - { - return; - } - - M2(); - } - - void M2() - { - } -} "); } [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] public async Task Test_InvertingCoalesceToUnknown() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { bool b { get; set; } void M(bool? p) { - [|if|] (p??b) + if (p??b) { M2(); } @@ -437,23 +305,6 @@ void M2() { } } -", @" -class C -{ - bool b { get; set; } - void M(bool? p) - { - if (!(p ?? b)) - { - return; - } - - M2(); - } - void M2() - { - } -} "); } @@ -668,14 +519,14 @@ void M2() } [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] - public async Task Test_WhenIsExpressionCsharp8() + public async Task Test_WhenIsExpressionCSharp8() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { void M(object o) { - [|if|] (o is string) + if (o is string) { M2(); } @@ -685,35 +536,18 @@ void M2() { } } -", @" -class C -{ - void M(object o) - { - if (!(o is string)) - { - return; - } - - M2(); - } - - void M2() - { - } -} ", options: WellKnownCSharpTestOptions.Default_CSharp8); } [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] public async Task Test_WhenIsExpression() { - await VerifyDiagnosticAndFixAsync(@" + await VerifyNoDiagnosticAsync(@" class C { void M(object o) { - [|if|] (o is string) + if (o is string) { M2(); } @@ -723,23 +557,23 @@ void M2() { } } -", @" +"); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.ReduceIfNesting)] + public async Task TestNoDiagnostic() + { + await VerifyNoDiagnosticAsync(""" class C { - void M(object o) + private void Foo(string bar, int baz) { - if (o is not string) + if (bar == "bar" && baz == 123) { - return; + var foo = "baz"; } - - M2(); - } - - void M2() - { } } -"); +"""); } }